从传统GPIO开发开始
使用过STM32的人都知道,一个要使用一个GPIO口需要先配置某个PIN的复用功能,速度,上下拉等电气属性,然后在设置PIN所对应的GPIO。这个过程一般由程序员阅读芯片手册然后根据对寄存器的操作去控制这些因素。由于大多数32位SOC的引脚设置都基本是这两个方面,因此Linux封装了两个子系统,分别是Pinctrl和Gpio子系统
GPIO子系统和Pinctrl子系统的关系
Pinctrl子系统的作用,正如它全称所表明的那样:Pin Control,引脚控制器。 对于板子上的引脚,pinctrl 子系统主要工作内容如下: ①、获取设备树中 pin 信息。 ②、根据获取到的 pin 信息来设置 pin 的复用功能 ③、根据获取到的 pin 信息来设置 pin 的电气特性,比如上/下拉、速度、驱动能力等。 一组引脚的功能可能是复用作IIC或者SPI等,其中一种选择就是GPIO功能,当它们作为GPIO使用时,GPIO子系统就开始作用起来。由他来控制这些引脚的设置,是输入还是输出,如果是输出是输出高还是输出低 其工作方式类似与下图: 从左到右,左边是实际引脚。通过pinctrl子系统来决定他们的电气特性,分组(group)并设定功能(function)。图中画出的选择有GPIO I2C SPI三种功能,如果选择设置为GPIO,此时就由GPIO子系统开始接管对这组引脚的控制。
Pinctrl在设备树中的表示
Pinctrl是软件上的一种概念,他应该分为两个部分,类似互联网技术中服务端和客户端的意思 服务端对应的就是: pin controller 客户端对应的是: client device
Pin controller就是选择的服务提供商,负责将引脚分组,设置功能,以供client选择。Pin Controller作为提供方其描述一般写在.dtsi 中 一般以下图的格式描述自己所提供的服务: 其中: ts,pins 用于描述这组(groups)服务所包含的引脚,这里只测试一个PK7的引脚,如果需要更多引脚 可以在尖括号内追加 使用空格隔开 mux,val 所代表的是你想设置的功能(functions),这里的选择由不同的公司所设计而决定。 具体细节查询路径:/Documentation/devicetree/bindings/pinctrl 下厂家提供的binding文件
此处所选中的语句就是对mux,val 的值的解释,说明这其中有0到3的选项可以选择。 根据我对手上的表格的查询: 最左边是引脚,右边对应的0就是default所对应的功能,其功能号码从0~3可选 每个引脚,0~3所对应的功能和其他引脚都是不同的。 服务商的dts语法格式,每个芯片厂商的写法都是不太一样的,但是虽然写法不一,在程序中所实现的解析dts中引脚信息的函数所做的事情都是差不多的,都是根据of函数获取到设备树中的节点信息,以此来作为pin controller的设置依据。服务商提供了选择后,在dts文件中就可以使用这些选择了。在这张图中,左边就是对信息的Pinctrl声明,而右边是设备在引用所需使用的引脚信息。gpio 子系统的主要目的就是方便驱动开发者使用 gpio,驱动开发者在设备树中添加 gpio 相关信息,然后就可以在驱动程序中使用 gpio 子系统提供的 API函数来操作GPIO, Linux 内核向驱动开发者屏蔽掉了 GPIO 的设置过程,极大的方便了驱动开发者使用 GPIO。 pinctrl配置好以后就是设置GPIO了,假设我们需要一个引脚作为检测设备插入的引脚 我们需要让设备驱动程序知道需要去检测哪一个引脚,这就需要在设备树上提前写好:在设备数中 的xx设备节点下添加一个属性来描述检测引脚就可以了。驱动程序直接读取这个属性值就知道检测功能用的是哪个引脚了。
韦东山 https://blog.csdn.net/thisway_diy/article/details/119910335 https://cloud.tencent.com/developer/article/1709010
正点原子的开发手册
风雨兼程 https://blog.csdn.net/yangguoyu8023/article/details/122329717
Hello Cruel World https://www.cnblogs.com/hutiann/p/7780185.html#:~:text=gpio-ranges
XiaoBaWu https://blog.csdn.net/qq_28992301/article/details/53321610
https://blog.csdn.net/qq_26093511/article/details/88413324
|