許 曉, 畢遠(yuǎn)偉
(煙臺(tái)大學(xué) 計(jì)算機(jī)與控制工程學(xué)院, 山東 煙臺(tái) 264005)
計(jì)算機(jī)技術(shù)、嵌入式技術(shù)和圖像處理技術(shù)的日益進(jìn)步,推動(dòng)了嵌入式圖像采集系統(tǒng)朝著高速化、集成化、高分辨率、智能化[1]的方向發(fā)展。 目前,嵌入式圖像采集系統(tǒng)正廣泛應(yīng)用于電子及半導(dǎo)體、包裝、汽車、交通、印刷等領(lǐng)域[2]。 嵌入式圖像采集系統(tǒng)[3]依托于計(jì)算機(jī)技術(shù)和圖像處理技術(shù),為機(jī)器視覺的研究和應(yīng)用提供高品質(zhì)的本地視頻圖像采集和處理平臺(tái)。
傳統(tǒng)的圖像采集系統(tǒng)主要由攝像頭模組和上位機(jī)組成。 攝像頭模組只負(fù)責(zé)圖像采集,后續(xù)的圖像處理依賴上位機(jī),系統(tǒng)的采集模塊和處理模塊相分離,給安裝和操作造成不便。 隨著圖像采集系統(tǒng)的廣泛應(yīng)用,介紹嵌入式圖像采集系統(tǒng)的資料越來越多,但是相關(guān)研究資料中大多采用USB、DVP接口[4]的攝像頭,攝像頭的成像質(zhì)量和抗干擾性較差。 在嵌入式平臺(tái)上, 對(duì)MIPI接口攝像頭[5]的開發(fā)工作缺乏相關(guān)論文指導(dǎo)。
本文圖像采集系統(tǒng)的處理器選用三星公司的S5P6818。 S5P6818是64位8核Cortex-A53架構(gòu)的ARM處理器,可穩(wěn)定的運(yùn)行在1.4 GHz主頻以上,同時(shí)具有MIPI和DVP圖像數(shù)據(jù)輸入接口。 圖像傳感器選用OmniVision公司推出的500萬像素CMOS感光芯片OV5645[6],支持MIPI接口。作者研究并實(shí)現(xiàn)了硬件電路設(shè)計(jì),OV5645攝像頭驅(qū)動(dòng)編寫[7],并在應(yīng)用程序中成功通過調(diào)用V4L2提供的API實(shí)現(xiàn)圖像采集[8,10],完成了基于MIPI接口的嵌入式的圖像采集系統(tǒng)軟硬件實(shí)現(xiàn)的全過程。
嵌入式圖像采集系統(tǒng)按照功能可以劃分為圖像采集模塊、圖像數(shù)據(jù)處理模塊和通信接口模塊3個(gè)部分。 系統(tǒng)的硬件組成框圖如圖1所示。
系統(tǒng)正常工作時(shí),由CMOS圖像傳感器OV5645將光學(xué)信號(hào)轉(zhuǎn)換成數(shù)字信號(hào),然后利用camera接口將采集到的圖像數(shù)據(jù)傳至圖像處理模塊,在嵌入式系統(tǒng)上進(jìn)行圖像處理,如格式轉(zhuǎn)換、壓縮、保存。 系統(tǒng)可以進(jìn)一步利用通信接口模塊完成和上位機(jī)的數(shù)據(jù)傳輸。
圖1 系統(tǒng)硬件組成框圖
MIPI(Mobile Industry Processor Interface)是為移動(dòng)應(yīng)用處理器制定的開放標(biāo)準(zhǔn)和一個(gè)規(guī)范。 其 子協(xié)議CSI是針對(duì)攝像頭的高速串行接口應(yīng)用。 同DVP接口相比較,MIPI接口需要的信號(hào)線很少,且信號(hào)成對(duì)存在。 MIPI接口采用一對(duì)同步的差分時(shí)鐘和1-4對(duì)差分?jǐn)?shù)據(jù)線來進(jìn)行數(shù)據(jù)傳輸。OV5645的MIPI接口電路如圖2所示。
OV5645支持 (MDP0,MDN0)和(MDP1,MDN1)2對(duì)差分?jǐn)?shù)據(jù)線。 在傳輸圖像信號(hào)時(shí),數(shù)據(jù)通道工作在高速模式下,此時(shí)通道狀態(tài)為差分的0或1。 (MCP,MCN)為OV5645傳輸時(shí)鐘的引腳。 SDA和SCL是OV5645的I2C控制信號(hào),用來設(shè)置攝像頭的時(shí)鐘、圖像輸出格式、分辨率等。 由于MIPI采用差分信號(hào)高速傳輸,因此在進(jìn)行PCB設(shè)計(jì)時(shí)要嚴(yán)格按照差分對(duì)走線要求,并實(shí)現(xiàn)阻抗匹配。
圖2 MIPI接口電路
由于本文的開發(fā)環(huán)境是在X86平臺(tái)上,而嵌入式Linux操作系統(tǒng)和應(yīng)用程序最終運(yùn)行在ARM架構(gòu)處理器平臺(tái)上。因此需要為開發(fā)平臺(tái)搭建交叉編譯環(huán)境。 本次設(shè)計(jì)在虛擬機(jī)VMware Workstation上安裝了Ubuntu16.04操作系統(tǒng),所采用編譯器版本為arm-linux-gcc-4.5.1,下載對(duì)應(yīng)版本的安裝包解壓,并添加系統(tǒng)環(huán)境變量就完成了基礎(chǔ)開發(fā)環(huán)境搭建。 嵌入式系統(tǒng)所需的Linux內(nèi)核、根文件系統(tǒng)和應(yīng)用程序,需要在該環(huán)境下編譯成功,再燒寫到嵌入式系統(tǒng)上。
OV5645屬于視頻輸入設(shè)備,其驅(qū)動(dòng)包括2部分的內(nèi)容: 一是控制接口驅(qū)動(dòng)。 從OV5645的硬件連接電路可知,攝像頭和處理器之間的通信是由I2C總線實(shí)現(xiàn)。 OV5645作為I2C從設(shè)備,在這一部分主要完成Linux I2C子系統(tǒng)的搭建,為S5P6818與OV5645攝像頭之間的數(shù)據(jù)交互提供管道。二是實(shí)現(xiàn)攝像頭自身功能的驅(qū)動(dòng)部分。這一部分的工作主要圍繞V4L2驅(qū)動(dòng)框架展開,完成video設(shè)備驅(qū)動(dòng),為應(yīng)用程序提供控制接口。 OV5645攝像頭在Linux內(nèi)核中的驅(qū)動(dòng)框架如圖3所示。
I2C設(shè)備驅(qū)動(dòng)是基于總線-設(shè)備-驅(qū)動(dòng)模型。其實(shí)現(xiàn)過程可以劃分為設(shè)備注冊(cè)和驅(qū)動(dòng)注冊(cè)2個(gè)步驟。 圖4為總線設(shè)備驅(qū)動(dòng)模型。
I2C設(shè)備的注冊(cè)就是創(chuàng)建和注冊(cè)一個(gè)i2c_client的過程。在BSP文件device.c中對(duì)struct i2c_board_info填充從設(shè)備所需要的id、name、addr、adapter、driver等數(shù)據(jù)。 在板級(jí)初始化時(shí),內(nèi)核通過調(diào)用i2c_register_board_info函數(shù)將填充的I2c從設(shè)備OV5645的相關(guān)信息加入到設(shè)備鏈表__i2c_board_list中,調(diào)用i2c_get_adapter函數(shù)和i2c_new_device函數(shù)來指定設(shè)備相連的適配器和注冊(cè)一個(gè)新的I2C設(shè)備。
圖3 視頻采集驅(qū)動(dòng)框架
圖4 總線-設(shè)備-驅(qū)動(dòng)模型
I2C設(shè)備驅(qū)動(dòng)注冊(cè)和設(shè)備注冊(cè)步驟類似,先分配、設(shè)置一個(gè)i2c_driver的數(shù)據(jù)結(jié)構(gòu),實(shí)現(xiàn)其成員函數(shù)probe、remove、id_table,利用i2c_add_driver函數(shù)注冊(cè)i2c_driver,最終把驅(qū)動(dòng)程序添加到驅(qū)動(dòng)列表中。
I2C設(shè)備注冊(cè)和驅(qū)動(dòng)注冊(cè)完成后,系統(tǒng)調(diào)用I2C總線結(jié)構(gòu)i2c_bus_type提供的match函數(shù)比較設(shè)備結(jié)構(gòu)i2c_client和驅(qū)動(dòng)結(jié)構(gòu)i2c_driver結(jié)構(gòu)的name是否相同,若相同則調(diào)用驅(qū)動(dòng)程序中的probe函數(shù)。 I2C設(shè)備和I2C設(shè)備驅(qū)動(dòng)注冊(cè)不分前后,二者的注冊(cè)函數(shù)都會(huì)嘗試進(jìn)行驅(qū)動(dòng)和設(shè)備的綁定。 圖5為I2C設(shè)備和驅(qū)動(dòng)匹配的函數(shù)調(diào)用關(guān)系圖。
V4L2是Linux下視頻類設(shè)備處理模型,為訪問視頻設(shè)備提供了通用接口。 V4L2驅(qū)動(dòng)中有3個(gè)核心結(jié)構(gòu)體v4l2_device、v4l2_subdev、video_device。 v4l2_device是所有v4l2_subdev的父設(shè)備,負(fù)責(zé)管理注冊(cè)在其下面的子設(shè)備, v4l2_device通常被嵌入到一個(gè)特定的結(jié)構(gòu)體中,在S5P6818中被嵌入到nxp_v4l2中。v4l2_subdev代表子設(shè)備,描述了子設(shè)備的相關(guān)屬性和操作。 video_device結(jié)構(gòu)體用于生成設(shè)備節(jié)點(diǎn)。
(a) match過程 (b) probe過程
(a) match process (b) probe process
圖5I2C設(shè)備和驅(qū)動(dòng)匹配過程
Fig.5I2Cdeviceanddrivermatchingprocess
驅(qū)動(dòng)程序首先分配設(shè)置一個(gè)video_device結(jié)構(gòu)體,并重點(diǎn)實(shí)現(xiàn)2個(gè)操作集:v4l2_file_operations和v4l2_ioctl_ops,然后調(diào)用video_register_device函數(shù)注冊(cè)video設(shè)備,最終OV5645以節(jié)點(diǎn)/dev/video1的形式暴露給應(yīng)用層。
由圖3 Linux內(nèi)核的視頻采集驅(qū)動(dòng)框架可知,在實(shí)現(xiàn)攝像頭OV5645的驅(qū)動(dòng)過程中,其既作為I2C子系統(tǒng)中的從設(shè)備i2c_client,又作為V4L2驅(qū)動(dòng)模型中的子設(shè)備v4l2_sbudev。二者之間通過初始化函數(shù)v4l2_i2c_subdev_init(sd, client, &ov5645_subdev_ops)建立v4l2_subdev和i2c_client聯(lián)系,使得video通過用戶傳入的ioctl命令來對(duì)設(shè)備進(jìn)行控制。
在Linux下,攝像頭OV5645硬件已經(jīng)被映射為設(shè)備文件”/dev/video1”,直接利用open()打開對(duì)應(yīng)的設(shè)備文件,通過ioctl函數(shù)來控制攝像頭,如設(shè)置圖像分辨率、視頻數(shù)據(jù)格式、開始/結(jié)束視頻顯示等。調(diào)用V4L2接口進(jìn)行視頻采集的流程如圖6所示。
在數(shù)據(jù)采集過程中,驅(qū)動(dòng)程序?qū)⒉杉降囊曨l數(shù)據(jù)存放在內(nèi)核空間中,此時(shí)用戶無法直接訪問。為了獲取相機(jī)采集到的視頻數(shù)據(jù),V4L2提供了2種方法: 一種是用直接read和write方式。 雖然這種直接把視頻數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間的方法比較簡(jiǎn)單,但是視頻數(shù)據(jù)過多,造成了拷貝效率過低以及內(nèi)核空間的過度占用等問題。 另一種是mmap的方式。 mmap是v4l2_file_operation結(jié)構(gòu)體的成員函數(shù),相機(jī)驅(qū)動(dòng)文件通過對(duì)v4l2_file_operation數(shù)據(jù)結(jié)構(gòu)中填充mmap函數(shù),就可以利用mmap函數(shù)建立緩沖區(qū)和用戶空間的映射,直接在用戶空間讀取到視頻數(shù)據(jù)。 同直接讀寫方式相比,利用mmap的方式采集視頻數(shù)據(jù)不需要從內(nèi)核拷貝大量的視頻數(shù)據(jù),工作效率更高,因此本次設(shè)計(jì)采用內(nèi)存映射的方式采集數(shù)據(jù)。
部分代碼如下:
Buffers[i].start=mmap(NULL,buffers[i].length,PROT_READ|PROT_WRITE,MAP_SHARED,fd_v4l,buffers. offset);
圖6 視頻采集流程圖
按照上述視頻采集流程,編寫應(yīng)用程序,利用arm-linux-gcc-4.5.1編譯器交叉編譯后,通過FileZilla下載到飛凌嵌入式提供的開發(fā)板上進(jìn)行實(shí)驗(yàn)驗(yàn)證。 最終將采集到的圖像數(shù)據(jù)壓縮成jpeg格式的圖片并保存為IMGresult. jpg,存放到同級(jí)目錄下。將實(shí)驗(yàn)結(jié)果上傳到Ubuntu環(huán)境下進(jìn)行查看結(jié)果。圖7為OV5645抓取的圖片效果圖。
圖7 OV5645采集的圖像
本文提出了在Cortex-A53平臺(tái)上構(gòu)建嵌入式圖像采集系統(tǒng)的設(shè)計(jì)方案。 完成了MIPI接口攝像頭同S5P6818的硬件電路設(shè)計(jì),介紹了嵌入式系統(tǒng)開發(fā)環(huán)境的搭建方法,并且詳細(xì)介紹基于V4L2驅(qū)動(dòng)框架攝像頭驅(qū)動(dòng)設(shè)計(jì)和相關(guān)工作,實(shí)現(xiàn)了調(diào)用V4L2提供的接口抓取圖像過程。 對(duì)在Linux下進(jìn)行攝像頭驅(qū)動(dòng)開發(fā)以及相關(guān)應(yīng)用研究有一定指導(dǎo)作用。