原创 基于UB4020EVB的嵌入式数据库SQLite的移植

2009-6-27 11:30 3711 4 6 分类: MCU/ 嵌入式

基于UB4020EVB的嵌入式数据库SQLite的移植<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


 


摘要


 


本文首先对嵌入式数据库SQLite做了简单的介绍,对移植所采用的软硬件平台作了简单的说明。然后以SQLite3为蓝本对移植过程中的细节作了详细的说明,并对移植后的SQLite3数据库进行了测试。测试结果表明,本文所采取的移植方式是有效的。


 


关键字:ARM-Linux、嵌入式、SQLite


 


Port SQLite to UB4020EVB Platform


 


Abstract


 


This paper first give a brief introduction to SQLite database and the hardware and software platform to port. Then demonstrate SQLite3’s porting process to ARM-Linux in detail and test the ported SQLite3. The testing result states that the porting method this paper proposed is effective.


 


Keywords: ARM-LinuxembeddedSQLite


 


1、引言


本文将简要介绍如何在ARM-Linux平台上移植SQLite嵌入式数据库。SQLite是一个采用C语言开发的嵌入式数据库引擎。SQLite的最新版本是3.3.8,在不至于引起混淆的情况下,本文也将其简称为SQLite3


数据库的目标是 实现对数据的存储、检索等功能。传统的数据库产品除提供了基本的查询、添加、删除等功能外,也提供了很多高级特性,如触发器、存储过程、数据备份恢复等。 但实际上用到这些高级功能的时候并不多,应用中频繁用到的还是数据库的基本功能。于是,在一些特殊的应用场合,传统的数据库就显得过于臃肿了。在这种情况下,嵌入式数据库开始崭露头角。嵌入式数据库是一种具备了基本数据库特性的数据文件,它与传统数据库的区别是:嵌入式数据库采用程序方式直接驱动,而传统数据库则采用引擎响应方式驱动。嵌入式数据库的体积通常都很小,这使得嵌入式数据库常常应用在移动设备上。由于性能卓越,所以在高性能的应用上也经常见到 嵌入式数据库的身影。


SQLite是一种嵌入式数据库。SQLite的目标是尽量简单,因此它抛弃了传统企业级数据库的种种复杂特性,只实现那些对于数据库而言非常必要的功能。尽管简单性是SQLite追求的首要目标,但是其功能和性能都非常出色。它具有这样一些特点[1]


l  支持ACID事务(ACIDAtomicConsistentIsolatedDurable的缩写);


l  零配置,不需要任何管理性的配置过程;


l  实现了大部分SQL92标准;


l  所有数据存放在一个单独的文件之中,支持的文件大小最高可达2TB


l  数据库可以在不同字节序的机器之间共享;


l  体积小,在去掉可 选功能的情况下,代码体积小于150KB,即使加入所有可选功能,代码大小也不超过250KB


l  系统开销小,检索效率高,执行常规数据库操作时速度比客户 /服务器类型的数据库快;简单易用的API接口;


l  可以和TclPythonC/C JavaRubyLuaPerlPHP等多种语言绑定;


l  自包含,不依赖于外部支持;良好注释的代码;


l  代码测试覆盖率达95%以上;


l  开放源码,可以用于任何合法用途。


由于这样一些杰出的优点, SQLite获得了由GoogleO’Reilly举办的2005 Open Source Award


由于SQLite具有功能强大、接口简单、速度快、占用空间小这样一些特殊的优点,因此特别适合于应用在嵌入式环境中。SQLite在手机、PDA、机顶盒等设备上已获得了广泛应用。本文将说明如何在ARM-Linux内核的基础上移植SQLite3


2、软硬件平台


本文中采用的硬件平台为南京博芯公司的UB4020EVB(1.5)嵌入式开发板,处理器为东南大学国家专用集成电路系统工程技术研究中心设计SEP4020。采用0.18um标准CMOS的工艺设计,内嵌ASIX CORE(32RISC内核,带8KB指令数据Cache,完全兼容ARM720T内核)SEP4020芯片中集成各种功能,包括:


l  8/16SRAM/NOR FALSH接口,16SDRAM接口


l  硬件NAND FLASH控制器,支持NAND FLASH自启动


l  <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />10M/100M自适应以太网MAC,支持RMII接口


