王宏志,宇皓林
(長春工業(yè)大學 計算機科學與工程學院,長春 130012)
嵌入式技術(shù)目前已成為集網(wǎng)絡通信、信號處理和圖像應用等功能為一體的、拓展性能強的綜合性技術(shù).新興的嵌入式遠程監(jiān)控系統(tǒng)就是基于嵌入式技術(shù),與網(wǎng)絡技術(shù)相結(jié)合產(chǎn)生的新一代監(jiān)控體系.
本文設計一種以COALL2440開發(fā)板為基礎的遠程視頻監(jiān)控系統(tǒng).該系統(tǒng)采用B/S(瀏覽器/服務器)結(jié)構(gòu),基于ARM9和Linux操作系統(tǒng);服務器圖像采集端采用USB接口的CMOS傳感器攝像頭,運用MPEG-4壓縮編碼方式,利用boa和CGI設計 Web服務器,通過以太網(wǎng)發(fā)送到遠程客戶端,客戶端可使用PC機和智能手機接收監(jiān)控圖像,從而使客戶端實現(xiàn)遠程監(jiān)控.
根據(jù)系統(tǒng)對硬件的要求,本文設計的嵌入式遠程視頻監(jiān)控系統(tǒng)采用基于ARM920T核的S3C2440微處理器作為硬件平臺,主頻400MHz,COALL2440開發(fā)板配置一個64Mb NAND Flash(K9F1208)和64Mb SDRAM,一個 20 芯 Multi-ICE 標準JTAG 接口,一個 DM9000AEP 10M/100M網(wǎng)口,一個連接視頻攝像頭的USB接口,一個可直接掛接硬盤的IDE接口.硬件結(jié)構(gòu)如圖1所示.
圖1 硬件結(jié)構(gòu)Fig.1 Hardware structure
系統(tǒng)使用Linux操作系統(tǒng),內(nèi)核版本為Linux 2.6.30,根文件系統(tǒng)為Cramfs文件系統(tǒng).嵌入式系統(tǒng)分4個層次:1)引導加載程序;2)Linux內(nèi)核;3)根文件系統(tǒng);4)用戶應用程序.
2.1 建立交叉編譯環(huán)境 制定所需的Linux系統(tǒng)前要先搭建交叉編譯環(huán)境.由于嵌入式系統(tǒng)本身的存儲空間有限,不宜直接在嵌入式系統(tǒng)上進行開發(fā),因此需要建立交叉編譯環(huán)境.嵌入式Linux使用的交叉編譯是在宿主機上生成開發(fā)板上的可執(zhí)行代碼,包括編譯、編輯引導程序(bootloader)、Linux2.6內(nèi)核和Cramfs根文件系統(tǒng).本文系統(tǒng)使用arm-linux-gcc-3.4.1版本編譯器.
Bootloader,即引導加載程序,通過一段小程序可將系統(tǒng)的軟硬件置于一個合適的運行環(huán)境中.Bootloader一般分為兩個階段:1)運行在Flash內(nèi),初始化CPU內(nèi)部,如寄存器和內(nèi)存等;2)運行在RAM中,初始化網(wǎng)卡和串口等,但最初都放在Flash內(nèi).
2.2 Linux系統(tǒng)的移植與配置 由于Linux系統(tǒng)默認不支持ARM處理器,因此必須修改系統(tǒng)配置以實現(xiàn)對ARM的支持.進入內(nèi)核目錄,修改Makefile文件時要設置PATH環(huán)境變量,該環(huán)境變量是交叉編譯工具編輯時增加的路徑,使ARM能找到建立的交叉編譯工具鏈[1].
1)進行Linux配置內(nèi)核make menuconfig.根據(jù)遠程視頻監(jiān)控系統(tǒng)特定的需求,選擇在配置菜單中添加內(nèi)核的相關(guān)支持選項.系統(tǒng)需要添加對處理器S3C2440的支持、Video4Linux支持、USB設備的支持、網(wǎng)絡的支持和對Cramfs文件系統(tǒng)的支持等.
2)輸入make zImage編譯內(nèi)核,得到Linux內(nèi)核壓縮映像zImage.
3)使用mkcramfs把根文件目錄制成COALL2440.cramfs映像文件.制作根文件系統(tǒng)會用到busybox,它集成了最常用的Linux命令和工具.
4)安裝DM9000網(wǎng)卡和USB口的驅(qū)動程序,即完成了系統(tǒng)的移植與配置.
3.1 視頻數(shù)據(jù)采集模塊 Linux對視頻數(shù)據(jù)采集設備的支持通過Video4Linux(V4L)實現(xiàn).V4L是一種應用程序編程接口(API),API分為兩層:下層為音頻視頻驅(qū)動程序;上層為Linux內(nèi)核提供給用戶空間的API.對于USB接口攝像頭,驅(qū)動程序中有一個struct file_operation結(jié)構(gòu),它描述了在設備上能進行的各種操作.本文系統(tǒng)中包括基本的I/O操作接口函數(shù)open(),close(),read(),write()和對I/O通道控制接口函數(shù)ioctl()[2].
編寫圖像采集應用程序時,先定義一個結(jié)構(gòu)用于保存圖像采集時的各種參數(shù)和信息,該結(jié)構(gòu)如下:
圖2 視頻采集流程Fig.2 Flowchart of video capture
要完成攝像頭對視頻圖像數(shù)據(jù)的采集,就要先獲得視頻采集設備信息和圖像信息,并進行相應的初始化,才能保證采集圖像順利進行.若有需要可在采集過程中更改設備相關(guān)設置[3].視頻采集流程如圖2所示.
3.2 視頻數(shù)據(jù)壓縮模塊 獲取視頻數(shù)據(jù)后,要先去掉冗余信息,減輕網(wǎng)絡負載,并在網(wǎng)絡傳輸前對其進行壓縮.本文系統(tǒng)中,對攝像頭采集到的圖像數(shù)據(jù)采用開源軟件xvidocre進行MPEG-4標準壓縮[4].
3.3 網(wǎng)絡通信模塊 Linux具有強大的網(wǎng)絡功能,遠程監(jiān)控的實質(zhì)是運用網(wǎng)絡對采集到的數(shù)據(jù)進行遠程傳輸.根據(jù)不同指令的自身特點及對網(wǎng)絡的要求,分別采用不同的協(xié)議進行管理,本文系統(tǒng)的網(wǎng)絡模塊,對控制指令和數(shù)據(jù)指令分別采用TCP/IP協(xié)議和RTP/RTCP協(xié)議進行管理,使用不同的包封裝策略.
3.3.1 RTP/RTCP協(xié)議 目前解決實時流媒體傳輸問題的最好方法是RTP(實時傳輸協(xié)議),JRTPLIB是一個用C++語言實現(xiàn)的RTP庫,用于幫助實現(xiàn)實時流媒體編程[5].
RTP被劃分在傳輸層,建立在UDP上.與UDP協(xié)議一樣,為實現(xiàn)實時傳輸功能,RTP也有自己固定的封裝形式.RTP為端到端的實時傳輸提供時間信息和流同步,RTP本身并不能為按序傳輸數(shù)據(jù)包提供可靠的保證,服務質(zhì)量由RTCP(實時傳輸控制協(xié)議)提供.RTP協(xié)議將得到的MPEG-4視頻數(shù)據(jù)封裝成RTP數(shù)據(jù)包,并交給下層UDP協(xié)議進行處理,MEPG-4數(shù)據(jù)包的封裝形成以IP/UDP/RTP協(xié)議為基礎的包封裝.RTP協(xié)議同時接收下層通過UDP傳遞的報文.RTCP協(xié)議負責完成服務質(zhì)量的監(jiān)測、反饋和控制報文的發(fā)送[6].當RTP會話被一個應用程序建立后,其即被指定一對傳輸?shù)刂?一般的傳輸?shù)刂酚梢粋€網(wǎng)絡地址和一個端口組成,但RTP會話需要多一個端口給RTCP包.RTP數(shù)據(jù)包發(fā)向是偶數(shù)端口,RTCP即發(fā)向偶數(shù)端口+1的奇數(shù)端口,兩個端口協(xié)同工作保障RTP包的正確發(fā)送.RTP主要流程如下:
1)生成一個RTPSession類來實例此次RTP會話,并獲得接收端的IP地址和端口號.dip=inet_addr(argv[1]);dip=ntohl(dip);dport=atoi(argv[2]).
2)創(chuàng)建此次RTP會話sess.Create(bport);參數(shù)為此次RTP會話所采用的端口號;獲取會話接收端的地址和端口sess.AddDestination(dip,dport).
3)設置RTP會話默認參數(shù),從而簡化數(shù)據(jù)發(fā)送.同一個RTP會話中,負載類型sess.SetDefaultPayloadType(), 標 識 sess.SetDefaultMark(), 時 戳 增 量sess.SetDefaultTimeStampIncrement()都相同,在發(fā)送數(shù)據(jù)時只需指明發(fā)送的數(shù)據(jù)和其長度即可.
4)發(fā)送流媒體數(shù)據(jù)sess.SendPacket(buf,strlen(buf)).
5)RTP數(shù)據(jù)接收端調(diào)用sess.PollData()方法接收RTP,通過調(diào)用GotoFirstSourceWithData()和循環(huán)調(diào)用GotoNextSourceWithData()方法檢測那些攜帶RTP數(shù)據(jù)的數(shù)據(jù)包,并不斷調(diào)用sess.GetNextPacket()從指定的端口讀取RTP數(shù)據(jù)包,處理完數(shù)據(jù)后及時釋放數(shù)據(jù)包.
3.3.2 TCP/IP協(xié)議 TCP(傳輸控制協(xié)議)是面向連接的,提供可靠的數(shù)據(jù)傳輸,因此適合傳輸控制指令.TCP套接口通信工作流程如圖3所示.創(chuàng)建套接口,綁定端口和IP地址,服務器端監(jiān)聽網(wǎng)絡中的客戶端.服務器阻塞,等待連接請求,直到客戶端程序發(fā)送連接請求.當服務器端接收到一個連接請求時,會創(chuàng)建一個新的進程,以后的數(shù)據(jù)傳輸和讀取就通過這個新進程處理,原來的進程繼續(xù)監(jiān)聽網(wǎng)絡.客戶端同樣建立一個套接口,并填充要連接的服務器端資料,連接遠程計算機指定的端口,成功連接后,即可實現(xiàn)客戶端與服務器端的數(shù)據(jù)傳輸.完成通信,關(guān)閉連接[7].
圖3 TCP套接口工作流程Fig.3 Flowchart of TCP socket
3.4 Linux下的多線程技術(shù) 多線程是現(xiàn)代操作系統(tǒng)所支持的一種重要多任務機制.線程是內(nèi)核進行調(diào)度的基本單元,每個用戶級的線程都一一映射到內(nèi)核,一個線程進行系統(tǒng)調(diào)用被阻塞不會影響同一個進程所創(chuàng)建的其他線程.實施遠程監(jiān)控系統(tǒng)中需要用到的視頻采集模塊、視頻壓縮模塊和圖像傳輸模塊等通過多線程技術(shù)實現(xiàn)對多個程序的并發(fā)執(zhí)行,極大提高了系統(tǒng)的整體運行效率,節(jié)省開銷和耗時.
Linux下使用多線程技術(shù)進行程序設計主要是使用POSIX標準所規(guī)定的API接口實現(xiàn).多線程程序設計時,經(jīng)常要用到數(shù)據(jù)共享區(qū),因此實現(xiàn)多線程程序設計的關(guān)鍵是多線程之間的同步.pthread_t,pthread_mutex_t和pthread_cond_t是常用的數(shù)據(jù)結(jié)構(gòu),分別定義線程的標識符、互斥鎖和條件變量.條件變量的觸發(fā)特性和互斥鎖的二值性決定了兩者必須搭配使用,條件變量用于阻塞一個線程,互斥體用于確保一個線程對共享數(shù)據(jù)進行獨占式訪問、獲取或修改.使用時,先指定的互斥鎖將被線程釋放,然后線程將阻塞,等待條件變量被其他線程觸發(fā).函數(shù)返回前,線程重新獲取互斥鎖并繼續(xù)測試條件是否滿足[8].
多線程技術(shù)使用的主要函數(shù)如下:1)pthread_create(),創(chuàng)建一個新的線程;2)pthread_cond_signal(),喚醒條件變量cond上阻塞的線程;3)pthread_cond_wait(),使線程阻塞在一個條件變量cond上;4)pthread_mutex_lock(),用于對mutex指向的互斥體進行加鎖(阻塞).
4.1 嵌入式Web server 本文系統(tǒng)選用boa作為服務器,支持CGI,單線程Web server,因此boa不會fork出新的進程用于處理用戶的并發(fā)連接請求,即boa是被進行類似于獨占式訪問的,只有CGI腳本運行時boa才會fork出新的進程執(zhí)行.
CGI是Web server與外部擴展應用程序交互的一種標準接口,CGI程序由html頁面和運行在服務器上面的程序組成.開發(fā)時應先構(gòu)建html頁面(表單),再編寫服務器程序(CGI程序)[9].
圖4 Boa服務器工作流程Fig.4 Flowchart of boa server
遠程客戶端瀏覽器通過HTTP協(xié)議向Web服務器發(fā)送請求,服務器接收請求.由于一個URL指向一個CGI腳本,服務器按照URL指向的CGI應用程序,執(zhí)行應用程序.CGI腳本通過環(huán)境變量和標準輸入從Web服務器得到要執(zhí)行的操作,通過環(huán)境變量和標準輸出將結(jié)果返回給服務器,服務器再把結(jié)果返回給客戶端,其流程如圖4所示.
4.2 智能手機客戶端的實現(xiàn) 為了方便客戶端進行實時視頻監(jiān)控,本文系統(tǒng)采用JDK+eclipse設計在Android智能手機上運行的應用程序,通過網(wǎng)絡連接到嵌入式Web服務器即可實現(xiàn)遠程監(jiān)控.
設計網(wǎng)絡瀏覽器軟件時,主要流程如下:
1)使用urlText=(EditText)findViewByID(R.id.url)從 myweb.xml文件中得到輸入的網(wǎng)址,其中myweb.xml是布局文件,由它得到觸屏的輸入;
2)使用ToPage(urlText.getText().toString().trim())函數(shù)處理獲取的網(wǎng)址,在函數(shù)中使用loadurl(wv,url)函數(shù)設置 WebView要顯示的網(wǎng)頁,其中:url是輸入網(wǎng)址;wv是頁面的顯示.在loadurl(wv,url)中使用view.loadUrl(url)真正實現(xiàn)網(wǎng)頁的載入顯示.
設計視頻播放軟件時,主要流程如下:
1)設置MediaPlayer將要播放的視頻文件 myMediaPlayer.setDataSource(path),其中path為視頻源的路徑;
2)設置 MediaPlayer的視頻輸出界面 myMediaPlayer.setDisplay(mySurfaceHolder);SurfaceView用于顯示視頻,SurfaceHolder用于控制SurfaceView,將播放視頻的SurfaceView對應的SurfaceHolder對象作為setDisplay()的參數(shù);
3)myMediaPlayer.prepare();在設置播放的視頻數(shù)據(jù)源后,MediaPlayer需要對其進行解碼;
4)MediaPlayer開始視頻播放myMediaPlayer.start().
由于客戶端只需播放已經(jīng)在嵌入式系統(tǒng)中存儲好的視頻文件,因此只需兩個功能模塊即能實現(xiàn)智能手機的網(wǎng)絡監(jiān)控:Web瀏覽器模塊和視頻播放器模塊.在Android手機上使用已經(jīng)編譯好的apk應用軟件,輸入IP地址連接到嵌入式服務器,選擇要播放的圖像文件進行視頻播放,實現(xiàn)在移動客戶端的視頻圖像播放.手機視頻圖像監(jiān)控圖像截圖如圖5所示,網(wǎng)絡瀏覽器截圖如圖6所示.
圖5 視頻圖像監(jiān)控Fig.5 Video surveillance
圖6 網(wǎng)絡瀏覽器Fig.6 Internet browser
[1]何永琪.嵌入式Linux系統(tǒng)實用開發(fā) [M].北京:電子工業(yè)出版社,2010.
[2]ZHANG Xiao-dong,LI Xiu-juan,ZHANG Jie.Design of Embedded Remote Monitoring System Based on the ARM [J].Modern Electronics Technique,2008,31(6):22-23.(張曉東,李秀娟,張杰.基于ARM的嵌入式遠程監(jiān)控系統(tǒng)設計 [J].現(xiàn)代電子技術(shù),2008,31(6):22-23.)
[3]YANG Ying,CHEN Zhi-long,HUANG Jie,et al.Embedded Remote Monitoring System Based on the USB Camera[J].Security and Safety Technology Magazine,2007(3):24-26.(楊穎,陳之龍,黃杰,等.基于USB攝像頭的嵌入式遠程視頻監(jiān)控系統(tǒng) [J].安防科技,2007(3):24-26.)
[4]劉禾.數(shù)字圖像處理及應用 [M].北京:中國電力出版社,2006:227-230.
[5]Cline L S,Du J,Keany B,et al.DirectShowTMRTP Support for Adaptivity in Networked Multimedia Applications[C]//Proceedings of the IEEE International Conference on Multimedia Computing and Systems.Washington:IEEE Computer Society,1998:13.
[6]Tanenbaum A S.計算機網(wǎng)絡 [M].熊桂喜,王小虎,譯.北京:清華大學出版社,2002:99-199.
[7]Kurose J F,Ross K W.計算機網(wǎng)絡 [M].陳鳴,譯.北京:機械工業(yè)出版社,2009:211-233.
[8]WANG Chen-ying.Design and Research of Embedded Remote Monitoring System Based on the ARM9 [D].Beijing:Beijing University of Posts and Telecommunications,2009.(王晨營.基于ARM9的嵌入式遠程監(jiān)測系統(tǒng)的設計與實現(xiàn) [D].北京:北京郵電大學,2009.)
[9]張移山.CGI程序設計指南 [M].北京:中國水利水電出版社,2002:33-80.