摘 要: 提出了在電梯嵌入式監控中使用SQLite數據庫的方案。在介紹SQLite的特點及監控方案整體結構的基礎上,以電梯B/S" title="B/S">B/S監控CGI程序訪問數據庫為例,著重介紹了SQLite的用法,最后介紹了基于三星2410的監控終端硬件平臺。
關鍵詞: 嵌入式數據庫" title="嵌入式數據庫">嵌入式數據庫 SQLite B/S監控 S3C2410
基于嵌入式的B/S監控方案由于其成本低、體積小、使用方便,越來越受到工程技術人員的關注。與此同時,在設備的嵌入式" title="的嵌入式">的嵌入式B/S遠程監控" title="遠程監控">遠程監控、故障診斷中需交換的數據越來越多,對數據庫的要求越來越高。傳統的桌面數據庫建立的開發模型是數據庫控制應用程序,需要專門的管理和配置,使用復雜、體積大、不便于移植。因此,對適合嵌入式的數據庫的研究已成為數據庫領域一個新的研究方向。
在小區或樓宇的電梯監控中,大多是基于PC機的C/S或B/S監控。一種是利用CAN總線或電話網絡接入PC機,采用電梯監控采集卡向下通過CAN總線與電梯通信,向上通過RS232接口接入PC機。一種是采用以太網的SOCKET方式,由PC機實現B/S或C/S監控。這些方案運用傳統的桌面數據庫來實現基于PC機的C/S或B/S監控,功能相對強大,但成本較高。在智能下移、以太網應用到設備層的趨勢下,研究嵌入式數據庫在電梯B/S監控中的應用是非常有意義的。
1 SQLite數據庫簡介
SQLite是由D.Richard Hipp于2000年編寫的執行自容納、可嵌入、零配置數據庫引擎的小型C庫。它支持多數SQL92標準,可以在所有主要的操作系統上運行,并且支持大多數計算機語言。其作為PHP V4.3中的一個選項引入,已構建在PHP V5中,比MySQL快2倍以上,且完全開放。SQLite雖然比Berkeley DB功能稍弱,但是Berkeley DB不支持SQL,體積比SQLite大,在某些商業應用上不是免費的,況且在開源社區的推動下SQLite的功能在增強,因此SQLite正在成為受歡迎的開源數據庫之一。
嵌入式數據庫來自于其嵌入式運行模式,它使用精簡代碼編寫,零配置,直接在應用程序進程中運行,并且占用資源非常少。嵌入式數據庫系統沒有管理員,具有自調節和自適應能力,能夠“無處不在”。SQLite是一個非常適合嵌入式應用的數據庫,這可以從其設計的目的和獨特的特點看出。SQLite設計的主要目的是簡單:簡單的管理、簡單的操作、簡單地嵌入、簡單的維護。SQLite的特征如下:
(1)零配置。SQLite在使用前不需要安裝設置,不需要進程來啟動、停止或配置,不需要管理員去創建新數據庫或分配用戶權限,在系統崩潰或失電之后自動恢復。
(2)無服務器。大多數SQL數據庫引擎是作為一個單獨的服務器進程被執行。訪問數據庫的程序使用某種內部進程通信(典型的是TCP/IP)與服務器通信,完成發送請求到服務器和接收查詢結果的工作。SQLite不采用這種工作方式。使用SQLite時,訪問數據庫的程序直接從磁盤上的數據庫文件讀寫,沒有中間的服務器進程。
(3)精簡性。當尺寸優化后,在不減少功能的情況下,整個SQLite庫小于225KB。如果在編譯時去掉一些不需要的特性,庫的大小能被減小到170KB。IBM最新發行的CloudScape數據庫引擎是2MB的罐文件,壓縮后仍比SQLite大10倍;Firefox宣稱其客戶訂制的庫只有350KB,但是不包括數據庫引擎;來自Sleepycat的Berkeley DB庫是450KB,并且刪去了SQL支持。通過比較可知:SQLite非常小。
(4)簡單的訪問。一個SQLite數據庫是一個單獨的普通磁盤文件,能夠被定位在路徑層次的任何地方。如果SQLite能讀寫磁盤文件,則它也能訪問數據庫。大多數SQL數據庫引擎趨向于把數據存為一個大的文件集合,通常這些文件在一個標準的定位中,只有數據庫引擎本身能訪問它。
(5)可變長度的記錄。一般的SQL數據庫引擎在表中為每一個記錄分配一個固定的磁盤空間數,SQLite只使用一個記錄中實際存儲信息的磁盤空間數。顯然,這會使數據庫非常小,同時,由于在磁盤上移動的信息很少,也使數據庫很快。
SQLite不僅小、快,而且簡單、可靠,這是它受歡迎的主要原因。對于嵌入式場合,管理、執行、維護的簡單化比企業數據庫引擎提供的許多復雜應用更重要,因此SQLite數據庫是一個很好的選擇。
2 電梯嵌入式B/S監控系統" title="監控系統">監控系統的整體結構
本監控系統分為兩層:嵌入式終端、遠方樓宇中心或電梯公司的監測中心。監控軟件的主要功能是:與電梯通信接口通信,采集電梯運行狀態和故障數據并存入數據庫;對故障報警優先處理,自動發短信至維保人員手機,并將現場數據實時存入數據庫,以便進一步故障分析和統計。數據庫成為連接前后臺的中間件,存儲狀態數據供B/S遠程監控和本地LCD顯示,同時接收瀏覽器和本地鍵盤輸入,由通信程序、CGI程序完成控制命令的下傳及運行狀態的上傳;同時數據庫還實現故障的分析統計和查詢。軟件程序主要分為四個模塊:與電梯接口的CAN/RS485通信程序,GPRS故障報警程序,本地的人機交互程序,遠程B/S監控程序。
3 嵌入式數據庫SQLite的應用
3.1 SQLite的C語言API函數
嵌入式數據庫SQLite的C語言API以下面三個核心函數為基礎:
sqlite*sqlite_open(const char*dbname,int mode,char**errmsg);
void sqlite_close(sqlite*db);
int sqlite_exec(sqlite*db,char*sql,int(*Callback)(void*,int,char**,char**),void*parg,char**errmsg);
其中,前兩個函數用于打開與關閉數據庫,sqlite_exec函數用來處理SQL查詢,它含有五個參數:
(1)調用sqlite_open函數獲得的數據庫結構的指針。
(2)容納了一個或更多SQL語句的字符串。
(3)指向Callback函數的指針,查詢結果的每一條記錄都調用該函數。
(4)成為Callback函數第一個參數的指針。
(5)指向錯誤串的指針。
其中,Callback函數由用戶編寫,用來接收查詢結果,查詢結果的每一條記錄都會調用Callback函數一次,其原型為:
int Callback(void*pArg,int argc,char**argv,char**
columnNames)
{return 0;
}
其中,第一個參數接收客戶代碼的任意信息;第二個參數是字段數;第三個參數是一個字符串數組,每一個串是記錄的一個字段值;第四個參數是字段名。Callback函數是用戶根據應用編寫的,正常應返回0。如果Callback函數非0,則查詢失敗。
此外,一些擴展的API提供了有用的接口函數。這里著重介紹sqlite_exec_printf( )。
int sqlite_exec_printf(sqlite*,char*sql,int(*)(void*,
int,char**,char**),void*,char**errmsg,……);
它與sqlite_exe一樣執行同樣的查詢功能,但采用printf-style格式的字符串代替完整的SQL語句。作為第二個參數,這個格式串產生SQL語句,并且在函數結尾可以綁定任意參數。使用sqlite_exec_printf函數的好處是:(1)sqlite_exec_printf為了容納產生的SQL語句,通常會分配足夠的緩存,因此不會產生靜態緩存溢出的危險;(2)擴展了%Q和%q兩個新格式以支持SQL中的串值。
3.2 SQLite在電梯監控中的應用
在電梯的B/S監控中,電梯的運行狀態需要在瀏覽器端實時顯示,實時記錄故障信息,并能統計查詢,同時通過客戶瀏覽器進行一些控制和參數設置。因此對數據庫的訪問有上端的以太網通信程序和下端的CAN/RS485通信程序。這里著重討論以太網通信程序。下面以電梯故障查詢中CGI程序訪問數據庫為例說明SQLite數據庫Callback函數、API函數的用法。Callback函數編寫如下:
int fault_dis(void*p_data,int fields_count,char**
p_fields,char**p_columnN)
{
int *p=malloc(sizeof(int));
p=(int*)p_data;(*p)++;
printf(″<tr>n″);
printf(″<td><div align=″center″><span class=″style7″> %s </span></div></td>n″,p_fields[0]);
printf(″<td class=″style7″><div align=″center″>%s</div></td>n″,p_fields[1]);
printf(″<td height=″58″><div align=″center″ class=″style7″>%s</div></td>n″,p_fields[2]);
printf(″<td><div align=″center″class=″style7″>%s</div></td>n″,p_fields[3]);
printf(″<td><div align=″center″class=″style7″>%s</div></td>n″,p_fields[4]);
printf(″</tr>n″);
return 0;
}
C語言編制的CGI程序中用SQLite的API函數調用Callback函數的關鍵語句為:
int*precs=malloc(sizeof(int));
char**errmsg=malloc(100);
char*q0=malloc(10);
……
sqlite*p_elevator=sqlite_open(″elevator″,777,0);
/*打開數據庫*/
sqlite_exec_printf(p_elevator,″select*from faultinfo where 電梯號=′%s′;″,fault_dis,precs,errmsg,q0);
/*調用Callback函數fault_dis,*/
……
sqlite_close(p_elevator)/*關閉數據庫*/
free(precs);
free(errmsg);
free(q0);
4 運行測試
本監控終端的硬件核心板采用華恒公司的HHARM2410-K1,包括CPU模塊、Flash、SDRAM存儲部分。底板主要包括LCD及鍵盤、CAN/RS485通信模塊、以太網控制芯片、GPRS模塊等。核心板CPU采用三星公司2410芯片。2410芯片基于ARM920T內核,ARM920T核由ARM9TDMI、存儲管理單元MMU和高速緩存三部分組成,運行頻率可達203MHz。MMU管理虛擬內存,實現虛擬地址物理地址的轉換。與μCLinux相比, 在ARM-Linux下可簡單地開發更強大的嵌入式程序。CAN總線通信芯片采用Microchip公司的MCP2510。它支持CAN2.0A、CAN2.0B兩種模式,與CAN總線通信能力更強。與國內常用的SJA1000相比,MCP2510數據吞吐率高,使用簡單。
從www.sqlite.org下載源代碼包,本文選擇sqlite-2.8.16并移植到ARM平臺。移植時采用armv4l-unknown-linux編譯工具。移植時,在環境變量中要加入工具鏈的路徑,否則,即使Makefile文件指定絕對路徑,make時也會報錯。若采用靜態鏈接,strip過的庫,也可以使一個CGI程序達600KB,而采用動態鏈接只有十幾KB。為了使CGI程序不太大,采用了動態鏈接。Web Server選用boa,它支持認證及CGI,源碼開放易于移植,適合嵌入式應用。用CGI應用程序制作ramdisks映像,通過tftp下載燒寫到板子上,設置目標板的靜態IP為202.196.9.16,在宿主機上通過瀏覽器訪問目標板,CGI程序能正常訪問數據庫,監控界面運行正常。調試時要注意幾個問題:(1)庫要燒寫到板子上,否則即使調試好的程序在用nfs調試時,瀏覽器仍會報錯;(2)要根據boa.conf文件放置好CGI程序和HTML文件路徑;(3)調試時注意權限;(4)sqlite.so、sqlite.so.0、sqlite.so.0.8.6要放入板子/lib目錄。
嵌入式數據庫SQLite在電梯遠程監控中的應用,實現了電梯的嵌入式B/S監控,符合監控系統e網到底、成本低廉、界面友好、升級維護方便的趨勢,對于設備的嵌入式網絡化遠程監控和故障診斷具有重要的意義。同時為Web Services技術在工控領域的應用奠定了基礎。
參考文獻
1 李建中.日新月異的數據庫研究領域——數據庫技術的回顧與展望[J].計算機應用與軟件,2003;(11)
2 宗 群,王宇波,李愛國.CAN總線在電梯遠程監控中的應用[J].制造業自動化,2004;26(7)
3 周文瑜.基于網絡技術的電梯遠程監測系統——監測中心及樓宇子系統軟件設計.中國優秀碩博論文全文數據庫.北京:清華大學,2004
4 Edmund X..Dejesus/蘇欣.嵌入式數據庫[J].中文信息,1999;Z1:90~94