裸机开发时,如果要点亮一个 LED,我们要做如下内容:
有了设备树以后,我们可以通过 pinctrl 和 gpio 子系统来配置上述内容。
pinctrl 子系统用于配置复用为不同功能时的电气属性,这就需要找到一个名为 iomuxc 的节点,这个节点会在两个地方出现:一个是通用 dtsi 设备树文件(如 imx6ull.dtsi),一个是板级设备对应的 dts 文件(如imx6ull-alientek-emmc.dts)。
在 imx6ull.dtsi 中定义了一个 iomuxc 通用节点,该节点包含了 iomuxc 控制器的基地址,一般用于控制引脚复用。但光从这里似乎看不出来,可以复用为哪些外设,不同板级设备的外设不一样,所以外设相关的具体内容不会放在这里。
注意:IOMUXC 除了 iomuxc 外,还包含 iomuxc_snvs、gpr
具体的外设节点会放到对应板级设备的 .dts 文件中。&iomuxc 会找到通用节点中的 iomuxc,然后实际编译的时候会将两者的内容合并。后续将在这里为不同功能对应的引脚配置电气属性。
首先在板级设备的 dts 文件中找到 &iomuxc,这里板级设备对应的 dts 文件是 imx6ull-alientek-emmc.dts。我们在 imx6ul-evk 下创建一个节点,在其他地方我们将以 " &别名 " 的方式引用节点。
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
// "别名:节点名 {}" 的格式目的是为了在其他地方通过别名引用这个节点
// "节点名 {}" 的格式目的仅仅只是为了描述一些信息,无法在其他地方引用
pinctrl_gpiotest: testgrp {
// ...
};
}
}
配置属性解析
接下来我们要添加的属性名为 "fsl,pins" 。以 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 为例,MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 是一个属性名,也是宏定义,定义在 xxx-pinfunc.h 文件中(这里是 imx6ul-pinfunc.h),而 0x17059 是属性值。
可以在 imx6ul-pinfunc.h 文件中找到 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 的宏定义,可以看到宏定义的内容分为了五部分:
#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031C 0x0000 0x5 0x0
宏定义各个字段 | 宏定义各个字段的值 | 代表含义 |
0x0090 | IOMUXC_SW_MUX_CTL 寄存器的偏移量 | |
0x031C | IOMUXC_SW_PAD_CTL 寄存器的偏移量 | |
0x0000 | input_reg 寄存器(若无该寄存器,默认为 0x0) | |
0x5 | IOMUXC_SW_MUX_CTL 寄存器的值 (即选择复用为哪个功能) |
|
0x0 | input_reg 寄存器的值 |
添加复用引脚配置属性
现在我们要复用为 GPIO1_IO03,因此需要在 imx6ul-pinfunc.h 文件中找到与 GPIO1_IO03 结尾的宏定义。赋予的电气属性值为 0x10b0。
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
pinctrl_gpiotest: testgrp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10b0 /* GPIO1_IO03 */
>;
};
}
}
要引用 pinctrl 节点主要用到 pinctrl-names 属性和 pinctrl-x 属性。pinctrl-names 代表当前外设状态的名字,pinctrl-0 表示了当前状态下的配置方案。以下面这个为例
当然,一次可以根据状态不同,配置不同的方案,以下面这个为例:
我们在根节点下新增一个 gpio-led 节点,在该节点中引入 pinctrl 节点
gpio-led {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_leds>; // pinctrl_gpio_leds 是 iomuxc下添加的节点别名
status = "okay";
};
上面已经通过 pinctrl 子系统快速配置引脚复用,而gpio 子系统的主要目的是快捷设置 gpio 引脚的初始值(即初始状态为低电平还是高电平)
基本格式为:
属性名 = <&引脚组 引脚编号 初始状态>
假设要将 gpio1 的第 3 号引脚设置为低电平,具体写法为:
led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>
最终引入 pinctrl 子系统和 gpio 子系统的节点模板为
gpio-led {
pinctrl-names = "default"; // pinctrl 子系统
pinctrl-0 = <&pinctrl_gpio_leds>;
led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; // gpio 子系统
status = "okay";
};
其中 pinctrl_gpio_leds 的定义为:
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
pinctrl_gpiotest: testgrp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10b0 /* GPIO1_IO03 */
>;
};
}
}