目录

目录

前言

DTS配置参考

LEDS_GPIO的DTS配置参考

LEDS_PWM的DTS配置参考

LEDS_GPADC的DTS配置参考

内核配置参考

 LEDS_GPIO的内核配置参考

 LEDS_PWM的内核配置参考

LEDS_GPADC的内核配置参考

验证测试参考

常见问题

配置了LED的Devicetree和Menuconfig是正确的但是LED控制打开后始终不亮

配置了LED的Devicetree和Menuconfig后发现LED控制打开后LED灯反而是灭的

总结


前言

LED指示灯,即发光二极管指示灯,是一种以发光二极管为核心光源的电子元件,主要用于显示设备或电路的工作状态。‌其核心作用是通过不同颜色和闪烁模式的灯光,直观反映设备的运行情况,例如电源供应、连接状态或信号传输等,从而便于用户快速判断设备是否正常工作或诊断故障。‌

Linux LED驱动开发主要涉及两种方式:一是编写自定义的字符设备驱动直接操作硬件寄存器;二是利用内核内置的LED子系统,通过设备树配置。

Linux内核原生已经支持LED驱动,其中内核文档路径为:linux-x.xx/Documentation/devicetree/bindings/leds,其描述了相应的设备树节点如何编写。

这里推荐使用‌Linux内核内置LED驱动,减少重复的工作。Linux内核提供基于platform框架的GPIO LED驱动(文件路径为:drivers/leds/leds-gpio.c)。


DTS配置参考

LEDS_GPIO的DTS配置参考

leds {
      compatible = "gpio-leds";

      timer_led {
            gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;
            label = "timer_led";
            linux,default-trigger = "timer";
            default-status = "on";
            status = "okay";

      };
};

LEDS_PWM的DTS配置参考

pwm-leds {
    compatible = "pwm-leds";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_pwm1>;

    pwm-led@1 {
        label = "pwmled";
        pwms = <&pwm 1 50000 1>;
        max-brightness = <255>;
        linux,default-trigger = "heartbeat";
    };
};

pinctrl: pinctrl@xxxxxxxx {
    pinctrl_pwm1: pwm1-grp {
        test,pins = "gpioc-1";
        test,pin-function = <6>;
        test,pin-pud = <ENABLE_PULL_UP>;
        test,pin-drv = <DRV_LEVEL3>;
    };
};

LEDS_GPADC的DTS配置参考
 

leds_gpadc {
    compatible = "gpadc-leds";

    ir_led {
        label = "ir_led";
        gpadc_channel = <1>;
        linux,default-trigger = "timer";
        default-state = "on";
        status = "okay";
    };
};

内核配置参考

 LEDS_GPIO的内核配置参考
 

CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y (触发器功能根据实际情况来打开)
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_ACTIVITY=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=y

 LEDS_PWM的内核配置参考
 

CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_PWM=y
CONFIG_LEDS_TRIGGERS=y (触发器功能根据实际情况来打开)
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_ACTIVITY=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=y

LEDS_GPADC的内核配置参考
 

CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPADC=y
CONFIG_LEDS_TRIGGERS=y(触发器功能根据实际情况来打开)
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_ACTIVITY=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_LEDS_TRIGGER_NETDEV=y

验证测试参考

1. 配置好LED相关的DTS和内核配置后,编译并烧录固件,主控板正常启动。

2. 验证LEDS_GPIO,输入操作命令并观察对应的LED的亮灭情况,例如:

# cat /sys/class/leds/timer_led/trigger (查看当前的触发器类型。)
   none [timer] oneshot mtd nand-disk heartbeat backlight gpio cpu cpu0 activity default-on transient flash torch panic netdev mmc0 mmc1

# echo heartbeat > /sys/class/leds/timer_led/trigger(改变触发器类型为心跳触发类型。)
# cat /sys/class/leds/timer_led/trigger (查看当前的触发器类型。)
   none timer oneshot mtd nand-disk [heartbeat] backlight gpio cpu cpu0 activity default-on transient flash torch panic netdev mmc0 mmc1

# echo timer > /sys/class/leds/timer_led/trigger(改变触发器类型为定时器触发类型。)
# cat /sys/class/leds/timer_led/trigger(查看当前的触发器类型。)
   none [timer] oneshot mtd nand-disk heartbeat backlight gpio cpu cpu0 activity default-on transient flash torch panic netdev mmc0 mmc1

