武寧寧,鮑玉琦
(1.青島理工大學(xué)臨沂校區(qū) 山東 臨沂 273400;2.江蘇科技大學(xué) 江蘇 鎮(zhèn)江 212003)
溫濕度是工業(yè)現(xiàn)場(chǎng)最常見的監(jiān)測(cè)參數(shù)。在許多場(chǎng)合,溫濕度是重要的監(jiān)測(cè)參數(shù)和故障判斷的首要依據(jù),因此,溫濕度的實(shí)時(shí)存儲(chǔ)具有十分重要的實(shí)用價(jià)值。
溫濕度的實(shí)時(shí)存儲(chǔ)很早就受到工程師們的重視,最早的溫濕度實(shí)時(shí)存儲(chǔ)是通過數(shù)據(jù)的遠(yuǎn)傳,存儲(chǔ)在電腦上,現(xiàn)場(chǎng)的溫濕度傳感器只是負(fù)責(zé)數(shù)據(jù)的采集,數(shù)據(jù)的實(shí)時(shí)存儲(chǔ)和管理完全是由上層的PC機(jī)來完成。后來,現(xiàn)場(chǎng)的傳感器不斷升級(jí)換代,逐漸具有了實(shí)時(shí)存儲(chǔ)的功能,但是那是的存儲(chǔ)器空間比較小,只能存儲(chǔ)十分有限的數(shù)據(jù)。
近年來,隨著存儲(chǔ)器和嵌入式技術(shù)的飛速發(fā)展,現(xiàn)在的存儲(chǔ)器可以存儲(chǔ)大量的數(shù)據(jù),甚至有的存儲(chǔ)器可以保持?jǐn)?shù)年的不斷存儲(chǔ)[1],而且嵌入式技術(shù)可以有效的管理這部分存儲(chǔ)數(shù)據(jù),從而實(shí)現(xiàn)數(shù)據(jù)的科學(xué)存儲(chǔ)和管理。
文中重點(diǎn)介紹了基于SQLite數(shù)據(jù)庫(kù)的溫濕度實(shí)時(shí)存儲(chǔ)系統(tǒng),該系統(tǒng)充分利用SQLite數(shù)據(jù)庫(kù)的優(yōu)點(diǎn)和嵌入式系統(tǒng)的管理功能,實(shí)現(xiàn)了溫濕度的實(shí)時(shí)存儲(chǔ)和科學(xué)管理。
SQLITE數(shù)據(jù)庫(kù)采用的是模塊化的設(shè)計(jì),主要有內(nèi)核、SQL處理器、后端和附件4部分組成[2],其體系結(jié)構(gòu)如圖1所示。
圖1 SQLITE的體系結(jié)構(gòu)Fig.1 The architecture of SQLite
1)接口(Interface)。SQLite的接口是一些已經(jīng)編寫好的C庫(kù),雖然使用不同語言的API,但在底層仍然使用C庫(kù)執(zhí)行。
2)編譯器(SQL Compiler)。 SQL語句通過接口后進(jìn)入SQL編譯器,SQL處理器主要有標(biāo)志處理器、分析器和代碼生成器3個(gè)部分組成。接口程序接收字符串之后,首先將其傳給標(biāo)志處理器,標(biāo)志處理器的主要任務(wù)是把這些字符串分成一個(gè)個(gè)標(biāo)識(shí)符,把這些標(biāo)識(shí)符傳給分析器。然后分析器在收集完標(biāo)識(shí)符,把它轉(zhuǎn)換成完整的SQL語句,并且調(diào)用代碼生成器來產(chǎn)生虛擬的機(jī)器代碼,其中這些機(jī)器代碼是按照SQL語句的要求來工作。最后代碼生成器產(chǎn)生的程序送給虛擬機(jī)器來運(yùn)行。
3)虛擬機(jī)(VirtualMachine)。虛擬機(jī)是 SQLITE數(shù)據(jù)庫(kù)體系結(jié)構(gòu)中十分核心的部分,它位于SQLITE數(shù)據(jù)庫(kù)后端的上一層,通常被稱之為虛擬數(shù)據(jù)庫(kù)引擎。它不僅會(huì)完成與數(shù)據(jù)相關(guān)的全部操作,而且還是客戶和存儲(chǔ)信息之間進(jìn)行信息交換的中間單元。操作具體過程是用戶發(fā)出SQL語句請(qǐng)求,先由前端編譯器處理,生產(chǎn)專門的字節(jié)代碼程序,其中這些字節(jié)代碼程序可以執(zhí)行查詢、讀取和修改數(shù)據(jù)庫(kù)等操作,然后由VM解釋執(zhí)行,通常會(huì)調(diào)用B-tree模塊相關(guān)的接口,最后輸出執(zhí)行結(jié)果。
4)后端(Backend)。后端的第一層是 B-tree,SQLITE 數(shù)據(jù)庫(kù)中的每個(gè)目錄和表格都是使用一個(gè)單獨(dú)的 B-tree,并且所有的 B-tree都被儲(chǔ)存在同一個(gè)磁盤文件里。因此可以通過可調(diào)整的頁(yè)面緩沖獲得對(duì)數(shù)據(jù)的快速查找和存儲(chǔ)。
SQLITE數(shù)據(jù)庫(kù)獨(dú)特的體系結(jié)構(gòu),使得它具有更好的實(shí)時(shí)性,并且系統(tǒng)開銷小,底層控制能力很強(qiáng),能夠高效的利用系統(tǒng)有限資源,可大大提高數(shù)據(jù)庫(kù)的存取速度,增強(qiáng)系統(tǒng)的安全性[3-8]。
本系統(tǒng)是將嵌入式SQLITE數(shù)據(jù)庫(kù)應(yīng)用到S3C2440+Linux環(huán)境中,首先下載 sqlite-3.5.6.tar.gz,然后在在宿主機(jī)的交叉編譯環(huán)境下,編譯生成SQLITE的可執(zhí)行文件,最后將其下載到ARM板的相關(guān)目錄下。移植SQLITE的主要步驟如下:
1)解壓sqlite-3.5.6.tar.gz工具包,命令為 tar-zxvf sqlite-3.5.6.tar.gz。
2)解壓完成之后進(jìn)入sqlite-3.5.6目錄下新建一個(gè)文件夾build。
3)進(jìn)入build文件夾,執(zhí)行./configure--host=arm-linuxprefix=/opt/sqlite-3.5.6/build,其中host是指定進(jìn)行編譯的交叉編譯器,prefix是編譯后目標(biāo)存放的路徑。
4)執(zhí)行 make和 make install命令,在新建的 build目錄下生成 bin、lib、include、share 4 個(gè)文件夾。
5)將build/bin目錄下的文件拷貝到ARM板的/usr/bin中,將build/lib目錄下的文件拷貝到ARM板的lib文件夾下。
6)修改ARM板/usr/bin/sqlite3的權(quán)限,命令為chmod 755 sqlite3。
完成上述6步后,可以在ARM板的終端輸入:sqlite3 test.db來驗(yàn)證SQLITE數(shù)據(jù)庫(kù)是否移植成功。如果SQLITE數(shù)據(jù)庫(kù)成功移植,將在終端出現(xiàn)圖2所示的畫面。
圖2 SQLITE數(shù)據(jù)庫(kù)成功移植畫面Fig.2 The successful transplanted picture of SQLITE database
SQLITE數(shù)據(jù)庫(kù)提供了許多C語言的API接口,這些接口使得對(duì)數(shù)據(jù)庫(kù)的操作變得十分的方便。下面主要介紹SQLITE常用的API函數(shù)。
1)打開數(shù)據(jù)庫(kù):
int sqlite3_open(
const char*filename, //filename是數(shù)據(jù)庫(kù)的文件名
sqlite3**db //輸出SQLITE數(shù)據(jù)庫(kù)的句柄
);
2)運(yùn)行SQL函數(shù):
int sqlite3_exec(
sqlite3*, //打開的數(shù)據(jù)庫(kù)句柄
const char**sql, //要執(zhí)行的 SQL語句
sqlite3_callback, //回調(diào)函數(shù)
void*, //回調(diào)函數(shù)的第一個(gè)參數(shù)
char**errmsg //返回錯(cuò)誤信息
);
3)查詢數(shù)據(jù):
int sqlite3_get_table(
sqlite3*, //打開的數(shù)據(jù)庫(kù)句柄
const char*sql, //要執(zhí)行的 SQL 語句
char***result,
int*nrow,int*ncolumn, //返回結(jié)果的行數(shù)和列數(shù)
char**errmsg //返回錯(cuò)誤信息
);
4)關(guān)閉數(shù)據(jù)庫(kù):
int sqlite3_close(sqlite3*);
溫濕度存儲(chǔ)程序主要是對(duì)采集的溫、濕度數(shù)據(jù)進(jìn)行實(shí)時(shí)存儲(chǔ),在存儲(chǔ)程序的設(shè)計(jì)過程中要考慮上層用戶的方便查看,下面將對(duì)溫濕度存儲(chǔ)程序設(shè)計(jì)過程中數(shù)據(jù)庫(kù)的創(chuàng)建、帶有系統(tǒng)時(shí)間的表的創(chuàng)建和SQLITE數(shù)據(jù)庫(kù)動(dòng)態(tài)數(shù)據(jù)的插入3個(gè)方面進(jìn)行詳細(xì)介紹。
1)創(chuàng)建數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)的創(chuàng)建可以在程序中完成,也可以在終端上直接輸入相關(guān)的命令來完成,這里采用后一種方法,直接在終端輸入:mkdir/sbin/dht11.db命令來創(chuàng)建數(shù)據(jù)庫(kù)。
2)創(chuàng)建帶有系統(tǒng)時(shí)間的表。創(chuàng)建的表帶有時(shí)間信息可以方便后續(xù)的查看和管理,而且從某種程度上說,采集的溫、濕度數(shù)據(jù)只有與采集時(shí)間結(jié)合起來才有意義。同樣,創(chuàng)建表也有兩種方式,這里我們也是采用在終端輸入命令的方式來創(chuàng)建表,具體命令如下:
Create table dht11 (timestamp not null default(datetime(‘now’,‘localtime’)),ID integer,humidity integer,temperature integer);
上述命令的功能是創(chuàng)建一個(gè)帶有當(dāng)?shù)貢r(shí)間、序列號(hào)、濕度、溫度4個(gè)參數(shù)的表。
3)數(shù)據(jù)庫(kù)動(dòng)態(tài)數(shù)據(jù)插入。溫濕度存儲(chǔ)程序是實(shí)現(xiàn)對(duì)不斷更新變化的數(shù)據(jù)進(jìn)行實(shí)時(shí)存儲(chǔ),這里是通過下面的sqlite3_mprintf()函數(shù)來實(shí)現(xiàn)的。
sqlite3_mprintf (“insert into dht11 (ID,humidity,temperature) values (‘%d’, ‘%d’, ‘%d’)”,m,result1,result2);
上述程序語句中,m表示一個(gè)自增的變量,result1代表緩存區(qū)的濕度變量,result2代表緩存區(qū)的溫度變量。
圖3 溫濕度存儲(chǔ)程序流程圖Fig.3 Flow diagram of temperature and humidity storage program
上面介紹了溫濕度程序中建立系統(tǒng)時(shí)間和插入動(dòng)態(tài)數(shù)據(jù)的實(shí)現(xiàn)方式,下面將對(duì)整個(gè)程序的結(jié)構(gòu)進(jìn)行分析。其中圖3是溫濕度存儲(chǔ)程序的流程圖。
從上面的流程圖可以看出,整個(gè)程序主要包括3個(gè)部分:打開設(shè)備、打開數(shù)據(jù)庫(kù)、插入動(dòng)態(tài)數(shù)據(jù)。實(shí)現(xiàn)這3個(gè)部分功能的程序如下:
intmain(void)
{
int fd ,m;
m=0;
int retval;
char buf[5];
fd=open ( “/dev/dht11”, O_RDONLY); //以只讀方式打開設(shè)備
if(fd==-1)
{
perror("open dht11 error "); //打開失敗
exit(-1);
}
printf( “open/dev/dht11 successfully ” ) ;
while(1)
{
sleep(1);
retval=read(fd,buf,5);
if(retval==-1)
{
perror ( “read dht11 error” ) ;
printf( “read dht11 error” ) ;
exit(-1);
}
char*errmsg;
int ret,result,result1,result2,m;
m++;
result1=buf[0];
result2=buf[2];
sqlite3*db=NULL;
result=sqlite3_open(“/sbin/dht11.db”,&db); //打開數(shù)據(jù)庫(kù)
if(result!=SQLITE_OK)
{
fprintf(stderr,“Could notopen database:%s ”,errmsg);
sqlite3_close(db); //關(guān)閉數(shù)據(jù)庫(kù)
exit(1);
}
printf(“open databases successfully ”);
char*value=sqlite3_mprintf (“insert into dht11 (ID,humidity,temperature)value( ‘%d’,‘%d’,‘%d’)”,m,result1,result2); //插入動(dòng)態(tài)溫、濕度數(shù)據(jù)
ret=sqlite3_exec(db,value,0,0,&errmsg);
if(ret!=SQLITE_OK)
{
fprintf(stderr,"SQL error:%s ",errmsg);
sqlite3_close(db); //關(guān)閉數(shù)據(jù)庫(kù)
exit(1);
}
printf (“insert into dht11 successfully ”); //數(shù)據(jù)成功插入數(shù)據(jù)庫(kù)
sqlite3_close(db);
sleep(10); //延時(shí) 10 s
}
close(fd); //關(guān)閉設(shè)備
}
將上述程序編寫完成后,保存為time_sqlite3.c,然后利用交叉編譯工具對(duì)其進(jìn)行編譯。具體命令如下:
[root@localhost home]# arm-linux-gcc -I?/opt/build/include-L/opt/build/lib-o time_sqlite3 time_sqlite3.c-lsqlite3其中參數(shù)-I?/opt/build/include表示頭文件,參數(shù)-L/opt/build/lib表示編譯鏈接庫(kù),編譯完成后,會(huì)在home目錄下生成time_sqlite3二進(jìn)制文件。
將該文件下載到開發(fā)板的相關(guān)目錄下,并將其權(quán)限修改為可執(zhí)行文件,然后在終端輸入./time_sqlite3,將出現(xiàn)圖4所示的畫面。
圖4 溫濕度存儲(chǔ)程序執(zhí)行畫面Fig.4 Implementalpictureof temperature and humidity storage program
從上面圖4可知,溫濕度采集數(shù)據(jù)被成功的插入的數(shù)據(jù)庫(kù)中,經(jīng)過多次重復(fù)實(shí)驗(yàn),程序未出現(xiàn)“跑飛”現(xiàn)象,說明編寫的溫濕度存儲(chǔ)程序可以完成對(duì)采集數(shù)據(jù)的實(shí)時(shí)存儲(chǔ)。
文中首先介紹了SQLite3數(shù)據(jù)庫(kù)的體系結(jié)構(gòu),然后介紹了在嵌入式系統(tǒng)下構(gòu)建SQLite數(shù)據(jù)開發(fā)平臺(tái),最后設(shè)計(jì)了溫濕度實(shí)時(shí)存儲(chǔ)的程序,并進(jìn)行了試驗(yàn)驗(yàn)證。從試驗(yàn)的結(jié)果可以看出,設(shè)計(jì)的溫濕度實(shí)時(shí)存儲(chǔ)程序能夠滿足實(shí)時(shí)性的要求,并且能夠長(zhǎng)時(shí)間的穩(wěn)定工作。
[1]趙彩云.內(nèi)存數(shù)據(jù)庫(kù)性能分析及優(yōu)化[D].天津:南開大學(xué),2008.
[2]楊柳,龐和明,姜琳穎,等.嵌入式Linux及SQLite數(shù)據(jù)庫(kù)在智能監(jiān)控中的應(yīng)用研究[J].微計(jì)算機(jī)信息,2010,26(12):65-67.YANG Liu,PANG He-wei,JIANG Lin-ying,et al.Application research of embedded Linux and SQLite database in the intelligentmonitoring system[J].Micro computer information,2010,26(12):65-67.
[3]謝輝.嵌入式數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)[D].太原:太原科技大學(xué),2008.
[4]張媛媛.嵌入式數(shù)據(jù)庫(kù)管理系統(tǒng)的研究與實(shí)現(xiàn) [D].上海:華東師范大學(xué),2007.
[5]陸堅(jiān)毅.網(wǎng)絡(luò)應(yīng)用監(jiān)控系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[D].武漢:華中科技大學(xué),2012.
[6]解輝,徐玉斌,李建偉,等.基于SQLite的嵌入式數(shù)據(jù)采集系統(tǒng)的研究[J].計(jì)算機(jī)與數(shù)字工程,2008(6):91-94.XIE Hui,XU Yu-bin,LI Jian-wei,et al.The research of embedded data acquisition system based on SQLite[J].Computer and Digital Engineering,2008(6):91-94.
[7]高凱武,任傳勝.基于嵌入式linux網(wǎng)頁(yè)服務(wù)器的大壩安全監(jiān)測(cè)數(shù)據(jù)采集[J].工業(yè)儀表與自動(dòng)化裝置,2013(6):95-98.GAO Kai-wu,REN Chuan-sheng.Dam safetymonitoring data collected based on embedded linux web server[J].Industrial Instrumentation&Automation,2013(6):95-98.
[8]趙俊生.嵌入式Linux系統(tǒng)及其構(gòu)造[J].工業(yè)儀表與自動(dòng)化裝置,2013(3):16-19.ZHAO Jun-sheng.The embedded Linux system and its structure[J].Industrial Instrumentation&Automation,2013(3):16-19.