摘 要:數(shù)據(jù)采集卡是典型的字符設(shè)備,以其為例,分析了VxWorks下字符設(shè)備驅(qū)動程序的結(jié)構(gòu),說明了字符設(shè)備驅(qū)動的開發(fā)思路,列出了開發(fā)的具體步驟,為驅(qū)動開發(fā)人員提供了參考。而用戶在使用該設(shè)備驅(qū)動時,無需了解底層實現(xiàn),即設(shè)備寄存器的操作,只需熟悉VxWorks下標準的I/O函數(shù)即可實現(xiàn)對數(shù)據(jù)采集卡的操作,極大地方便了應(yīng)用程序開發(fā)。
關(guān)鍵詞:VxWorks;字符設(shè)備;驅(qū)動;ADT700
中圖分類號:TP316文獻標識碼:B
文章編號:1004-373X(2008)07-113-02
Driver Development of Data Acquisition Card under VxWorks
YANG Yang,YANG Zhihui,LI Xu,LI Zhengxi
(Machine and Electronic Engineering School,North China University of Technology,Beijing,100041,China)
Abstract:The data acquisition card is a typical character equipment.Taking it as the example,the paper analyzes the structure of the character device drives under VxWorks,explains the development ideas of the character device drivers,lists the concrete step of development and provides a reference to driver developers.At the same time,users don′t need to know how to operate the device register,but only pay attention to the standard I/O function,which is convenient to develop program.
Keywords:VxWorks;character device;driver;ADT700
1 引 言
隨著嵌入式技術(shù)的發(fā)展,數(shù)據(jù)采集廣泛應(yīng)用于現(xiàn)場設(shè)備中。本文根據(jù)實際項目需求,開發(fā)了數(shù)據(jù)采集卡在VxWorks操作系統(tǒng)下的驅(qū)動程序,以方便應(yīng)用程序開發(fā)。
本文采用的數(shù)據(jù)采集卡為盛博協(xié)同公司基于PC/104總線的ADT700采集卡,他通過總線與PC/104嵌入式系統(tǒng)構(gòu)成一個高性能的數(shù)據(jù)采集與控制系統(tǒng)。ADT700具有如下特點:
模擬輸入[HTSS] 16單端/8差分輸入;12位分辨率;100 kHz最大A/D采樣率;0 ~ +10 V,-5~+5 V,-10~+10 V雙極性或單極性輸入量程;1,2,4,8倍可編程增益;DMA實現(xiàn)數(shù)據(jù)的高速傳輸。
模擬輸出[HTSS] 4通道輸出;-5~+5 V,-10~+10 V,0~5 V,0~10 V量程可選;通道單獨置數(shù)或4通道同時置數(shù)。
數(shù)字量I/O[HTSS] 可編程外圍接口,24通道TTL/CMOS兼容;I/O接口上拉或下拉限流電阻。
定時/計數(shù)器[HTSS] 6個16位、10 MHz(最大)定時/計數(shù)器。
2 VxWorks及其字符設(shè)備驅(qū)動
VxWorks是一個基于搶占式的實時操作系統(tǒng),他以其高度的可靠性、優(yōu)秀的實時性、靈活的可裁性廣泛應(yīng)用到許多行業(yè)中。在VxWorks中,I/O系統(tǒng)提供了與設(shè)備無關(guān)的用戶接口,應(yīng)用程序可以通過標準的接口函數(shù)如:create( ),remove( ),open( ),close( ),read( ),write( ),ioctl( )等來訪問設(shè)備驅(qū)動程序,而不用關(guān)心驅(qū)動程序是如何實現(xiàn)的。ADT700屬于字符型設(shè)備,他的驅(qū)動程序需要支持以上接口函數(shù)。
下面以字符設(shè)備中open( )操作為例,說明字符設(shè)備驅(qū)動程序結(jié)構(gòu)。
如圖1所示,當應(yīng)用程序調(diào)用fd=open(“/xx0”,O[CD#*2]RDONLY,0)時,I/O系統(tǒng)根據(jù)文件名“/xx0”在設(shè)備列表中查找設(shè)備(設(shè)備是以文件形式存在的,文件名即設(shè)備名)(如①所示);查找到相應(yīng)設(shè)備后根據(jù)驅(qū)動號定位到驅(qū)動表中(如②所示);I/O系統(tǒng)在文件描述表中預(yù)留一個表項fd=3(如③所示);然后I/O系統(tǒng)調(diào)用驅(qū)動程序中的xxoOpen( )函數(shù),返回需要保留的值,即設(shè)備描述指針(如④所示);I/O系統(tǒng)將驅(qū)動號和驅(qū)動返回值填到文件描述符表中(如⑤所示);最后,I/O系統(tǒng)返回新open( )的文件在文件描述符表中的索引,應(yīng)用程序得到文件描述符fd=3(如⑥所示)。用戶可以通過操作文件來訪問I/O設(shè)備。
圖1 字符設(shè)備驅(qū)動程序結(jié)構(gòu)
3 驅(qū)動實現(xiàn)
3.1 功能分類
ADT700具有A/D,D/A轉(zhuǎn)換,數(shù)字I/O,定時/計數(shù)等功能,對其進行分析,可分為3類:
(1) A/D轉(zhuǎn)換為只讀,而D/A轉(zhuǎn)換為只寫;
(2) 數(shù)字I/O既可讀又可寫;
(3) 定時/計數(shù)器基本無需讀寫,只設(shè)置即可。
根據(jù)以上功能,得出需要實現(xiàn)3個驅(qū)動,分別為:
(1) adtDrv驅(qū)動,用于讀入A/D轉(zhuǎn)換后的數(shù)據(jù),寫出D/A轉(zhuǎn)換的數(shù)據(jù),設(shè)備描述符為“/adt”;
(2) ppiDrv驅(qū)動,用于讀入或?qū)懗鰯?shù)字I/O的數(shù)字,設(shè)備描述符為“/ppi”;
(3) pitDrv驅(qū)動,用于設(shè)置定時/計數(shù)器,設(shè)備描述符為“/pit”。
3.2 基本流程
(1) 安裝驅(qū)動
I/O系統(tǒng)的功能是將用戶的I/O請求轉(zhuǎn)換成對相應(yīng)驅(qū)動程序具體操作函數(shù)的調(diào)用,他通過維護一個包括所有驅(qū)動程序操作函數(shù)的地址表來實現(xiàn)的。通過調(diào)用iosDrvInstall( )可以動態(tài)安裝驅(qū)動程序,該函數(shù)的參數(shù)就是7種基本I/O操作函數(shù)指針。iosDrvInstall( )函數(shù)將這些地址寫入驅(qū)動表中的一塊空閑存儲區(qū)中,并返回這塊存儲區(qū)的編號,編號即驅(qū)動程序號,可被與驅(qū)動程序相關(guān)聯(lián)的設(shè)備使用。iosDrvInstall( )的原型是:
int iosDrvInstall(FUNCPTR pCreate,F(xiàn)UNCPTR pDelete,F(xiàn)UNCPTR pOpen,F(xiàn)UNCPTR pClose,F(xiàn)UNCPTR pRead,F(xiàn)UNCPTR pWrite,F(xiàn)UNCPTR pIoctl);
當調(diào)用iosDrvInstall( )注冊I/O函數(shù)成功后,在shell下用iosDrvShow命令可以觀察驅(qū)動表中ADT700的驅(qū)動入口。
(2) 創(chuàng)建設(shè)備
創(chuàng)建設(shè)備過程即是調(diào)用設(shè)備創(chuàng)建函數(shù)iosDevAdd( )將此設(shè)備加入到I/O系統(tǒng)的設(shè)備列表中。iosDevAdd( )的原型為:
STATUS iosDevAdd ( DEV[CD#*2]HDR *pDevHdr,char *name,int drvnum);
其中:DEV[CD#*2]HDR是一個指向該設(shè)備的描述符指針;而DEV[CD#*2]HDR結(jié)構(gòu)中的第一項則指向下一個設(shè)備的描述符指針。
設(shè)備創(chuàng)建成功后,在shell下用devs命令可以觀察設(shè)備列表中ADT700的設(shè)備描述符。
以ADT700中adtDrv驅(qū)動為例,以上兩步的完成過程如圖2所示。
圖2 adtDrv驅(qū)動程序安裝
(3) 實現(xiàn)I/O函數(shù)
安裝驅(qū)動和創(chuàng)建設(shè)備完成后,就需要實現(xiàn)I/O函數(shù),即填充驅(qū)動表中的函數(shù)了。對于字符型設(shè)備而言,打開設(shè)備操作與創(chuàng)建設(shè)備操作通常使用相同的函數(shù),底層驅(qū)動中都用xxOpen( )完成;而設(shè)備驅(qū)動一旦安裝,就無需刪除, remove( )無效,因此在底層驅(qū)動中xxRemove( )為空。下面給出了ppiDrv驅(qū)動中ppiRead( )的實現(xiàn)模板。
int ppiRead(int ppiDevId,UCHAR *pBuf, int nByte)
{
PPI[CD#*2]DEV* pPpiDev= (PPI[CD#*2]DEV*)ppiDevId;
int ReadLength = ERROR;
UCHAR ch;
if(pPpiDev == (PPI[CD#*2]DEV*)NULL)
{
errnoSet(S[CD#*2]PPI[CD#*2]NODEV);
return (ERROR);
}
if(pPpiDev->ReadyToRead)
{
ReadLength = 0;
while(ReadLength < nByte)
{
if((pPpiDev->pinnum)PORTA) /* 如果輸入口為A*/
{
ch = ReadDigitalIO(0); /* 讀A 口數(shù)據(jù)*/
pBuf[ReadLength++] = ch;
}
/* 讀其他輸入口*/
}
}
return (ReadLength);
}
完成以上3步,就基本實現(xiàn)了驅(qū)動程序,此時,在應(yīng)用程序中可以用標準接口函數(shù)進行操作了。以打開ADT700中定時/計數(shù)器(驅(qū)動為pitDrv)為例。
int fd = open(\"/pit/timer\",O[CD#*2]RDWR,0);
此時,在shell用iosFdShow命令可以觀察到新創(chuàng)建的文件描述符“/pit/timer”。
4 結(jié) 語
本文以數(shù)據(jù)采集卡驅(qū)動程序為例,詳細介紹了VxWorks操作系統(tǒng)下字符設(shè)備驅(qū)動程序的開發(fā)過程。本驅(qū)動程序封裝了ADT700幾乎所有功能,支持標準的I/O系統(tǒng)接口函數(shù)。用戶可將ADT700當作文件,只需定義文件名建立文件描述符,而無需關(guān)心底層實現(xiàn),即可完成對他的操作,從而縮短了應(yīng)用程序開發(fā)時間,提高了效率。
參 考 文 獻
[1]盛博協(xié)同科技有限公司.SEM/ADT700技術(shù)手冊(版本1.2)[Z].2006.
[2]周啟平,張楊.VxWorks下設(shè)備驅(qū)動程序及BSP開發(fā)指南[M].北京:中國電力出版社,2006.
[3]李忠民,楊剛,顧亦然,等.ARM嵌入式VxWorks實踐教程[M].北京:北京航空航天大學出版社,2006.
注:本文中所涉及到的圖表、注解、公式等內(nèi)容請以PDF格式閱讀原文。