l  64K Byte高速片上SRAM


l  USB1.1 Device,全速12Mbps


l  支持I2S音频接口


l  支持MMC/SD


l  LCD控制器,支持TFT彩屏和STN黑白、灰度屏


l  RTC,支持日历功能/WatchDog,支持后备电源


l  10通道TIMER,支持捕获、外部时钟驱动和MATCH OUT


l  4通道PWM,支持高速GPIO


l  4通道UART,均支持红外


l  2通道SSI,支持SPIMicrowire协议


l  2通道SmartCard接口,兼容ISO7816协议


l  支持最多97GPIO14个外部中断


l  支持外部DMA传输


l  片上DPLL,支持多种功耗模式:IDLESLOWNORMALSLEEP


底层软件系统是以ARM-Linux内核为基础的,目前版本号为SEP4020 Linux SDK 3.1beta


要将SQLite3移植到Sitsang评估板上,除了要有底层操作系统的支持外,还必须要有相应的交叉编译工具链。由于UB4020EVB(1.5)采用的是ARM-Linux作为底层操作系统,因此需要首先安装ARM-Linux工具链。关于ARM-Linux工具链的安装可以参阅文献[4]ARM-Linux工具链通常安装在/usr/local/arm-linux/bin/目录下,通常以arm-linux-开头。本文中将会涉及到的主要是arm-linux-gccarm-linux-ararm-linux-ranlib这样三个工具。


3、移植过程


首先从http://sqlite.org下载SQLite 3.3.8。本文中假设将sqlite-3.3.8.tar.gz下载到/root目录下。然后,通过下列命令解压缩sqlite-3.3.8.tar.gz并将文件和目录从归档文件中解压出来:


[root@localhost ~]# tar zxvf sqlite-3.3.8.tar.gz


解压抽取完成之后将会在/root目录下生成一个sqlite-3.3.8/子目录,在该目录中包含了编译所需要的所有源文件和配置脚本。SQLite3的所有源代码文件都位于sqlite-3.3.8/src/目录下。


与在PC环境下编译SQLite3不同,不能通过sqlite-3.3.8/目录下的configure脚本来生成Makefile文件。而是必须手动修改Makefile文件。在sqlite-3.3.8/目录下有一个Makefile范例文件Makefile.linux-gcc


首先通过下面的命令拷贝此文件并重命名为Makefile


[root@localhost ~]# cd sqlite-3.3.8


[root@localhost sqlite-3.3.8]#cp Makefile.linux-gcc Makefile


接下来,用gedit打开Makefile文件并手动修改Makefile文件的内容。


[root@localhost sqlite-3.3.8]#gedit Makefile


找到Makefile文件中的下面这样一行:


TOP = ../sqlite


将其修改为:


TOP = .


找到下面这样一行:


TCC = gcc -O6


将其修改为:


TCC = arm-linux-gcc -O6


找到下面这样一行:


AR = ar cr


将其修改为:


AR = arm-linux-ar cr


找到下面这样一行:


RANLIB = ranlib


将其修改为:


RANLIB = arm-linux-ranlib


找到下面这样一行:


MKSHLIB = gcc -shared


将其修改为:


MKSHLIB = arm-linux-gcc -shared


注释掉下面这一行:


TCL_FLAGS = -I/home/drh/tcltk/8.4linux


注释掉下面这一行:


LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl


原则上,对Makefile的修改主要包括两个方面:首先是将编译器、归档工具等换成交叉工具链中的对应工具,比如,gcc换成arm-linux-gccar换成ar-linux-arranlib arm-linux-ranlib等等;其次是去掉与TCL相关的编译选项,因为默认情况下,将会编译SQLite3Tcl语言绑定,但是在移植到ARM-Linux的时候并不需要,因此将两个与TCL有关的行注释掉。


Makefile的所有修改总结如下所示。


TOP = ../sqlite


TOP = .


73


TCC = gcc -O6


TCC = arm-linux-gcc -O6


81


AR = ar cr


AR = arm-linux-ar cr


83


RANLIB = ranlib


RANLIB = arm-linux-ranlib


86


MKSHLIB = gcc -shared


MKSHLIB = arm-linux-gcc -shared


96


TCL_FLAGS = -I/home/drh/tcltk/8.4linux


#TCL_FLAGS = -I/home/drh/tcltk/8.4linux


