引言
现阶段大部分的系统都是基于上位机的显示界面,结合SQL Server系列的大型数据库,大大浪费了系统的资源,因此,本系统中研究的基于嵌入式SQLite和Apache web技术的融合,是目前嵌入式停车场系统中的一大创新点[12]。
1 Apache技术
1.1 Apache简介
由于在停车场系统中,管理人员要及时地对系统的各个参数进行查询,所以设计一个良好的界面和使用一个优秀的WEB服务器[3]是很重要的。BOA在现在的嵌入式系统中也用的很多,但是不满足停车场系统中的多线程处理机制,而Apache是WEB服务器中功能比较完善的一个软件,它最初源于NCSAhttpd服务器,后来经过多次修改后成为目前世界上最流行的WEB服务器软件之一。Apache取自“a patchy server”,意思是充满补丁的服务器,因为它是自由软件,所以不断有人来为它开发新的功能、新的特性、修改原来的缺陷,可以运行在几乎所有广泛使用的计算机平台之上,具有很好的跨平台和安全性。
Apache具有一些比较重要的特性:
① 支持最新的HTTP/1.1通信协议。
② 简单的基于文件的配置安装过程。
③ 支持通用网关接口。
④ 支持多种方式的HTTP认证方式。
⑤ 支持FastCGI、Socket层(SSL)、Java Servlets(第三方模块)。
1.2 Apache在AT91SAM9260上的移植过程
① 从http://www.apache.org/上面下载apache_1.3.39.tar.gz,解压下载下来的源代码——tar xzf apache_1.3.39.tar.gz,进入apache_1.3.39目录修改Makefile,使用本地的gcc编译器编译。
② 创建一个目标平台为AT91SAM9260版本的目录,将源代码解压至此目录下,修改编译器类型为armlinuxgcc,并按照上述步骤配置和编译。
ARM版本的该程序无法在本机运行,把本地编译的文件apache_1.3.39/src/main/gen_test_char覆盖这个ARM版本的文件,继续编译直至成功。
③ 安装Apache,执行make install,所有ARM版本的程序都安装到了指定的目录下面,把此目录打包成tar cjf apache_1.3.39.tar.bz2 apache_1.3.39,并将目录上传至终端。
④ 修改配置文件,修改 conf/http.conf文件中相关项,保存。至此,Apache在AT91SAM9260平台上的移植完成。
1.3 Apache在AT91SAM9260上的测试过程
在实际的停车场系统中,要求操作人员能实时地对车位进行查询,这就要求服务器工作能实时、高效。因此对Apache服务器做了以下的测试。
在主控制器内部设定一个局域网固定IP地址,比如 192.168.1.116,测试采用个人笔记本PC机,用无线网卡登陆停车场主控制器,显示以下认证画面,如图1所示。
图1 Apache移植测试图
2 SQLite技术
2.1 SQLite简介[4]
SQLite是一个开源的、嵌入式关系型数据库。最初发布于2000年,在便携性、易用性、紧凑性、高效性和可靠性方面有突出的表现。SQLite拥有一个精致的、模块化的体系结构[5],并引进了一些独特的方法进行关系型数据库的管理。它由被组织在3个子系统中的8个独立的模块组成,如图2所示。这个模型将查询过程划分为几个不连续的任务,就像在流水线上工作一样。在体系结构栈的顶部编译查询语句,在中部执行它,在底部处理操作系统的存储和接口[6]。
图2 SQLite的体系结构
2.2 SQLite在AT91SAM9260上的移植过程[9]
① 下载sqlite3.3.8。将下载的代码包解开,将生成sqlite3.3.8目录。
② 修改configure文件,将下面语句注释去掉
#if test "$cross_compiling" = "yes"; then
……
#else
# test "$cross_compiling" = yes &&
……
#else
……
③ 配置并设置相关目录“./configureprefix=/data0/sqlite disabletcl host=armlinux”。
④ 修改Makefile文件,将SQLite3程序以静态链接库方式编译。先需增加libsqlite3.a的编译,再将“sqlite3$(TEXE):$(TOP)/src/shell.c.libs/libsqlite3.la sqlite3.h”改成“lite3$(TEXE): $(TOP)/src/shell.c .libs/libsqlite3.a sqlite3.h”,将“o $@ $(TOP)/src/shell.c .libs/libsqlite3.la \\”改成“o $@ $(TOP)/src/shell.c .libs/libsqlite3.a \\”,上述完成后编译“make”。
对可执行程序去掉一些调试信息如“armlinuxstrip SQLite3”,然后将SQLite3上传至终端。至此SQLite3在AT91SAM9260上的移植完成。
2.3 SQLite测试与API的应用
停车场系统SQLite数据库中包含的信息有车位传感器采集的停车位信息、电池电量传感器采集的电量信息、以及采集信息的时间。因此数据库中必须包含以上信息。
(1) 创建数据库
CREATE TABLE parkinglot (id integer primary key,
车位信息 text not null collate nocase,
电量信息 text not null ,
采集时间 text not null,
Unique (车位信息,电量信息));
(2) SQLiteAPI应用
int sqlite3_open_v2(const char *filename,Sqlite3 **ppDB,Int flags,Const char *zVfs);//数据库打开函数
int sqlite3_close(sqlite3*);//数据库关闭连接函数,如果连接上有打开的事务,则该事务将自动回滚
int sqlite3_exec(sqlite3*,Const char *sql,Sqlite_callback,Void *data Char **errmsg);//解析和执行sql字符串中每个命令,并且提供了获得select语句结果的回调机制
回调函数申明如下:
Typedef int (*sqlite3_callback) (void *,Int,Char **,Char **);
Sqlite3_last_insert_rowid()//获取最后插入记录的主键值
数据库中保存了停车场车位上车位传感器采集的实时车位数据和电量数据,对整个系统的稳定性以及高效性起着至关重要的作用,因此对数据库的测试也是一项重要的工作。SQLite测试页面如图3所示。
图3 SQLite测试页面
3 停车场系统中的Web技术
3.1 CGI技术简介
公共网关接口CGI(Common GatewayInterface) 是WWW技术中最重要的技术之一,有着不可替代的重要地位。CGI是外部应用程序(CGI程序)与Web服务器之间的接口标准,是在CGI程序和Web服务器[10]之间传递信息的规程。CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体。
(1) GET方式获取
对于那些使用了属性“METHOD=GET”的表单(或者没有METHOD属性,这时候GET是其缺省值),CGI定义为:当表单被发送到服务器中断后,表单中的数据被保存在服务器上一个叫做QUERY_STRING的环境变量中。这种表单的处理相对简单,只要读取环境变量就可以了。
(2) POST方式获取
GET的处理方法可以看作是“纯查询(pure query)”类型的,它与状态无关。同样的数据可以被提交任意的次数,而不会引起任何的问题(除了服务器的一些小小的开销)。而现在的POST方式获取就不同了,它要改变一个文件的内容,因而,可以说它是与状态有关的,这也算是POST和GET的区别之一。而且,GET对于表单的长度是有限制的,POST则不然,但相对来说对GET的处理速度就要比POST快一些。
3.2 SQLite、Apache和CGI交互
为了实现在嵌入式系统平台AT91SAM9260上面通过网页形式访问服务器来查询有效信息,采用了在停车场主控制器上的服务器构建一系列网页的方式,当登陆系统网址时将看到以下登陆界面,如图4所示。
图4 Apache登陆页面
图5 系统交互流程图
登陆认证成功后,将进入一系列的车位信息查询界面,管理人员就可以通过在相应的地方输入相关信息来查询停车场系统中的实时参数。比如,在表单中输入停车场编号,则Apache服务器处理表单数据并传给后台CGI采集程序,后台程序通过查询数据库并处理相关事务后,通过打印网页的形式把返回结果显示给用户。系统的交互流程图如图5所示。
3.2.1 本地登录认证及CGI实现
停车场主控制器服务器需要检测操作人员权限,只有规定的人员才能进入系统。本地认证代码为:
int len = atoi(getenv("CONTENT_LENGTH"));
shmid = shmget((key_t)1119,MAX_SIZE,IPC_CREAT | 0666);
ptr = (unsigned char *)shmat(shmid,0,0));
fd = open("/etc/sh-user", O_RDONLY);
用户的用户名和密码存储在主控制器本地FLASH中,掉电不丢失。操作人员输入认证指令后,HTTP服务器会通过GET或者POST方式获取环境变量的内容。在对本地用户集进行核对后,如果用户合法则允许其进入系统内部,如不合法则予以自动退出系统。防止非法用户入侵查询系统。
当管理员用户成功登陆系统后,就可以看到一系列的操作,比如获取实时的车位停车信息等。对每一个停车场系统,以城市名拼音的第一个字母加上数字的形式命名,比如成都的第一个停车场以“cd0001”的格式命名。这样,管理人员在进行查询的时候只要输入相应的名称就可以查询相关信息。网页就以简单的文本输入框的形式接受参数。在相应的表单中,Apache服务器通过从浏览器表单中获取相应数据,经过HTTP协议[11]处理后,由相关环境变量交由后台CGI程序处理。车位信息的采集由无线串状传感器网络部分完成,并存储在本地数据库SQLite中。ARM端后台CGI工作模式流程图如图6所示。
图6 ARM端后台CGI工作模式流程图
表单输入的数据通过URL编码后传输到服务器端,然后服务器对传递进来的URL编码进行解码得到表单数据。CGI表单数据获取函数:
char* getcgidata(FILE* fp, char* requestmethod);
其中第二个参数为获取的环境变量。关键代码如下所示:
if (!strcmp(requestmethod, "GET"))
input = getenv("QUERY_STRING");
else if (!strcmp(requestmethod, "POST"))
len = atoi(getenv("CONTENT_LENGTH"));
input = (char*)malloc(sizeof(char)*(size + 1));
3.2.2 本地数据库SQLite查询
在通用网关接口程序对登陆用户账户进行认证后,开始处理相关数据库操作。处理操作包括查询、插入、更新等。
(1) 查询
iRc = sqlite3_open("/CarParking.db", &database);
"select * from parkinglotwhere rowid in (select max(rowid)from carparking);";
iRc = sqlite3_exec(database, sql, mycallback, data, &acErr);
车位、电量查询页面如图7、图8所示。
图7 车位查询页面
图8 电量查询页面
(2)插入
"INSERT INTO parkinglot(车位号,车位信息,电池电量,时间) VALUES ('%d','有车','-1','%s');"
(3)更新
"update parkinglot set电池电量 = '正常' where车位号 = '%d';"
4 系统测试
对车位管理子系统中的车位传感管理主机进行测试时,通过网页的表单输入指令,后台CGI程序操作本地数据库中传感器串状网络采集的传感器实时信息。此信息是通过主机发送测试数据信息,传感器节点1收到数据并通过串口返回采集信息回应帧给主控制器的。测试的主要信息有车位车辆信息、电池电量信息和采集时间等功能。经过一系列的测试过程,返回的数据与本地数据库中存储的信息一致,能很好地实现用户对停车场信息的查询。用户查询界面和指定了停车场编号的查询返回界面略——编者注。
结语
本文主要探讨了基于Apache的Web技术和嵌入式SQLite技术,并在此基础上应用到了嵌入式停车场系统中。以实际的停车场系统项目为背景,全方位介绍了Apache技术和SQLite技术,同时引入了CGI通用网关接口[12]技术,分析了在项目中技术的具体实现。最后,对整个系统做了系统的测试和分析,测试结果证明基于嵌入式Linux的Apache服务器和SQLite数据库的结合在停车场车位管理主机中的应用具有较好的应用效果和使用价值。