TA的每日心情 | 开心 2022-4-12 14:51 |
---|
签到天数: 163 天 连续签到: 1 天 [LV.7]常住居民III
|
Led接口调试
一直想尝试用Eclipse编译调试ATMEL官网SAMA5D3 XPLAIEND开发板GNU例程,但没有找到突破点,编译入门程序getting started总是错误,头文件和库路径添加后仍是错误。无奈下参考周立功网站发布的“嵌入式Linux开发教程 (上册)”学习使用操作接口控制LED灯。
查看led操作接口
查看SAMA5D3开发板系统下led操作接口,led操作接口位于/sys/class/leds下
[root@buildroot /]# ls sys
block/ class/ devices/ fs/ module/
bus/ dev/ firmware/ kernel/ power/
[root@buildroot /]# ls sys/class/
backlight/ graphics/ mdio_bus/ rtc/ spidev/ vtconsole/
bdi/ i2c-adapter/ mem/ scsi_device/ tty/
block/ i2c-dev/ misc/ scsi_disk/ ubi/
dma/ ieee80211/ mmc_host/ scsi_host/ udc/
firmware/ input/ mtd/ sound/ vc/
gpio/ leds/ net/ spi_master/ video4linux/
[root@buildroot /]# ls sys/class/leds
d2@ d3@
注释:
d2 d3分别对应开发板上的两个LED指示灯
[root@buildroot /]# ls sys/class/leds/d2/
brightness max_brightness subsystem@ uevent
device@ power/ trigger
注释:
led属性文件用途(参考“嵌入式Linux开发教程 (上册)”)
brightness 用于控制LED亮灭(需要将LED灯设置为用户控制)
Subsystem 符号链接,指向父目录。
trigger 写入“none”可以将指示灯设置为用户控制;写入“heartbeat”可以将指示灯设置为心跳灯;写入“nand-disk”可以将指示灯设置为NAND Flash读写灯
power 设备供电方面的相关信息
指令控制d2 指示灯
通过输入指令控制d2指示灯亮灭
[root@buildroot /]# echo none>/sys/class/leds/d2/trigger
[root@buildroot /]# echo 1>/sys/class/leds/d2/brightness
-sh: echo: write error: Invalid argument
注释:echo 1 >后面应添加空格
[root@buildroot /]# echo 0 >/sys/class/leds/d2/brightness
[root@buildroot /]# echo 1 >/sys/class/leds/d2/brightness
注释:1点亮 2灭
上述操作如图1所示:
程序控制d2 指示灯
参考书上代码在Eclipse下编译提示有3个告警,write等未声明用途,查看书上配套源文件例程添加部分头文件,重新编译通过后,通过nfs调试led文件,一直提示No such file or directory ;直接在终端输入:arm-none-linux-gnueabi-gcc led.c -o led –static,再调试led文件,输入.\led后提示:
[root@buildroot mnt]# ./led
usage : ./led led_run[root@buildroot mnt]#
注释:程序没有运行,刚进main函数后,运行到
if(argv[1] == NULL)
{
printf("usage : ./led led_run");
return 0;
}
程序退出,通过查找资料,大致意思是.\led后缺少操作数,输入
[root@buildroot mnt]# ./led 2
open: No such file or directory
运行扔提示打开接口错误,尝试打印path路径,在open接口前打印path[]数组值,显示如下:
/sys/class/leds/d2/t
发现定义path[]数组大小值小了,更改后运行正常
Runnig!
/sys/class/leds/d2/trigger|���l
Sleeping
Sleeping
注释:程序中sleep()函数单位为妙,在sleep(1)后添加打印printf("\n Sleeping \n")
程序运行如图2所示
源程序如下:
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
//#include <sys/types.h>
//#include <sys/stat.h>
#include <string.h>
//#include <linux/types.h>
#define TRIGGER "trigger"
#define LED_PATH "/sys/class/leds/d2/"
#define LED_STATUS "brightness"
#define TRIGGER_NONE "none"
int main(int argc,char **argv)
{
unsigned char i;
char path[40],data[2];
int fd, ret, flag;
if(argv[1] == NULL)
{
printf("usage : ./led led_open_error");
return 0;
}
printf("\n Runnig! \n");
strcpy(path, LED_PATH);
// strcat(path, argv[1]);
// strcat(path, "/" TRIGGER);
strcat(path, TRIGGER);
for(i=0;i<40;i++)
{
printf("%c",path);
}
sleep(1);
printf("\n Sleeping \n");
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);
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);
printf("\n Sleeping \n");
}
return 0;
}
注释:
C当中strcpy函数与strcat函数的区别
1)strcat是用来连接两个字符串的,原型是char *strcat(char *dest,char *src),作用是把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'2) strcpy是用来把字符串拷贝到指定的地方的,原型是char *strcpy(char *dest,const char *src),作用是把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间注意strcat是从dest的结尾处开始操作的,而strcpy是直接覆盖dest指向的内容。3)C语言中,头文件均为<stringh>
距离上一篇分享经验又隔了一个月,真是惭愧,有愧于爱板网站,一部分原因:作为初学者,一直在走网路;另一部分原因:Linux操作系统不甚明白,不求甚解。在看坛友“liunian__92”分享文章和周立功提供的imx287开发板学习手册时,看到Eclipse编译环境,于是想到结合ATMEL官网提供的GNU源码调试,但尝试失败,可能加载头文件和库不对,继续摸索。
Wspytu
150701 |
|