103


LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl


#LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl


接下来,还需要修改的一个的文件是main.mk,因为Makefile包含了这个文件。找到这个文件中的下面一行:


select.o table.o tclsqlite.o tokenize.o trigger.o \


把它替换成:


select.o table.o tokenize.o trigger.o \


也就是把该行上的tclsqlite.o去掉。这样编译的时候将不会编译SQLite3Tcl语言绑定。


自此,修改工作就完成了,接下来就可以开始编译SQLite3了,这通过make命令即可完成:


[root@localhost sqlite-3.3.8]# make


编译完成之后,将在sqlite3.3.8/目录下生成库函数文件libsqlite3.a和头文件sqlite3.h以及sqlite3,这就是所需要的三个文件了。


4、程序测试


这里以SQLite官方站点http://sqlite.orgquick start文档中的测试程序为例对移植到ARM-Linux上的SQLite3进行测试。


测试一:该程序清单如下:


#include <stdio.h>


#include <sqlite3.h>


 


static int callback(void *NotUsed, int argc, char **argv, char **azColName)


 {


    int i;


 


    for (i = 0; i < argc; i++ )


            {


 


         printf("%s = %s\n", azColName, argv? argv : "NULL");


 


            }


   printf("\n");


   return 0;


}


 


int main(int argc, char **argv)


{


    sqlite3 *db;


    char *zErrMsg = 0;


    int rc;


 


    if (argc != 3)


         {


   


    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);


    exit(1);


 


         }


    rc = sqlite3_open(argv[1], &db);


 


    if (rc)


          {


 


    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));


    sqlite3_close(db);


    exit(1);


 


           }


    rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);


 


    if (rc != SQLITE_OK)


          {


 


    fprintf(stderr, "SQL error: %s\n", zErrMsg);


    sqlite3_free(zErrMsg);


 


         }


 


 


    sqlite3_close(db);


    return 0;


}


1、将此源程序保存为test.c,然后,通过如下命令编译该程序:


[root@localhost sqlite-3.3.8]# arm-linux-gcc -I /root/sqlite-3.3.8/ -L /root/sqlite-3.3.8 -o test test.c -lsqlite3


上述编译命令中:


l  -I /root/sqlite-3.3.8指明了头文件sqlite3.h所在的目录;


l  -L /root/sqlite3.3.8 指定了库函数文件libsqlite3.a所在的目录;


l  -o test指定编译生成的文件名为testtest.c是源程序文件;


l  -lsqlite3指明要链接静态库文件libsqlite3.a


编译完成后,可以通过NFS或者tftptest下载到UB4020EVB开发板上,通过ls命令可以看到test的大小只有300K左右:


[root@Sitsang2 root]$ll -h test


-rwxr-xr-x 1 root root 323.5k Jan1 00:07 test


接下来就可以测试test程序了。test程序接受两个参数:第一个参数为数据库文件名,第二个参数为要执行的SQL语句。程序中与SQLite3API相关的地方主要有四个:第27行的sqlite3_open(),第33行的sqlite3_exec(),第30行和第38行的sqlite3_close(),第36行的sqlite3_free()。关于SQLite3API接口请参阅文献[1]


2、将可执行文件test拷贝到根文件系统nfs


[root@localhost sqlite-3.3.8]#cp test /nfs


3、开发板上电开启,进入文件系统。


下面是测试test程序的完整过程,(注意的是如果由于命令较长,每一个命令都可分成了多行输入,这样看起来要清楚一些)。


4、建立名为wenruyou.db的数据库文件和tb10数据表,表中包含两个字段,字段name是一个变长字符串,字段number的类型为smallint,如下:


/ #./test wenruyou.db "create table tbl0(name varchar(10), number smallint);"


向数据库的tbl0表中插入了两条记录(‘cyc’,1)(‘dzy’,2)


/ #./test wenruyou.db "insert into tbl0 values('cyc', 1);"


/ #./test wenruyou.db "insert into tbl0 values('dzy', 2);"


查询表tbl0中的所有内容,与预期的一样,这条命令打印除了数据库中的两条刚插入的记录:


/ #./test wenruyou.db "select * from tbl0;"


name = cyc


number = 1


name = dzy


number = 2


由此可以得出结论,这几条命令确实都已经按照预期的目标工作了。