# cat /sys/class/leds/timer_led/delay_on (查看当前定时器触发的亮灯延时时间。)
   500

# cat /sys/class/leds/timer_led/delay_off (查看当前定时器触发的灭灯延时时间。)
   500

# echo 3000 > /sys/class/leds/timer_led/delay_on(改变定时器触发的亮灯延时时间为3000ms。)
# cat /sys/class/leds/timer_led/delay_on(查看当前定时器触发的亮灯延时时间。)
   3000

# echo 3000 > /sys/class/leds/timer_led/delay_off(改变定时器触发的灭灯延时时间为3000ms。)
# cat /sys/class/leds/timer_led/delay_off(查看当前定时器触发的灭灯延时时间。)
   3000

3. 验证LEDS_PWM,输入操作命令并观察对应的LED的亮灭情况,例如:

# echo 2 > /sys/class/leds/pwmled/brightness
# echo 4 > /sys/class/leds/pwmled/brightness
# echo 12 > /sys/class/leds/pwmled/brightness
# echo 16 > /sys/class/leds/pwmled/brightness
# echo 20 > /sys/class/leds/pwmled/brightness
# echo 24 > /sys/class/leds/pwmled/brightness
# echo 28 > /sys/class/leds/pwmled/brightness

4. 验证LEDS_GPADC,输入操作命令并观察对应的LED的亮灭情况,例如:
 

 # cat /sys/class/leds/ir_led/trigger
   none [timer] oneshot mtd nand-disk heartbeat backlight gpio cpu cpu0 activity default-on transient flash torch panic netdev mmc0 mmc1

# cat /sys/class/leds/ir_led/delay_on
   500

# cat /sys/class/leds/ir_led/delay_off
   500

# echo 3000 > /sys/class/leds/ir_led/delay_off
# cat /sys/class/leds/ir_led/delay_off
   3000

# echo 3000 > /sys/class/leds/ir_led/delay_off
# cat /sys/class/leds/ir_led/delay_off
   3000

常见问题

配置了LED的Devicetree和Menuconfig是正确的但是LED控制打开后始终不亮

【问题现象】

调试的PCB板子或整机正常上电后,配置了LED的Devicetree和Menuconfig是正确的但是LED软件控制打开后始终不亮。

【解决方法】

下面以某个LED-红绿双色灯的电路原理图为例。
 

1. 可以先检查LED部分的电路是否正常。比如LED-R软件控制打开后始终不亮,可以先检查D11是否贴反或虚贴,然后再检查R778是否漏贴或虚贴,最后LED-R直接飞线
接地,查看D11的R灯是否可以正常亮。

2. LED部分的电路检查正常后,可以跑软件进行控制下LED(比如:LED-R)。
 

配置了LED的Devicetree和Menuconfig后发现LED控制打开后LED灯反而是灭的


【问题现象】

配置了LED的Devicetree和Menuconfig后发现LED控制打开后LED指示灯反而是灭的。

【解决方法】

1. 可以先检查DTS的LED部分配置是否正确。比如下面的LED节点配置中,“gpios = <&gpioc 18 1>”配置的led2实际上打开时GPIOC18置为低电平了,因为此时的GPIO_ACTIVE_LOW的值实际上就是1而不是0,GPIO_ACTIVE_HIGH的值实际上就是0而不是1,建议使“GPIO_ACTIVE_LOW”或“GPIO_ACTIVE_HIGH”来表示。

leds {
        compatible = "gpio-leds";

        led@0 {
                label = "led0";
                gpios = <&gpioc 14 GPIO_ACTIVE_LOW>;
                default-state = "on";
        ;

        led@1 {
                label = "led1";
                gpios = <&gpioc 15 GPIO_ACTIVE_LOW>;
                default-state = "on";
        };

        led@2 {
                label = "led2";
                gpios = <&gpioc 18 1>;
                default-state = "on";
        };
   };

2. 检查并正确修改DTS的LED部分配置后,跑软件进行控制LED(比如:led2),观察LED指示灯的亮灭情况。


总结

像 LED 这样非常基础的设备驱动,  Linux内核已经集成了。 Linux内核的LED驱动采用platform框架,因此我们只需按要求在设备树(DTS)文件中添加相应的 LED 节点配置即可。


Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