点亮主板LED灯 Firefly-RK3288 主板上有两颗 LED 灯,在 OTG 接口附近,一颗黄色,一颗蓝色。蓝色灯在开机后会被点亮。 根据 Firefly-RK3288 的文档说明,这两颗 LED 是由 GPIO 控制的。
分别是:
GPIO8_A1
控制黄色灯。
GPIO8_A2
控制蓝色灯。
从官方源码仓库中搜索les
关键字发现其设备树定义在 kernel/arch/arm/boot/dts/rk3288-firefly-port.dtsi 文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 leds { compatible = "gpio-leds"; work { label = "firefly:blue:power"; linux,default-trigger = "ir-power-click"; gpios = <&gpio8 1 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&led_power>; default-state = "on"; }; user { label = "firefly:yellow:user"; linux,default-trigger = "ir-user-click"; gpios = <&gpio8 2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&led_user>; default-state = "off"; }; };
分别有两个名字:
firefly:blue:power
firefly:yellow:user
以设备的方式控制 LED 查看 LED 设备也能发现它们:
1 2 $ ls /sys/class/leds/ firefly:blue:power firefly:yellow:user
所以在用户层可以通过设备文件控制它:
1 2 3 4 5 echo 0 >/sys/class/leds/firefly:blue:power/brightnessecho 1 >/sys/class/leds/firefly:blue:power/brightness
用户还可以使用 cat 命令获取 trigger 的可用值:
1 2 $ cat /sys/class/leds/firefly:blue:power/trigger [none] kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock ir-power-click mmc0 mmc1 mmc2 timer oneshot default-on rfkill0 rfkill1 rfkill2
还可以通过 echo 向其 trigger 属性输入命令控制每一个 LED:
1 2 echo none >/sys/class/leds/firefly:blue:power/triggerecho default-on >/sys/class/leds/firefly:blue:power/trigger
在内核中操作 LED 这部分是复制官方的。
1 2 3 4 5 6 7 8 9 10 11 #include <linux/leds.h> DEFINE_LED_TRIGGER(ledtrig_ir_click); led_trigger_register_simple("ir-power-click" , &ledtrig_ir_click); led_trigger_event(ledtrig_ir_click, LED_FULL); led_trigger_event(ledtrig_ir_click, LED_OFF);
查找 GPIO 编号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 $ cat /sys/kernel/debug/gpio GPIOs 0-23, platform/pinctrl, gpio0: gpio-5 ( |GPIO Key Power ) in hi gpio-10 ( |hp_ctl_gpio ) out lo gpio-11 ( |vcc28_dvp ) out hi gpio-12 ( |vcc_otg_5v ) out hi gpio-14 ( |vcc_host_5v ) out hi GPIOs 24-55, platform/pinctrl, gpio1: GPIOs 56-87, platform/pinctrl, gpio2: GPIOs 88-119, platform/pinctrl, gpio3: GPIOs 120-151, platform/pinctrl, gpio4: gpio-127 ( |mdio-reset ) out hi gpio-139 ( |bt_default_rts ) in hi gpio-146 ( |bt_default_wake ) in hi gpio-148 ( |reset ) out hi gpio-149 ( |bt_default_reset ) out lo gpio-151 ( |bt_default_wake_host) in hi GPIOs 152-183, platform/pinctrl, gpio5: GPIOs 184-215, platform/pinctrl, gpio6: GPIOs 216-247, platform/pinctrl, gpio7: gpio-227 ( |vcc_sd ) out hi gpio-228 ( |dvdd_1v2 ) out lo gpio-231 ( |? ) in lo GPIOs 248-263, platform/pinctrl, gpio8: gpio-249 ( |? ) out hi gpio-250 ( |? ) out lo
显然,gpio8 中仅有的249
和250
对应了两颗LED灯。 尝试反复开关灯,检查后面是out lo
还是out hi
即可将编号对应起来,不过这属于“笨”办法。
官方文档中提供了GPIO编号的计算公式:
1 2 3 4 5 6 7 8 9 10 11 12 13 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;
但是要注意了,这个公式中假定了每组GPIO有32个引脚,然而GPIO0只有24个,GPIO8是16个,所以需要调整这个公式。 这点可以从/sys/kernel/debug/pinctrl/pinctrl/pins
中查看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 $ cat /sys/kernel/debug/pinctrl/pinctrl/pins registered pins: 264 pin 0 (gpio0-0) pin 1 (gpio0-1) pin 2 (gpio0-2) pin 3 (gpio0-3) pin 4 (gpio0-4) pin 5 (gpio0-5) pin 6 (gpio0-6) pin 7 (gpio0-7) pin 8 (gpio0-8) pin 9 (gpio0-9) pin 10 (gpio0-10) pin 11 (gpio0-11) pin 12 (gpio0-12) pin 13 (gpio0-13) pin 14 (gpio0-14) pin 15 (gpio0-15) pin 16 (gpio0-16) pin 17 (gpio0-17) pin 18 (gpio0-18) pin 19 (gpio0-19) pin 20 (gpio0-20) pin 21 (gpio0-21) pin 22 (gpio0-22) pin 23 (gpio0-23) ... pin 248 (gpio8-0) pin 249 (gpio8-1) pin 250 (gpio8-2) pin 251 (gpio8-3) pin 252 (gpio8-4) pin 253 (gpio8-5) pin 254 (gpio8-6) pin 255 (gpio8-7) pin 256 (gpio8-8) pin 257 (gpio8-9) pin 258 (gpio8-10) pin 259 (gpio8-11) pin 260 (gpio8-12) pin 261 (gpio8-13) pin 262 (gpio8-14) pin 263 (gpio8-15)
根据前面的返回结果:
1 2 3 GPIOs 248-263, platform/pinctrl, gpio8: gpio-249 ( |? ) out hi gpio-250 ( |? ) out lo
应该是:
GPIO8_A1
对应的是 248 + (0 * 8) + 1 = 249。
GPIO8_A2
对应的是 248 + (0 * 8) + 2 = 250。
用 GPIO 点亮自己的 LED 前面点亮的是主板上自带的 LED,如果想进一步,可以用 GPIO 口来点亮扩展的 LED。 首先查看主板说明,从扩展接口中找到一个没有使用的 GPIO: 我这里选择了图片中的第37个角,GPIO8_A7_U。
增加设备树 根据前面的经验,我们编辑文件/kernel/arch/arm/boot/dts/rk3288-firefly-port.dtsi
,在leds
下增加一个节点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 leds { compatible = "gpio-leds"; work { label = "firefly:blue:power"; linux,default-trigger = "ir-power-click"; gpios = <&gpio8 1 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&led_power>; default-state = "on"; }; user { label = "firefly:yellow:user"; linux,default-trigger = "ir-user-click"; gpios = <&gpio8 2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&led_user>; default-state = "off"; }; user2 { label = "firefly:blue:user2"; gpios = <&gpio8 7 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&led_user2>; default-state = "off"; }; };
从user
粘贴一份,将其配置为高电平有效,即GPIO_ACTIVE_HIGH
,因为我们将其用作电源输入,物理上接线是这样:
1 GPIO -> LED(+) -> LED(-) -> GND
然后向下翻到pinctrl
节点配置引脚:
1 2 3 4 5 6 7 8 9 10 11 12 13 leds { led_power: led-power { rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_none>; }; led_user: led-work { rockchip,pins = <8 2 RK_FUNC_GPIO &pcfg_pull_none>; }; led_user2: led-work2 { rockchip,pins = <8 7 RK_FUNC_GPIO &pcfg_pull_none>; }; };
重新编译内核
1 2 3 4 5 ./build.sh kernel ./mkfirmware.sh
刷入固件即可。
验证 1 2 3 4 5 6 7 firefly@firefly:~$ ll /sys/class/leds total 0 drwxr-xr-x 2 root root 0 Mar 23 19:09 ./ drwxr-xr-x 60 root root 0 Mar 23 19:08 ../ lrwxrwxrwx 1 root root 0 Mar 23 19:08 firefly:blue:power -> ../../devices/platform/leds/leds/firefly:blue:power/ lrwxrwxrwx 1 root root 0 Mar 23 19:08 firefly:blue:user2 -> ../../devices/platform/leds/leds/firefly:blue:user2/ lrwxrwxrwx 1 root root 0 Mar 23 19:08 firefly:yellow:user -> ../../devices/platform/leds/leds/firefly:yellow:user/
找到了 led,测试一下:
1 echo 1 >/sys/class/leds/firefly:blue:user2/brightness
成功点亮 万用表测了下电压为2.9V。
相关阅读 LED 使用 GPIO 使用 GPIO 配置与使用 设备树使用 GPIO Firefly-RK3288 硬件文档 Rockchip_RK3288_Datasheet_V2.7-20191227.pdf