GPIO 配置与使用¶
GPIO, 全称 General-Purpose Input/Output(通用输入输出),是一种软件运行期间能够动态配置和控制的通用引脚。
以下通过控制 ROC-RK3399-PC Pro 的 LED 为例,对于其他设备,方法是类似的。
ROC-RK3399-PC Pro 的主控是 RK3399,RK3399 有 5 组 GPIO bank:GPIO0~GPIO4,每组又以 A0~A7, B0~B7, C0~C7, D0~D7 作为编号区分。
GPIO 编号计算¶
ROC-RK3399-PC Pro 板载两个 LED,如下:
DIY_LED 网络是接到引脚 GPIO0_B5:
PIO pin 脚计算公式:
pin = bank * 32 + number
GPIO 小组编号计算公式:
number = group * 8 + X
例如 GPIO0_B5:
bank = 0; // GPIO0_B5 => 0, bank ∈ [0,4]
group = 1; // GPIO0_B5 => 1, group ∈ {(A=0), (B=1), (C=2), (D=3)}
X = 5; // GPIO0_B5 => 5, X ∈ [0,7]
number = group * 8 + X = 1 * 8 + 5 = 13;
pin = bank * 32 + number = 0 * 32 + 13 = 13;
注意:这个引脚在官方发布的固件中默认已被 LED 子系统占用,因此首先需要找到以下节点将其 disable!
ROC-RK3399-PC Pro 是定义在arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
:
user {
status = "disabled"; // 添加这一行
label = "firefly:yellow:user";
linux,default-trigger = "ir-user-click";
default-state = "off";
gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&led_user>;
};
然后编译与重新烧写内核固件。
用户态使用 GPIO¶
1、申请 GPIO
echo 13 > /sys/class/gpio/export
2、配置引脚方向
查看默认引脚方向:
cat /sys/class/gpio/gpio13/direction
配置成输出方向:
echo out > /sys/class/gpio/gpio13/direction
3、配置引脚输出电平
从前面的原理图可知,输出高电平为点亮 LED:
echo 1 > /sys/class/gpio/gpio13/value
熄灭 LED:
echo 0 > /sys/class/gpio/gpio13/value
设备树使用 GPIO¶
在设备树中配置 GPIO,需要配置引脚的功能复用与电气属性
对于 rockchip 引脚,配置如下:
rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>
其中:
PIN_BANK
:引脚所在的 bankPIN_BANK_IDX
:引脚所在 bank 的引脚号MUX
:功能复用配置,0
表示普通 GPIO,1-N
表示特殊的功能复用phandle
:引脚一般配置,例如内部上拉、电流强度等,在Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
文件中描述
配置 GPIO0_B5 引脚:
rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_pull_none>;
此处的含义:
PIN_BANK
等于0
PIN_BANK_IDX
等于13
RK_FUNC_GPIO
代表使用普通 GPIO 功能pcfg_pull_none
代表普通配置
对于 LED,Linux 定义了一套 GPIO 子系统,设备树的配置如下:
/ {
gpio_led: gpio-led {
compatible = "gpio-leds";
diy_led: diy-led {
label = "diy-led";
default-state = "on"; // 默认打开
linux,default-trigger = "default-on"; // 默认触发
gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; // 引脚设置
pinctrl-names = "default";
pinctrl-0 = <&diy_led_pin>; // 引用 pinctrl
};
};
};
&pinctrl {
gpio-led-pin {
diy_led_pin: diy-led-pin {
rockchip,pins =
<0 13 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
然后编译与重新烧写内核固件,重启系统会看到 LED 默认点亮。
如果希望 LED 具有闪烁效果,可以修改linux,default-trigger
属性实现:
linux,default-trigger = "timer";
配置该属性后,LED 默认每 500ms 间隔闪烁。
更多属性配置可以参考Documentation/devicetree/bindings/leds/leds-gpio.txt
。
以上设备树配置可以在arch/arm64/boot/dts/rockchip/firefly-gpio-demo.dtsi
找到!有需求的用户在板极设备树中包含该文件即可(记得要首先 disable rk3399-roc-pc.dtsi
里面冲突部分):
#include "firefly-gpio-demo.dtsi"