2008年9月6日星期六
My ECG Device (2)
第二天,一大早醒来已经八点多了,昨天晚上交待L学长早上起来叫我一起起来,没想到他一个人走了……后来问他他说是因为看我睡太香-_-! 于是我又等着G学长起来,刷牙洗脸洗澡,然后我请G学长带我一起去买点生活用品,因为我没有刷牙用的被子,所以就没刷牙就出去了结果直接导致我没有早餐吃,饿了一个上午。虽然平常我就不吃早餐,但是一般也不会这么早起来,早上也没什么活动,哪里像这个,购物走来走去。饿半死。跟G学长一起去买东西,最重要的是买了几大瓶的纯净水。买完东西回来后。 回到住处之后洗漱一下,喝掉半瓶水,这个时候我才感觉我像个人!!!真的,我真的是这种感觉,洗漱喝水之前我真的觉得我不像个人,但是洗漱完喝完水后,浑身那个爽啊,我才又感到我像一个正常人了。感觉强烈!!然后,我又自己出去了一趟,想买张手机卡,但是一问价钱,贼贵,一张卡卖80里面只有30元话费,汗,不买了,还是打公用电话吧,于是IP电话打回家。打完电话,找了家盖饭吃了顿。完后,我有一种重新做人的感觉啊……下午就去实验室了,开机,哇塞我的HP工作站真的不错哦。于是慢慢的装上一些工作用的软件什么的,这部分省略……下午有件事情不知道是怎么回事,在实验室没看到G学长,他下午回泉州了,我也没去送他,这件事情我一直很遗憾。到实验室很后悔的一件事情是没把纯净水带过来,因为我以为既然实验室又开水喝了,就不用带纯净水了,后来发现这水合起来味道实在是不行,于是后来我就带了水过来了,但是后来因为出去买水很难,因为要走很远,那个开水我也就慢慢习惯了。然后是开始学习,没什么特别的……
My ECG Device (1)
最近的一个月主要完成的任务就是这个,从8月6号在校内网上发布这条状态信息到现在,整好一个月:
其实我也没这么专啦,一个月时间如果天天做这个,那我就会成仙~~
一个月前到厦门软件园的时候,我就想写篇日志,但是懒啊,懒没办法,拖了一天又一天,想最后来写个总结,这不,写总结来了。 从到厦门软园的第一天开始讲起吧。(真正的流水账啊)
一个月前今天:现在正在准备呢,心里一定在想:我去哪里之后努力学习,我就会知道嵌入式开发究竟是怎么回事了。下午,一点开始,基本上就收拾一下衣服,生活用品之类的,装箱子里,三点收拾完毕,跟G学长打个招呼,三点二十出发,去承露泉等车,车还真准时,说四点开,三点五十八都看不到影子。G学长说车到厦门的时间是一个小时零三分钟,结果到厦门下车的时候看了下表,发现准啊,只偏差了一分钟左右,还是因为路上在修路。这个时候我们在厦门校区旁的马路上,也就是如果在厦门坐公交车停靠的“兑山”站。然后呢,因为本来想去坐另一趟始发站的车,需要走路一段,但是走了一会儿,发现行李还是太重哇,索性在路边等54路的车了,哇塞,真的很挤,车票也贵啊,一人四元,这票价,真的是泉州风格(泉州公交车估计是全国最贵的吧)。G学长问我有没有零钱,我就拿了八块出来,没想到G学长退还我四块,自己用e通卡刷了四块,原来G学长跟我坐公交车也AA制,呵呵。车到SM城市广场下车,再东拐西拐,吃了个沙县小吃(学长又说AA制,搞的我想感谢下都不行),坐芙蓉苑到软件园的车,又是很挤。软件园的上一站是三安电子,哇塞,原来三安电子还蛮有派头的嘛,以后找工作考虑下。一到软件园我们学校的据点,就给我一个下马威:门是锁住的,G学长没钥匙,但是就在我纳闷时候,说时迟,那时快,G学长“嗖”的一声从窗户跳了进去,然后是我跳进去,G学长说,这里不是每个人都有钥匙,而且房间需要通风,所以窗户没关,所以房间里东西也老丢。我进去一看,哇塞,那哪里是寝室啊,整个一个展览厅,原来是我们学校向厦门软件园里的公司展示风采的地方,被我们用来做大寝室了。里面摆上了七八个铁床。我把东西放一下,看了下卫浴,条件艰苦啊……水龙头就一个,而且是洗手池里的,洗手池很小,连个脸盆都放不下,怎么洗澡啊~~唉,G学长又发话了:“早说过这里条件艰苦,你如果不来就不要来嘛”,我就说了,学习东西嘛,条件艰苦也就一个月嘛。把东西整理好之后,我们就去把重要的东西转移到实验室去,到了实验室后,发现很是壮观啊,跟公司里的白领似的,事实上后来了解到,那个实验室一半是我们学校的,另一半确实是一家公司,做的产品是网络收音机,要卖1000多块钱一台的收音机呢,买的人真是傻子。在实验室的学长学姐们真的是很热情,马上给我安排一个位置,又从后面的仓库里抬出一台新的电脑出来,给我摆在桌子上了,我一看那配置,哇塞,这电脑太强大了吧,后来我去网上查过,这电脑是惠普工作站级别的,得一万多主机,显示器也得一千多。学校真是钱多,舍得花钱啊。等我把系统装完之后,差不多就可以回去了,这个时候我问旁边的学长,喝水的问题怎么解决,因为我实在是渴啊,这附近又没有卖水的地方。结果学长说需要从洗手间打水过来烧开用。正好这里还有自来水,于是我烧了点,喝了点,因为太烫,没喝很多,后来的事情使我后悔没有趁热多喝点,烫着也值啊……回到住处,口渴的厉害,问L学长附近有没有卖水的地方,得到的答复是没有,不过好像我过来的时候看到路上有一家便利店,于是我又跑出去看看,也关门了,郁闷,回来之后,我口渴的已经快生烟了,L学长拿出一个纯净水的瓶子,里面还有一点水,叫我喝,按照我往常的风格,就算是再渴也不会喝别人喝剩下的水吧?但是刚来这里,也不好拒绝学长的好意,喝了。后来的一个月我都没看到学长买水到住处,或者没买过水,真不知道他第一天晚上给我的那点水是怎么来的,现在想来都觉得喝这水比喝自来水不靠谱的太多啊。所以说之前烫着也要多喝啊。经过艰苦的洗漱,上床睡觉了,我睡的是别人的床,因为我第一天晚上过去,来不及买床垫。睡了,下一节讲明天的故事。
明天去厦门,预计在厦门软件园呆一个月左右。(错了,是今天,现在已经凌晨半点了)
其实我也没这么专啦,一个月时间如果天天做这个,那我就会成仙~~
一个月前到厦门软件园的时候,我就想写篇日志,但是懒啊,懒没办法,拖了一天又一天,想最后来写个总结,这不,写总结来了。 从到厦门软园的第一天开始讲起吧。(真正的流水账啊)
一个月前今天:现在正在准备呢,心里一定在想:我去哪里之后努力学习,我就会知道嵌入式开发究竟是怎么回事了。下午,一点开始,基本上就收拾一下衣服,生活用品之类的,装箱子里,三点收拾完毕,跟G学长打个招呼,三点二十出发,去承露泉等车,车还真准时,说四点开,三点五十八都看不到影子。G学长说车到厦门的时间是一个小时零三分钟,结果到厦门下车的时候看了下表,发现准啊,只偏差了一分钟左右,还是因为路上在修路。这个时候我们在厦门校区旁的马路上,也就是如果在厦门坐公交车停靠的“兑山”站。然后呢,因为本来想去坐另一趟始发站的车,需要走路一段,但是走了一会儿,发现行李还是太重哇,索性在路边等54路的车了,哇塞,真的很挤,车票也贵啊,一人四元,这票价,真的是泉州风格(泉州公交车估计是全国最贵的吧)。G学长问我有没有零钱,我就拿了八块出来,没想到G学长退还我四块,自己用e通卡刷了四块,原来G学长跟我坐公交车也AA制,呵呵。车到SM城市广场下车,再东拐西拐,吃了个沙县小吃(学长又说AA制,搞的我想感谢下都不行),坐芙蓉苑到软件园的车,又是很挤。软件园的上一站是三安电子,哇塞,原来三安电子还蛮有派头的嘛,以后找工作考虑下。一到软件园我们学校的据点,就给我一个下马威:门是锁住的,G学长没钥匙,但是就在我纳闷时候,说时迟,那时快,G学长“嗖”的一声从窗户跳了进去,然后是我跳进去,G学长说,这里不是每个人都有钥匙,而且房间需要通风,所以窗户没关,所以房间里东西也老丢。我进去一看,哇塞,那哪里是寝室啊,整个一个展览厅,原来是我们学校向厦门软件园里的公司展示风采的地方,被我们用来做大寝室了。里面摆上了七八个铁床。我把东西放一下,看了下卫浴,条件艰苦啊……水龙头就一个,而且是洗手池里的,洗手池很小,连个脸盆都放不下,怎么洗澡啊~~唉,G学长又发话了:“早说过这里条件艰苦,你如果不来就不要来嘛”,我就说了,学习东西嘛,条件艰苦也就一个月嘛。把东西整理好之后,我们就去把重要的东西转移到实验室去,到了实验室后,发现很是壮观啊,跟公司里的白领似的,事实上后来了解到,那个实验室一半是我们学校的,另一半确实是一家公司,做的产品是网络收音机,要卖1000多块钱一台的收音机呢,买的人真是傻子。在实验室的学长学姐们真的是很热情,马上给我安排一个位置,又从后面的仓库里抬出一台新的电脑出来,给我摆在桌子上了,我一看那配置,哇塞,这电脑太强大了吧,后来我去网上查过,这电脑是惠普工作站级别的,得一万多主机,显示器也得一千多。学校真是钱多,舍得花钱啊。等我把系统装完之后,差不多就可以回去了,这个时候我问旁边的学长,喝水的问题怎么解决,因为我实在是渴啊,这附近又没有卖水的地方。结果学长说需要从洗手间打水过来烧开用。正好这里还有自来水,于是我烧了点,喝了点,因为太烫,没喝很多,后来的事情使我后悔没有趁热多喝点,烫着也值啊……回到住处,口渴的厉害,问L学长附近有没有卖水的地方,得到的答复是没有,不过好像我过来的时候看到路上有一家便利店,于是我又跑出去看看,也关门了,郁闷,回来之后,我口渴的已经快生烟了,L学长拿出一个纯净水的瓶子,里面还有一点水,叫我喝,按照我往常的风格,就算是再渴也不会喝别人喝剩下的水吧?但是刚来这里,也不好拒绝学长的好意,喝了。后来的一个月我都没看到学长买水到住处,或者没买过水,真不知道他第一天晚上给我的那点水是怎么来的,现在想来都觉得喝这水比喝自来水不靠谱的太多啊。所以说之前烫着也要多喝啊。经过艰苦的洗漱,上床睡觉了,我睡的是别人的床,因为我第一天晚上过去,来不及买床垫。睡了,下一节讲明天的故事。
2008年8月14日星期四
sqlite在ARM7+uclinux上的移植
下载源码:
http://www.sqlite.org/sqlite-amalgamation-3_6_1.zip
http://www.sqlite.org/sqlite-source-3_6_1.zip
下面的包我们只用到shell.c,
把shell.c从sqlite-source-3_6_1.zip中解压出来和从sqlite-amalgamation-3_6_1.zip中解压出来的三个源文件放在一起。
编译:(我用的是博创的UP-NETARM 3000)
[CODE]
arm-uclibc-gcc *.c -c -g -O2 -D__linux__ -DSQLITE_OMIT_LOAD_EXTENSION -I/uclinux/uClinux-2.4.x/include -I/uclinux/uClibc-0.9.19/include -fno-builtin -nostartfiles
arm-uclibc-gcc *.o -Wall -elf2flt -static -L/uclinux/uClibc-0.9.19/lib -lc -lpthread -o sqlite3
[/CODE]
好了,把sqlite3拷到开发板上去就可以用了
http://www.sqlite.org/sqlite-amalgamation-3_6_1.zip
http://www.sqlite.org/sqlite-source-3_6_1.zip
下面的包我们只用到shell.c,
把shell.c从sqlite-source-3_6_1.zip中解压出来和从sqlite-amalgamation-3_6_1.zip中解压出来的三个源文件放在一起。
编译:(我用的是博创的UP-NETARM 3000)
[CODE]
arm-uclibc-gcc *.c -c -g -O2 -D__linux__ -DSQLITE_OMIT_LOAD_EXTENSION -I/uclinux/uClinux-2.4.x/include -I/uclinux/uClibc-0.9.19/include -fno-builtin -nostartfiles
arm-uclibc-gcc *.o -Wall -elf2flt -static -L/uclinux/uClibc-0.9.19/lib -lc -lpthread -o sqlite3
[/CODE]
好了,把sqlite3拷到开发板上去就可以用了
2008年8月10日星期日
编译hello world也能出错……
代码就是:
[code:c]
#include "stdio.h"
int main()
{
printf("hello, world \n");
return 0;
}
[/code]
Makefile:
[code]
CC=arm-uclibc-gcc
EXEC = hello
OBJS = hello.o
CFLAGS +=
LDFLAGS+=-elf2flt -static
all:$(EXEC)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
clean:
-rm -f $(EXEC) *.elf *.gdb *.o
[/code]
make一下发现错误:
hello.c:1: '#include' expects 'FILENAME' or'半天都没明白是怎么回事,后来又在linux里用gedit编辑了一个新的hello.c,可以了……
原来原因就是:不能在windows里写程序拿到linux里去编译 -_-!
[code:c]
#include "stdio.h"
int main()
{
printf("hello, world \n");
return 0;
}
[/code]
Makefile:
[code]
CC=arm-uclibc-gcc
EXEC = hello
OBJS = hello.o
CFLAGS +=
LDFLAGS+=-elf2flt -static
all:$(EXEC)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
clean:
-rm -f $(EXEC) *.elf *.gdb *.o
[/code]
make一下发现错误:
hello.c:1: '#include' expects 'FILENAME' or
原来原因就是:不能在windows里写程序拿到linux里去编译 -_-!
2008年8月3日星期日
发现Keil uVision 3 for C51 bug一只
今天早上7点20才睡。 -_-!
原因是我一整晚都在调试一个单片机程序,本来一个非常简单的程序,但是却一直有问题,整晚都抓狂的很,不过最终问题的答案找到了,是
编译器的bug ! 我的汗啊……
贴出我的源码:
1, main.c :
[code:c]
#include "kernel.h"
#include "stdio.h"
unsigned char print_timer = NO_TASK ;
int print ()
{
printf ( "i am in print \n" ) ;
}
void flash_led ()
{
printf ("flash \n" ) ;
}
void reg()
{
static bit f = 1 ;
if ( f )
{
if ( print_timer == NO_TASK )
{
print_timer = reg_task ( print, 40 ) ;
printf(" task create seccess ! id : %d \n", (int)print_timer ) ;
}
}
else
{
unreg_task ( &print_timer ) ;
printf (" task print has been unreg ! \n" ) ;
}
f = ~f ;
}
void main()
{
SBUF = ' ' ;
kernel_init () ;
//reg_task ( flash_led, 40 ) ;
reg_task ( flash_led, 400 ) ;
reg_task ( reg, 80 ) ;
while (1) ;
}
[/code]
2, kernel.c :
[code:c]
#include "kernel.h"
void kernel_init ()
{
TMOD |=0x01;
PT0=1; //设置定时器的优先级高,精确定时
TH0=0x9e; //40HZ,25ms kernel freq
TL0=0x57;
EA = 1 ;
ET0=1; //允许定时器0中断
TR0=1; // 核心定时器运行
}
static TASK funp[MAX_TASK+1] = { (TASK)0 } ; //存放函数地址
static int freq[MAX_TASK+1] = { (int)0 } ; // 每隔多少个25ms运行一次
static int counter = 1 ;
static int max_id = 0 ;
int reg_task ( TASK t, int f ) // 定时器的时间是 time*25ms
{
disable_kernel ;
if ( (max_id == MAX_TASK) || (f==0) || (t==(TASK)0) )
{
enable_kernel ;
return 0 ;
}
max_id ++ ;
funp[max_id] = (TASK)t ;
freq[max_id] = f ;
enable_kernel ;
return max_id ;
}
void unreg_task ( int * task_id )
{
int id ;
disable_kernel ;
id = *task_id ;
if ( id == 0 )
{
enable_kernel ;
return ; // 没有0这个任务,不用注销任务
}
funp[id] = funp[max_id] ;
freq[id] = freq[max_id] ;
max_id -- ;
*task_id = 0 ; // 这样在外面检测任务ID的时候,显示为0,表示这个任务不存在。
enable_kernel ;
}
void time_0_kernel() interrupt 1 //using 2 但是为什么我不能切换寄存器组呢????一旦去掉注释,输出结果马上不同
{
int id ;
ET0 = 0; // 禁用中断
if ( counter++ == 26400 ) counter = 1 ; // 最长定时器为一个小时
//定时器任务调度
id = max_id ;
while ( id )
{
if ( freq[id] > 0 )
if ( (counter%freq[id]) == 0 )
(funp[id])() ;
id -- ;
}
TH0=0x9e; //40HZ,25ms kernel freq
TL0=0x57;
ET0 = 1 ; // 开启定时器中断
}
[/code]
3, kernel.h :
[code:c]
#ifndef MY_KERNEL_H
#define MY_KERNEL_H
#include "REGX51.H"
#include "stdio.h"
#include "intrins.h"
#define disable_interrupt ( EA = 0 )
#define enable_interrupt ( EA = 1 )
#define disable_kernel (TR0 = 0 )
#define enable_kernel ( TR0 = 1 )
#define MAX_TASK 6
typedef void ( * TASK ) () ;
void kernel_init () ;
int reg_task ( TASK timer_task, int time ) ;
void unreg_task ( int * id ) ;
#endif
[/code]
上面是没有问题的代码可以在Keil uVison3 for 51 中仿真运行,结果如图:
![]()
src='http://music.blogcn.com/wp-content/uploads/154/15462/2008/08/right_result.jpg' alt='right_result.jpg' />
但是,如果我把 kernel.c中的那个注释去掉,即我切换寄存器组,马上就会出问题。输出的结果立即不同 :
![]()
src='http://music.blogcn.com/wp-content/uploads/154/15462/2008/08/wrong_result.jpg' alt='wrong_result.jpg' />
这甚至只是错误结果的一种,因为还有好几种输出情况,但都是错误的。
一开始我以为是我切换寄存器有问题,不能切换,但是我找半天也找不到不能切换的理由,而是找到要切换的理由:我可以省下8字节的堆栈空
间。怎么想都得不到答案,最后我拼了,把它反汇编之后从汇编指令一条条查看,最后发现错误的原因在这里:
![]()
src='http://music.blogcn.com/wp-content/uploads/154/15462/2008/08/keil_bug.JPG' alt='keil_bug.JPG' />
下面我来分析一下这几行汇编指令:
这一段代码的目的是把我传递过来的函数指针值存放在适当的地方,这样,适当
时候我可以从这个地方取出函数指针,并进行函数调用。
这里编译器设置把函数地址存放在2AH开始后的一个数组里,因为在keil C51里一
个函数指针占用三个字节,第一个字节存放的是指针类型,第二个和第三个字节
分别存放高位和地位的地址。所以,第一个函数的地址存放在2BH(高位)和2CH(低
位),第二个就存放在2EH和2FH了,依次类推。
第1行 : 把我传递过来的函数指针值的高位存到寄存器R2
第2行 : 把我传递过来的函数指针值的低位存到寄存器R1
第3行 : 3FH里存放的是函数指针值数组的偏移量,把偏移量赋值给A
第4行 : 把每个地址占用的长度赋值给B
第5行 : 做一个乘法,得到的结果就是A,其中就是我现在应该存放函数指针值
的地址的偏移量
第6行 : 把得到的偏移量加上数组的基址2AH得到最终应该存放的地址
第7行 : 把地址值给R0,即将用R0做寄存器寻址之用
第8行 : 把该指针的类型值(存放在13H)先存入
第9行 : 寄存器指针指向下一个字节
第10行: 把函数指针值的高位存入
第11行: 寄存器指针指向下一个字节
第12行: 把函数指针值的低位存入
如果只看我的注释的话是一点问题也没有的,如果你看代码就应该发现一点不对劲了,在第10行和第12行,分别把函数指针值的高位和地位存
入,而函数指针值的高位和地方在前面两行就暂存在了R2和R1中,所以这个时候应该用:
MOV @R0, R2和MOV @R0, R1才对吧?对,这是最保险的,但是图中编译器生成的代码如果使用的是寄存器第0组的话也是没有问题的,因为第0
组的R2和R1地址就是02H和01H,但是目前的问题是,我已经切换了寄存器组,所以应该用R2和R1才是对的。我不知道编译器这个时候在耍什么
小聪明,好好的R2和R1不用,用绝对地址来表示。
找到问题的原因后,通过直接修改汇编代码,程序又成功运行了。
这个时候是早上四点半,接着上网和jerome聊了会天,五点半了,细细刷刷,6点了,开电视看,七点二十,睡了……
八点四十又起来了,因为我一天多没去实验室,据说今天要调试,我就过去了,不一会儿,调试完毕,写篇日志,睡了……
原因是我一整晚都在调试一个单片机程序,本来一个非常简单的程序,但是却一直有问题,整晚都抓狂的很,不过最终问题的答案找到了,是
编译器的bug ! 我的汗啊……
贴出我的源码:
1, main.c :
[code:c]
#include "kernel.h"
#include "stdio.h"
unsigned char print_timer = NO_TASK ;
int print ()
{
printf ( "i am in print \n" ) ;
}
void flash_led ()
{
printf ("flash \n" ) ;
}
void reg()
{
static bit f = 1 ;
if ( f )
{
if ( print_timer == NO_TASK )
{
print_timer = reg_task ( print, 40 ) ;
printf(" task create seccess ! id : %d \n", (int)print_timer ) ;
}
}
else
{
unreg_task ( &print_timer ) ;
printf (" task print has been unreg ! \n" ) ;
}
f = ~f ;
}
void main()
{
SBUF = ' ' ;
kernel_init () ;
//reg_task ( flash_led, 40 ) ;
reg_task ( flash_led, 400 ) ;
reg_task ( reg, 80 ) ;
while (1) ;
}
[/code]
2, kernel.c :
[code:c]
#include "kernel.h"
void kernel_init ()
{
TMOD |=0x01;
PT0=1; //设置定时器的优先级高,精确定时
TH0=0x9e; //40HZ,25ms kernel freq
TL0=0x57;
EA = 1 ;
ET0=1; //允许定时器0中断
TR0=1; // 核心定时器运行
}
static TASK funp[MAX_TASK+1] = { (TASK)0 } ; //存放函数地址
static int freq[MAX_TASK+1] = { (int)0 } ; // 每隔多少个25ms运行一次
static int counter = 1 ;
static int max_id = 0 ;
int reg_task ( TASK t, int f ) // 定时器的时间是 time*25ms
{
disable_kernel ;
if ( (max_id == MAX_TASK) || (f==0) || (t==(TASK)0) )
{
enable_kernel ;
return 0 ;
}
max_id ++ ;
funp[max_id] = (TASK)t ;
freq[max_id] = f ;
enable_kernel ;
return max_id ;
}
void unreg_task ( int * task_id )
{
int id ;
disable_kernel ;
id = *task_id ;
if ( id == 0 )
{
enable_kernel ;
return ; // 没有0这个任务,不用注销任务
}
funp[id] = funp[max_id] ;
freq[id] = freq[max_id] ;
max_id -- ;
*task_id = 0 ; // 这样在外面检测任务ID的时候,显示为0,表示这个任务不存在。
enable_kernel ;
}
void time_0_kernel() interrupt 1 //using 2 但是为什么我不能切换寄存器组呢????一旦去掉注释,输出结果马上不同
{
int id ;
ET0 = 0; // 禁用中断
if ( counter++ == 26400 ) counter = 1 ; // 最长定时器为一个小时
//定时器任务调度
id = max_id ;
while ( id )
{
if ( freq[id] > 0 )
if ( (counter%freq[id]) == 0 )
(funp[id])() ;
id -- ;
}
TH0=0x9e; //40HZ,25ms kernel freq
TL0=0x57;
ET0 = 1 ; // 开启定时器中断
}
[/code]
3, kernel.h :
[code:c]
#ifndef MY_KERNEL_H
#define MY_KERNEL_H
#include "REGX51.H"
#include "stdio.h"
#include "intrins.h"
#define disable_interrupt ( EA = 0 )
#define enable_interrupt ( EA = 1 )
#define disable_kernel (TR0 = 0 )
#define enable_kernel ( TR0 = 1 )
#define MAX_TASK 6
typedef void ( * TASK ) () ;
void kernel_init () ;
int reg_task ( TASK timer_task, int time ) ;
void unreg_task ( int * id ) ;
#endif
[/code]
上面是没有问题的代码可以在Keil uVison3 for 51 中仿真运行,结果如图:
src='http://music.blogcn.com/wp-content/uploads/154/15462/2008/08/right_result.jpg' alt='right_result.jpg' />
但是,如果我把 kernel.c中的那个注释去掉,即我切换寄存器组,马上就会出问题。输出的结果立即不同 :
src='http://music.blogcn.com/wp-content/uploads/154/15462/2008/08/wrong_result.jpg' alt='wrong_result.jpg' />
这甚至只是错误结果的一种,因为还有好几种输出情况,但都是错误的。
一开始我以为是我切换寄存器有问题,不能切换,但是我找半天也找不到不能切换的理由,而是找到要切换的理由:我可以省下8字节的堆栈空
间。怎么想都得不到答案,最后我拼了,把它反汇编之后从汇编指令一条条查看,最后发现错误的原因在这里:
src='http://music.blogcn.com/wp-content/uploads/154/15462/2008/08/keil_bug.JPG' alt='keil_bug.JPG' />
下面我来分析一下这几行汇编指令:
这一段代码的目的是把我传递过来的函数指针值存放在适当的地方,这样,适当
时候我可以从这个地方取出函数指针,并进行函数调用。
这里编译器设置把函数地址存放在2AH开始后的一个数组里,因为在keil C51里一
个函数指针占用三个字节,第一个字节存放的是指针类型,第二个和第三个字节
分别存放高位和地位的地址。所以,第一个函数的地址存放在2BH(高位)和2CH(低
位),第二个就存放在2EH和2FH了,依次类推。
第1行 : 把我传递过来的函数指针值的高位存到寄存器R2
第2行 : 把我传递过来的函数指针值的低位存到寄存器R1
第3行 : 3FH里存放的是函数指针值数组的偏移量,把偏移量赋值给A
第4行 : 把每个地址占用的长度赋值给B
第5行 : 做一个乘法,得到的结果就是A,其中就是我现在应该存放函数指针值
的地址的偏移量
第6行 : 把得到的偏移量加上数组的基址2AH得到最终应该存放的地址
第7行 : 把地址值给R0,即将用R0做寄存器寻址之用
第8行 : 把该指针的类型值(存放在13H)先存入
第9行 : 寄存器指针指向下一个字节
第10行: 把函数指针值的高位存入
第11行: 寄存器指针指向下一个字节
第12行: 把函数指针值的低位存入
如果只看我的注释的话是一点问题也没有的,如果你看代码就应该发现一点不对劲了,在第10行和第12行,分别把函数指针值的高位和地位存
入,而函数指针值的高位和地方在前面两行就暂存在了R2和R1中,所以这个时候应该用:
MOV @R0, R2和MOV @R0, R1才对吧?对,这是最保险的,但是图中编译器生成的代码如果使用的是寄存器第0组的话也是没有问题的,因为第0
组的R2和R1地址就是02H和01H,但是目前的问题是,我已经切换了寄存器组,所以应该用R2和R1才是对的。我不知道编译器这个时候在耍什么
小聪明,好好的R2和R1不用,用绝对地址来表示。
找到问题的原因后,通过直接修改汇编代码,程序又成功运行了。
这个时候是早上四点半,接着上网和jerome聊了会天,五点半了,细细刷刷,6点了,开电视看,七点二十,睡了……
八点四十又起来了,因为我一天多没去实验室,据说今天要调试,我就过去了,不一会儿,调试完毕,写篇日志,睡了……
2008年7月14日星期一
ubuntu8.04使用virtualbox_1.5.6的若干问题
不知道是不是ubuntu新版本发布的太快的原因,可能早先版本做的很好的地方新版本可能出现问题,原来我从6.10升级到7.04就领教过了,这次还是有这种问题。
原来我用kubuntu7.10的时候,用virtualbox很除了USB的问题,其他还好,并且速度也非常快,尤其是磁盘操作,让我非常的佩服linux的磁盘管理,但是现在用ubuntu8.04一上来我就碰到一个这样的:我创建虚拟磁盘的时候一个2GB的磁盘居然花费近半分钟来创建,要知道之前那个几乎是不花费时间的!
然后是发现按下右Ctrl键不能从客户机从切换出来,郁闷至极,后来乱按到Print键才得以脱身!还发现不能在客户机中使用键盘,摆渡google几下之后,发现有好几个办法,但是我不想装新输入法……而且那个简单的方法又对我没用,我又不想去掉复制字符输入……
最后在这里找到这样的一段话,呵呵
http://www.douban.com/group/topic/3074741/
PS:USB的问题,还没解决……
原来我用kubuntu7.10的时候,用virtualbox很除了USB的问题,其他还好,并且速度也非常快,尤其是磁盘操作,让我非常的佩服linux的磁盘管理,但是现在用ubuntu8.04一上来我就碰到一个这样的:我创建虚拟磁盘的时候一个2GB的磁盘居然花费近半分钟来创建,要知道之前那个几乎是不花费时间的!
然后是发现按下右Ctrl键不能从客户机从切换出来,郁闷至极,后来乱按到Print键才得以脱身!还发现不能在客户机中使用键盘,摆渡google几下之后,发现有好几个办法,但是我不想装新输入法……而且那个简单的方法又对我没用,我又不想去掉复制字符输入……
最后在这里找到这样的一段话,呵呵
http://www.douban.com/group/topic/3074741/
scim冲突而已
写个脚本,在virtualbox启动前屏蔽掉scim即可
自己写的一个StartVBox.sh:
export XMODIFIERS=""
export GTK_IM_MODULE=""
export QT_IM_MODULE=""
virtualbox
保存,chmod +x StartVBox.sh,以后运行这个sh即可
也可以在桌面建立一个到这个sh的图标
问题终于得到解决!
PS:USB的问题,还没解决……
2008年7月8日星期二
让opera 9.5支持迅雷
opera 9.5 非常的不错,发布没多久我就用上了,但是却发现这个版本居然不知道迅雷菜单了,原来用opera 9.2的时候,我可以用右键选择 “使用迅雷下载”,现在的9.5,虽然我在迅雷里配置了支持opera,迅雷也提示配置成功,但是右键选择那个菜单根本没反应。
今天考完了,无聊,把这个网上搜一下,发现大家都有这个问题(说明不是我的RP问题),网上的解决办法是用o-get还是什么修改的,好像是要装插件。
我不想装插件。于是我自己写了一个,用起来的感觉不错!使用方法:在你的opera 9.5的右键菜单有“使用迅雷下载”这个项目后(但是点了没反应),你把我提供的压缩包中的两个文件解压覆盖到迅雷安装目录的Components\ExplorerHelper子目录,比如我迅雷安装在E:\Soft\Thunder,那么我就把两个文件覆盖到E:\Soft\Thunder\Components\ExplorerHelper。
好了,用opera选择“使用迅雷下载”吧!
修正文件下载:FixOperaThunder.zip
今天考完了,无聊,把这个网上搜一下,发现大家都有这个问题(说明不是我的RP问题),网上的解决办法是用o-get还是什么修改的,好像是要装插件。
我不想装插件。于是我自己写了一个,用起来的感觉不错!使用方法:在你的opera 9.5的右键菜单有“使用迅雷下载”这个项目后(但是点了没反应),你把我提供的压缩包中的两个文件解压覆盖到迅雷安装目录的Components\ExplorerHelper子目录,比如我迅雷安装在E:\Soft\Thunder,那么我就把两个文件覆盖到E:\Soft\Thunder\Components\ExplorerHelper。
好了,用opera选择“使用迅雷下载”吧!
修正文件下载:FixOperaThunder.zip
2008年7月6日星期日
一天十份实验报告 -_-!
昨天一天写了十份实验报告,包括1份生产实习报告(10页纸写满!NND,最他妈的不爽的就是这个,抄了整整一个下午),数字信号处理实验报告4份(copy一份直接打印,都确定要挂科了,谁写啊,他妈的戴生奎就是一头畜生!),IC测试实验5份(乱改改)
真的是冇语……
真的是冇语……
2008年6月29日星期日
网络安装ubuntu8.04
因为硬盘比较小而且分区不是很合理,导致现在用起来很不爽,很不小心就提示空间不足了……
没办法,把我的两个linux(redflag 6和kubuntu7.10)都格式化了,接下来就为选择哪个发行版烦恼了一阵子,之前就有下载了OpenSUSE 11,但是去网上搜索了很久,愣是不知道怎么进行硬盘安装,说只有DVD版的可以……然后我又考虑了redflag 6 但是想想自己这么菜鸟,以后要装个软件依赖性搞个半天我还不疯狂,于是边把重心转移到debian上来了(因为ubuntu或者kubuntu都用过好多次了,想换换口味),因为对debian不是很有信心,也就不想去下载整个光盘,于是下载了一个网络安装的文件,但是启动之后愣是识别不出我的网卡,晕。
现在思维完全转到网络安装上了,不自觉的我就去下了ubuntu的网络安装文件,没想到一路安装下去,直到完成,那么就这样吧。
中间有一段时间下载软件包的时候提示"please wait...",良久都没有反应我还以为出问题了差点想重启算了,这个时候我神出鬼没的按下了Ctrl+Alt+F2玩了玩shell,没什么好玩的,于是又按到Ctrl+Alt+F4发现有文字在滚动!原来它还在下载软件包!看到这里我才放心了,耐心的等它装完,一等就是3个小时-_-!
安装完成,发现比以前版本的ubuntu漂亮多了:)
准备考完这两科然后就在上面制作一个ARM编译的交叉环境,暑假好好学学嵌入式开发。嘿嘿
没办法,把我的两个linux(redflag 6和kubuntu7.10)都格式化了,接下来就为选择哪个发行版烦恼了一阵子,之前就有下载了OpenSUSE 11,但是去网上搜索了很久,愣是不知道怎么进行硬盘安装,说只有DVD版的可以……然后我又考虑了redflag 6 但是想想自己这么菜鸟,以后要装个软件依赖性搞个半天我还不疯狂,于是边把重心转移到debian上来了(因为ubuntu或者kubuntu都用过好多次了,想换换口味),因为对debian不是很有信心,也就不想去下载整个光盘,于是下载了一个网络安装的文件,但是启动之后愣是识别不出我的网卡,晕。
现在思维完全转到网络安装上了,不自觉的我就去下了ubuntu的网络安装文件,没想到一路安装下去,直到完成,那么就这样吧。
中间有一段时间下载软件包的时候提示"please wait...",良久都没有反应我还以为出问题了差点想重启算了,这个时候我神出鬼没的按下了Ctrl+Alt+F2玩了玩shell,没什么好玩的,于是又按到Ctrl+Alt+F4发现有文字在滚动!原来它还在下载软件包!看到这里我才放心了,耐心的等它装完,一等就是3个小时-_-!
安装完成,发现比以前版本的ubuntu漂亮多了:)
准备考完这两科然后就在上面制作一个ARM编译的交叉环境,暑假好好学学嵌入式开发。嘿嘿
2008年6月26日星期四
纪念我用了一年的WINDOWS XP
今天晚上,我终于下定决心重装系统了,导火索是因为我不能用我的USB转串口线,驱动的安装一直有问题,而就在两个小时之前不能使用ADS1.2也使我火大。
我对这个系统的得意之处在于它的安全性实在是太高了,看我的装备:
以上几款软件就是我保证电脑长期安全工作,每天都有好的工作环境的秘密武器了。
这个系统上装了太多的东西,以至于我认为重装 就像是一个装满个人身份信息和证明的钱包丢了一样难办,因为要恢复到现在的工作环境,需要太多的努力了……
看看我的各种各样的软件:

