今天正式踏上我的tiny6410的实战学习旅程,希望在这里记录下学习的点点滴滴,包括学习中遇到的问题,解决过程和思考。
江湖背景:
宿主机环境:Ubuntu10.04
交叉编译工具:arm-linux-gcc-4.5.1
硬件环境:FriendlyARM tiny6410
开篇--张灯结彩
初学一个板子,我们往往都从流水灯学起,依江湖老规矩走,我先按照友善提供的LED代码,编译后下载到开发板上运行,代码如下:
/*file_name: testLED*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
int main(int argc,char**argv)
{
int on;
int led_no;
int fd;
//check the two parameters of leds
if(argc!=3||sscanf(argv[1],"%d",&led_no)!=1||sscanf(argv[2],"%d",&on)!=1||on<0||on>1||led_no<0||led_no>3){
fprintf(stderr,"Usage:leds led_no 0|1\n");
exit(1);
}
//open /dev/leds devices
fd=open("/dev/leds0",0);
if(fd<0){
fd=open("/dev/leds",0);
}
if(fd<0){
perror("open devices leds");
exit(1);
}
ioctl(fd,on,led_no);
close(fd);
return 0;
}
运行的时候遇到俩问题:
1、程序不能运行,Permission denied;
2、运行后,无明显现象。
第一个问题,是文件权限的问题,修改成可执行文件即可,我直接执行:chmod 777 testLED,执行后可以正常运行了。
然后是第二个问题,运行之后,很奇怪,执行testLED 1 0你看不到任何现象,应该是第一个LED灯会被熄灭才对,怎么回事??LED灯还是一直默认的流水灯跑着并没有变化。会不会是因为这个正在运行的流水灯程序混淆了现象??于是,我将当前运行的流水灯程序停掉,执行/etc/rc.d/init.d/leds stop,然后我又运行testLED,可以明显的控制LED的亮灭,问题解决O(∩_∩)O哈哈~
江湖向来风生水起,我不满足于这个例程,想创造点自己的“一招半式”,于是开始设计自己的流水灯程序,但我现在还非常的不熟悉linux下的应用程序编程,比如对linux下的常用函数不熟悉,想办事又没关系,那我只能从友善的例程中“托关系”,依葫芦画个瓢吧,分析下例程中用到的函数,控制灯亮灭的函数是ioctl,查一下这个函数,第一个参数向它传递file id,第二个参数传递LED的编号,第三个参数控制LED亮(1)灭(0),弄懂这个函数,就可以开始编写自己的流水灯了,以下是我写的流水灯源程序:
/*file_name:testLED_CYCLE.c*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
void main(void)
{
int fd,i;
while(1){
fd=open("/dev/leds0",0);
if(fd<0){
fd=open("/dev/leds",0);
}
if(fd<0){
perror("open device leds");
exit(1);
}
for(i=0;i++;i<4){ //此等错误,情何以堪~~注意!这个错误编译不报错!!!!
ioctl(fd,i,1);
usleep(10000);
ioctl(fd,i,0); //这个函数用错了,第二个参数是控制灯亮灭,第三个参数是灯的索引编号。
}
close(fd);
}
}
编译没有错误,下载到开发板上,程序一直处于运行状态,LED没有按预想的流水亮灭,暂时没分析出个所以然,在宿主机上用gdb调试,没法运行,估计是调试程序不合适。
下一步:
1、学习ARM程序的调试工具;
2、跟踪程序的运行,分析原因。
******************************************************************************************************************
问题解决------2012-03-09
******************************************************************************************************************
又折腾了N次,还在循环语句前单独控制某个灯的亮灭来检测程序的运行(是正常的),愣就是想不明白程序为什么没按预想的来执行,编译也没错啊!!!
分析错误可能出现的原因,可能在ioctl()这个函数上,分析了下,原来是参数传递搞反了,看来依葫芦没把瓢画好啊~~ 改好后,期待。。。还是不行!!!不经意间,看到for循环,真有点“众里寻他千百度,暮然回首,那人却在灯火阑珊处”的味道,接下来垂头顿足的滑稽表情大家想想就知道了~~但最后,看到板子上跑着自己写的流水灯程序,还是开心的,哈哈!下面是修正后的流水灯程序。
/*file_name:testLED_CYCLE.c*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
void main(void)
{
int fd,led;
while(1){
fd=open("/dev/leds0",0);
if(fd<0){
fd=open("/dev/leds",0);
}
if(fd<0){
perror("open device leds");
exit(1);
}
ioctl(fd,0,1);
for(led=0;led<4;led++){
ioctl(fd,1,led);
sleep(1);
ioctl(fd,0,led);
}
close(fd);
}
}
关于arm-linux-gdb及gdbserver,这个问题足够大,得抽空开个专题来研究一下它了!想想如果有它的话,错误是显而易见的,非常好纠错!
欢迎大家扫描下方二维码关注我的个人微信公众号,一起交流学习,谢谢。