摘要:介紹了一個基于嵌入式Linux 的網絡視頻監控系統的設計與實現,重點闡述其嵌入式服務器軟硬件部分的設計思想和體系架構,對其中涉及的若干關鍵技術進行了較為詳細的介紹,完成應用程序向目標平臺的移植,并終實現視頻監控調試和運行。
關鍵詞:嵌入式系統;Linux;Video4Linux;S3C2410;網絡視頻監控
引言
隨著計算機技術及網絡技術的迅猛發展,視頻監控系統的發展趨勢必然是全面數字化、網絡化,即采用嵌入式網絡攝像機,利用網絡進行傳輸,利用嵌入式監控設備體積小巧、性能穩定、通訊便利等特點,將使視頻監控無處不在。目前,我國基于嵌入式技術的網絡視頻監控系統剛剛起步,因此,研究并開發基于嵌入式系統的網絡視頻監控系統具有很大的工程實際意義。
本文針對網絡視頻監控設備的實際應用需求,結合圖像采集和嵌入式系統兩方面的新技術,設計了基于ARM 32 位單片機系統和圖像采集存儲系統的嵌入式網絡視頻監控設備,并實現了視頻數據的采集、壓縮與網絡傳輸。
系統平臺上的硬件系統
本文使用的系統平臺硬件功能框圖如圖1 所示。該平臺采用Samsung 公司的處理器S3C2410。該處理器內部集成了ARM公司ARM920T處理器核的32 位微控制器,資源豐富,帶獨立的16KB 的指令Cache 和16KB數據Cache,LCD控制器、RAM控制器、NAND閃存控制器、3 路UART、4 路DMA、4 路帶PWM的Timer、并行I/O口、8 路10 位ADC、Touch Screen 接口、I2C 接口、I2S 接口、2 個USB接口控制器、2 路SPI,主頻可達203MHz。在處理器豐富資源的基礎上,還進行了相關的配置和擴展,平臺配置了16MB 16 位的Flash和64MB 32位的SDRAM。通過以太網控制器芯片DM9000E擴展了一個網口,另外引出了一個HOST USB接口。通過在USB接口上外接一個帶USB接口的攝像頭,將采集到的視頻圖像數據放入輸入緩沖區中。然后,將緩沖區的圖像數據通過網絡傳輸到遠端計算機。
系統平臺中的軟件系統
Linux具有內核小,效率高,源代碼開放,內核直接提供網絡支持等優點。但嵌入式系統的硬件資源畢竟有限,因此不能直接把Linux 作為操作系統,需要針對具體的應用通過配置內核、裁減shell 和嵌入式C 庫對系統進行定制,使整個系統能夠存放到容量較小的Flash 中。Linux 的動態模塊加載,使Linux的裁減極為方便,高度模塊化的部件使添加非常容易。基于Linux 的上述優點,本文實現的平臺使用的操作系統是對Linux 進行了定制的armlinux。
嵌入式系統軟件開發通常采用交叉編譯調試的方式。宿主機通常為Intel 處理器,而目標板如圖1 所示為S3C2410,因此程序需要使用針對處理器特點的編譯器才能生成在相應平臺上可運行的代碼。對于嵌入式Linux,宿主機PC 上應安裝Linux系統,之后,在宿主機上建立交叉編譯調試的開發環境。本文采用移植性很強的C 語言在宿主機上編寫視頻采集程序,再利用交叉編譯調試工具編譯鏈接生成可執行代碼,向目標平臺移植。
視頻采集的實現
在Linux 下,設備驅動程序可以看成Linux 內核與外部設備之間的接口。設備驅動程序向應用程序屏蔽了硬件實現的細節,使得應用程序可以像操作普通文件一樣來操作外部設備,可以使用和操作文件中相同的、標準的系統調用接口函數來完成對硬件設備的打開、關閉、讀寫和I/O 控制操作,而驅動程序的主要任務也就是要實現這些系統調用函數。
Video4Linux (V4L) 是Linux 中關于視頻設備的內核驅動,它為針對視頻設備的應用程序編程提供一系列接口函數。對于USB 口攝像頭,其驅動程序中需要提供基本的I/O 操作接口函數open,read,write,close 的實現。當應用程序對設備文件進行系統調用操作時,Linux 內核將通過file_operations 結構訪問驅動程序提供的函數。在系統平臺上對USB 口數碼攝像頭進行驅動,首先把USB 控制器驅動模塊靜態編譯進內核,使平臺中支持USB 接口,再在需要使用攝像頭采集時,使用insmode 動態加載其驅動模塊,這樣攝像頭就可正常工作了。
攝像頭被驅動后,需要編寫一個對視頻流采集的應用程序。根據嵌入式系統開發特征,先在宿主機上編寫應用程序,再使用交叉編譯器進行編譯鏈接,生成在目標平臺的可執行文件。宿主機與目標板通信采用打印終端的方式進行交叉調試,成功后移植到目標平臺。
采集程序實現過程如圖2 所示。
首先打開視頻設備,開啟視頻設備文件,在使用硬件設備之前要象存取普通的磁盤文件那樣先打開設備文件。使用Open()調用。Open()調用成功后返回的文件描述符就代表了捕獲設備硬件。成功開啟設備文件后,通過調用video_get_capability() 和video_get_picture () 函數來獲取設備的信息以及圖像信息。視頻設備開始工作后會有大量數據持續輸入,為了提高設備的工作效率,采用MMAP 方式將設備映射到內存,以加速文件的I/O 操作,然后通過操作名為VIDIOCMCAPTURE的ioctl()函數調用啟動捕獲過程,完成一幀圖像的捕獲并將其存儲到內存映射區,并使用操作名為VIDIOSYNC 的ioctl()調用等待完成。捕獲完成以后關閉設備文件,調用close()函數即可完成設備文件的關閉。
網絡傳輸及監控的實現
本文采用通過在Gqcam 程序中嵌入client 模塊用來實現遠程視頻監控。Client 端與Server 端分別采用兩個數組來存放操作指令。當Gqcam 需要對攝像頭進行操作時,通過Client 服務將操作指令通過網絡發送到Server,Server 端解析接收到的操作指令,根據解析到的指令啟動相應操作,并將結果返回給Client,Gqcam 在得到正確的執行結果后繼續下一步操作。Server 通過網絡與Gqcam 實現互動,并將終采集到的圖像數據發送到Gqcam,由其實現監控圖像的顯示。
實現過程是將其對本地攝像頭的操作通過網絡連接變為對遠端(服務器端)攝像頭的操作,具體過程如圖3 所示。在圖像數據傳送過程中,采用數據包傳送方式來實現對數據傳送的控制,以免出現圖像數據的丟失或阻塞網絡,因此,在編程實現時,將數據包大小定義為整數(如1000)字節,當剩余字節數不足時,也將其作為一個數據包傳送到PC 機,從而實現數據傳送的控制。
Client 端和Server 端收發數據實現部分代碼如下:
int receive_image (int fd, void *databuf, int count) {//Client 端接收圖像數據
……
for (i=0; i< (count/image_pack); i++) {
//接受數據量控制
if ((m=recv (ss, databuf+i*image_pack, image_pack, 0)) =
=image_pack) { //接收圖像數據send (ss, &yes, 1,0);
n+=m;
}
……
}
if ((m=recv (ss, databuf+i*image_pack, count%image_pack,0)) ==count%image_pack) { send (ss, &yes, 1,0);
//接收剩余不足整包數據
n+=m;
}
……
int send_image (int fd, void *databuf, int count) { //Server 端發送圖像數據
……
for (i=0; i< (fd/image_pack); i++) { //發送數據量控制
write (client_sockfd, buf+i*image_pack, image_pack); //發送圖像數據
}
}
write (client_sockfd, buf+i*image_pack, fd%image_pack);
//發送剩余不足整包數據
……
結論
應用本文所述方法實現的網絡視頻監控,構成了一個智能終端設備,性能穩定,畫面流暢,同時可以實現連續視頻和圖像的實時保存,可用于工廠、銀行及小區等場合全天候的智能監控,具有廣闊的市場和應用前景。