pinctrl和gpio子系统

简介: pinctrl和gpio子系统

前言

原始字符设备驱动,patform框架,设备树这三种方法来点亮led灯的原理都是配置gpio寄存器。但在实际开发中,需要用到的引脚非常多。都是用前面讲到的方法不显示,麻烦。实际开发中我们常用pinctrl和gpio子系统来进行GPIO驱动开发。


一、pinctrl子系统

传统的配置 pin 的方式就是直接操作相应的寄存器,但是这种配置方式比较繁琐、而且容易出问题(比如 pin 功能冲突)。而pinctrl子系统就是为了解决这种问题而引入的,pinctrl子系统的主要工作内容:

1.获取设备树中pin的信息

2.依据获取到的pin信息设置pin的复用功能

3.依据获取到的pin信息设置pin的电气属性。

使用时我们只需要在设备树里面设置好某个 pin 的相关属性即可,其他的初始化工作均由 pinctrl 子系统来完成。例如:

&iomuxc {
  pinctrl-names = "default";
  pinctrl-0 = <&pinctrl_hog_1>;
  imx6ul-evk {
     pinctrl_led: ledgrp {
       fsl,pins = <
         MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */
       >;
     };

搜索“pinctrl_led”就会找到 pin引脚的gpio设置:

gpioled {
     #address-cells = <1>;
     #size-cells = <1>;
     compatible = "atkalpha-gpioled";
     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_led>;
     led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
     status = "okay";
   };

注意:pinctrl_led节点和gpioled 节点是我自己添加上去的,不是原来就有的。

我们先说明pinctrl子系统。gpio1_3在这里我们用来点亮led灯:

MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 

这是一个宏定义,在arch/arm/boot/dts/imx6ul-pinfunc.h中可以找到:

#define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03                          0x0068 0x02F4 0x0000 0x5 0x0

后面跟着5个数字,为该宏定义的具体值。

<mux_reg conf_reg input_reg mux_mode input_val>

0x0068 :mux_reg 寄存器偏移地址,设备树中的 iomuxc 节点就是 IOMUXC 外设对应的节点 , 根 据 其 reg 属 性 可 知 IOMUXC 外 设 寄 存 器 起 始 地 址 为 0x020e0000 。 因 此0x020e0000+0x0068 =0x020e0068, MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 寄存器地址正 好 是 0x020e0068,

0x020e0000+mux_reg 就是 PIN 的复用寄存器地址。

0x02F4 : conf_reg 寄存器偏移地址,和 mux_reg 一样, 0x020e0000+0x02F4 =0x020e02F4c,这个就是寄存器 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的地址。

0x0000: input_reg 寄存器偏移地址,有些外设有 input_reg 寄存器,有 input_reg 寄存器的外设需要配置 input_reg 寄存器。没有的话就不需要设置, GPIO1_IO03这个 PIN 在做GPIO1_IO03的时候是没有 input_reg 寄存器,因此这里 intput_reg 是无效的。

0x5 : mux_reg 寄 存 器 值 , 在 这 里 就 相 当 于 设 置MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 寄存器为 0x5,也即是设置 GPIO1_IO03这个 PIN 复用为 GPIO1_IO03。

0x0: input_reg 寄存器值,在这里无效。至于pin引脚的电气属性,由我们自行设置:

MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */

0x10B0 设置的就是 conf_reg 寄存器值,在这里就相当于设置寄存器MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 的值为 0x10B0 。

二、gpio子系统

pinctrl 子系统重点是设置 PIN(有的 SOC 叫做 PAD)的复用和电气属性,如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话,那么接下来就要用到 gpio 子系统,gpio 子系统就是用于初始化 GPIO 并且提供相应的 API 函数,比如设置 GPIO为输入输出,读取 GPIO 的值等。

gpioled {
     #address-cells = <1>;
     #size-cells = <1>;
     compatible = "atkalpha-gpioled";
     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_led>;
     led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
     status = "okay";
   };

pinctrl-0 属性设置 LED 灯所使用的 PIN 对应的 pinctrl 节点。led-gpio 属性指定了 LED 灯所使用的 GPIO,在这里就是 GPIO1 的 IO03,低电平有效。稍后编写驱动程序的时候会获取 led-gpio 属性的内容来得到 GPIO 编号,因为 gpio 子系统的 API 操作函数需要 GPIO 编号。

三、pinctrl与gpio子系统的使用

pinctrl使用模板

1、创建对应的节点

同一个外设的 PIN 都放到一个节点里面,打开 imx6ull-alientek-emmc.dts,在 iomuxc 节点中的“imx6ul-evk”子节点下添加“pinctrl_test”节点,注意!节点前缀一定要为“pinctrl_”。添加完成以后如下所示:

pinctrl_test: testgrp {
 /* 具体的 PIN 信息 */
 };

2、添加“fsl,pins”属性

设备树是通过属性来保存信息的,因此我们需要添加一个属性,属性名字一定要为“fsl,pins”,因为对于 I.MX 系列 SOC 而言, pinctrl 驱动程序是通过读取“fsl,pins”属性值来获取 PIN 的配置信息,完成以后如下所示:

pinctrl_test: testgrp {
 fsl,pins = <
 /* 设备所使用的 PIN 配置信息 */
 >;
 };

3、在“fsl,pins”属性中添加 PIN 配置信息

最后在“fsl,pins”属性中添加具体的 PIN 配置信息,完成以后如下所示:

pinctrl_test: testgrp {
 fsl,pins = <
 MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 config /*config 是具体设置值*/
 >;

gpio模板

1、创建 test 设备节点

在根节点“/”下创建 test 设备子节点,如下所示:

test {
 /*节点内容*/
 };

2、添加 pinctrl 信息

在 前面中我们创建了 pinctrl_test 节点,此节点描述了 test 设备所使用的 GPIO1_IO00 这个 PIN 的信息,我们要将这节点添加到 test 设备节点中,如下所示:

test {
 pinctrl-names = "default";
 pinctrl-0 = <&pinctrl_test>;
 /* 其他节点内容 */
 };

添加 pinctrl-names 属性,此属性描述 pinctrl 名字为“default”。

添加 pinctrl-0 节点,此节点引用 前面中创建的 pinctrl_test 节点,表示 tset 设备的所使用的 PIN 信息保存在 pinctrl_test 节点中。

3、添加 GPIO 属性信息

我们最后需要在 test 节点中添加 GPIO 属性信息,表明 test 所使用的 GPIO 是哪个引脚,添加完成以后如下所示:

test {
 pinctrl-names = "default";
 pinctrl-0 = <&pinctrl_test>;
 gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
 };

pinctrl与gpio子系统内核实现





目录
相关文章
|
SQL Java Shell
OBCP实践 - OceanBase 执行计划
在OceanBase数据库管理系统中,执行计划(Execution Plan)是数据库优化器基于SQL查询语句生成的一种逻辑表示,它详细说明了数据库如何执行SQL查询,包括选择合适的索引、连接顺序、临时数据处理方式、排序算法等一系列操作步骤,最终目的是为了最有效地获取所需数据并返回给客户端。
415 0
|
SQL 分布式计算 MaxCompute
PyODPS实现MaxComputer表数据把控
该脚本的最初设计目标是根据ODPS表中的不同二级分区,统计每个字段的详细量级,以便为下游用户提供数据支持。这有助于对中台数据资产进行有效管理,并能够及时关注上游数据质量问题。
1080 0
|
Linux
如何在 Linux 中创建带有特殊字符的文件?
如何在 Linux 中创建带有特殊字符的文件?
280 0
|
Linux API 芯片
Linux GPIO 和 Pinctrl 子系统的使用(十四)
Linux GPIO 和 Pinctrl 子系统的使用(十四)
442 1
|
安全 前端开发 数据挖掘
电子商务平台的构建与优化:技术与策略的深度融合
【6月更文挑战第23天】构建电子商务平台涉及需求分析、技术选型、架构设计、功能实现及测试部署,而优化则聚焦用户体验、性能、安全和SEO。用户体验优化包括界面布局和交互设计,性能优化涉及代码和数据库优化,安全优化需保障数据传输和防御网络攻击。SEO和移动端优化提升可见性和便捷性,数据分析驱动策略调整,以增强平台竞争力。
|
人工智能 缓存 搜索推荐
百度/Bing/Google搜索引擎使用技巧
本文分享了百度、Bing和Google三大搜索引擎的实用技巧,涵盖精确匹配、排除关键词、站内及文件类型搜索等,如使用双引号进行精确搜索“人工智能应用”,排除特定词如“人工智能 -游戏”,以及在特定网站如“site:baidu.com 人工智能”内查找内容等,帮助提高搜索效率和准确性。
百度/Bing/Google搜索引擎使用技巧
|
9月前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
本文源自2024云栖大会苏雅诗的演讲,探讨了K8s集群业务为何需要灾备及其重要性。文中强调了集群与业务高可用配置对稳定性的重要性,并指出人为误操作等风险,建议实施周期性和特定情况下的灾备措施。针对容器化业务,提出了灾备的新特性与需求,包括工作负载为核心、云资源信息的备份,以及有状态应用的数据保护。介绍了ACK推出的备份中心解决方案,支持命名空间、标签、资源类型等维度的备份,并具备存储卷数据保护功能,能够满足GitOps流程企业的特定需求。此外,还详细描述了备份中心的使用流程、控制台展示、灾备难点及解决方案等内容,展示了备份中心如何有效应对K8s集群资源和存储卷数据的灾备挑战。
|
安全 网络安全 数据安全/隐私保护
网络攻防演练需要注意哪些
【8月更文挑战第14天】
468 1
|
存储 缓存 数据管理
深入理解Linux内核I/O机制:探索文件系统与设备驱动(上)
深入理解Linux内核I/O机制:探索文件系统与设备驱动
|
存储 机器学习/深度学习 物联网
云计算的物联网应用:智能化转型的关键
本文探讨了物联网(IoT)与云计算的结合及其在数据处理中的应用。物联网通过连接设备进行数据交换,而云计算提供资源处理和存储。核心概念包括物联网的无线通信、传感、微控制器及数据技术,以及云计算的虚拟化、分布式计算、存储和网络技术。两者协同工作,云计算助力物联网处理大量数据,实现高效分析。文章还介绍了数据预处理、分析(如统计学、机器学习、深度学习)和应用的算法,以及数据应用的实例,展示了如何在智能家居系统中运用这些方法。未来,面对大数据、安全与隐私、实时性及边缘计算的挑战,物联网与云计算将继续发展。
1965 2