[摘 要] 研究了使用DriverStudio在windowsXP平臺(tái)下pci9054芯片的驅(qū)動(dòng)開(kāi)發(fā),從幾個(gè)關(guān)鍵方面入手,從而編寫(xiě)驅(qū)動(dòng)程序。
[關(guān)鍵詞] 驅(qū)動(dòng)程序;PCI總線(xiàn);DriverStudio;DMA;配置空間
PCI的含義為外設(shè)部件互聯(lián),它支持64位數(shù)據(jù)傳送,多總線(xiàn)主控和線(xiàn)性突發(fā)方式,其數(shù)據(jù)傳輸率最大可大528Mb/s.
在PCI設(shè)備插入PCI插槽上電后,總線(xiàn)配置機(jī)構(gòu)自動(dòng)根據(jù)PCI設(shè)備的要求實(shí)現(xiàn)配置。在WindowXP系統(tǒng)中,為了保證系統(tǒng)運(yùn)行的安全性和可移植性,對(duì)應(yīng)用程序在硬件上的操作做了限制。不支持直接對(duì)系統(tǒng)硬件資源的操作。
DriverStudio是用于Windows設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)和應(yīng)用程序開(kāi)發(fā)的軟件,它包括DriverAgent,VtoolsD,Driverworks等功能強(qiáng)大的模塊。DriverAgent用于快速生成硬件測(cè)試的驅(qū)動(dòng)程序。VtoolsD提供了VxD編程全線(xiàn)C++類(lèi)庫(kù)支持;DriverWorks能自動(dòng)生成設(shè)備驅(qū)動(dòng)程序源框架??傊?,DriverStudio的強(qiáng)大性能使得驅(qū)動(dòng)程序的編寫(xiě)不再困難。
1、驅(qū)動(dòng)開(kāi)發(fā)環(huán)境
驅(qū)動(dòng)開(kāi)發(fā)環(huán)境的安裝順序:先安裝VC++,再安裝DDK,最后安裝DriverStudio在Windows下開(kāi)發(fā)驅(qū)動(dòng)程序需要安裝DDK(Driver Development Kit)。DriverStudio集成開(kāi)發(fā)環(huán)境對(duì)DDK提供的函數(shù)進(jìn)行封裝,以類(lèi)的形式提供方便的接口,同時(shí)提供方便編程的程序生成向?qū)?,提高開(kāi)發(fā)效率,因此,該集成開(kāi)發(fā)環(huán)境被廣泛應(yīng)用。
2、DMA傳輸
使用DMA的目的是最小化CPU介入數(shù)據(jù)傳輸操作,要做到這一點(diǎn),DMA設(shè)備使用了一個(gè)輔助處理器,叫作DMA控制器,用來(lái)在內(nèi)存和外圍設(shè)備之間傳輸數(shù)據(jù)。這樣就允許CPU在進(jìn)行I/0操作的同時(shí)繼續(xù)做其他有益的工作。
DriverWorks為我們提供了三個(gè)類(lèi):KDmaAdapter、KDmaTransfer和KCommonDmaBuffer,用于實(shí)現(xiàn)DMA操作。KdmaAdapter類(lèi)用于建立一個(gè)DMA適配器,它標(biāo)明一個(gè)DMA通道的特性和提供串行化訪(fǎng)問(wèn)的服務(wù)。KdmaTransfer類(lèi)用于控制DMA的傳輸,啟動(dòng)一個(gè)DMA傳輸、DMA傳輸數(shù)據(jù)緩沖區(qū)物理地址和傳輸字節(jié)數(shù)、以及DMA傳輸結(jié)束后數(shù)據(jù)由公用緩沖區(qū)拷貝到應(yīng)用程序數(shù)據(jù)緩沖區(qū),這些工作都是由KdmaTransfer類(lèi)實(shí)現(xiàn)的。KCommonDmaBuffer類(lèi)用于申請(qǐng)系統(tǒng)提供的公用緩沖區(qū),對(duì)于DMA操作,系統(tǒng)提供了一個(gè)特殊的內(nèi)存,即物理上連續(xù)的內(nèi)存,稱(chēng)為公用緩沖區(qū)。對(duì)于支持分散,聚集DMA的設(shè)備,因其并不要求在物理上連續(xù)的內(nèi)存,可以不使用公用緩沖區(qū)。
3、中斷管理
PCI設(shè)備的中斷是可以共享的,電瓶觸發(fā),在指定中斷引腳寄存器指定INTA#給PCI板卡,即給INTPIN賦值為1.中斷線(xiàn)寄存器INTLN是PCI板卡用來(lái)向主機(jī)系統(tǒng)聲明自己希望申請(qǐng)的系統(tǒng)終端資源IRQ號(hào)。Plx9054_IntEnable(hPlx9054,AddressOfPlx9054_IntHandlerRoutine)是實(shí)現(xiàn)中斷的關(guān)鍵庫(kù)函數(shù),在Plx9054_IntEnable中封裝了InterruptThreadEnable中斷使能函數(shù),Plx9054_IntHandlerRoutine是中斷處理例程,在中斷服務(wù)程序中完成充電和逆變控制。
4、訪(fǎng)問(wèn)PCI配置空間
遵循PCI標(biāo)準(zhǔn)的設(shè)備為其配置信息提供了一個(gè)獨(dú)立的地址空間,每個(gè)PCI卡都有1到8個(gè)函數(shù),并且每個(gè)函數(shù)都有自己配置信息的存儲(chǔ)空間,空間為256個(gè)字節(jié),其中前64個(gè)字節(jié)是頭信息。PCI協(xié)議定義了多種頭信息格式,通常頭信息是通過(guò)結(jié)構(gòu)體PCI_CONFIG_HEADER_0來(lái)定義的。
驅(qū)動(dòng)程序通過(guò)類(lèi)KPciConfiguration可以訪(fǎng)問(wèn)一個(gè)PCI設(shè)備配置信息。在使用這個(gè)類(lèi)之前,首先要了解PCI設(shè)備的信息,如VenderID等。按照下列步驟可以建立訪(fǎng)問(wèn)PCI設(shè)備的配置信息的驅(qū)動(dòng)程序:(1)聲明一個(gè)類(lèi)KPciConfiguration型對(duì)象,這個(gè)對(duì)象通常在構(gòu)造體中接受參數(shù)VenderID和DeviceID。如:#define VENDOR_ID 0x7CE0#define DEVICE_ID 0X1000KPciConfiguration MyPciCFG(VENDOR_ID,DEVICE_ID);(2)測(cè)試構(gòu)建是否正確,如果為真,則對(duì)這個(gè)PCI設(shè)備正確定位;(3)申請(qǐng)?jiān)O(shè)備需要資源。一般通過(guò)類(lèi)KResourceRequest和KResourceAssignment來(lái)進(jìn)行資源申請(qǐng)及分配。當(dāng)然KResourceAssignment一般只能使用一次;(4)對(duì)于支持多個(gè)PCI設(shè)備系統(tǒng)主板來(lái)說(shuō),驅(qū)動(dòng)程序必須列舉這些設(shè)備并且產(chǎn)生相應(yīng)的設(shè)備對(duì)象。
5、PLX9054驅(qū)動(dòng)程序
PLX9054芯片是PLX公司推出的PCI橋接芯片,該芯片符合PCI規(guī)范2.2標(biāo)準(zhǔn),它帶有兩個(gè)獨(dú)立的DMA控制器,支持32位/33MHz、內(nèi)部有6種可編程FIFO存儲(chǔ)器。應(yīng)用較廣泛。
程序的入口函數(shù)DriverEntry中,主要的邏輯功能是指定該驅(qū)動(dòng)程序的各個(gè)功能函數(shù)的入口:
pDriverObject->DriverUnload = DriverUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch_Create;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch_Close;
pDriverObject->MajorFunction[IRP_MJ_READ] = Dispatch_Read;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch_Write;
pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = Dispatch_Cleanup;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch_IoControl;
pDriverObject->MajorFunction[IRP_MJ_PNP] = Dispatch_Pnp;
pDriverObject->MajorFunction[IRP_MJ_POWER] = Dispatch_Power;
pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Dispatch_SystemControl;
pDriverObject->DriverExtension->AddDevice = AddDevice;
根據(jù)這些指定的函數(shù)入口,操作系統(tǒng)對(duì)該驅(qū)動(dòng)的各種操作都在這些函數(shù)中響應(yīng)。比如,函數(shù)AddDevice在驅(qū)動(dòng)程序啟動(dòng)的時(shí)候調(diào)用,功能是創(chuàng)建一個(gè)設(shè)備對(duì)象,并將其安裝到設(shè)備堆棧中。IRP_MJ_READ命令對(duì)應(yīng)函數(shù)Dispatch_Read,在設(shè)備需要向系統(tǒng)傳遞數(shù)據(jù)時(shí)執(zhí)行該函數(shù)。
6、驅(qū)動(dòng)程序的調(diào)試
編寫(xiě)設(shè)備驅(qū)動(dòng)程序需要對(duì)操作系統(tǒng)底層有一定的了解,并且需要程序員有一定的硬件知識(shí)背景。而且驅(qū)動(dòng)程序工作在具有最高權(quán)限的Ring0層,程序行為處在無(wú)保護(hù)狀態(tài),不當(dāng)?shù)尿?qū)動(dòng)程序可能使設(shè)備工作不正常,干擾其他設(shè)備,嚴(yán)重的可以引起系統(tǒng)崩潰。所以程序員必須保證驅(qū)動(dòng)程序可靠。驅(qū)動(dòng)程序的調(diào)試成為了開(kāi)發(fā)難點(diǎn)之一。本設(shè)計(jì)采用了NuMega公司開(kāi)發(fā)的SoftIce作為調(diào)試工具,SoftIce功能強(qiáng)大,可以在單片機(jī)上運(yùn)行。本設(shè)計(jì)的驅(qū)動(dòng)程序調(diào)試過(guò)程如下:(1)首先用SoftIce產(chǎn)生IO讀寫(xiě)信號(hào)以確認(rèn)硬件設(shè)備正常運(yùn)行;(2)使用SoftIce產(chǎn)生斷點(diǎn)或調(diào)試宏跟蹤驅(qū)動(dòng)程序。確認(rèn)驅(qū)動(dòng)程序正常裝載;(3)使硬件發(fā)送有規(guī)律的數(shù)據(jù),通過(guò)查看內(nèi)存數(shù)據(jù),以確認(rèn)數(shù)據(jù)傳輸?shù)恼_;(4)對(duì)于最核心的中斷響應(yīng)代碼,可以用SoftIce的Genint命令產(chǎn)生虛擬中斷,單步跟蹤中斷響應(yīng)函數(shù);(5)測(cè)試在各種工作條件下驅(qū)動(dòng)程序的可靠性與實(shí)時(shí)性。
參考文獻(xiàn):
[1]楊波,柳征,姜文利.WindowsXP環(huán)境下的PCI設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)[J].科技信息,2007.(1):9-10.
[2]張宏超.Windows平臺(tái)下PCI設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)[J].信息化研究,2010.36(2):41-44.
[3]王峰,張文軍,余松煜.PCI設(shè)備驅(qū)動(dòng)程序中幾個(gè)關(guān)鍵問(wèn)題的設(shè)計(jì)與實(shí)現(xiàn)[J].測(cè)控技術(shù).2003.21(8):58-60.
作者簡(jiǎn)介:金 鵬,重慶交通大學(xué)。