【STM32MP257学习笔记】4.控制LED
在 Linux 系统中,绝大多数硬件设备都有非常成熟的驱动框架,对于LED设备,Linux提供了LED子系统驱动框架,使用了 LED 子系统驱动的设备,会被展现在/sys/class/leds 目录下,可在主机和开发板使用如下命令查看,命令的输出可能会因为硬件环境不同而不一样:ls /sys/class/leds/
可以看到这个板子上有个蓝色的心跳指示灯,这是个指向/sys/devices/platform/gpio-leds/leds/blue:heartbeat的链接,进入到blue:heartbeat看看里面都有什么
max_brightness 文件:表示 LED 灯的最大亮度值。
brightness 文件:表示当前 LED 灯的亮度值,它的可取值范围为 ,一些LED 设备不支持多级亮度,直接以非 0 值来表示 LED 为点亮状态, 0 值表示灭状态。
trigger 文件:指示了 LED 灯的触发方式,查看该文件的内容时,该文件会列出它的所有可用触方式,而当前使用的触发方式会以“[]”符号括起。
常见的触发方式如下表所示
none 无触发方式
disk-activity 硬盘活动
nand-disk nand flash 活动
mtd mtd 设备活动
timer 定时器
heartbeat 系统心跳
在终端中可以用下面的命令直接控制LED
echo none > trigger //切换为无触发方式
echo 1 > brightness //打开LED
echo 0 > brightness //关闭LED
接下来实现编程控制LED
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define LED_PATH_BRI "/sys/class/leds/blue:heartbeat/brightness"
#define LED_PATH_TRI "/sys/class/leds/blue:heartbeat/trigger"
//ledtest 0
//ledtest 1
//ledtest 2 heartbeat
int main(int argc,char **argv)
{
int fd;
if(argc < 2)
{
printf("need led commmand 0:close 1:open 2:trigger \n");
return -1;
}
if(strlen(argv) == 1)
{
if(argv == '0' || argv == '1')
{
fd = open(LED_PATH_BRI,O_RDWR);
write(fd,argv,1);
}
else if(argv == '2')
{
if(argc < 3)
{
printf("need trigger \n");
return -1;
}
fd = open(LED_PATH_TRI,O_RDWR);
write(fd,argv,strlen(argv));
}
else
{
printf("led commmand error 0:close 1:open 2:trigger \n");
return -1;
}
}
else
{
printf("led commmand error 0:close 1:open 2:trigger \n");
return -1;
}
close(fd);
return 0;
}编译后上传到开发板执行以下命令
./ledtest 1 //打开LED
./ledtest 0 //关闭LED
./ledtest 2 heartbeat //修改LED触发方式为系统心跳效果如下
接下来做个有UI的,通过按钮切换LED状态
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define LED_PATH_BRI "/sys/class/leds/blue:heartbeat/brightness"
#define LED_PATH_TRI "/sys/class/leds/blue:heartbeat/trigger"
static void led_ctrl(uint8_t cmd,char *trigger)
{
int fd;
if(cmd < 3)
{
if(cmd < 2)
{
fd = open(LED_PATH_BRI,O_RDWR);
write(fd,cmd==0?"0":"1",1);
}
else
{
if(strlen(trigger) < 1)
{
g_print("need trigger \n");
return ;
}
fd = open(LED_PATH_TRI,O_RDWR);
write(fd,trigger,strlen(trigger));
}
}
else
{
g_print("led commmand error 0:close 1:open 2:trigger \n");
return -1;
}
close(fd);
}
static void gw_led_off(GtkWidget *widget,gpointer data)
{
led_ctrl(0,NULL);
}
static void gw_led_on(GtkWidget *widget,gpointer data)
{
led_ctrl(1,NULL);
}
static void gw_led_trigger_heartbeat(GtkWidget *widget,gpointer data)
{
led_ctrl(2,"heartbeat");
}
static void gw_led_trigger_none(GtkWidget *widget,gpointer data)
{
led_ctrl(2,"none");
}
static voidactivate (GtkApplication *app,gpointer user_data)
{
GtkWidget *window;
GtkWidget *button0;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *button3;
GtkWidget *button_box;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "LED Test");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (window), button_box);
button0 = gtk_button_new_with_label ("LED Off");
g_signal_connect (button0, "clicked", G_CALLBACK (gw_led_off), NULL);
gtk_container_add (GTK_CONTAINER (button_box), button0);
button1 = gtk_button_new_with_label ("LED On");
g_signal_connect (button1, "clicked", G_CALLBACK (gw_led_on), NULL);
gtk_container_add (GTK_CONTAINER (button_box), button1);
button2 = gtk_button_new_with_label ("heartbeat");
g_signal_connect (button2, "clicked", G_CALLBACK (gw_led_trigger_heartbeat), NULL);
gtk_container_add (GTK_CONTAINER (button_box), button2);
button3 = gtk_button_new_with_label ("trigger none");
g_signal_connect (button3, "clicked", G_CALLBACK (gw_led_trigger_none), NULL);
gtk_container_add (GTK_CONTAINER (button_box), button3);
gtk_widget_show_all (window);
}
int main (int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.ledtest", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}运行效果
以非 0 值来表示 LED 为点亮状态, 0 值表示灭状态。----这么说的话,无法实现呼吸灯的效果?我认为肯定有方法能实现 Linux提供了LED子系统驱动框架,使用了 LED 子系统驱动的设备
页:
[1]