上面还只是三分之一而已,好像很大一部分都没有快捷方式在上面 ,喔喔,重装后真不知道要干到何年何月才能搞得像现在一样的方便。
最后发几张桌面的截图纪念一下:

我对这个系统的得意之处在于它的安全性实在是太高了,看我的装备:
- EQsecure V3.41 ( V4.0 容易引起莫名死机,电脑速度变的超级慢,弃之不用)
- Sandboxie 3.26 , 这个软件是最常用的安全软件,当需要以身试毒或者去冒险的时候就派它上吧。
- PowerShadow V2.8 ,我倒是想用2008版的,但是2008是收费的搞的我很不爽,于是我开始用下面的那个:
- Shadow Defender V1.1 ,当Sandboxie不能满足要求时,就派这个上吧
- Avast V4.7 home edition 这是我从买电脑一直用到现在的杀毒软件,优点嘛,免费,占用资源相对较少,技术也是世界一流的,我几乎都不主动去扫描硬盘,因为平常开着防护病毒想进来可就是非常难的了
- Feng Yun Personal Firewall ,这是一款国产的防火墙,个人愚见认为这是世界上最好的防火墙,它极低极低的资源占有率和各种特色功能使得我成为它坚定的粉丝。
以上几款软件就是我保证电脑长期安全工作,每天都有好的工作环境的秘密武器了。
这个系统上装了太多的东西,以至于我认为重装 就像是一个装满个人身份信息和证明的钱包丢了一样难办,因为要恢复到现在的工作环境,需要太多的努力了……
看看我的各种各样的软件:
上面还只是三分之一而已,好像很大一部分都没有快捷方式在上面 ,喔喔,重装后真不知道要干到何年何月才能搞得像现在一样的方便。
最后发几张桌面的截图纪念一下:
2008年6月10日星期二
确定我的研究方向
我一直跟一瓶万金油似的,什么东西都想研究,但是我又发现我什么东西都搞不透,马上就要面临找工作了,很是烦恼,今天晚上在linux驱动开发的群里面的一些讨论,还有《linux设备驱动开发详解》作者宋宝华老师的话(他说,不要一会儿Windows一会而Linux,学东西要专一就行了)让我下定了搞linux驱动开发,并且下定了只用学习linux平台的决心,虽然那些道理我都懂,但是还是今晚我才下的这个觉定,我再也不想去学Visual Studio之类的东西了,如果我要做linux应用程序的话,我会选择ecere的。
我的完美计划:
暑假和学长参加嵌入式开发大赛,借机学习Linux驱动,这样,暑假过后,我写简历的时候就吹:精通linux驱动开发,呵呵。
加油,祝我成功!:)
我的完美计划:
暑假和学长参加嵌入式开发大赛,借机学习Linux驱动,这样,暑假过后,我写简历的时候就吹:精通linux驱动开发,呵呵。
加油,祝我成功!:)
2008年5月28日星期三
Our IM win the first prize
Our IM win the first prize of huaqiao university computer-festival
I use much time at it, this project lasted a month. although it seems very simply ( it really very simply ), but in fact it is very hard when i write it, because most of the problem is unexpected , in chinese, we can say "It is easy to say but hard to do", You know it's true !
today afternoon, my partner tell me the final test will coming soon, we will show our program to referees, he say our competition order is No.1 so we can win the frist prize. facts have proved that !
he told me remember today : may 27th, 2008 ( i write this blog on early in the morning, so it is date of yesterday )
happy !
PS: IM is Instant Message ( like QQ, ICQ, MSN )
I use much time at it, this project lasted a month. although it seems very simply ( it really very simply ), but in fact it is very hard when i write it, because most of the problem is unexpected , in chinese, we can say "It is easy to say but hard to do", You know it's true !
today afternoon, my partner tell me the final test will coming soon, we will show our program to referees, he say our competition order is No.1 so we can win the frist prize. facts have proved that !
he told me remember today : may 27th, 2008 ( i write this blog on early in the morning, so it is date of yesterday )
happy !
PS: IM is Instant Message ( like QQ, ICQ, MSN )
2008年5月26日星期一
5月计划
上个礼拜其实一直很想写一篇日志,写下应聘友达实习生失败的感受,没写的原因,一是因为我想等我对失败的原因认识不那么的偏激的时候再写,那样或许更接近与实际情况,二当然是我一直都没时间让自己动手了。
现在分析原因是因为我对人的礼貌问题,现在相来,如果当晚的宣讲会我没去的话不定现在我就被录取了…… 实在是想不到下一秒会发生什么,what will happen in next second ?
闲话不多说了,这里计划一下接下来一段时间要做的事情:
1, Pass CET-4
2, Review analog and digital circuit, High-Frenquency Electronic Circuit
3, Study data structure, eC, python, VHDL
4, Pass NERC Network Engineer or Database Engineer
5, Use 30 minutes study French everyday
ok,我想也够多了。
……
省略数千字关于找工作的感想
现在分析原因是因为我对人的礼貌问题,现在相来,如果当晚的宣讲会我没去的话不定现在我就被录取了…… 实在是想不到下一秒会发生什么,what will happen in next second ?
闲话不多说了,这里计划一下接下来一段时间要做的事情:
1, Pass CET-4
2, Review analog and digital circuit, High-Frenquency Electronic Circuit
3, Study data structure, eC, python, VHDL
4, Pass NERC Network Engineer or Database Engineer
5, Use 30 minutes study French everyday
ok,我想也够多了。
……
省略数千字关于找工作的感想