祝夏雨,熊九龍,王志虎,王曉明
(國防科技大學(xué) 機(jī)電工程與自動(dòng)化學(xué)院,長沙 410073)
?
達(dá)芬奇平臺(tái)的嵌入式Linux圖像采集與顯示
祝夏雨,熊九龍,王志虎,王曉明
(國防科技大學(xué) 機(jī)電工程與自動(dòng)化學(xué)院,長沙 410073)
在模式識(shí)別等領(lǐng)域,需要進(jìn)行實(shí)時(shí)快速的圖像處理。本文設(shè)計(jì)了基于達(dá)芬奇系列芯片TMS320DM6446的硬件平臺(tái),介紹了建立Linux開發(fā)環(huán)境的方法,利用Video4Linux和framebuffer實(shí)現(xiàn)了基于嵌入式Linux的USB攝像頭圖像采集與顯示,采集到的圖像可以直接送給DSP內(nèi)核,進(jìn)行高速的圖像處理。
達(dá)芬奇;Linux;圖像采集;DM6446;Video4Linux;framebuffer;USB攝像頭
嵌入式圖像采集系統(tǒng)具有體積小、成本低、穩(wěn)定性高等優(yōu)點(diǎn),在遠(yuǎn)程可視電話、計(jì)算機(jī)視覺、網(wǎng)絡(luò)會(huì)議等領(lǐng)域應(yīng)用廣泛。然而,一些圖像處理領(lǐng)域,如無人駕駛、模式識(shí)別,對(duì)運(yùn)算速度、運(yùn)算量要求較高,傳統(tǒng)的基于ARM芯片的嵌入式圖像采集系統(tǒng)往往無法滿足這一要求。
TI公司的達(dá)芬奇技術(shù)集成了DSP內(nèi)核和ARM內(nèi)核,是典型的基于共享存儲(chǔ)的嵌入式多處理器環(huán)境[1]。它既具有ARM對(duì)外設(shè)強(qiáng)大的管理能力,又擁有DSP對(duì)數(shù)據(jù)信號(hào)的高速處理能力,因而可以很好地滿足圖像處理對(duì)運(yùn)算速度和運(yùn)算量的要求。
Linux操作系統(tǒng)具有內(nèi)核穩(wěn)定、功能強(qiáng)大、支持多種硬件平臺(tái)、源代碼開放、可裁剪和低成本等眾多優(yōu)點(diǎn),使其在嵌入式領(lǐng)域備受青睞。
本文在基于達(dá)芬奇技術(shù)的嵌入式linux平臺(tái)上,利用OV511為控制芯片的網(wǎng)眼2000 USB攝像頭為采集模塊,使用Video4Linux內(nèi)核API接口函數(shù)以及framebuffer編寫相應(yīng)的程序,實(shí)現(xiàn)了圖像的采集與顯示,為DSP內(nèi)核后續(xù)的圖像處理奠定了基礎(chǔ)。
本文使用的系統(tǒng)硬件平臺(tái)采用TI公司的TMS320DM6446處理器(簡(jiǎn)稱DM6446),它是一款雙核嵌入式處理器,內(nèi)部集成了ARM926EJS內(nèi)核和C64x+DSP內(nèi)核,DSP的數(shù)據(jù)處理能力達(dá)到4752 MIPS。該款芯片的ARM子系統(tǒng)是采用管道流水線的32位RISC處理器,工作頻率高達(dá)297 MHz,帶有獨(dú)立的16 KB的指令Cache,8 KB的數(shù)據(jù)Cache,16 KB RAM,16 KB ROM[2]。其片上外設(shè)還包括USB接口、10M/100M以太網(wǎng)卡、UART接口、SPI接口。在處理器豐富資源的基礎(chǔ)上,還進(jìn)行了擴(kuò)展,配置了128 MB 32位的SDRAM和128 MB的FLASH。另外,還配有分辨率為320×240的256色LCD。系統(tǒng)框圖如圖1所示。
圖1 系統(tǒng)框圖
2.1 主機(jī)開發(fā)環(huán)境的建立
ARM的開發(fā)一般需要三個(gè)系統(tǒng),即Windows系統(tǒng)、PC-Linux系統(tǒng)、ARM-Linux系統(tǒng)。其各自的功能如圖2所示。
圖2 三系統(tǒng)功能圖
三系統(tǒng)的搭建有兩種方法:一種是三臺(tái)分立的單系統(tǒng)機(jī)器組合,一種是一臺(tái)雙系統(tǒng)PC機(jī)和一臺(tái)單系統(tǒng)ARM開發(fā)板。本文采用后一種方式,一可以節(jié)約硬件資源,二可以使開發(fā)流程、開發(fā)環(huán)境的搭建更加簡(jiǎn)單。
本系統(tǒng)PC機(jī)采用WindowsXP+VMware虛擬機(jī)+Linux的開發(fā)環(huán)境。其中VMware采用的是6.0版本,Linux采用的是較為成熟的Redhat9,內(nèi)核版本是2.4.20。
2.2 交叉編譯環(huán)境的建立
在進(jìn)入嵌入式開發(fā)之前,還需要建立一個(gè)交叉開發(fā)環(huán)境,這是一套編譯器、連接器和libc庫等組成的開發(fā)環(huán)境[3]。其開發(fā)模型如圖3所示。
圖3 交叉開發(fā)模式
圖3中,TARGET是目標(biāo)板,HOST是開發(fā)主機(jī)。在開發(fā)主機(jī)上,可以安裝開發(fā)工具,編輯、編譯目標(biāo)板的Linux引導(dǎo)程序、內(nèi)核和文件系統(tǒng),然后在目標(biāo)板上運(yùn)行。這種在主機(jī)環(huán)境下開發(fā),在目標(biāo)板上運(yùn)行的開發(fā)模式叫做交叉開發(fā)。
構(gòu)建交叉開發(fā)環(huán)境,首先要安裝交叉編譯工具鏈。Linux使用GUN的工具,社區(qū)的開發(fā)者已經(jīng)編譯出了常用體系結(jié)構(gòu)的工具鏈,從因特網(wǎng)上下載ARM體系結(jié)構(gòu)的編譯器,安裝即可。安裝后需要在環(huán)境變量PATH中添加路徑,該路徑必須是工具鏈的安裝路徑,這樣就可以直接使用arm-linux-gcc命令了。
2.3 內(nèi)核定制
嵌入式系統(tǒng)的存儲(chǔ)空間有限,要將Linux用于嵌入式系統(tǒng)就得對(duì)Linux操作系統(tǒng)進(jìn)行定制(或叫裁剪),使整個(gè)Linux系統(tǒng)能夠存放到容量較小的開發(fā)板FLASH中[4]。
由于本系統(tǒng)采用OV511芯片的USB攝像頭進(jìn)行圖像采集,所以在定制內(nèi)核時(shí),一定要使內(nèi)核支持USB總線和OV511攝像頭。此外,視頻采集設(shè)備的正常使用依賴于對(duì) Video4Linux驅(qū)動(dòng)程序的支持,所以在定制內(nèi)核時(shí)也要添加這一項(xiàng)支持。
在定制內(nèi)核時(shí),應(yīng)該選中:
[*]Video for Linux
[*]support for usb
[*]USB ov511 Camera Support
Video4Linux(簡(jiǎn)稱V4L)是Linux中關(guān)于視頻設(shè)備的內(nèi)核驅(qū)動(dòng),它為針對(duì)視頻設(shè)備的應(yīng)用程序編程提供一系列接口函數(shù),這些視頻設(shè)備包括TV卡、視頻捕捉卡和USB攝像頭等。在Linux環(huán)境下,利用V4L應(yīng)用程序接口獲取視頻圖像,可以通過調(diào)用open()、ioctl()等函數(shù),像操作普通文件一樣,進(jìn)行視頻硬件初始化、硬件屬性設(shè)置和硬件中斷調(diào)用等操作。
視頻采集程序的基本流程如圖4所示。
圖4 視頻采集流程
V4L模塊提供的主要API函數(shù)有:VIDIOCGCAP函數(shù),以數(shù)據(jù)結(jié)構(gòu)video_capability返回視頻采集設(shè)備的基本信息,包括設(shè)備名稱、設(shè)備類型、信道數(shù)、最大及最小像素高度和寬度等;VIDIOCSPICT函數(shù),使用數(shù)據(jù)結(jié)構(gòu)video_picture來獲取和設(shè)置采集圖像幀的屬性,如亮度、色調(diào)、對(duì)比度、調(diào)色板等[5];VIDIOCGMBUG函數(shù),使用數(shù)據(jù)結(jié)構(gòu)video_mbuf獲得攝像頭設(shè)備圖像存儲(chǔ)的相關(guān)信息;VIDIOCMCAPTURE函數(shù)用于視頻采集。以上函數(shù)都可以在videodev.h文件中查看定義。
首先必須聲明兩個(gè)頭文件sys/types.h、linux/videodev.h,接著利用open函數(shù)打開視頻設(shè)備,其中設(shè)備文件為/dev/video0。隨后,調(diào)用ioctl(fd, VIDIOCGCAP, &capability)函數(shù)的VIDIOCGCAP宏命令,獲取有關(guān)視頻設(shè)備的基本信息。接著,調(diào)用ioctl(fd, VIDIOCGPICT, &picture)函數(shù)的VIDIOCGPICT宏命令,獲取所采集圖像的屬性。至此,圖像采集的前期準(zhǔn)備工作已經(jīng)完成。接著就是關(guān)鍵的圖像采集部分。
圖像采集有兩種方法:一種是用內(nèi)存映射方式讀取圖像,一種是直接讀取視頻設(shè)備。本文采用前者,獲取圖像的關(guān)鍵代碼如下:
struct video_mmap mmap;
/*定義video_mmap型結(jié)構(gòu)變量mmap*/
/*以下為設(shè)置圖像緩沖區(qū)信息*/
mmap.frame=1;
/*采集幀數(shù)為2幀,交替出現(xiàn),以完成顯示圖像的連續(xù)性*/
mmap.height=320; /*圖像高度*/
mmap.width=480; /*圖像寬度*/
mmap.format= picture.palette; /*圖像的調(diào)色板格式*/
struct video_mbuf mbuf;
ioctl(fd, VIDIOCGMBUG ,& mbuf);
/*獲取存儲(chǔ)圖像的內(nèi)存大小*/
unsigned char *map = mmap(0, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0) /*內(nèi)存映像*/
ioctl(fd, VIDIOCMCAPTURE, & mmap) /*采集圖像*/
截取圖像后還要調(diào)用函數(shù)ioctl(fd, VIDIOCSYNC, &frame)進(jìn)行同步操作,函數(shù)返回0表示圖像已經(jīng)獲取完畢。圖像存儲(chǔ)在以map為起始地址,長度為mbuf.size的存儲(chǔ)空間中。map +mbuf.offsets[frame_current]處。其中frame_current=0,即為第一幀的位置,frame_current=1,為第二幀的位置。由于DSP內(nèi)核和ARM內(nèi)核是共享DDR內(nèi)存的,所以ARM可以直接傳遞該數(shù)據(jù)地址指針給DSP內(nèi)核進(jìn)行圖像處理,無需大塊的數(shù)據(jù)搬移。
Framebuffer(幀緩沖),它作為基礎(chǔ)圖形設(shè)施,是出現(xiàn)在Linux2.2內(nèi)核當(dāng)中的一種驅(qū)動(dòng)程序接口,是作為其他高級(jí)圖形或者圖形應(yīng)用程序的基本函數(shù)庫。這種接口將顯示設(shè)備抽象為幀緩沖區(qū)。用戶可以將它看成是顯示內(nèi)存的一個(gè)映像,而不必關(guān)心物理顯存的位置、換頁機(jī)制等等具體細(xì)節(jié),這些都是由Framebuffer設(shè)備驅(qū)動(dòng)來完成的。只要將其映射到進(jìn)程地址空間之后,就可以直接進(jìn)行讀/寫操作,而寫操作可以立即反應(yīng)在屏幕上。該設(shè)備使用特殊的設(shè)備節(jié)點(diǎn),通常位于/dev目錄,如/dev/fb*。用戶若要使用它,需要在編譯內(nèi)核時(shí)選中FrameBuffer[6]。其簡(jiǎn)單的使用程序如下:
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
int fb = open("/dev/fb0", O_RDWR);
ioctl ( fb, FBIOGET_FSCREENINFO, &finfo) ;
/*獲取與Framebuffer有關(guān)的固定的信息*/
ioctl( fb, FBIOGET_VSCREENINFO, &vinfo) ;
/*獲取與Framebuffer有關(guān)的可變信息*/
從vinfo和finfo中取得顯存起始地址、分辨率、色深等信息,然后根據(jù)這些計(jì)算出需映射的顯存的大小。
screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;
/*計(jì)算顯存所需的字節(jié)數(shù),其中xres,yres,bits_per_pixel分別為x、y軸分辨率和色深*/
char * fbp = mmap ( 0 , screensize ,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
/*通過調(diào)用mmap()用來實(shí)現(xiàn)內(nèi)存映射IO*/
由此便可以直接操作大小為screensize,起始地址為fbp的內(nèi)存空間,利用Video4Linux采集的圖像數(shù)據(jù)映射到Framebuffer的內(nèi)存區(qū)域中,便可以直接顯示到LCD上了。
如前所述,DaVinci是DSP和ARM雙核架構(gòu)的SOC芯片,ARM核負(fù)責(zé)芯片與外界的交互,DSP核處理相關(guān)算法,它們之間的通信和交互是通過引擎(Engine)和服務(wù)器(Server)來完成的[7],其框架如圖5所示。
圖5 Codec框架
Codec Engine是連接ARM和DSP的橋梁,是介于應(yīng)用層(ARM端的應(yīng)用程序)和信號(hào)處理層(DSP端的算法)之間的軟件模塊。ARM應(yīng)用程序調(diào)用Codec Engine的VISA(Video, Image, Speech, Audio)API,以VIDENC_process(a、 b、 c)為例。首先,Codec Engine的stub(ARM端)會(huì)把參數(shù)a、b、c以及要調(diào)用DSP端process函數(shù)這個(gè)信息打包;隨后,通過Engine SPI、OSAL和DSP Link傳遞給DSP;接著,Codec Engine的skeleton(DSP端)會(huì)解開這個(gè)包,把參數(shù)a、b、c轉(zhuǎn)換成DSP端對(duì)應(yīng)的參數(shù)x、y、z(比如ARM端傳遞的是虛擬地址,而DSP只能認(rèn)物理地址);最后,DSP端的Codec server(優(yōu)先級(jí)較低,負(fù)責(zé)和ARM通信的任務(wù))會(huì)根據(jù)process這一信息創(chuàng)建一個(gè)DSP端的process(x, y, x)任務(wù),最終實(shí)現(xiàn)VIDENC_process(a、b、c)的操作。
Linux代碼完全開源,系統(tǒng)具有良好的移植性,可方便地進(jìn)行各種擴(kuò)展,利用嵌入式Linux進(jìn)行的圖像采集和顯示運(yùn)行穩(wěn)定,效果良好。本文利用達(dá)芬奇平臺(tái)實(shí)現(xiàn)了圖像采集和顯示,采集到的圖像可以給DSP內(nèi)核進(jìn)行高速處理,為后續(xù)的工作奠定了基礎(chǔ),可廣泛應(yīng)用于對(duì)
Embedded Linux Image Acquisition and Display Based on DaVinci
Zhu Xiayu, Xiong Jiulong, Wang Zhihu, Wang Xiaoming
(School of Mechatronics Engineering and Automation, National University of Defense Technology, Changsha 410073,China)
Real time and fast image processing are needed in some field such as Pattern Recognition. This paper first designs the hardware platform based on TMS329DM6446, then introduces a method of building Linux development environment, finally achieves image acquisition and display of the USB camera based on Embedded Linux. The DSP kernel can realize image processing directly with high-speed.
DaVinci SoC; Linux; image acquisition; DM6446; Video4Linux; framebuffer; USB camera
TP391.41
A