04 Pincontrl子系统和GPIO子系统
Official Document
Documentation\devicetree\bindings\gpio\gpio.txt
Documentation\gpio\Pinctrl-bindings.txt
Documentation\devicetree\bindings\Pinctrl\Pinctrl-bindings.txt
修改示例
1. Pincontrol and GPIO Subsystem Synopsis
Pincontrol:是控制使用那些引脚复用为什么功能模块,怎么配置这个引脚。相当于IOMUX功能
GPIO Subsystem:是具体配置引脚的信息
使用方法:
指定节点的配置Pincontrol使用状态(status),Pincontrol状态(pinctrol-name),Pincontrol状态引用的GPIO Subsystem配置(pinctrl-x)
编写GIOP Subsystem配置信息
其中4、5、6步骤为GPIO Subsystem实现
2. GPIO Subsystem
关于GPIO Subsystem存在已下两个属性
gpio-controller;
#gpio-cells = <2>
gpio-controller
表示这个节点是GPIO Controller
#gpio-cells = <2>
则表示此控制器每个引脚需要2个32位的数来表示。常见用法为一个cell表示引脚,一个cell表示有效电平
GPIO_ACTIVE_HIGH : 高电平有效
GPIO_ACTIVE_LOW : 低电平有效
GPIO Controller的定义是原厂的工作,我们使用时使用[<name>-]gpios
去声明引脚就ok了
reset-gpios = <&gpio_spi 1 GPIO_ACTIVE_LOW>;
gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;
2.1 Linux中操作GIPO Subsystem
在驱动中存在两套操作GPIO子系统的接口:基于操作符(descriptor-base);老一套(legacy)
这里只使用基于操作符这一套
2.1.1 基于操作符(descriptor-base)
带有gpiod_
前缀,它使用gpio_desc
结构体表示一个引脚
头文件
#include <linux/gpio/consumer.h> // descriptor-based
常用函数
gpiod_get | 设备树节点中只存在单个引脚时使用 power-gpios = <&gpio 1 GPIO_ACTIVE_LOW>; |
---|---|
gpiod_get_index | 设备树节点中存在多个引脚时使用 led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, <&gpio 16 GPIO_ACTIVE_HIGH>, <&gpio 17 GPIO_ACTIVE_HIGH>; |
gpiod_get_array | |
devm_gpiod_get | 含有devm表示设备资源管理器。此类函数是一种自动释放资源的机制。当设备不存在时资源便会自动释放。使用devm申请内存时,如果失败可以直接返回。设备的销毁函数会自动释放已经申请的GPIO(推荐使用) |
devm_gpiod_get_index | |
devm_gpiod_get_array | |
gpiod_direction_input | |
gpiod_direction_output | |
gpiod_get_value | 此处获取值为逻辑值,并非实际值 |
gpiod_set_value | 此处设置值为逻辑值,并非实际值。生效值可以在设备树中进行调整。这样可以确保函数的适配性 |
gpiod_put | |
gpiod_put_array |
devm_gpiod_put | |
---|---|
devm_gpiod_put_array |
2.2 GPIO命令行操作
echo 111 > /sys/class/gpio/export # 创建相关的file
echo in > /sys/class/gpio/gpio111/direction # 设置方向为in还out
echo 1 > /sys/class/gpio/gpio111/value # 设置值
echo 111 > /sys/class/gpio/unexport # 删除相关文件
3. NXP的devicetree代码生成软件使用
NXP官方提供了一个软件Pins_Tool_for_i.MX_Processors_v6_x64.exe。可以帮助我们生成设备树代码
4.知识点扩展
-
dev_err,dev_info, dev_dbg
dev_err、dev_info、dev_dbg本质上还是printk。目前内核不建议直接使用printk。
dev_err、dev_info、dev_dbg支持打印模块信息,dev信息
支持动态调试
-
platform_driver中driver结构体的name就算不使用也需要初始化。
因为platform的match机制中首先去匹配platform_device中的driver_override与platform_driver中的name。然后才去匹配devicetree中的compatible