前言:
为什么要有pinctrl和gpio子系统呢?--->>>因为LZ不在想推着凯迪拉克其上班了。
1.pinctrl子系统:
因为 ST 针对 STM32MP1 提供的 Linux 系统中,其 pinctrl 配置的电气属性只能在platform 平台下被引用,前面的实验都没用到 platform,所以 pinctrl 配置是不起作用的!
L内核针对系统PIN的配置,如复用功能、速度、上下拉和驱动力等。
在“stm32mp151.dtsi”中有如下代码:
对于STM32MP1来说,其中 PA~PK 这 9 组 GPIO 的寄存器都在一起,起始地址为0X50002000,终止地址为0X5000C3FF。这个可以在《STM32MP157 参考手册》里面找到。PZ 组寄存器起始地址为0X54004000,终止地址为 0X540043FF,所以 stm32mp151.dtsi 文件里面还有个名为“pinctrl_z”的子节点来描述 PZ 组 IO。pinctrl 节点用来描述 PA~PK 这 11 组 IO,因此 ranges 属性中的0x50002000 表示起始地址,0xa400 表示寄存器地址范围。
pinctrl子系统中子节点的存放的引脚外设信息:
(1)pinmux属性:pinmux = <STM32_PINMUX(port, line, mode)>;
例如:pinmux = <STM32_PINMUX('H', 13, AF9)>;
port:表示用那一组 GPIO(例:H 表示为 GPIO 第 H 组,也就是 GPIOH)。
line:表示这组 GPIO 的第几个引脚(例:13 表示为 GPIOH_13,也就是 PH13)。
mode:表示当前引脚要做那种复用功能。
(2)电气特性:互斥分组3-2-2-1。
设备树里同一个PIN被被多个外设定义了:PH13 做了 FDCAN1 的 TX 功能,还能做 UART4 的 TX 功能,不是冲突了吗?这是不会冲突的,因为 pinctrl 驱动只会把设备树 pinctrl 节点解析出来的数据存储到一个链表里,只有当外设调用这个 pinctrl 节点的时候才会真的使用。但是,如果你要同时使用 FDCAN1 和 UART4 的话就会出问题,因此 PH13 同一时间只能用于一个外设,所以为了方便开发,还是建议大家一个 PIN 最好只能被一个外设使用。
如何添加一个pinctrl节点:(在&pinctrl节点追加gpio-led子节点)、(打开 stm32mp15-pinctrl.dtsi 文件,STM32MP1 的所有引脚 pinctrl 配置都是在这个文件里面完成的)。
2.gpio子系统:
(如果pinctrl将一个PIN复用为GPIO的话,那么就会用到gpio子系统了。)
L内核针对GPIO的电气属性配置,如复用输入/输出的方向和状态等。
int gpio_request(unsigned gpio, const char *label) | |
void gpio_free(unsigned gpio) | |
int gpio_direction_input(unsigned gpio) | |
int gpio_direction_output(unsigned gpio, int value) | |
#define gpio_get_value __gpio_get_value int __gpio_get_value(unsigned gpio) | |
#define gpio_set_value __gpio_set_value void __gpio_set_value(unsigned gpio, int value) | |
如何添加一个gpio节点:(在stm32mp157d-atk.dts文件的根节点“/”下创建LED灯的gpio子节点)
其中“GPIO_ACTIVE_LOW”是枚举类型,如下:可做或运算组合。