隨著網絡技術和嵌入式技術的迅猛發(fā)展,通過網絡來實現(xiàn)視頻監(jiān)控已經得到了廣泛的應用,3G網絡以其高帶寬使得傳輸流暢的視頻信息成為可能,本文在采用3G技術的基礎上設計了一款基于嵌入式Linux的無線終端,在數據處理部分采用了Linux的Netfilter架構,通過掛載鉤子函數來實現(xiàn)數據包在內核態(tài)的獲取及高效轉發(fā),并且通過在Linux內核開辟一片緩沖區(qū),解決了視頻服務器與3G模塊撥號延時而造成的速率不匹配的問題,減少了數據丟包。配合Netfilter用戶態(tài)管理工具iptables的使用,可實現(xiàn)包過濾防火墻,及NAT等功能,從而便于本系統(tǒng)對流經其數據包的管理。
另一方面對嵌入式Linux的視頻采集程序的設計進行了詳細的介紹,并將其實際應用到了本系統(tǒng)的數據采集模塊中去,完成了數據的采集工作,同時針對目前市場上對與3G模塊通常只提供Windows CE下的驅動這一情況,開發(fā)了嵌入式Linux系統(tǒng)下的3G模塊驅動程序,在軟件設計上充分發(fā)揮了開源軟件的優(yōu)勢,采用高效的Xvidcore編解碼庫,來完成視頻的編碼,以及使用PPP源碼來編譯撥號上網工具,成本低廉并且縮短了系統(tǒng)的開發(fā)周期,使得本系統(tǒng)具有較強的工程實用價值。
1 系統(tǒng)硬件結構
硬件上采用“ARM 3G模塊”系統(tǒng)架構。ARM與3G模塊采用分離模塊的設計方法,通過USB線相連,較整體設計而言具有更好的靈活性,使得一些現(xiàn)有的以ARM為主處理器的系統(tǒng)能夠很好地擴展3G功能,便于產品的過渡。本系統(tǒng)的核心處理器是S3C2440A,S3C2440A是一款由SamSu-ng半導體公司推出的基于ARM920T內核的16/32位RISC微處理器。內部帶有全性能的MMU(內存處理單元),主頻為400MHz最大可達到533MHz,提供了一個數字攝像頭接口(Camera Interface)。具有高性能、低功耗、接口豐富和體積小等優(yōu)良特性。而3G模塊核心部件采用的是MC8630模塊,該模塊具有語音、短信和高速數據業(yè)務等功能,可以廣泛應用于高速數據傳輸、安防、無線媒體、直放站監(jiān)控、鐵路終端和車載監(jiān)控等領域。
系統(tǒng)硬件結構如圖1所示。
2 系統(tǒng)軟件設計
系統(tǒng)主要由視頻采集模塊、數據處理模塊、網絡轉發(fā)模塊組成。
2.1 視頻采集模塊設計
根據項目的實際需要,在本系統(tǒng)中視頻數據來源主要有兩個方面:
1)系統(tǒng)與可提供主動上傳功能的視頻服務器通過RJ45網線直接相接 主要用于完成多路視頻圖像采集。視頻服務器的主要功能是將攝像頭采集的數據完成編碼壓縮,并且將壓縮的數據以IP包的形式發(fā)送給接收端,由于該類視頻服務器通常是在局域網內使用,目前還很少有對于3G網絡的支持,隨著3G技術在國內發(fā)展的不斷深入,將在很大程度上取代有線網絡。所以本系統(tǒng)可作為現(xiàn)有視頻服務器的3G功能擴展。針對在外接視頻服務器時只需對收到的數據包進行轉發(fā)而無需對IP數據本身做分析處理的問題,并且在系統(tǒng)啟動到3G模塊撥號成功獲得IP地址之間會有一定的延遲,在本系統(tǒng)中提出了采用Linux的Netfilter架構的方法以及緩沖機制,通過在數據流經TCP/IP協(xié)議棧時掛載鉤子函數,實現(xiàn)IP數據在內核態(tài)的獲取,并且通過在內核開辟一塊足夠大的環(huán)形緩沖區(qū)來存儲數據。由于系統(tǒng)需要頻繁對緩沖區(qū)進行讀寫,為避免產生內存碎片,在本系統(tǒng)中采用了環(huán)形隊列的數據結構。在3G模塊獲得IP地址后,再通過驅動讀取緩沖區(qū)中的數據,由3G網絡完成轉發(fā),從而降低丟包率并且提高數據包的轉發(fā)效率。因為傳統(tǒng)的方法是采用socket API來進行網絡編程,其對數據的訪問通常發(fā)生在用戶態(tài),對于Linux操作系統(tǒng)來說,用戶進程的優(yōu)先級和所占用的CPU時間要遠遠小于內核線程,同時內核進程擁有較高的執(zhí)行優(yōu)先度,故在網絡布局允許獲得IP數據包的條件下,將用戶態(tài)的數據包獲取功能載入內核態(tài),可進一步提高系統(tǒng)的處理能力,增加系統(tǒng)的有效帶寬,本方法還可用于其他對IP數據本身進行處理并且對處理效率有苛刻要求的系統(tǒng)中,例如:本方法在本實驗室與某航空院合作開發(fā)的IP-TS協(xié)議轉換器上也得到了成功的應用,具有一定的通用性。Netfilter是Linux 2.6.x系列內核提供的一套數據包過濾框架,基于該框架的軟件能夠實現(xiàn)如數據包過濾、網絡地址轉換(NAT)等功能。要使用Netfilter,在內核編譯時設置“Network Packet Fihering”選項。Netfilter提供了一個抽象、通用化的框架,作為中間件,為每種網絡協(xié)議(IPv4、IPv6等)定義一套鉤子函數。對于Ipv4協(xié)議定義了5個鉤子函數,這些鉤子函數在數據報流過協(xié)議棧的5個關鍵點被調用,Netfilter可以在通過TCP/IP協(xié)議棧的路徑中的幾個定義良好的點上捕獲數據包,IPv4中的一個數據包通過netfilter系統(tǒng)的過程如圖2所示。
NF_IP_PRE_ROUTING
在對數據包進行初始正確性檢查(校驗和等)后,截獲該數據包。
NF_IP_LOCAL_IN
如果數據包將要到達本地主機,則捕獲該數據包。
NF_IP_FORWARD
如果數據包將要到達某些其他主機,則捕獲該數據包。
NF_IP_LOCAL_OUT
在本地捕獲其目的地是外部的已創(chuàng)建的數據包。
NF_IP_POST_ROUTING
這是最后的鉤子,在此之后將傳輸數據包。
內核netfilter結構在/usr/src/inelude/linux/netfilter.h中定義,類似如下:
參數是:
list
Netfilter本身是一個鉤子鏈;它指向netfilter鉤子的頭部,通常設置為{NULL,NULL}。
hook
該函數在數據包碰到鉤子點時被調用。該函數與前面描述的函數相同,它必須返回NF_ACCEPT、NF_DROP或NF_QUEUE。如果返回NF_ACCEPT,則下一個鉤子將被附加到將要調用的點。如果返回NF_DROP,則數據包被丟棄。如果返回NF_QUEUE,則對數據包進行排隊。sK_buff指針被傳遞到該函數中,并用數據包信息如IP報頭、TCP報頭等進行填充,可以使用sk_buff結構指針來操作或刪除數據包(要刪除數據包,只需將skb指針設置為空即可)。
pf
協(xié)議簇;例如,適用于IPv4的PF_INET。
hooknum
鉤子的掛載點,由于本系統(tǒng)不需要在本地對數據包進行任何處理,因此選擇的掛在點為NF_IP_PRE_ROUTING,在對數據包進行正確性校驗后就調用鉤子函數處理數據包。Priority表明鉤子的優(yōu)先級,在本系統(tǒng)中采用高優(yōu)先級處理NF_IP_PRI_FIRST。
內核數據處理的關鍵是鉤子函數的編寫,此函數規(guī)定了數據包在到達時需要進行的處理過程。
鉤子函數框架如下:
設定好特定的鉤子函數之后,調用函數
int nf_register_hook(struct nf_hook_ops*req);
將鉤子函數注冊至內核。一旦該結構注冊到內核中,Linux將調用這里定義的函數來處理數據包。
使用函數
void nf_unregister_hook(struct nf_hook_ops*req);
可以將已經注冊入內核的鉤子函數取消,此時,接收到數據包將按照內核的默認規(guī)則來進行處理。流程如圖3所示。
2)直接采用CMOS攝像頭作為視頻采集裝置 該視頻采集模塊在硬件上S3C2440帶有CMOS攝像頭接口,在開發(fā)板上通過稱為CAMERA的接口引出,并且?guī)в衏amera控制器,在本系統(tǒng)中使用了OmniVision公司的OV9650攝像頭。S3C2440支持ITU-R BT601/656格式的數字圖像輸入,支持2個通道的DMA,Preview通道和Codec通道,參見圖4。
Preview通道可以將YCbCr4:2:2格式的圖像轉換為RGB(16bit或24bit)格式的數據,并存放于為PreviewDMA分配的內存中,最大分辨率為640×480。主要用于本地液晶屏顯示,Codec通道可以輸出YCbCr4:2:0或YCbCr4:2:2格式到為Codec DMA分配的內存中。最大分辨率為4 096x4 096,主要用于圖像的編解碼處理。在本系統(tǒng)中使用的是Codec通道。
視頻采集模塊的設計采用的是V4L2(Video for Linux Two)V4L2,它是Linux下開發(fā)視頻采集設備驅動程序的一套規(guī)范,該規(guī)范采用分層的方法給驅動程序的開發(fā)提供了清晰的模型和一致的接口,并且正對視頻設備的應用程序編程也提供了一系列接口函數。其中應用程序處于最上層,V4L2處于中間層,而實際的硬件設備則處于下層,其本身包括兩層驅動結構,上層是videodev模塊,下層為V4L2驅動程序。video-dev通過V4L2驅動程序的成員函數來調用V4L2驅動。在V4L2驅動的驅動程序初始化過程中,它首先枚舉它將要處理的系統(tǒng)中的設備,為每個設備填充struct v412_device結構,并且將指向該結構的指針傳遞給v412_register_device()函數,該函數調用v4L2_deviee結構體中的初始化函數對設備進行初始化。當v412驅動程序初始化完成后,v412通過傳遞一個包含驅動程序成員函數,次設備號以及相關信息的結構給videod-ev,從而完成它將要處理設備在videodev的注冊工作,當應用程序通過系統(tǒng)調用觸發(fā)了某個驅動程序時,控制權首先傳遞給videodev中的函數,videodev將應用程序傳遞的文件或i節(jié)點結構指針轉換為相應的v412結構指針,并調用v412中的處理函數。以本系統(tǒng)以OV9650攝像頭為例,其驅動框架如圖5所示。
視頻采集過程如下,應用程序首先打開視頻設備文件,攝像頭在系統(tǒng)中對應的設備文件為/dev/camera,通過系統(tǒng)調用“open(“/ dev/camera”,O_RDWR)”函數打開該設備,獲得一個文件描述符fd,利用ioctl(fd,VIDIOCGPICT,&capability)函數獲取攝像頭的相關信息,例如設備名稱、支持的最大最小分辨率、信號源信息等,填充在結構體video_capability中,通過調用ioctl(fd,VIDIOCGPICT,&pict-ure)獲取圖像的相關信息如采集圖像的對比度、亮度、調色板等屬性,并且填充在video_picture結構體中,在獲取這類信息后,可根據實際需要來對其重新賦值,具體做法是將需要設置的值賦給相應結構體,然后通過系統(tǒng)調用ioctl(fd,VIDIOCSPICT,&)函數寫入設備。在圖像獲取方式上使用mmap()系統(tǒng)調用來實現(xiàn)內存映射達到各進程共享內層的目的,利用共享內存通信的一個顯而易見的好處是效率高,因為進程可以直接讀寫內存,而不需要任何數據的拷貝。使用mmap方式獲取圖像數據,需要首先設置圖像幀的緩沖區(qū)結構,即struct video_mmap,如每次采集幀數,圖像高度、寬度,圖像調色板格式等等。然后調用ioctl(fd,VIDIOCMCAPTURE,&grab_buf)啟動捕獲過程。調用iotcl(fd,VI-DIOCSYNC,&frame)等待采集完成,若該函數成功返回則表示采集完畢,采集到的圖像將放在通過mmap()映射的內存區(qū)域內,讀取該內存數據即可獲得圖像數據,其中frame為當前截取的幀數,V4L2允許一次采集多幀數據,可通過設置grab buf.frame來實現(xiàn)。調用close(fd)函數關閉設備文件,終止圖像采集。
2.2 視頻數據處理模塊設計
由視頻采集模塊獲取的視頻圖像需要通過3G網絡來進行傳輸,而從攝像頭直接采集的未經壓縮的數據量非常大,為了在不影響圖像質量的前提下提高傳輸效率,本系統(tǒng)中對原始獲得的視頻圖像進行了壓縮編碼。由于MPEG-4是專門為播放流式媒體的高質量視頻而設計的,并且MPEG-4標準以其高壓縮比、高質量、低傳輸率已經成為目前網絡多媒體傳輸的主要格式和標準。它可利用很窄的帶寬,通過幀重建技術壓縮和傳輸數據,以求使得用最少的數據獲得最佳的圖像質量并且能夠保存接近于DVD畫質的小體積視頻文件。在本系統(tǒng)中選用開源的Xvidcore作為視頻壓縮模塊的核心算法。Xvidcore是一個高效而且便于移植的編碼軟件。它不僅支持Simple Profile和Advanced Profile,還支持I/P Frames B-Frames Interlacing和GMC,以鉆石和方塊模式來進行PMVFast和EPZS運行估計,是目前比較流行的MPEG-4編碼軟件。Xvidcore源碼可從網上下載免費獲得,目前最新版為xvidcore-1.2.2,它提供了一系列的庫函數及接口函數供應用程序使用。但針對嵌入式系統(tǒng)平臺,要使用該庫需要將其移植到嵌入式系統(tǒng)中。移植過程如下:
解壓源代碼:tar-zxvf xvidcore-1.2.2.tar.gz;在使用前需要對xvidcore-1.2.2進行交叉編譯,步驟如下:
1)設置環(huán)境變量:export=“xvidcore當前所在目錄”;
2)進入/build/generic目錄;
3)生成Makefrle:/configure-host=local hostbuild=arm-linux-gcc;//指定交叉編譯工具以便進行交叉編譯;
4)編譯源代碼:make。
將交叉編譯生成的庫文件libxvidcore.so.*拷貝到交叉編譯器工作目錄lib子目錄中。完成編碼庫的移植工作。
以上對個獨立模塊進行了介紹,在軟件實現(xiàn)上對系統(tǒng)進行了整體設計,將各個模塊有機的組合在一起,并充分考慮了系統(tǒng)的可擴展性。
主要結構體如下:
以視頻壓縮模塊為例,其軟件流程如圖6所示。
2.3 網絡轉發(fā)模塊設計
在完成對采集圖像的壓縮或者接收完視頻服務器后,需要將數據通過3G網進行轉發(fā),完成網絡數據轉發(fā)通常采取的辦法是利用Linux提供的socket API進行,socket給用戶提供了統(tǒng)一的編程接口,網絡傳輸協(xié)議通常有TCP和UDP兩種,對于TCP每次要通過3次握手建立連接,在等待亂序及重傳丟失數據時會產生較大延時,而UDP又缺乏流量控制,所以都不太適用于實時數據傳輸,在這種情況下運行于UDP之上的RTP則具有很大的優(yōu)勢,目前對于有實時要求的數據傳輸RTP是最好的協(xié)議,故在本系統(tǒng)中使用了RTP協(xié)議作為數據傳輸協(xié)議,流程如圖7所示。
2.4 3G模塊驅動設計及聯(lián)網
3G模塊與ARM是通過USB相連的。無線終端到3G網絡的連接是通過PPP協(xié)議實現(xiàn)的,PPP協(xié)議是一種點對點串行通信協(xié)議,為在點對點連接上傳輸多協(xié)議數據包提供了一個標準方法。由于目前嵌入式市場上的3G模塊基本上都是提供Windows CE操作系統(tǒng)下的驅動程序,但對于嵌入式Linux下面的目前還沒有驅動支持,所以為本系統(tǒng)開發(fā)了3G模塊的驅動程序。要完成3G模塊的撥號上網功能,需要3個層面的支持:1)是內核層面;2)驅動層面;3)應用程序層面的支持。內核層面主要是通過對內核的重新配置來完成,由于3G模塊與ARM通過USB線連接,而上層的PPP通信采用的是串行協(xié)議,所以要在內核中加入USB轉串口的支持,通過makemenuconfig命令進入內核配置界面,依次選擇Device Drivers->USB support->USB Serial Converter Support選擇USB Generic Serial Driver按兩次空格鍵使項目前加『*』將其編譯入內核,其中加*為編譯成內核模塊,加M為編譯為模塊。由于采用的是PPP協(xié)議,故要在內核中加入PPP的支持。進入內核配置界面以后,依次選擇DeviceDrivers->Network device support->PPP(point-to-point)protocol support選中,將PPP編譯入內核,同時選擇PPP展開項,將其全部編譯入內核,保存退出。對于驅動層面,3G模塊的驅動開發(fā)主要是通過修改兩個文件generic.c以及usb-serial.c,其中generic.c為USB通用程序,usb-serial.c為USB轉串口程序。通過在其中加入一些網絡層的hook函數來達到對上層協(xié)議的支持。將修改過后的文件復制到/linux2.6.29/drivers/usb/serial,重新編譯內核,生成zImage鏡像,然后下載到板子上。完成3G模塊驅動的設計以及內核對PPP協(xié)議的支持,對于撥號上網應用程序的支持,主要是通過PPP提供的兩個工具pppd和chat來實現(xiàn)的,其中PPP提供了一種點對串行線路上傳輸數據流的方法,chat主要用于撥號并等待提示。可從網上下載PPP源碼,在本系統(tǒng)中采用的版本為PPP-2.4.0,下載后要解壓并且根據目標板的類型來進行交叉編譯得到撥號程序。
3 結束語
本文在一塊ARM開發(fā)板上實現(xiàn)了多種功能,包括無線數據視頻終端,通過外接視頻服務器實現(xiàn)了現(xiàn)有視頻服務器的3G功能擴展,通過采用了Netfilter與socket結合的方法,將數據包獲取功能從用戶態(tài)載入Linux內核態(tài),避免了數據的內存拷貝,提高了處理效率,同時引入內核緩沖機制。解決了3G撥號延時而造成的視頻服務器丟包問題,配合Netfilter用戶工具iptables的使用,可以在本系統(tǒng)上實現(xiàn)NAT,包過濾防火墻等功能。方便對流經系統(tǒng)數據包的管理。
針對目前市場上的3G模塊大多只提供Windows CE下驅動這一問題,開發(fā)了3G模塊驅動,使得現(xiàn)有3G模塊可使用與嵌入式Linux系統(tǒng)下,用戶可直接在此基礎上通過socket進行編程,而無需考慮底層的硬件通信問題。在軟件設計上充分發(fā)揮開源軟件的優(yōu)勢,采用Xvideore進行視頻編碼,以及PPP源碼編譯撥號軟件等,縮短了系統(tǒng)開發(fā)周期,系統(tǒng)在軟件的整體設計上提出了一套相對通用的軟件架構,可方便實現(xiàn)功能的擴展及升級。