SQLite在嵌入式Web服务器中的应用
雷小俊
(大连理工大学电子与信息工程学院,大连,116023)
摘要:介绍了基于ARM的嵌入式Web服务器的系统组成与工作原理,SQLite系统的特点和体系结构。在arm-linux平台上成功移植了SQLite,。结合表单和CGI技术,并利用SQLite提供的C语言API,成功地实现了客户与SQLite嵌入式数据库系统的动态交互。此方案可以广泛应用在工业设备远程控制、远程家庭医疗设备、信息家电控制中心等应用领域。
关键词:SQLite;嵌入式系统;Web服务器;CGI
TheApplication of SQLite in Embedded Web Server
LeiXiao-jun(Dalian University ofTechnology, School of Electronic and Information Engineering, Dalian,116023)
Abstract:This article explained the principle and the constitution ofembedded web server basedon ARM , the characteristic and the systemstructure of SQLite system. SQLite was transplanted to arm-linuxembedded platform successfully. The dynamic alternation betweenclients and
SQLitewas built by C API that was offered by SQLite, which was used by Formtechnology and CGI technology. This scheme can be applied in variousfields, such as remote industry automatization equipment, remotefamily medial treatment equipment, control centre of InfromationAppliances and so on.
Keywords: SQLite; embedded system; Web server; CGI
引言
嵌入式Web服务器系统用已有的Internet网络,远程不需要专用的监控软件,操作、维护方便,体积小,适用范围广泛,广泛应用于网络传感器、信息家电、工业自动化、局部环境自动监测等领域,成为后PC时代研究的热点[1]。
但由于TCP/IP通讯协议复杂,它对于计算机的存储器、运算速度等的要求比较高,因此实现嵌入式Web服务的接入在技术上有一定的难度。目前,主要采取以下三种策略:一是采用已在其上实现了TCP/IP协议的芯片,专门充当系统的通信控制器。但是由于没有一个专用芯片会实现所有的TCP/IP协议功能,因此这些芯片都有各自的局限性,这种方案一般只用于专用的系统;二是采用网络接口芯片+精简TCP/IP协议。这种方案要自行开发实现TCP/IP协议的软件,因此开发周期比较长。功能受到一定的限制;三是采用高性能的微处理器+嵌入式操作系统。比如采用32位ARM微控制器,其上运行嵌入式Linux、VxWorks等嵌入式操作系统。在此平台上可嵌入较完整的TCP/IP协议,实现较强的Web服务功能。并且系统中能集成多种接口部件,可以完成较多复杂的功能。这种方案随着高档处理器成本的降低以及开源软件的进一步丰富,其应用范围必将越来越大。
从嵌入式Web服务器已实现的功能来看,目前大多数的嵌入式Web服务器只是一个实施远程监控的平台,实现了由Internet外网协议向被监控对象内部通信协议转换的功能,即只是实现了一个网关的功能。而随着市场上各种信息产品功能的不断丰富,人们开始要求能通过嵌入式Web服务器对这些产品的数据信息进行管理(检索、排序等)、共享。基于此,本论文提出在基于ARM的嵌入式Web服务器中内嵌一小型数据库管理系统,在服务器端应用程序中调用数据库提供的API函数完成服务器对数据库的访问与更新,进一步扩展嵌入式Web服务器的功能。以适应其在一些高端场合中的应用需求。
1嵌入式Web服务器设计与工作原理
1.1嵌入式Web服务器的硬件结构
如上所述,为了进一步扩展嵌入式Web服务器的功能,以提供对数据资源的处理能力,采用了以ARM9微处理器+嵌入式Linux操作系统做嵌入式Web服务器平台,系统硬件结构图如图1所示。Web服务器中的微处理器选用ATMEL公司的AT91RM9200微处理器,在180MHz的工作频率下运行速度为200MIPS。能够实现作为网络协议转换、控制数据转发以及数据处理等的工作要求。以太网接口芯片选用符合IEEE802.3协议的接口芯片DM9161,完成与局域网在物理层上的通信任务,采用RJ-45接口,可以直接连接到局域网上。存储模块采用Fujitusn公司的MBM29LV320BENOR Flash(4M)和SamsungK9D1208VOM NANDFlash(64M),分别用于存放系统启动代码、linux内核、用户应用程序等和系统数据。UART接口用于与被监控设备微控制器的UART连接通信。
1.2嵌入式Web服务器的软件实现
为完成既定的嵌入式Web服务器的功能,软件开发分以下四个模块来进行:第一,由于嵌入式系统本身不具备自主开发能力,必须有一套开发工具有交叉编译环境才能进行开发,所以首先建立交叉编译环境。第二,BOOtloader的开发或移植。嵌入式系统中的Bootloader是与所用硬件紧密相关的一些指令代码,类似于PC机上的BIOS。第三,完成嵌入式Linux操作系统内核的定制与移植。操作系统内核主要完成进程管理、进程间通信、内存管理、任务调度等基本功能。第四完成硬件驱动和应用程序的开发。由于篇幅有限本论文只讨论有关应用程序开发的细节。
嵌入式Web服务器的应用软件构成如图2所示。其中:BOA是一个运行在类UNIX系统中的小型Web服务器开源软件,对它的移植细节不再详述。它的基本功能包括:和客户端建立连接,接收客户提交的HTTP请求消息,将HTTP响应消息返回给客户,关闭连接等;CGI(CommonGatewayInterface公共网关接口)规范给出了Web服务器和CGI应用程序进程之间传递信息的标准,是嵌入式Web服务器中实现客户与服务器动态交互的主要手段;网关应用程序也叫CGI应用程序,遵循CGI规范和Web服务器进行交互,并能通过在网关
2嵌入式数据库SQLite的特征与体系结构
同普通数据库相比,嵌入式数据库就是一种具备了基本数据库特性的数据文件[2]。嵌入式数据库通常与操作系统和具体应用集成在一起,无须独立运行数据库引擎,由程序直接调用相应的API去实现对数据的存取操作。嵌入式数据库与其它数据库产品的区别是,前者是程序驱动式,而后者是引擎响应式。嵌入式数据库的一个很重要的特点是它们的体积非常小,编译后的产品也不过几十KB , 在一些移动设备上也极具竞争力。
从目前嵌入式应用的发展趋势来看,嵌入式数据库的实现必须充分体现系统的可定制
性,即系统选择的技术路线要面向具体的行业应用,因而研究源码开放的嵌入式数据库具
有特殊意义。并且嵌入式开发中有很多应用,用户需求决定了开发中需要有一个大小适中且
功能齐备的数据库来实现对数据的管理。
在目前常用的数据库产品中,Oracle,IBMDB等功能强大,但系统宠大,需付费使用,
适用于大型商业型数据库。而MySQL在保持中等体积的情况下,提供了较为适用的功能已成为中小规模数据库应用的首选,但商业应用也需付费,而且对于嵌入式系统来说空间占用仍然太大。小型数据库mSQL适用于嵌入式系统,但只有30天的使用期限,并非完全开源。而在开源的数据库中,PostgreSQL功能完善,但体积较大。而BerkeleyDB则是开发难度比较大。SQLite则在体积与功能之间做到了较好的平衡,是“理想的嵌入式数据库”[3]。
2.1SQLite 的典型特征
SQLite是D.RichardHipp开发出来的用一个小型C库实现的一种强有力的嵌入式关系数据库管理体制。SQLite自2000年5月诞生至今,已发展到SQLite3-3.2.1版本。它具有以下特征:
·源代码开放:作为产品的开发,开放的代码不仅可以减少产品的生产成本,更重要的
是为产品的维护完善和稳定运行都提供了最为彻底的解决手段。
·体积较小,速度快:全部源码大约3万行C代码,250KB。比目前流行的大多数数据库对数据的操作要快。
·功能完善:支持ACID事务,既保证了数据的完整性,也会提高运行速度。它提供了对SQL92的大多数支持:支持多表和索引、事务、视图、触发器,支持嵌套SQL。SQL数据库储
存在单一磁盘文件中,可以在不同字节顺序的机器间自由共享,支持数据库大小至2TB。
·提供丰富API支持:目前SQLite支持包括C/C++、PHP、Perl等编程语言通过API来和数据库文件进行通信。
2.2SQLite 的体系结构
SQLite体系结构如图3所示[4]。主要由以下几个主要的子系统组成:接口(Interface)
是一个C语言库,即使使用的是不同语言的API,在底层执行的都是C语言库。从接口接收到命令后传到SQL命令处理器(SQLCommandProcessor),SQL命令处理器是由三个独立的步骤组成:标志处理器(Tokenizer)、分析器(Parser)、代码生成器(CodeGenerator)。SQLite
的分析生成器(柠檬分析器lemon),类似于windows/linux中的yacc和bison。但是柠檬分析
器可以更快速地生成高效的代码,并有效地防止资源的泄漏。
虚拟机(VirtualMachine)是为操作数据库文件而执行的一个抽象的计算机引擎。在虚拟机和低层存储、恢复程序之间,SQLite使用了一个抽象层执行B-树,页面缓冲(Pager),和操作系统接口(OSInterface)。B-树结构,用于存储数据库到磁盘,这样可以通过减少磁盘的查找来达到快速访问数据的目的。页面缓冲主要处理读、写以及B-树存储机制所需的数字缓冲,包括为了保证事务原子性的回退及提交操作所需的缓冲。操作系统接口主要是为了方便在不同平台的操作而执行的一个底层与操作系统有关的抽象层。
体系结构的核心是虚拟数据库引擎(VDBE)。VDBE完成与数据库操作相关的全部操作并且是客户和存储之间信息进行交互的中间单元。在SQL语句被分析之后,代码生成器将分析树翻译成一个袖珍程序,随后这些袖珍程序又被组合成用VDBE的虚拟机器语言表示的一系列指令。如此反复,VDBE执行每条指令,最终完成SQL语句指定的查询请求。
3SQLite 的应用开发
如前所述,嵌入式Web服务器端的应用程序是建立在CGI基础之上的。因此项目中SQLite的应用开发就是如何应用CGI程序建立、访问、更新SQLite数据库的过程。可以分为三步来完成:
(1)建立一个后端数据库。后端数据库与以往的数据库相比最大的好处就是省去了前端界面的开发,因为数据库的所有操作来自于网络,网络中的所有请求都是以HTML数据流的形式存在的,所以数据库的前端界面直接写入HTML文档,与Web页面融为一体,不仅界面友好,而且开发简单。
在SQLite嵌入式数据系统中提供了两种工具供新建、访问与修改数据库。如果习惯在图形界面方式下工作的话,可以选择SQLite数据库浏览器(SQLiteDatabase Browser)。这个工具可以运行在包括windows和linux等多种平台了,并且开放的源代码在网上可以下载。不过很显然,这个工具需要有显示输出设备来做基础,所以在开发应用中可以根据自己的硬件条件来决定取舍。另一种方法就是命令行的方式。在SQLite嵌入式数据库中绑定了一个命令行接口,使得可以通过输入命令来操作数据库文件。SQLite提供了两种命令方式:一种是SQL语句+“;”,另一种就是点命令方式。例如在SQLite提示符下只要键入:
CREATETABLE users(
idINTERGER PRIMARY,
nameCHAR MOT NULL,
passwordCHAR NOT NULL)
就可以创建一个供客户注册的简单数据库表。可以看出SQLite基本兼容SQL的语法,可以很方便地用命令行方式创建一个数据库文件。
(2)通过HTML文档制作一个Web页面及内建表单。表单是HTML文档中一个比较特别的区域,从Web网页的角度来看,表单为客户提供了一个交互界面,客户将对数库的所有操作都填写在表单控件中,之后浏览器将表单的内容提交给Web服务器端的应用程序,应用程序再根据用户的要求实时地去操作数据库。从应用程序的角度来看,表单为应用程序提供了一种通过Web文档与客户进行交互的机制。这时表单就是数据库的前端界面。由于对数据库的访问只与浏览器有关,这就使得数据库可被不同的机型和操作系统所使用,从而达到了跨平台的目的。
(3)编写CGI程序。一般来讲CGI程序可分为三个部分[5]:解码部分,即将从客户端
获取的诸环境变量进行分析,得到支持CGI程序运行的必要信息,解码属于CGI编程范畴这里不做介绍;功能部分,即利用得到的信息完成CGI程序所实现的功能,如建立与数据库的连接,建立数据库,访问数据库等;输出部分,即将运行的结果返回服务器,最终返回给客户。下面主要说明如何在CGI程序(C代码)中利用SQLite提供的API函数来操作数据库。
使用C语言API,首先要提供文件名和访问模式来调用sqlite_open()连接数据库,然后调用sqlite_exe()函数来执行SQL语句,最后执行sqlite_close()关闭数据库。此外,如果想取回SQL语句访问数据库的结果,就要对每一个记录执行回掉函数callback()。下面结合代码来说明在嵌入式Web服务器中如何将客户的注册信息,通过CGI程序写入数据库文件mydb中的表usrs中的。其中name[],password[]是在CGI程序中定义的两个字符数组,用于存放客户通过表单提交的注冊信息:姓名与密码。
#include
#include
#include“sqlite.h”
#defineMAXQRY 200
main()
{
char*errmsg;
intret;
charqry[MAXQRY];
sqlite*db=sqlite_open(“mydb”,0777,&errmsg);//打开数据库文件
if(db==0)
{
fprintf(stderr,“Couldnot open database:%s\n”,errmsg);
sqlite_freemem(errmsg);
exit(1);
}
sprintf(qry,“INSERTINTO USERS (name, password) \n”
“VALUES(‘%s’,‘%s’)”,name, password);
ret=sqlite_exec (db, qry, NULL, NULL, &errmsg);//SQL 语句的执行程序
if(ret !=SQLITE_OK)
{
fprintf(stderr, “SQLerror: %s\n%s\n”,errmsg, qry);
}
else
{
printf(“%s%s (%s) was inserted as ID %d\n”,name, password,
sqlite_last_insert_rowid(db));
}
sqlite_close(db);//关闭数据库
}
CGI应用程序将标准输出(stdout)作为向Web服务器传递数据的一种重要途径。通常,CGI应用程序将执行结果输出到标准输出,Web服务器从CGI应用程序中的标准输出中读取信息,并将这些信息返回给客户端。因此,在程序中如果要将SQL查询结果输出给客户的话,CGI应用程序中可以使用printf()函数将查询结果以HTML的形式输出到标准输出,进而Web服务器向客户端返回动态页面。实现了客户、Web服务器与SQLite嵌入式数据的交互。
4总结
虽然不同的嵌入式Web服务器的用途各不相同,但是它们有一个共同之处,就是都需要进行数据的处理。目前很多的嵌入式Web服务器系统多数采用文件作为数据存取的逻辑载体。文件作为数据存储载体主要有以下的缺点:一是增加了应用开发的难度与代价,所有的应用都独立重复了数据管理的工作;二是数据共享性差,而数据交互在网络时代是必需的;三是独立性、语义性、移植性差,造成了软件的可重用性差。如果嵌入式Web服务器在设计时采用在数据处理方面具有得天独厚优势的数据库作为数据存储方式,将会极大地丰富嵌入式Web服务器的功能,提高系统的开发效率和系统的可移植性。本论文设计的嵌入式Web服务器,定位于需要高性能的场合,可以在如家庭智能控制中心,POS终端、智能手机以及远程分布式测控等系统中广泛应用。
参考文献
1张喜民,张建国,周利华.微嵌入式系统Web服务器技术.电子科技大学学报(自然科学版).2005,32(1):116-121
2王京谦,万莅新.开源嵌入式数据库BerkeleyDB 和SQLite的比较.单片机与嵌入式系统应用.2005,28(2):5-7
3黄布毅,张晓华.基于ARM-Linux的SQLite嵌入式数据库技术.单片机与嵌入式系统应用.2005,30(4): 21-24
4Chris Newman. SQLite. Indianapolis:Sams Publishing. November2004:5-180
5张文彬,张浩学.CGI 与WEB数据库的研究.哈尔滨理工大学学报.2001,6(6):92-95
6刘峥嵘,张智超,许振山等.嵌入式Linux应用开发详解.北京:版社.2004:435-448