Firefly-RK3288 点亮LED灯
2025-03-23 19:28:34

点亮主板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/brightness

# 开灯
echo 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/trigger
echo 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>

// 定义LED触发器
DEFINE_LED_TRIGGER(ledtrig_ir_click);

// 注册该触发器
led_trigger_register_simple("ir-power-click", &ledtrig_ir_click);

// 控制 LED 的亮灭
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 中仅有的249250对应了两颗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
# 编译 kernel
./build.sh kernel

# 更新各部分镜像链接到 rockdev/ 目录
./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