二、
從廣義上來說,設(shè)備驅(qū)動(dòng)程序就是控制硬件設(shè)備的一組函數(shù)。PCI 驅(qū)動(dòng)程序的開發(fā),就是取得PCI板卡所占用的各種資源(內(nèi)存、端口、中斷和DMA 等),并提供給用戶一條可以訪問這些資源的途徑。對(duì)于所有的PCI板卡,基本上都可以用下面的方法來開發(fā)驅(qū)動(dòng)程序。
2.1 取得PCI 板卡所占用的資源
無論是ISA 板卡還是PCI 板卡,用戶要使用它,就必須能訪問它所占用的各種資源。對(duì)于ISA板卡,它所占用的資源是定死的,可以直接訪問;而PCI板卡是即插即用的,它占用的所有資源都是由系統(tǒng)分配的,要想訪問這些資源,就必須先取得這些資源。
2.2 建立起上層應(yīng)用程序和底層驅(qū)動(dòng)程序之間的映射關(guān)系
因?yàn)樵赪IN98 /NT等系統(tǒng)下,各種資源的訪問對(duì)用戶來講是透明的,用戶不能在上層應(yīng)用程序里直接訪問硬件資源,只能靠底層驅(qū)動(dòng)程序來訪問它。因此用戶要實(shí)現(xiàn)對(duì)板卡的控制,就必須在應(yīng)用程序和底層驅(qū)動(dòng)程序之間架起一座橋梁,來實(shí)現(xiàn)應(yīng)用程序和驅(qū)動(dòng)程序之間的聯(lián)系。通過這個(gè)橋梁,用戶可以實(shí)現(xiàn)參數(shù)的傳遞和硬件資源的訪問。
2.3 通過底層驅(qū)動(dòng)程序?qū)崿F(xiàn)對(duì)硬件資源的訪問
用戶的最終目的是實(shí)現(xiàn)對(duì)硬件資源的直接訪問,而在上層應(yīng)用程序中根本就做不到這一點(diǎn)。萬幸的是,在開發(fā)驅(qū)動(dòng)程序的環(huán)境中有可以直接訪問各個(gè)資源的函數(shù),用戶可以在驅(qū)動(dòng)程序中實(shí)現(xiàn)對(duì)所需資源的訪問。
三、PCI驅(qū)動(dòng)程序的特點(diǎn)
在設(shè)計(jì)驅(qū)動(dòng)程序之前,首先要對(duì)欲控制的硬件設(shè)備進(jìn)行細(xì)致地分析,更需要詳細(xì)了解硬件設(shè)備的特性。硬件設(shè)備的特性會(huì)對(duì)驅(qū)動(dòng)程序設(shè)計(jì)產(chǎn)生重大的影響。需要了解的最主要的硬件特性包括。
(1)設(shè)備的總線結(jié)構(gòu)。設(shè)備采用什么總線結(jié)構(gòu)非常關(guān)鍵,因?yàn)椴煌目偩€類型(如ISA和PCI)在許多硬件工作機(jī)制上是不同的,所以驅(qū)動(dòng)程序設(shè)計(jì)也不同。
(2)寄存器。要了解設(shè)置的控制寄存器、數(shù)據(jù)寄存器和狀態(tài)寄存器,以及這些寄存器工作的特性。
(3)設(shè)備錯(cuò)誤和狀態(tài)。要了解如何判斷設(shè)備的狀態(tài)和錯(cuò)誤信號(hào),這些信號(hào)要通過驅(qū)動(dòng)程序返回給用戶。
(4)中斷行為。要了解設(shè)備產(chǎn)生中斷的條件和使用中斷的數(shù)量。
(5)數(shù)據(jù)傳輸機(jī)制。最常見的數(shù)據(jù)傳輸機(jī)制是通過I/O端口(port),也就是通過CPU的IN/OUT指令進(jìn)行
數(shù)據(jù)讀寫。PC的另一種重要的傳輸機(jī)制是DMA,但PCI規(guī)范不包括從屬DMA的說明。
(6)設(shè)備內(nèi)存。許多設(shè)備自身帶有內(nèi)存,PCI設(shè)備大多是采用映射的方式映射到PC系統(tǒng)的物理內(nèi)存。有的設(shè)備還要通過驅(qū)動(dòng)程序設(shè)置設(shè)備的接口寄存器。有關(guān)驅(qū)動(dòng)程序的加載和響應(yīng)用戶請(qǐng)求的內(nèi)容,在DDK文檔中有規(guī)定,所以設(shè)計(jì)設(shè)備驅(qū)動(dòng)程序主要的面臨問題是如何進(jìn)行硬件操作,這是根據(jù)設(shè)備的不同而不同的。而硬件驅(qū)動(dòng)程序的功能雖然千差萬別,但基本功能就是完成設(shè)備的初始化、對(duì)端口的讀寫操作、中斷的設(shè)置、響應(yīng)和調(diào)用以及對(duì)內(nèi)存的直接讀寫。
四、開發(fā)實(shí)例
在開發(fā)PCI卡中,我們利用PCI9052作為接口芯片,把TMS320C6201B橋接到PCI總線上,該卡的主要功能是實(shí)現(xiàn)數(shù)據(jù)采集、參數(shù)提取,以作為數(shù)字接收機(jī)的一部分。編的驅(qū)動(dòng)程序是vxd(VirtualDeviceDriver),用vtoolsD編的,可以用VC++直接編譯成vxd文件。vxd的主要任務(wù)就是在系統(tǒng)中找到PCI卡,并讀出本地芯片所映射的內(nèi)存物理地址,在Windows系統(tǒng)中,用戶程序不能直接訪問物理地址,只能使用線性地址,所以vxd還有做的一件事就是將物理地址轉(zhuǎn)換成線性地址供winapp使用。vxd查找PCI卡就是靠搜索vendorID和deviceID,它是通過依次搜索總線號(hào)和設(shè)備號(hào),看是否有符合指定的vendorID和deviceID,如果符合則認(rèn)為找到了PCI卡的配置空間,因?yàn)榕渲每臻g的第一個(gè)雙字就是vendorID和deviceID.然后向下面的地址依次讀就可以讀出PCI卡的配置空間其他信息,包括space0映射的內(nèi)存基地址。讀出此地址來再進(jìn)行物理地址到線性地址的轉(zhuǎn)換,就可以完全供winapp使用了(可以通過指針訪問),來讀取9052local上掛的芯片了。具體的查找方式主要通過vxd程序中首先向I/O地址0xcf8寫入最高位為1的雙字0x80000000,這個(gè)數(shù)的第16到23位代表了總線號(hào),第11到15位代表了設(shè)備號(hào),第8到14位代表了功能號(hào),然后就可以讀取I/O地址0xcfc的雙字,如果有效的話說明此PCI配置空間地址上掛了一個(gè)PCI卡,從0xcfc讀出的數(shù)則為此PCI卡配置空間的第一個(gè)雙字,即vendorID和deviceID,判斷讀出的雙字是否等于在9052配置EEPROM中標(biāo)定的數(shù),如果是則說明找到了的PCI卡,如果不是則繼續(xù)找。向0xcf8寫入的數(shù)+0x800,在繼續(xù)讀0xcfc,依次下去,直到找到。如果當(dāng)此數(shù)加到0x80ffff00時(shí)還沒找到(即總線號(hào)搜索完畢),則表明沒法找到,那就要找找自己的原因了,可能是板子的配置錯(cuò)了。找到了PCI卡的配置空間后,讀出space0的基地址,然后進(jìn)行物理地址到線性地址的轉(zhuǎn)換,直接用VC++編譯成vxd就可以共winapp使用了。所以實(shí)際上我的app程序使用了兩個(gè)vxd,一個(gè)用來專門找卡,一個(gè)用來地址轉(zhuǎn)換。至于app如何調(diào)用vxd,可以參看VC的參考書,一般都有介紹。
[Version]
Signature=$CHICAGO$
Class=PLX
Provider=%XIANGHE%
[Manufacturer]
%Manufacture%=SECTION0
[SECTION0]
%my_card%=my.install,PCIVEN_10b5&DEV_9052
[my.install]
CopyFiles=CopyFiles_PLX10b5
AddReg=AddReg_PLX10b5
[CopyFiles_PLX10b5]
Vxd8_25.vxd
[AddReg_PLX10b5]
HKR,,DevLoader,0,Vxd8_25.vxd
[Strings]
Manufacture="BUAA202"
my_card="PLX9052"
下面提供了vxd中查詢PCI卡的代碼:
BOOL findpci(DWORD DeviceVendor,PCIINF *pciinf)
{
DWORD io_cf8;
DWORD io_cfc;
int i;
DWORD buf[16];
io_cf8=0x80000000;
for(;;)
{
}
return 0;
}
4 結(jié)束語
以上完成了驅(qū)動(dòng)程序的初步開發(fā),對(duì)于不同的開發(fā)環(huán)境,如VB不包括直接讀寫I/O端口的語句,所以可以考慮根據(jù)不同軟件的需要對(duì)驅(qū)動(dòng)程序進(jìn)行不同的封裝,如以DLL、
ActiveX、VCL和C++類庫進(jìn)行封裝。
聯(lián)系客服