Linux应用-LED
基础
在Linux下控制LED硬件。涉及到了SYSFS文件系统 Linux中的SYSFS文件系统
-
设备树文件
可知,LED被注册为了sys-led的label
cleds { compatible = "gpio-leds"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio_leds &pinctrl_beep>; led1{ label = "sys-led"; gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; linux,default-trigger = "heartbeat"; default-state = "on"; }; beep{ label = "beep"; gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; default-state = "off"; }; };
在正点原子的I.MX6ULL的出厂系统中,将LED设备以系统内核自带的驱动进行加载,故在dev目录下没有对应的文件可以访问。要操控可以通过设置到/sys/class/leds 目录下的文件来进行操控
bash
root@ATK-IMX6U:/sys/class/leds/sys-led# ls
brightness device max_brightness power subsystem trigger uevent
重点关注以下三个文件
-
brightness: 可读可写的属性,用于设置当前的亮度。
-
max_brightness:只读文件,用于获取当前设备的最大亮度
-
trigger: 可读可写,用于设置触发模式。支持的属性有
bashroot@ATK-IMX6U:/sys/class/leds/sys-led# cat ./trigger none rc-feedback nand-disk mmc0 mmc1 timer oneshot [heartbeat] backlight gpio
因此,可以直接执行指令来修改led的sysfs文件,例如
bash
root@ATK-IMX6U:/sys/class/leds/sys-led# echo none > ./trigger
root@ATK-IMX6U:/sys/class/leds/sys-led# echo 1 > ./brightness
root@ATK-IMX6U:/sys/class/leds/sys-led# cat ./max_brightness
255
root@ATK-IMX6U:/sys/class/leds/sys-led# echo 0 > ./brightness
root@ATK-IMX6U:/sys/class/leds/sys-led#
程序控制
-
代码
c#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <stdbool.h> #define LED_Trigger "/sys/class/leds/sys-led/trigger" #define LED_Brightness "/sys/class/leds/sys-led/brightness" int main(int argc, char *argv[]) { int fd_trigger = -1, fd_brightness = -1; int ret = -1; //检查参数数量 if (argc != 3) { printf("错误用法:需要3个参数,但提供了%d个\n", argc); exit(-1); } bool isSetBrightness = false; //检查参数 if(strcmp(argv[1], "none") == 0){ isSetBrightness = true; } //打开文件 fd_trigger = open(LED_Trigger, O_RDWR); if(fd_trigger < 0) { perror("打开LED触发文件失败"); exit(-1); } fd_brightness = open(LED_Brightness, O_RDWR); if(fd_brightness < 0) { perror("打开LED亮度文件失败"); goto out1; } //设置LED触发模式 ret = write(fd_trigger, argv[1], strlen(argv[1])); if(ret < 0) { perror("写入LED触发模式失败"); goto out2; } if(ret != strlen(argv[1])) { fprintf(stderr, "Warning: Expected to write %zu bytes, but wrote %d bytes\n", strlen(argv[1]), ret); } if(isSetBrightness){ if(strcmp(argv[2], "1") == 0) { //设置LED亮度为1 ret = write(fd_brightness, "1", strlen("1")); } else if(strcmp(argv[2], "0") == 0) { //设置LED亮度为0 ret = write(fd_brightness, "0", strlen("0")); } else { printf("无效的亮度值。请使用'1'(开启)或'0'(关闭)。\n"); goto out2; } if(ret < 0) { perror("写入LED亮度失败"); goto out2; } if(ret != strlen(argv[2])) { fprintf(stderr, "警告:预期写入%zu字节,但实际写入%d字节\n", strlen(argv[2]), ret); } } printf("LED配置更新成功。\n"); out2: close(fd_brightness); out1: close(fd_trigger); return 0; } -
CMakeList.txt
cmakecmake_minimum_required(VERSION 3.10) project(led_control) # 设置C标准 set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) # 交叉编译配置 # ARM Cortex-A7 (armv7l) 架构 set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) # 交叉编译器配置 # 注意:在实际编译时,建议通过以下方式指定编译器: # cmake -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ .. # 或者设置环境变量:export CC=arm-linux-gnueabihf-gcc; export CXX=arm-linux-gnueabihf-g++ # 如果没有通过命令行指定编译器,则尝试默认路径 if(NOT DEFINED CMAKE_C_COMPILER) # 常见的ARM交叉编译器路径,可根据实际环境调整 find_program(CMAKE_C_COMPILER NAMES arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc-9 arm-linux-gnueabihf-gcc-10 PATHS /usr/bin /usr/local/bin /opt/toolchains ) endif() if(NOT DEFINED CMAKE_CXX_COMPILER) find_program(CMAKE_CXX_COMPILER NAMES arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++-9 arm-linux-gnueabihf-g++-10 PATHS /usr/bin /usr/local/bin /opt/toolchains ) endif() # 设置根文件系统路径(用于查找库和头文件) # 可通过 -DCMAKE_FIND_ROOT_PATH= 参数指定 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # ARM编译标志 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard") # 如果不需要硬浮点,可以用:-mfloat-abi=soft # 调试和优化标志(可选) # set(CMAKE_C_FLAGS_DEBUG "-g -O0") # set(CMAKE_C_FLAGS_RELEASE "-O2") # 启用详细编译输出(可选) # set(CMAKE_VERBOSE_MAKEFILE ON) message(STATUS "Build for: ${CMAKE_SYSTEM_PROCESSOR} (${CMAKE_SYSTEM_NAME})") message(STATUS "C compiler: ${CMAKE_C_COMPILER}") message(STATUS "C flags: ${CMAKE_C_FLAGS}") # 添加可执行文件 add_executable(led_control led.c) # 链接到必要的库(如果需要) # target_link_libraries(led_control m) # 数学库 -
cmake指令
bashcd /home/joe/Code/Embeed/ApplicationDevelop/MyImplement/Hardware/LED/build && cmake -DCMAKE_C_COMPILER=/ │ │ usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc │ │ -DCMAKE_CXX_COMPILER=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gn │ │ ueabihf-g++ -DCMAKE_FIND_ROOT_PATH=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/ar │ │ m-linux-gnueabihf/libc .. -
编译并通过scp传输到开发板上,进行验证
croot@ATK-IMX6U:~/AppDev# ./led_control none 1 LED配置更新成功。 root@ATK-IMX6U:~/AppDev# ./led_control none 0 LED配置更新成功。