)
1、触发器使得LED闪烁有些开发板的 LED 会硬件层面被配置成呼吸灯或心跳灯通过 PWM 或定时器直接驱动 GPIO不需要任何用户程序。即使你kill掉所有进程它还是会闪。你可以查看 LED 的触发器状态bashcat /sys/class/leds/rgb-led-r/trigger cat /sys/class/leds/rgb-led-g/trigger cat /sys/class/leds/rgb-led-b/trigger如果输出里有heartbeat或timer说明 LED 被内核的 LED 触发器控制着所以一直在闪烁。rootRK356X:/# cat /sys/class/leds/rgb-led-r/trigger none rfkill-any rfkill-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 mmc2 mmc0 [timer] rfkill0 mmc1 rfkill1 rfkill22、内核已经注册好了 LED 设备可以直接操作。当你执行ls /sys/class/leds/看到下面这行时rgb-led-b rgb-led-g rgb-led-r这就代表内核已经成功注册了 LED 设备。它干了三件事识别了硬件内核知道 GPIO 40、41、42 这三个引脚上接着 LED。创建了标准接口在/sys/class/leds/下为你创建了三个“控制面板”目录里面包含brightness和trigger等文件。提供了操作方法你往这些文件里写1或0内核驱动就会自动去翻转 GPIO 引脚的电平点亮或熄灭 LED。你完全不需要关心 GPIO 编号是怎么计算的比如 GPIO1_B0 对应 40也不需要用echo 40 export手动去申请这个引脚——因为内核已经帮你把这一切都做好了。 对比一下“没注册”是什么感觉如果你把 LED 接在一个内核不认识的 GPIO 引脚上比如某个空闲的引脚那就没有注册这回事。你需要做的流程是用echo 100 /sys/class/gpio/export手动申请。用echo out direction设置方向。再用echo 1 value控制电平。而现在因为内核“注册”了它前两步都给你省了直接跳到第三步甚至能用none和timer这种高级模式。分别实现点亮和关闭led的命令可以看到led返回值3、实现led交通闪烁#include stdio.h #include stdlib.h #include string.h #include unistd.h #define LED_RED /sys/class/leds/rgb-led-r #define LED_GREEN /sys/class/leds/rgb-led-g #define LED_BLUE /sys/class/leds/rgb-led-b void disable_trigger(const char *led_path); void set_led(const char *led_path, int on); void write_file(const char *path, const char *value); int main(void) { int i; const char *leds[] {LED_RED, LED_GREEN, LED_BLUE}; const char *colors[] {红色, 绿色, 蓝色}; printf(RGB LED 流水灯启动按 CtrlC 停止。\n); // 先禁用所有 LED 的触发器停止闪烁 for (i 0; i 3; i) { disable_trigger(leds[i]); set_led(leds[i], 0); // 先全部熄灭 } while (1) { for (i 0; i 3; i) { // 点亮当前 LED set_led(leds[i], 1); printf(点亮 %s LED\n, colors[i]); // 熄灭其他两个 LED int j; for (j 0; j 3; j) { if (j ! i) { set_led(leds[j], 0); } } usleep(500000); // 延时 500ms } } return 0; } // 设置 LED 触发器为 none停止自动闪烁 void disable_trigger(const char *led_path) { char path[256]; snprintf(path, sizeof(path), %s/trigger, led_path); write_file(path, none); } // 设置 LED 亮灭 void set_led(const char *led_path, int on) { char path[256]; snprintf(path, sizeof(path), %s/brightness, led_path); write_file(path, on ? 1 : 0); } // 写入文件函数 void write_file(const char *path, const char *value) { FILE *fp fopen(path, w); if (fp NULL) { perror(fopen); return; } fprintf(fp, %s, value); fclose(fp); }