|
今天看到下面的這個文章,真的是大愛?。∥恼轮v解的很詳細,很有用! 摘 要:在遠程抄表、智能家居等各種嵌入式系統(tǒng)中,都需要實現(xiàn)數(shù)據(jù)采集和遠程查詢。提出了一種基于goahead和sqlite的實現(xiàn)方案,并給出了實現(xiàn)細節(jié),包括移植編譯安裝以及交互式程序的編寫和其中遇到的問題。本方案在模塊化和擴展性方面要好于其他方案,容易借鑒,已得到成功應(yīng)用。 關(guān)鍵詞:goahead;sqlite;嵌入式web服務(wù)器;嵌入式數(shù)據(jù)庫
Data Gathering and Querying based on Goahead and SQLite Abstract: Many embedded systems, like remote meter reading system and intelligent home system,, need data gathering and remote querying. This paper proposed a solution based on goahead and sqlite, including cross compiling, installing, interaction programming and some problems. This solution has better modulization and expansibility than other solutions, which has already used in intelligent home remote control system. Key words: goahead;sqlite;embedded web server;embedded database
1 引 言在遠程抄表系統(tǒng)、智能家庭網(wǎng)關(guān)[1]等大量的嵌入式系統(tǒng)中,都涉及到數(shù)據(jù)的存儲和查詢。對于數(shù)據(jù)的存儲,考慮到數(shù)據(jù)的一致性管理以及程序編寫的便捷,普遍采用嵌入式關(guān)系數(shù)據(jù)庫。對于數(shù)據(jù)的查詢,分本地查詢和遠程查詢。諸如無線點菜系統(tǒng),需要編寫界面友好的GUI應(yīng)用程序查詢本地和遠程數(shù)據(jù),此時需要配備液晶和觸摸屏等外圍設(shè)備,成本因此增加,所以大量的嵌入式設(shè)備都只需要進行遠程的數(shù)據(jù)管理和查詢,普遍采用的技術(shù)是嵌入式web服務(wù)器和編寫動態(tài)web頁面程序訪問數(shù)據(jù)庫。 目前,嵌入式web服務(wù)器和嵌入式數(shù)據(jù)庫種類繁多,選擇什么樣的嵌入式數(shù)據(jù)庫和web服務(wù)器成為問題的焦點。在工業(yè)界,廣泛采用的嵌入式數(shù)據(jù)庫為SQLite,廣泛采用的嵌入式web服務(wù)器主要有兩種:BOA和goahead。前者已有大量的文獻記錄,后者相對要少得多。 筆者在智能家居遠程控制系統(tǒng)的研發(fā)中,使用zigbee無線模塊接收部署在各個點的溫度、濕度、煙霧傳感器數(shù)據(jù),這些數(shù)據(jù)都統(tǒng)一存儲在基于S3C2410的中央處理模塊中,該模塊集成了SQLite和goahead,前者存儲數(shù)據(jù),后者提供遠程數(shù)據(jù)管理。經(jīng)過比較分析,筆者認(rèn)為Goahead在功能、移植、使用、擴展等方面更甚一籌。實際上,這兩種軟件的獨立使用并不困難,難點在于如何在Goahead中訪問SQLite數(shù)據(jù)庫以及如何在頁面上顯示出來,諸多文獻[2]都只是簡單提及各自的API函數(shù),沒有給出具體實現(xiàn),實際上,在編譯和集成應(yīng)用中有很多需要解決的問題,這些問題成為工程應(yīng)用的一個個障礙,本文將逐一探討。 2 軟件架構(gòu)筆者所用的實驗平臺是北京博創(chuàng)科技的S3C2410-S嵌入式教學(xué)平臺,操作系統(tǒng)為嵌入式Linux 2.6.18。由于該平臺沒有zigbee無線模塊,因此單獨設(shè)計了一款采用CC2430的zigbee模塊用于數(shù)據(jù)和控制信息的無線傳輸,zigbee模塊與嵌入式平臺使用串口通信,為了使系統(tǒng)各功能之間模塊化更強,編寫了獨立的串口通信程序?qū)iT用于接收和存儲來自zigbee模塊的數(shù)據(jù),而遠程數(shù)據(jù)的查詢只針對已經(jīng)存儲到SQLite中的數(shù)據(jù),通過嵌入式web服務(wù)器以及編寫相應(yīng)的動態(tài)頁面程序來實現(xiàn)。 Goahead是一款嵌入式web服務(wù)器,它基本上屬于一個HTTP1.0標(biāo)準(zhǔn)的WEB服務(wù)器,對一些HTTP1.1的特性如(持久連接)也提供了支持,支持asp、cgi、embedded JavaScrip腳本語言,能夠運行在Windows CE,VxWorks,Linux等主流平臺上。 SQLite誕生于2000年5月,是實現(xiàn)了SQL 92標(biāo)準(zhǔn)的一個大子集的嵌入式數(shù)據(jù)庫,SQLite的內(nèi)存組織非常高效,只需在很小的內(nèi)存中維護其很小的尺寸,非常適合嵌入式應(yīng)用?! ?/p> 實際開發(fā)中發(fā)現(xiàn),除在Goahead中如何編寫程序訪問數(shù)據(jù)庫并在頁面中顯示出來之外,Goahead與SQLite的移植與編譯也非常重要,編譯如果通不過,就無法往下進行。 3 Goahead移植與編譯筆者移植的版本是2.1.8,可到文獻[3]下載。之前的版本在移植時可能與本文所敘述的過程差異較大,不建議使用。Goahead的編譯相對復(fù)雜,筆者認(rèn)為,編譯的不容易成功是影響Goahead普及的重要原因。 用命令tar zxvf webs218.tar.gz解壓,可以看到源碼目錄下有VXWORKS、CE、LINUX等子目錄,進入LINUX子目錄,修改Makefile文件[4]。在該文件開頭“all: compile”之前添加如下的黑斜體部分的文字。 CROSS_COMPILE = armv4l-unknown-linux- CC = $(CROSS_COMPILE)gcc ......(部分省略) CROSS_COMPILE為交叉編譯器的名字,armv4l-unknown-linux-gcc為筆者使用的交叉編譯器,要提前安裝好交叉編譯器,并且將路徑加入到PATH環(huán)境變量中。在該文件末尾將cc -c -o $@ $(DEBUG) $(CFLAGS) $(IFLAGS) $<修改為$(CC) -c -o $@ $(DEBUG) $(CFLAGS) $(IFLAGS) $<,然后在該目錄下直接輸入make進行編譯。 當(dāng)編譯出現(xiàn)main.c:325: warning: the use of `tempnam' is dangerous, better use `mkstemp' 警告時,需要修改main.c (LINUX子目錄) ,在函數(shù)websGetCgiCommName(..)函數(shù)中,將pname1 = tempnam(NULL, T("cgi"));修改為pname1 = (char_t *)mkstemp(T("cgi"));之后警告消除,編譯成功。 接著就是將編譯生成的可執(zhí)行文件和庫文件等下載到開發(fā)板中,然后運行webs,設(shè)置好IP地址,交叉線連接開發(fā)版與PC機,發(fā)現(xiàn)無法連接。解決辦法是直接在main.c的initwebs(...) 函數(shù)中寫入IP地址。
[cpp] view plaincopy
重新編譯后連接成功。筆者也曾在MIPS環(huán)境下用兩個不同版本的交叉編譯器進行編譯,均出現(xiàn)/lib/libc.so.6: version `GLIBC_2.3' not found (required by webs)問題無法運行,網(wǎng)上咨詢該問題的人很多,但很少有人清楚回答。經(jīng)查發(fā)現(xiàn),兩次所使用的GLIBC的版本都是libc-2.2.5.so,低于2.3,很多高版本軟件不僅對GCC編譯器有高版本要求,而且對GLIBC庫也要求高于2.3 版本,實際上只要高于所指定的2.3版本即可,并不要求必須等于該版本。 解決辦法是重新找一個高版本GLIBC庫(ftp://ftp.gnu.org/)重新編譯,或重新找一個已經(jīng)編譯好的工具鏈,或使用crosstool制作交叉編譯器。第一種方法不太容易成功。在拷貝覆蓋glibc庫時,注意符號連接信息不能丟失,用cp –raf方式拷貝,再次運行,此時會提示更莫名其妙的錯誤segmentation fault,通過ldd webs發(fā)現(xiàn)webs不僅依賴libc庫,而且還依賴ld,也是版本問題,于是將ld相關(guān)庫也從交叉編譯安裝目錄的lib下拷貝到嵌入式開發(fā)板根文件系統(tǒng)的lib下,重新運行就可以了。 4 SQLite移植與編譯同樣,在編譯SQLite前需要提前安裝和配置好交叉編譯環(huán)境,下載SQLite源碼[5]。用命令tar zxvf sqlite-3.5.9.tar.gz解壓,然后運行配置文件./configure --host=arm-linux --prefix=/dist-sqlite3 --disable-tcl,在開發(fā)板上如果不需要使用tcl,使用--disable-tcl參數(shù),--prefix是安裝路徑,可以隨意指定。注意等號右邊不能留有空格,如果一切順利,會根據(jù)系統(tǒng)環(huán)境生成Makefile。下一步就是編譯和安裝make && make install。如果編譯通過,會在/dist-sqlite3路徑中生成三個目錄:bin 有可執(zhí)行文件sqlite3 ,可以放在開發(fā)板上運行;include 內(nèi)有sqlite3.h與sqlite3ext.h兩個頭文件;lib 內(nèi)有libsqlite3.a靜態(tài)庫文件和libsqlite3.so.0.8.6動態(tài)庫文件。本文提到的SQLite版本相對以前的某些低版本而言編譯要簡單很多,所以要注意選擇,剩下的是程序的編寫。 SQLite的C語言API以下面三個核心函數(shù)為基礎(chǔ): [cpp] view plaincopy
其中, 前兩個函數(shù)用于打開與關(guān)閉數(shù)據(jù)庫, sqlite_exec函數(shù)用來處理SQL查詢, 它含有五個參數(shù):(1)調(diào)用sqlite_open 函數(shù)獲得的數(shù)據(jù)庫結(jié)構(gòu)的指針。(2)容納了一個或更多SQL語句的字符串。(3)指向Callback函數(shù)的指針,查詢結(jié)果的每一條記錄都調(diào)用該函數(shù)。(4)成為Callback函數(shù)第一個參數(shù)的指針。(5)指向錯誤串的指針。其中,Callback函數(shù)由用戶編寫,用來接收查詢結(jié)果, 查詢結(jié)果的每一條記錄都會調(diào)用Callback 函數(shù)一次,其原型為:int Callback(void* pArg, int argc , char* * argv, char* *columnNames);其中, 第一個參數(shù)接收客戶代碼的任意信息; 第二個參數(shù)是字段數(shù); 第三個參數(shù)是一個字符串?dāng)?shù)組, 每一個串是記錄的一個字段值; 第四個參數(shù)是字段名。Callback函數(shù)是用戶根據(jù)應(yīng)用編寫的, 正常應(yīng)返回0。如果Callback函數(shù)非0, 則查詢失敗。文獻[6]有詳細的參考范例。 5 Goahead中集成SQLite無論是數(shù)據(jù)查詢還是遠程管理,都需要web服務(wù)器支持動態(tài)頁面程序的編寫和運行。Goahead支持ASP、CGI等多種方式,經(jīng)過比較,推薦使用嵌入式Javascript方式。 嵌入式Javascript采用表單提交的方式,嵌入已經(jīng)實現(xiàn)的C函數(shù)至頁面文件中,在提交時,由已經(jīng)在系統(tǒng)定義并注冊的函數(shù)來接收處理,通過代碼寫web頁面來實現(xiàn)輸出。其過程主要涉及以下幾個方面: 1、頁面設(shè)計。嵌入式Javascript文件為ASP文件,其內(nèi)容可按照標(biāo)準(zhǔn)的頁面來設(shè)計,要達到交互使用,則必須響應(yīng)用戶提交,可以通過在頁面中加入<form action=/goform/formTest method=POST></form>來實現(xiàn),其中formTest即為響應(yīng)時系統(tǒng)調(diào)用的注冊后的函數(shù)。其函數(shù)格式為:static void formTest(webs_t wp, char_t *path, char_t *query); 2、注冊Form提交函數(shù)。在main.c中定義websFormDefine(T("formTest"), formTest); 3、formTest函數(shù)實現(xiàn)。 在瀏覽器中輸入http://localhost/forms.asp將能看到表單提交和頁面回顯的簡單示例,下面的代碼實現(xiàn)了從SQLite數(shù)據(jù)庫中讀取數(shù)據(jù),并在頁面顯示的基本功能。 [cpp] view plaincopy
由于用到了sqlite的庫函數(shù),需要加上sqlite3.h頭文件以及在編譯時加上sqlite3庫函數(shù),具體為修改Makefile文件,將其中的IFLAGS= -I..改為IFLAGS=-I.. -I/dist-sqlite3/include -L/dist-sqlite3/lib -lsqlite3。 6 結(jié)束語Goahead和sqlite在移植過程中出現(xiàn)的各種問題給移植和應(yīng)用帶來了障礙,兩者之間的融合也是一個技術(shù)難點。筆者嘗試了Goahead交互式編程的多種方法,發(fā)現(xiàn)其中提到的標(biāo)準(zhǔn)CGI方法在程序運行時出現(xiàn)segmentation fault錯誤,還沒有查到解決辦法。不過,本文提到的方法已經(jīng)完全可以滿足數(shù)據(jù)管理的需求,功能擴展和代碼修改都要比CGI簡單清晰。該方法已經(jīng)得到成功應(yīng)用,實際上有類似需求的系統(tǒng)廣泛存在,本文給出的流程以及結(jié)合參考文獻可以輕松地應(yīng)用在其他系統(tǒng)中。 參考文獻: [1]陳一明. 嵌入式數(shù)據(jù)庫的智能家居網(wǎng)關(guān)設(shè)計[J]. 微計算機信息,2009,(11). [2]石為人,張杰等.無線傳感器網(wǎng)絡(luò)嵌入式網(wǎng)關(guān)的設(shè)計與實現(xiàn)[J].計算機應(yīng)用,2006(11): 2525-2527. [3]GoAheadSoftware Inc.http://www./products/webserver/[EB/OL]. [4]goahead的移植.http://blog./u2/86537/showart_1667519.html[EB/OL]. [5]Sqlite download website. http://www./ [EB/OL]. [6]sqlite的移植.http://blog./u2/86537/showart_1676823.html[EB/OL]. |
|
|