jaguar_led@E04{
compatible="cma9,jaguar_led";
led-gpios=<&gpio_cs 0 1>;
cma9,default-trigger = "timer";
status = "okay";
};
本章主要讲述非标准(相对于PC而言)硬件接口编程。像通常的串口和网口,都是标准接口,有通用的编程规范,而这章讲述的如LED、GPIO、SPI和I2C这样的接口,在嵌入式系统中非常普通,由于这些接口的特殊性,没有统一的编程规范。而在实际应用中,往往又不可缺少,所以这章的内容很重要。
本章的内容与具体的开发平台结合比较紧密,如果在非对应的平台上使用这些范例,可能需要根据实际情况进行修改和调整。
15.1 点亮一个LED灯
本节介绍如何使用命令行或C程序来控制LED灯点亮或熄灭。开发板上的可控LED灯通常都是一端接高电平或GND,另一端接GPIO。通过操作GPIO来控制其点亮和熄灭。
图15.1 LED硬件连接示意图
如图15.1所示,两个LED是由发光二极管组成,一端接高电平,另一端若接入高电平,则二极管不导通,LED不会发光。另一端若接入低电平,则二极管导通,LED发光。高低电平一般由GPIO输出。
15.1.1 LED的操作接口
LED操作接口位于/sys/class/leds目录下。此目录下包含了关于LED操作的目录,如下所示:
# ls/sys/class/leds/
beep led-err led-run
其中led-err目录是ERR LED的操作接口,led-run目录是RUN LED操作接口。以RUN LED为例,进入led-run目录,该目录的内容为:
# ls/sys/class/leds/led-run/
brightness max_brightness subsystem uevent
device power trigger
各个文件作用介绍如表15.1所示。
表15.1 LED属性文件用途
文件名 | 作用 |
brightness | 用于控制LED亮灭(需要将LED灯设置为用户控制) |
Subsystem | 符号链接,指向父目录。 |
trigger | 写入“none”可以将指示灯设置为用户控制 |
写入“heartbeat”可以将指示灯设置为心跳灯 | |
写入“nand-disk”可以将指示灯设置为NAND Flash读写灯 | |
power | 设备供电方面的相关信息 |
15.1.2 LED控制
以led_run灯为例,点亮命令如下:
# echo none > /sys/class/leds/led-run/trigger #将LED RUN设置为用户控制
#echo 1 > /sys/class/leds/led-run/brightness #控制 LED 点亮
#echo 0 > /sys/class/leds/led-run/brightness #控制 LED 熄灭
15.1.3 在C程序中操作LED
C程序中操作LED,首先需要设置trigger属性。如下代码片段,将LED灯设置为用户控制方式:
#define TRIGGER_NONE "none"
int fd = open(path, O_RDWR); //path为trigger路径
...
ret = write(fd, TRIGGER_NONE, strlen(TRIGGER_NONE));
...
然后操作brightness属性,设置LED点亮或熄灭:
char data[2]; int fd;
...
fd = open(path, O_WRONLY); //path为brightness路径
data[0] = '0';
ret = write(fd, data, 1); //熄灭LED
...
下面给出的程序清单15.1,首先设置LED trigger属性为“none”,然后设置brightness属性交替为0和1。实现了LED每隔1s点亮一次。
程序清单15.1 LED操作
#define DEVICENAME "/sys/class/leds/jaguar_led/trigger"#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define TRIGGER "trigger"
#define LED_PATH "/sys/class/leds/"
#define LED_STATUS "brightness"
#define TRIGGER_NONE "none"
int main(int argc,char **argv)
{
char path[20],data[2];
int fd, ret, flag;
if(argv[1] == NULL) {
printf("usage : ./led led_run");
return 0;
}
strcpy(path, LED_PATH);
strcat(path, argv[1]);
strcat(path, "/" TRIGGER);
fd = open(path, O_RDWR);
if(fd < 0) {
perror("open");
return -1;
}
ret = write(fd, TRIGGER_NONE, strlen(TRIGGER_NONE));
if(ret < 0) {
perror("write");
return -1;
}
close(fd);
strcpy(path, LED_PATH);
strcat(path, argv[1]);
strcat(path, "/" LED_STATUS);
fd = open(path, O_WRONLY);
if(fd < 0) {
perror("open");
return -1;
}
for(;;)
{
data[0] = flag ? '0': '1';
ret = write(fd, data, 1);
if(ret < 0) {
perror("write");
return -1;
}
flag = !flag;
sleep(1);
}
return 0;
}
my code :#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define TRIGGER_NONE "none"
int main(int argc, char **argv)
{
int ret;
int fd;
const char buffer[10]={0x31,0x30};
char path[100];
// char i=0;
//int ret =0;
strcpy(path,DEVICENAME);
printf("Path is %s \n",path);
fd = open(path,O_RDWR);
ret = write(fd,TRIGGER_NONE,strlen(TRIGGER_NONE));
printf("ret is %d\n",ret);
close(fd);
return 0;
}
echo timer > trigger,echo none > trigger
echo 500 > delay_on