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拷到开发板上去就可以用了

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里去编译 -_-!

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点了,开电视看,七点二十,睡了……

八点四十又起来了,因为我一天多没去实验室,据说今天要调试,我就过去了,不一会儿,调试完毕,写篇日志,睡了……

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/



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

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编译的交叉环境,暑假好好学学嵌入式开发。嘿嘿

screenshot.png

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 ,这是一款国产的防火墙,个人愚见认为这是世界上最好的防火墙,它极低极低的资源占有率和各种特色功能使得我成为它坚定的粉丝。


以上几款软件就是我保证电脑长期安全工作,每天都有好的工作环境的秘密武器了。

这个系统上装了太多的东西,以至于我认为重装 就像是一个装满个人身份信息和证明的钱包丢了一样难办,因为要恢复到现在的工作环境,需要太多的努力了……

看看我的各种各样的软件:

software

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

最后发几张桌面的截图纪念一下:

MyDesktop

20080626004726625.png

2008年6月10日星期二

确定我的研究方向

我一直跟一瓶万金油似的,什么东西都想研究,但是我又发现我什么东西都搞不透,马上就要面临找工作了,很是烦恼,今天晚上在linux驱动开发的群里面的一些讨论,还有《linux设备驱动开发详解》作者宋宝华老师的话(他说,不要一会儿Windows一会而Linux,学东西要专一就行了)让我下定了搞linux驱动开发,并且下定了只用学习linux平台的决心,虽然那些道理我都懂,但是还是今晚我才下的这个觉定,我再也不想去学Visual Studio之类的东西了,如果我要做linux应用程序的话,我会选择ecere的。

我的完美计划:

暑假和学长参加嵌入式开发大赛,借机学习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 )

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,我想也够多了。

……

省略数千字关于找工作的感想

2008年3月28日星期五

linux device drivers study

最近几天都在看这本书《linux 设备驱动程序》,虽然我很早就“浏览”过这本书,但是那是真正的浏览,以至于看了跟没看是一个样,我看很多书都是这样,以至于我都可以认为图书馆7楼(电子,计算机类)的书我都有“浏览”过……

但是这一次不一样,我居然看懂了这本书都在讲什么,这个学习过程就是这么的折磨人。我想这些知识从整体来讲仿佛是一个平面,所以知识没有积累到一定的量,还就是看不懂,我大学期间目前为止所学到的每一个知识都是这么艰难的过程,尤其是大一的时候学习php。没人教,太困难了。

《linux 设备驱动程序》这本书我现在看到190页,到目前为止作者是以一个scull的驱动程序为主线,教我们怎么编写驱动,不过看到现在我今天才做第一个实验:编写hello,world的驱动程序(其实就是抄书啦):

[code:c]
#include "linux/init.h"
#include "linux/module.h"

MODULE_LICENSE("GPL");

static int __init eth_init(void)
{
printk(KERN_ALERT"hello, world\n");
return 0;
}
static void __exit eth_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world\n");
}
module_init(eth_init);
module_exit(eth_exit);
[/code]

另存为hello.c ,然后是要编写Makefile,看书上讲的,弄半天结果还是没出来,Google几下,然后知道几个要点是,内核源码树要先make menuconfig 然后 make 编译一会儿,其实我老早就有编译过,只不过是clean掉了,没想到编译驱动也需要这个。具体的Makefile如下:

[code]
PWD = $(shell pwd)
#please change next variable
# to the path of kernel source of yourself
KERNEL_SRC =/home/jia/kernel/linux-source-2.6.22/
obj-m := hello.o
module-objs := hello.o

all:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules

clean:
rm *.ko
rm *.o
[/code]

编译成功之后会生成hello.ko文件,用超级用户权限加载到内核:sudo insmod ./hello.ko ,卸载用命令 sudo rumod hello ,如果要查看printk 的输出,可以使用 dmesg 命令,可以看到刚才的输出。

:P 我对这个东西非常的感兴趣,我会继续深入学习的,hoho

2008年3月21日星期五

ipluss language engine V1.0

# ipluss_language_engine
# Copyright © ipluss 2008 All Rights Reserved

library download : ipluss_language_engine.rar

1.what is ipluss_language_engine ?
这是我写的一个语言引擎,当你要写的程序需要可以显示多国语言的话,使用这个引擎,你可以非常非常简单的完成这个语言显示部分,省去你的code时间。

2.why use this engine ?
高效率,小的代码量,及其简单的API接口,这都是我建议你使用这个语言引擎的原因。

3.how to make a foreign language support ?
只序言编写你想支持的语言的配置文件(相当的简单,只要你懂那门外语),然后放在你想要放的地方。在配置文件中,以 # 开头的是注释行,然后一行代表一条句子,逗号之前的是你对这一行的说明,我建议把它写成第几行(有效行,除去注释、空白行)就非常好,从0开始。注意文件的最后要有一个空白行就像你写程序一样。

3.how to program use it ?
你只需要下载本文附上的库文件。然后在你需要使用本引擎的程序中加入
#include "ipluss_language_engine.h"

在你需要显示语言之前,对引擎进行初始化,把函数的调用结果赋给 char ** lang 用完之后对它进行关闭。
这里是一个范例:
[code:c]
char ** lang ;
int line = 0 ;
//这里我用 argv[1] 代表我存放的语言文件
//这样我可以在程序启动的第一个参数提供语言文件的名称
//比如说 main.exe english.ini
lang = load_lang ( argv[1] );
printf("\n\n%s\n\n", lang[0]);
while ( lang[line] != NULL )
{
printf (lang[line]) ; // lang[line] 就代表你语言文件中的第line行(
有效行,除去注释、空白行)的文字
printf ("\n") ;
line++ ;
}
free_lang ( lang );
[/code]
我还提供一个可以打印所以语言条目的函数 new_print_file ( lang );然后在编译的时候加上链接ipluss_language_engine.a 的选项,我用gcc是这样的:
gcc main.c ipluss_language_engine.a -o main.exe

如果你使用IDE,请在链接选项里面加上这个库。

4.It is realy free library !

ps:一个完整的程序示例
[code:c]
#include "stdio.h"
#include "stdlib.h"
#include "ipluss_language_engine.h"
int main(int argc, char** argv) {
char ** lang ;
lang = load_lang ( argv[1] );
printf("\n\n%s\n\n", lang[0]);
free_lang ( lang );
return (0);
}
[/code]