同时,在向数据库中插入上面所示的数据之后,可以看到数据库文件wenruyou.db大小已经发生了变化:


[root@Sitsang2 root]$ll -h wenruyou.db


-rw-r--r-- 1 root root 2.0k Jan1 00:18 wenruyou.db

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

<?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />


此时数据库文件wenruyou.db的大小为2K。自此,SQLite3数据库在UB4020EVB开发板上移植完成。测试结果表明数据库能够正常工作。以上步骤过程如下图1示:

点击看大图


1 测试一过程


测试二:自动生成的sqlite3


1、将sqlite3拷贝到根文件系统nfsbin下:


[root@localhost sqlite-3.3.8]# cp sqlite3 /nfs/bin


2、加电并启动开发板,文件系统启动后,进入bin


/ # cd bin/


3、执行“sqlite3 wry.db”,结果(如图2)所示。


/ tmp # sqlite3 wry.db



点击看大图如图2


       4、此时,执行“.tables”,没有输出,因为现在还没有建表。


/tmp #.tables


       5、下面演示下用SQL语句建立一张表。输入“create table yihan(name varchar(10),age smallint);(如图3)



点击看大图3


6、现在可以执行“.tables”,就会看到刚才创建的表了(如图4)


点击看大图4


       7、我们向刚创建的yihan表中添加数据,使用命令“insert into yihan values("wenruyou",25);(如图5)


 sqlite> insert into yihan values("wenruyou",25);



点击看大图5


8、可以使用命令“select * from yihan;”,来查看表中的数据(如图6)。我们会发现刚才插入的数据显示出来了。


sqlite> select * from yihan;



点击看大图6


9、执行“.quit”,退出SQLite(7)


sqlite> .quit


 点击看大图7


       10、至此,两种SQLite程序测试完毕。


5、结论


SQLite是一个优秀的嵌入式数据库。本文详细描述了如何将SQLite3移植到ARM-Linux平台上,并对移植后的SQLite3进行了简单的测试。SQLite功能强大、效率高、零配置、体积小等诸多优点使得它很适用于嵌入式移动设备环境中。因此本文给出的移植SQLite3的细节具有积极意义。由于SQLite3采用C语言开发,因此可移植性非常好。本文所讨论的方法稍加修改也可适用于其它操作系统平台。


参考文献


[1] The Definitive Guide to SQLite[]Michael Owens著。Apress2006


[2] http://sqlite.org


[3] SQLite移植手记。Hily Jiangwww.sqlite.com.cn200611


[4] SEP4020 Linux2.6.16 SDK Develop ManualVersion 3.0 Beta1),南京博芯电子技术有限公司,20094

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户174379 2009-6-25 20:50

小弟不才,还不是研究生,目前是博芯一员工!

用户1361860 2009-6-25 19:14

BZ是博心的员工还是大龙的研究生啊
相关推荐阅读
用户174379 2009-09-29 14:05
PPPOE的移植及使用(超级详细)
    最近很忙,也发生了好多意料之外的事情,所以好久没写日志了。这期间,做的东西也不少,很杂,什么都搞,什么都是会些。    前一段时间,参考黎明学长的文章做了一个PPPOE,自己写了一篇更加详细的...
用户174379 2009-09-01 21:29
月薪一万的乞丐给我上了震撼的一课
我拎着刚买的levi’s从茂业出来,站在门口等一个朋友。一个职业乞丐发现了我,非常专业的、径直的停在我面前。这一停,于是就有了后面这个让我深感震撼的故事,就象上了一堂生动的市场调查案例课。为了忠实于这...
用户174379 2009-09-01 14:33
“volatile” 的理解
MSDN Library中写到: volatile 关键字表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈...
用户174379 2009-08-29 16:54
郁闷!!
    今天调了一下午的LCD,现在还没搞定。破屏连一点反应都没有。我都要崩溃了。。。。   还要努力,加油。。。。 ...
用户174379 2009-08-26 12:29
2009师资培训PPT之十二(系统启动与Boot Loader)
完。。。。。...
用户174379 2009-08-25 19:01
2009师资培训PPT之十(MiniGUI编程与Sqlite编程)
未完待续。。。。。。。。。 ...
EE直播间
更多
我要评论
2
4
关闭 站长推荐上一条 /3 下一条