王昱霖 王文華
摘 要QNX系統(tǒng)是面向嵌入式應(yīng)用的高性能實時操作系統(tǒng),基于QNX的圖像采集系統(tǒng)可用于對穩(wěn)定性和可靠性要求較高的工業(yè)及其他特殊環(huán)境中。本文簡要分析了QNX視頻采集系統(tǒng)的驅(qū)動原理,定制了用于視頻采集的QNX嵌入式系統(tǒng),并利用C++語言編寫了基于工業(yè)攝像機抓取圖像的上層應(yīng)用程序,通過抓取一楨圖像的實驗,驗證了該設(shè)計方法的可行性。
【關(guān)鍵詞】QNX 圖像采集 系統(tǒng)定制 驅(qū)動開發(fā)
1 前沿
隨著工控自動化技術(shù)的發(fā)展,工業(yè)領(lǐng)域中的大數(shù)據(jù)量視頻數(shù)據(jù)采集對實時性和穩(wěn)定性的要求越來越高。QNX Neutrino實時操作系統(tǒng)是一種功能全面、運行穩(wěn)健的操作系統(tǒng),其真正的微內(nèi)核設(shè)計和模塊化架構(gòu)可幫助使用者以極低的成本創(chuàng)建高度優(yōu)化和超可靠的系統(tǒng)。基于QNX操作系統(tǒng)進行視頻數(shù)據(jù)采集可有效滿足工業(yè)環(huán)境對實時性和穩(wěn)定性的要求。但QNX作為一款專用的嵌入式操作系統(tǒng)也存在開發(fā)難度大,開發(fā)周期長等問題,如何能夠快速開發(fā)基于QNX的工業(yè)攝像機使用的驅(qū)動程序模塊推廣應(yīng)用QNX系統(tǒng)的重要基礎(chǔ)。
2 QNX系統(tǒng)介紹
QNX是一個分布式、微內(nèi)核、搶占式、多用戶、多任務(wù)、可嵌入式的實時操作系統(tǒng)。被廣泛應(yīng)用到電信、航天儀器、工業(yè)自動化等方面[1]。QNX有獨特的微內(nèi)核和進程管理單元,以及基于消息傳遞的進程通信機制,同時采用內(nèi)核調(diào)度的搶占式優(yōu)先級進程管理,使得系統(tǒng)保證在任務(wù)時間內(nèi)完成對上下文的快速切換,具有極好的實時性。在QNX Neutrino 環(huán)境下,所有驅(qū)動程序、應(yīng)用程序、協(xié)議棧和文件系統(tǒng)都在內(nèi)核以外的內(nèi)存受保護的用戶空間內(nèi)安全運行。QNX操作系統(tǒng)符合POSIX基本標(biāo)準(zhǔn)和實時標(biāo)準(zhǔn),使其應(yīng)用可以方便的進行移植。QNX的微內(nèi)核僅提供進程通信、進程調(diào)度、中斷處理和底層網(wǎng)絡(luò)通信等4中服務(wù)。
QNX設(shè)備驅(qū)動與其他操作系統(tǒng)的設(shè)備驅(qū)動有所不同,其驅(qū)動程序與內(nèi)核運行在不同的地址空間中,即設(shè)備驅(qū)動無需編譯到內(nèi)核中去,而是由QNX特有的資源管理器管理,資源管理器負責(zé)給不同類型的設(shè)備提供接口。同時,不同的設(shè)備驅(qū)動還可以通過消息傳遞的方式,經(jīng)過進程管理器,將消息傳遞給其他設(shè)備驅(qū)動。QNX的網(wǎng)絡(luò)驅(qū)動核心是Network Manager, 應(yīng)用程序調(diào)用函數(shù)庫中的函數(shù),通過消息傳遞機制訪問資源管理器,并通過TCP/IP協(xié)議調(diào)用資源管理器中的函數(shù)與驅(qū)動程序進行連接。網(wǎng)絡(luò)驅(qū)動模塊的原理圖如圖1所示。
3 QNX系統(tǒng)定制
開發(fā)QNX驅(qū)動程序前首先需要定制系統(tǒng),其過程為:構(gòu)建Buildfile->編譯Buildfile生成系統(tǒng)映像文件->啟動目標(biāo)系統(tǒng)->嵌入式系統(tǒng)軟件設(shè)計。
其中最重要的就是構(gòu)建Buildfile。在通常的嵌入式系統(tǒng)中,都需要一個可啟動的操作系統(tǒng)映像文件(OS Image)。構(gòu)建Buildfile的過程就是配置操作系統(tǒng)映像的過程。Buildfile由三部分組成,分別為bootstrap script(啟動引導(dǎo)腳本)、startup script(啟動腳本)、file list(文件列表)。
首先構(gòu)建Buildfile。bootstrap script如下所示,
[virtual=x86,bIOS+compress].bootstrap = {
Start-bIOS –Ntarget
PATH=/proc/boot:/bin:/sbin:/usr/bin:/usr/sbin:/usr/photon/bin
LD_LIBRARY_PATH=/proc/boot:/dev/shmem:/lib:/lib/dll:/usr/lib:/usr/lib/dll procnto}
其中“virtual” 表明該Buildfile將構(gòu)造一個與啟動時產(chǎn)生的虛擬地址空間相對應(yīng)的啟動映象。關(guān)鍵詞“x86,bIOS” 則分別指處理器(x86)和機器類型(通過bIOS啟動)。而“+compress”使得映象文件被壓縮,以產(chǎn)生更小的映象文件。startup-bIOS是運行于具有BIOS的PC兼容系統(tǒng)的可執(zhí)行程序,主要負責(zé)利用BIOS檢測PC硬件資源。啟動腳本是在系統(tǒng)啟動后自動執(zhí)行的一系列命令列表,可在此對系統(tǒng)進行初步配置,如網(wǎng)絡(luò)配置,顯卡設(shè)置等操作。
將制作好的Buildfile導(dǎo)入到IDE中,編譯生成MyCamera.ifs文件。在開發(fā)機上將MyCamera.ifs復(fù)制到目標(biāo)機的/net/Target/.boot中,這樣就可以實現(xiàn)目標(biāo)機自動啟動QNX系統(tǒng),系統(tǒng)定制完成。
4 軟件實現(xiàn)
4.1 安裝API函數(shù)庫
本系統(tǒng)采用了德國basler pylon piA2400-17gc攝像頭,分辨率為2454*2056,幀速率可以達到17fps,采用千兆網(wǎng)卡接口,位深度為12bits。視頻采集卡采用intel PRO1000網(wǎng)卡。使用該攝像頭需要在目標(biāo)機上安裝API函數(shù)庫和設(shè)置環(huán)境變量,內(nèi)容如下所示:
sudo md /opt/pylon
sudo tar -C /opt/pylon -xzf pylon-bininst-32.tar.gz
export PYLON_ROOT=/opt/pylon
export GENICAM_ROOT_V2_1=${PYLON_ROOT}
export LD_LIBRARY_PATH=${PYLON_ROOT}/lib:${GENICAM_ROOT_V2_1}/bin/Linux32_i86:$LD_LIBRARY_PATH
mkdir -p $HOME/genicam_xml_cache export GENICAM_CACHE_V2_1=$HOME/genicam_xml_cac-he
4.2 軟件編寫
利用C++語言編寫上層應(yīng)用程序?qū)崿F(xiàn)抓取一幀數(shù)據(jù)并從控制臺顯示幀數(shù)據(jù)信息。軟件流程圖如圖2所示。
抓取一幀數(shù)據(jù)主要程序代碼如下,
#include
#include
#include
void pressEnterToExit()
int main(int argc, char* argv[])
{
Pylon::PylonAutoInitTerm autoInitTerm;
CTlFactory&TlFactory=CTlFactory::GetInstance();
Camera_t::DeviceClass()
ITransportLayer*pTl=TlFactory.CreateTl(Camera_t::DeviceClass());
Camera_t Camera(pTl->CreateDevice(devices[0]));
Camera.Open();
Camera_t::StreamGrabber_t StreamGrabber(Camera.GetStreamGrabber(0)); StreamGrabber.Open(); Camera.PixelFormat.SetValue(PixelFormat_Mono8);
Camera.OffsetX.SetValue(0);
Camera.OffsetY.SetValue(0); Camera.Width.SetValue(Camera.Width.GetMax()); Camera.Height.SetValue(Camera.Height.GetMax());
Camera.AcquisitionMode.SetValue(AcquisitionMode_SingleFrame);
Camera.ExposureMode.SetValue(ExposureMode_Timed);
Camera.ExposureTimeRaw.SetValue(100);
const size_t ImageSize = (size_t)(Camera.PayloadSize.GetValue());
uint8_t * const pBuffer = new uint8_t[ ImageSize ]; StreamGrabber.MaxBufferSize.SetValue(ImageSize);
StreamGrabber.MaxNumBuffer.SetValue(1);
StreamGrabber.PrepareGrab();
const StreamBufferHandle hBuffer =
StreamGrabber.RegisterBuffer(pBuffer, ImageSize);
StreamGrabber.QueueBuffer(hBuffer, NULL);
StreamGrabber.DeregisterBuffer(hBuffer);
StreamGrabber.FinishGrab();
StreamGrabber.Close();
Camera.Close();
delete[] pBuffer;
pressEnterToExit();
return 0;
}
4.3 實驗驗證
代碼編寫完成后,啟動目標(biāo)機,從啟動信息中可以看到IP信息,說明網(wǎng)卡驅(qū)動加載完成,通過QNX開發(fā)環(huán)境IDE編譯和仿真,由圖3所示,抓取的圖像幀信息顯示在控制臺窗口中,說明該系統(tǒng)可正常進行圖像采集。
5 結(jié)語
本文簡要分析了QNX視頻采集系統(tǒng)的驅(qū)動原理,定制了視頻采集系統(tǒng)的QNX嵌入式系統(tǒng),利用C++語言編寫了基于工業(yè)攝像機抓取圖像的上層應(yīng)用程序,通過抓取一楨圖像的實驗,驗證了該方法的可行性,為下一步開發(fā)基于QNX的圖像處理算法奠定了基礎(chǔ)。
參考文獻
[1]趙磊.QNX實時操作系統(tǒng)及其應(yīng)用分析[J].軟件導(dǎo)刊,2009(5):22-24.
[2]QNX Software Systems Ltd.System Architecture[DB/OL].http://www.qnx.org,2008.
[3]QNX Neutrino Real-time Operating System: Building Embedded Systems [DB/OL],2004.
[4]王斑,苗克堅.QNX驅(qū)動程序的編寫[J].測控技術(shù),2006,25(6):54-56.
[5]姜廣山,祖家奎.基于QNX的PC104總線設(shè)備驅(qū)動模塊的開發(fā)[J].測控技術(shù),2010,23(12):1-4.
作者簡介
王昱霖(1993-),男,碩士研究生學(xué)歷?,F(xiàn)在供職于山東科技大學(xué)機器人研究中心。研究方向為機器人學(xué)、智能控制。
作者單位
山東科技大學(xué)機器人研究中心 山東省青島市 266590