引言
随着Internet技术的成熟和嵌入式技术的不断发展,利用网络实现远程控制已成为一种发展趋势。在嵌入式设备的管理与交互中,基于网络方式的应用开发是目前嵌入式系统开发的主流,这种应用程序的结构采用的是B/S结构,即在嵌入式设备上运行一个支持脚本或具有CGI功能的WEB服务器,能够生成动态交互页面。在远程监控的过程中,通常会产生和处理很多的动态数据,而对数据的存取一般采取两种方式:一种是基于文件方式,另一种是基于数据库方式。基于文件方式来存取数据的缺点是显而易见的,而基于数据库方式的SQLite则可以通过事务进行调度与并发控制,可有效地对数据进行存取、查询等操作,从而提高系统的开发效率和系统的可移植性。
1嵌入式WEB服务器的软硬件设计[1]
嵌入式WEB服务器通过交换机或调制解调器与Internet连接,用户只需通过浏览器访问该远程服务器的IP地址,即可使用该服务器并实现对设备的访问。嵌入式WEB服务器的工作过程,如图1所示。
图1嵌入式WEB服务器的工作过程
图2为硬件系统结构框图。嵌入式WEB服务器采用S3C2410作为整个系统的处理器。S3C2410是Samsung公司的一款基于ARM920T内核的16/32位RISC嵌入式微处理器,主要面向手持设备以及高性价比、低功耗的应用。网络控制部分选用CS8900A作为以太网控制器。Flash选用Samsung公司的容量为64 MB的NAND Flash型K9F1208存储器,SDRAM选用容量为64 MB的HY57V561620AT存储器。
图2硬件系统结构框图
软件设计包括系统引导加载程序Bootloader、配置裁减过的Linux操作系统内核和CRAMFS根文件系统。
2嵌入式WEB服务器的构建[2]
典型的嵌入式WEB服务器有BOA和THTTPD等。这里选用BOA作为嵌入式WEB服务器,BOA是一个非常小巧的WEB服务器,可执行的代码大约60 KB。它是一个单任务的WEB服务器,只能一次完成用户的请求,而不会创建(fork)出新的进程来处理并发连接请求,但BOA支持CGI,并且能为CGI程序创建出一个新的进程来执行。BOA服务器的设计目标是速度快和安全性好,在其站点公布的性能测试中,BOA的性能要好于Apache服务器的性能。
嵌入式WEB服务器BOA和普通WEB服务器一样,能够完成接收客户端请求、分析请求、响应请求、向客户端返回请求结果等任务。嵌入式WEB服务器工作原理如图3所示。
图3嵌入式WEB服务器工作原理
嵌入式WEB服务器主要功能包括:
① 完成WEB服务器的初始化工作,如建立TCP套接字、绑定端口、开始侦听以及等待接收WEB浏览器的连接请求;
② 当有请求连接时,WEB服务器接收来自客户端请求;
③ 接收到客户端的连接请求之后,分析客户端请求,解析出请求的方法、URL目标、可选的查询信息及表单信息,同时根据请求进行相应的处理;
④ WEB服务器完成相应处理后,向WEB浏览器发送响应信息;
⑤ 关闭与客户端的连接。
嵌入式BOA服务器的构建过程如下:
① 从www.boa.org下载BOA源码,BOA的版本为0.94.13。
② 解压。
#tar xzvf boa0.94.13.tar.gz
③ 进入源代码目录。
#cd boa0.94.13/src
④ 运行configure文件,会生成Makefile文件。
#./configure
⑤ 修改Makefile文件,将
CC=gcc,CPP=gcc E改成
CC =armlinuxgcc,CPP = armlinuxgcc E
⑥ 进行交叉编译。
#make
⑦ 去除调试信息,减小文件大小。
#armlinuxstrip boa
3SQLite在ARM平台上的移植[3]
SQLite是由D.Richard Hipp用C语言开发的轻量级嵌入式数据库,它是应用最广泛的嵌入式数据库之一。SQLite的源代码完全开放,可以免费用于任何用途,包括商业目的。SQLite提供了对SQL92的大多数支持,如多表和索引、事务、视图、触发和一系列的用户接口及驱动。
SQLite的体系结构如图4所示。对数据库进行的各种操作都是按照此顺序执行的。顶层是标记处理器(tokenize)和分析器(parser)。底部是经过优化的B树,这样有助于运行在可调整页面缓冲时将对磁盘的查找降到最低。再往下是页面高速缓存,它作用在OS抽象层之上。该体系结构的核心是虚拟数据引擎(VDBE),完成与数据相关的全部任务,并且是客户和存储之间信息交换的中间单元。当SQL语句被分析后,虚拟数据库引擎就开始工作。代码生成器将分析树翻译成一个袖珍程序,随后又被组合成虚拟机器语言表示的一系列指令。
图4SQLite的体系结构
SQLite的主要接口函数有3个,分别是sqlite_open()、sqlite_close()和sqlite_exec()。其中,sqlite_open()用于打开一个SQLite数据库,如果成功打开则返回数据库的句柄,否则返回FALSE;sqlite_close()用于关闭SQLite数据库,无返回值;sqlite_exec()执行相应的SQL命令。
SQLite的移植过程如下:
① 从www.sqlite.org下载sqlite2.8.17.tar.gz源码,并解压。
② 在文件sqlite.h中指定SQLITE_PTR_SZ的值为4,使B树有正确的变量大小。
③ 修改配置文件configure,注释掉$cross_compiling相关的代码。
④ 配置以生成Makefile。
#./configure disable tcl host=armlinux
⑤ 进入Makefile文件,将BCC=armlinuxgccgO2改成BCC=gccgO2。由于编译生成的可执行文件要在ARM开发板上运行,为了方便,将后面指定生成的库libsqlite.la改成libsqlite.a,即编译成静态链接的形式。
⑥ 使用#make命令进行编译,以生成可执行文件sqlite3。
⑦ 去除其中的调试信息,以减小文件的大小。
#armlinuxstrip sqlite3
4基于CGI的数据库访问技术[45]
CGI(Common Gateway Interface,公共网关接口)定义了WEB服务器与外部扩展程序(CGI程序)之间进行交互的接口标准。在WEB环境下,客户端浏览器将数据传送给WEB服务器,WEB服务器通过调用CGI程序实现和WEB浏览器的交互。也就是说,CGI程序负责接收来自客户端的信息并进行相应的处理,将相应的结果再发送给WEB浏览器。CGI程序主要是从环境变量中获取相关信息并处理,最后的结果以HTML的格式输出返回给浏览器。通过编写不同的CGI外部扩展程序,可以完成对WEB网页中表单(Form)数据的处理、数据库的查询及现场设备数据的采集任务,因此客户端用户通过CGI程序和嵌入式WEB服务器就可以完成对动态数据的访问。
嵌入式WEB服务器要访问SQLite,CGI是一个非常不错的选择。CGI是外部扩展应用程序(例如用C语言编写的C脚本语言)与WEB服务器交互的一个标准接口。而CGI标准可简单概括为:CGI程序是通过标准输入(STDIN)或环境变量来得到服务器的输入信息,并通过标准输出(STDOUT)向服务器输出信息。按照CGI标准编写的外部扩展应用程序可以处理WEB浏览器输入的需要协同工作的数据,完成WEB浏览器与WEB服务器的交互操作。
在WEB环境下,浏览器与服务器之间的数据交互,大多是通过HTML中的Form表单实现的。Form提供了两种数据传输的方式——GET与POST。GET方式传输的数据受URL长度的限制,因此传输的数据量小,且在传输数据的过程中是不安全的,而POST方式则不存在上述的缺点,故选择用POST来进行数据的传输。根据CGI规范,对于POST方式,在WEB服务器中需要根据表单提交的数据长度,将其重定向为CGI程序的标准输入,这样CGI程序就可以通过标准输入来得到客户端提交的数据。重定向是通过UNIX管道机制来实现的。
POST方式下CGI的工作原理如图5所示。WEB服务器是WEB浏览器与CGI程序之间的通道。WEB服务器接收到CGI请求后,就创建出一个主进程,同时也将接收到的数据传递给主进程。主进程为了读取来自WEB服务器数据的长度,fork出一个子进程,创建出管道,并将管道的输入端重定向为CGI的标准输入。子进程通过管道将数据长度传递给CGI程序,CGI程序通过标准输出将处理的结果发送给服务器,服务器再将相应信息传递给客户端浏览器并显示出来。
图5POST方式下CGI的工作原理
要实现嵌入式远程数据的采集,先要将嵌入式设备采集的现场数据存储到服务器的SQLite数据库上,然后通过编写相应的CGI程序来访问SQLite数据库。CGI程序必须满足CGI规范,CGI程序使用C语言编写,因此CGI程序可以调用SQLite提供的接口函数来访问数据库,同样要使用sqlite3_open()、sqlite3_exec()和sqlite3_close()这3个接口函数来操作数据库。此外,如果想取回SQL语句访问数据库的结果,就要对每一个记录执行回调函数callback()。