本文总结了在 Luckfox Pico Mini 开发板上,通过 设备树(DTS)配置 PWM LED 外设 并通过内核提供的 sysfs 接口进行控制的完整流程。内容包含涉及的文件路径和具体配置示例,适合初学者理解设备树与 PWM LED 驱动的关系。


1. PWM 控制器节点

在 SoC 厂商提供的 DTS 文件 rv1106.dtsi 中,PWM 控制器已经定义如下:

pwm0: pwm@ff350000 {
    compatible = "rockchip,rv1106-pwm", "rockchip,rk3328-pwm";
    reg = <0xff350000 0x10>;
    interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
    #pwm-cells = <3>;
    pinctrl-names = "active";
    pinctrl-0 = <&pwm0m0_pins>;
    clocks = <&cru CLK_PWM0_PERI>, <&cru PCLK_PWM0_PERI>;
    clock-names = "pwm", "pclk";
    status = "disabled"; // 顶层 DTS 可以覆盖为 "okay"
};

配置说明

  • compatible:匹配 SoC 的 PWM 驱动
  • reg:PWM 控制器寄存器地址
  • #pwm-cells = <3>:描述 pwms 属性格式
  • pinctrl-0:对应 PWM 输出引脚
  • clocks / clock-names:时钟绑定
  • status = "disabled":顶层 DTS 中覆盖为 "okay" 可启用

2. LED 外设节点(pwm-leds)

在顶层 DTS 中添加 pwm_leds 节点,示例:

/ {
    model = "Luckfox Pico Mini";
    compatible = "rockchip,rv1103g-38x38-ipc-v10", "rockchip,rv1103";

    pwm_leds {
        compatible = "pwm-leds";

        pwm_user_led {
            label = "pwm-user-led";
            pwms = <&pwm0 0 1000000 0>;  // PWM0, 通道0, 周期1ms (1kHz), 占空比0
            max-brightness = <255>;
            linux,default-trigger = "none";
        };
    };
};

关键字段说明

  • compatible = "pwm-leds":指定 LED 驱动
  • pwms = <&pwm0 0 1000000 0><PWM控制器 通道 周期(ns) 占空比>
  • max-brightness:最大亮度值
  • linux,default-trigger:默认触发器,可选 "none", "heartbeat", "timer"

3. 编译 DTS 并更新内核

顶层 DTS 编译命令:

make dtbs
# 然后将生成的 dtb 文件替换到板子上
  • 编译完成后,重新启动开发板
  • 查看 sysfs 节点:
ls /sys/class/leds/
# 输出示例:
# pwm-user-led

4. 手动控制 LED

通过 sysfs 控制 LED 亮度:

# 设置亮度为一半
echo 128 > /sys/class/leds/pwm-user-led/brightness

# 设置全亮
echo 255 > /sys/class/leds/pwm-user-led/brightness

# 关闭 LED
echo 0 > /sys/class/leds/pwm-user-led/brightness
对于 PWM LED,brightness 会直接改变占空比。

5. Trigger 控制(可选)

查看可用 trigger:

cat /sys/class/leds/pwm-user-led/trigger

设置 trigger:

# heartbeat trigger(仅支持 invert 属性,周期不可调)
echo heartbeat > trigger
echo 1 > invert

# timer trigger(可设置 delay_on / delay_off 调整周期)
echo timer > trigger
echo 500 > delay_on
echo 500 > delay_off

注意事项

  • 一个 LED 同一时间只能有一个 trigger
  • heartbeat trigger 在你的 PWM LED 驱动下 仅提供 invert 属性,无法调整闪烁频率
  • timer trigger 可以自由设置高低电平持续时间
  • 平滑呼吸灯需要使用 用户空间脚本 调节 brightness,内核 trigger 默认不提供平滑曲线

6. 内核配置相关

相关配置影响 LED 驱动和 trigger 行为:

  • CONFIG_LEDS_PWM:使 PWM LED 驱动可用
  • CONFIG_LEDS_TRIGGER_PWM:允许 trigger 使用 PWM 占空比
  • CONFIG_LEDS_TRIGGER_TIMER:支持 timer trigger(可调周期)
  • CONFIG_LEDS_TRIGGER_HEARTBEAT:提供 heartbeat trigger
  • CONFIG_LEDS_TRIGGER_ACTIVITY:提供系统 I/O activity trigger

示例路径:

  • 内核默认配置:
    /home/mango/Luckfox/luckfox-pico/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_defconfig

7. 总结流程

  1. 确认 PWM 控制器节点,并在顶层 DTS 中启用
  2. 在 DTS 中定义 pwm-leds 外设
  3. 编译 DTS 并更新内核
  4. 查看 /sys/class/leds/ 下是否出现 LED
  5. 通过 brightness 或 trigger 控制 LED
  6. 如需平滑效果,可通过用户空间脚本控制 PWM 占空比

参考文件

  • sysdrv/source/kernel/arch/arm/boot/dts/rv1106.dtsi(SoC 厂商提供的 PWM 控制器定义)
  • 顶层 DTS( sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico-mini.dts
  • /sys/class/leds/pwm-user-led/(LED 控制 sysfs 接口)
  • 内核配置文件:
    luckfox-pico/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_defconfig

附:示例手动控制命令

# 设置 LED 半亮
echo 128 > /sys/class/leds/pwm-user-led/brightness

# 设置 heartbeat trigger 并反转逻辑
echo heartbeat > /sys/class/leds/pwm-user-led/trigger
echo 1 > /sys/class/leds/pwm-user-led/invert

# 设置 timer trigger 并控制周期
echo timer > /sys/class/leds/pwm-user-led/trigger
echo 500 > /sys/class/leds/pwm-user-led/delay_on
echo 500 > /sys/class/leds/pwm-user-led/delay_off

结论:通过 DTS 配置 PWM LED 节点,可以在内核启动时创建对应的 sysfs 接口,并通过 brightness 或 trigger 控制 LED。复杂的平滑呼吸或自定义闪烁周期可通过 timer trigger 或用户空间 PWM 脚本实现。

Last modification:November 3, 2025
If you think my article is useful to you, please feel free to appreciate