保定中力電力科技發(fā)展有限公司 石美傳
PCI-Express是一種最具發(fā)展前景的總線和接口標(biāo)準(zhǔn),早在2001年的春季英特爾開發(fā)者論壇(IDF)上,Intel公布了第三代I/O互聯(lián)技術(shù)(3GIO),用以取代PCI總線和多種芯片的內(nèi)部連接。2001年底,包括Intel、AMD、Dell、IBM等20多家業(yè)界主導(dǎo)公司起草了新技術(shù)的規(guī)范,對(duì)其正式命名為PCI Express,簡(jiǎn)稱PCI-E,代表著下一代I/O接口標(biāo)準(zhǔn)。PCI-E采用與全雙工通信技術(shù)類似的雙通道傳輸模式,具有速度快、點(diǎn)對(duì)點(diǎn)串行傳輸,是兩端設(shè)備可以獨(dú)享帶寬,擴(kuò)展靈活方便,支持熱插拔以及服務(wù)質(zhì)量(QoS)的優(yōu)點(diǎn)。PCI-E總線具有極高的傳輸速率,規(guī)格從x1通道到x32通道,其中x1通道雙向傳輸速度為5Gbps,而PCI-E 3.0規(guī)范中x32通道雙向傳輸速度可達(dá)320Gbps,滿足目前絕大部分場(chǎng)合的需要。PCI-E設(shè)備連接到計(jì)算機(jī)系統(tǒng)必須有相應(yīng)的驅(qū)動(dòng)程序才能在計(jì)算機(jī)系統(tǒng)上正常工作。PCI-E驅(qū)動(dòng)程序的優(yōu)劣直接關(guān)系到整個(gè)系統(tǒng)的性能和穩(wěn)定性,因此,設(shè)計(jì)和開發(fā)穩(wěn)定高效的PCI-E驅(qū)動(dòng)程序具有重要意義。
在設(shè)計(jì)PCI-E驅(qū)動(dòng)程序之前,先對(duì)要控制的硬件系統(tǒng)和工作流程做簡(jiǎn)要的分析介紹。硬件系統(tǒng)的基本結(jié)構(gòu)框圖如圖1所示。這是一套自行開發(fā)的基于PCI-E接口的分布式數(shù)據(jù)采集系統(tǒng),主要實(shí)現(xiàn)了分布式高速數(shù)據(jù)采集及傳輸。
圖1左側(cè)是基于FPGA的數(shù)據(jù)采集單元,采集單元不間斷采集實(shí)際運(yùn)行數(shù)據(jù),數(shù)據(jù)同步單元將多個(gè)采集單元的數(shù)據(jù)匯總打包,然后通過PCI-E傳送到PC后臺(tái)服務(wù)器。數(shù)據(jù)同步單元與采集單元、PC后臺(tái)服務(wù)之間均采用PCI-E連接,傳輸介質(zhì)為光纖。采集系統(tǒng)的核心是基于PowerPC處理器的數(shù)據(jù)同步單元,數(shù)據(jù)同步單元選用了FreeScale公司的MPC8536處理器,該處理器內(nèi)部集成PCI-E、USB、以太網(wǎng)、內(nèi)存等部件。用MPC8536配置與PC后臺(tái)服務(wù)器相連接的PCI-E總線接口,包括PCI-E接口寄存器、基地址寄存器、Memory空間。為了實(shí)現(xiàn)高速數(shù)據(jù)傳輸,本設(shè)計(jì)把MPC8536作為DMA主控制器,MPC8536自帶PCI-E有四路DMA通道,通過MPC8536來實(shí)現(xiàn)采集同步后的數(shù)據(jù)向PC后臺(tái)服務(wù)器的高速傳輸。
Jungo公司開發(fā)的WinDriver驅(qū)動(dòng)程序開發(fā)軟件包,易于使用,不需要熟悉操作系統(tǒng)的內(nèi)核知識(shí)及系統(tǒng)相關(guān)底層的東西,整個(gè)驅(qū)動(dòng)程序中的所有函數(shù)都工作在用戶態(tài),所以該軟件包開發(fā)的驅(qū)動(dòng)程序靈活和工作效率都很低。
NuMega公司開發(fā)的DriverStudio驅(qū)動(dòng)程序開發(fā)軟件包,采用面向?qū)ο蟮姆绞剑瑢Ⅱ?qū)動(dòng)程序編寫所需的與內(nèi)核訪問及對(duì)硬件的訪問封裝成類,加上驅(qū)動(dòng)程序代碼生成向?qū)riverWizard等工具,簡(jiǎn)化了驅(qū)動(dòng)程序開發(fā)的難度,減少了工作量,靈活性也很好。但該軟件目前已經(jīng)停止開發(fā),不支持Windows7、8等新版本的操作系統(tǒng)。
WDK(Windows Driver Kit)是Microsoft公司開發(fā)一種完全集成的驅(qū)動(dòng)程序開發(fā)系統(tǒng),包括WDF、頭文件重構(gòu)(Windows Vista和更高版本)、驗(yàn)證程序和靜態(tài)分析工具。極大地簡(jiǎn)化Windows驅(qū)動(dòng)程序的開發(fā),利用WDF開發(fā)驅(qū)動(dòng)程序具有代碼簡(jiǎn)單,結(jié)構(gòu)清晰,效率高,而且對(duì)整個(gè)體系結(jié)構(gòu)有很好的理解和把握。本文采用WDK進(jìn)行PCI-E的驅(qū)動(dòng)程序開發(fā)。
WDF(Windows Driver Foundation)是微軟提出的下一代全新的驅(qū)動(dòng)程序模型,是以WDM(Windows Driver Model)為基礎(chǔ)進(jìn)行建模和封裝,完全基于面向?qū)ο蠹夹g(shù)實(shí)現(xiàn),支持屬性、方法和事件。提供了高度靈活、可擴(kuò)展、可診斷的驅(qū)動(dòng)程序框架。WDF框架管理了大部分與操作系統(tǒng)相關(guān)的交互,實(shí)現(xiàn)了公共的驅(qū)動(dòng)程序功能,如電源管理、即插即用pnp等,降低了驅(qū)動(dòng)程序開發(fā)的難度。WDF提供了兩個(gè)框架:KMDF內(nèi)核模式驅(qū)動(dòng)程序框架和UMDF用戶模式驅(qū)動(dòng)程序框架。本文介紹的PCI-E驅(qū)動(dòng)程序?qū)儆贙MDF內(nèi)核模式。KMDF框架支持面向?qū)ο?、事件?qū)動(dòng)的驅(qū)動(dòng)程序模型。它定義了一系列的對(duì)象用來表示設(shè)備、驅(qū)動(dòng)、中斷等,每個(gè)對(duì)象有對(duì)應(yīng)的屬性、方法和事件。驅(qū)動(dòng)程序利用這些方法創(chuàng)建對(duì)象、設(shè)置屬性和響應(yīng)事件。
WDF的對(duì)象模型是層次化的模型。WDFDRIVER對(duì)象是根對(duì)象,其他對(duì)象都是它的子對(duì)象。對(duì)于大多數(shù)對(duì)象,驅(qū)動(dòng)程序在創(chuàng)建它們的時(shí)候可以指定父對(duì)象,如果沒有指定,則框架默認(rèn)其父對(duì)象為WDFDRIVER對(duì)象。
WDF大大簡(jiǎn)化了WDM中的pnp和電源管理的開發(fā)。WDF框架為設(shè)備停止、設(shè)備刪除、電源狀態(tài)切換等事件提供了適合的缺省行為,驅(qū)動(dòng)程序本身不再糾纏于復(fù)雜的pnp和電源管理事件處理。此外,WDF還集成了請(qǐng)求隊(duì)列的支持,一個(gè)設(shè)備可以有多個(gè)請(qǐng)求隊(duì)列,每個(gè)請(qǐng)求隊(duì)列可以有一種模式。
表1 DeviceIoControl功能碼及用途簡(jiǎn)介
圖1 采集系統(tǒng)結(jié)構(gòu)圖
圖2 驅(qū)動(dòng)程序整體框圖
最簡(jiǎn)單的是WdfIoQueueDispatchSerial模式,在這種模式下,請(qǐng)求隊(duì)列將請(qǐng)求串行化后再處理;而WdfIoQueueDispatchParallel模式則自動(dòng)在每個(gè)請(qǐng)求到來時(shí)調(diào)用相應(yīng)的回調(diào)函數(shù);最后WdfIoQueueDispatchManual模式允許驅(qū)動(dòng)程序手工分發(fā)請(qǐng)求,類似于WDM的工作方式。
第一次加載驅(qū)動(dòng)程序時(shí)調(diào)用DriverEntry例程,DriverEntry是WDF驅(qū)動(dòng)程序的標(biāo)準(zhǔn)入口函數(shù),DriverEntry例程負(fù)責(zé)驅(qū)動(dòng)程序和框架的初始化。在DriverEntry例程中主要?jiǎng)?chuàng)建驅(qū)動(dòng)程序?qū)ο骔DFDRIVER和設(shè)置EvtDeviceAdd例程地址,驅(qū)動(dòng)程序?qū)ο骔DFDRIVER代表PCI-E驅(qū)動(dòng)程序。
PCI-E驅(qū)動(dòng)程序整體框體如圖2所示,驅(qū)動(dòng)程序初始化后,當(dāng)PnP管理器檢測(cè)到新的PCI-E硬件設(shè)備時(shí),PnP管理器根據(jù)安裝驅(qū)動(dòng)程序時(shí)inf文件中的設(shè)備識(shí)別號(hào)和廠商識(shí)別號(hào)找到相應(yīng)的設(shè)備驅(qū)動(dòng),然后調(diào)用在DriverEntry例程中設(shè)置的EvtDeviceAdd對(duì)應(yīng)的回調(diào)例程。完成PCI-E設(shè)備驅(qū)動(dòng)程序的初始化。初始化過程主要完成創(chuàng)建設(shè)備對(duì)象、創(chuàng)建I/O隊(duì)列、設(shè)備GUID接口、初始化中斷處理、創(chuàng)建DMA操作對(duì)象,并設(shè)置各種事件的回調(diào)處理例程,如即插即用、電源管理、I/O處理等等。在該例程中創(chuàng)建設(shè)備對(duì)象作為目標(biāo)I/O設(shè)備,并將該設(shè)備對(duì)象附著到設(shè)備堆棧中。驅(qū)動(dòng)程序還將完成設(shè)備內(nèi)存空間的獲取及轉(zhuǎn)換,這點(diǎn)非常重要,因?yàn)檫@將直接影響驅(qū)動(dòng)程序工作時(shí)的正確性和穩(wěn)定性,具體過程是通過調(diào)用EvtDevicePrepareHardware例程獲取設(shè)備的內(nèi)存的物理地址和長(zhǎng)度,部分代碼如下:
用WdfCmResourceListGetCount函數(shù)獲取配置資源的個(gè)數(shù),用WdfCmResourceListGetDescriptor函數(shù)獲取該資源的描述符,其類型屬性包括CmResourceTypeMemory(存儲(chǔ)器)、CmResource-TypePort(IO端口)、CmResourceTypeInterrupt(中斷)等,對(duì)于存儲(chǔ)器地址,用MmMapIoSpace將物理地址轉(zhuǎn)換成系統(tǒng)內(nèi)核模式地址,并將該內(nèi)核模式地址保存到設(shè)備擴(kuò)展對(duì)象中供以后使用,
數(shù)據(jù)傳輸是驅(qū)動(dòng)程序和同步單元MPC8536的Memory之間進(jìn)行的數(shù)據(jù)傳輸,本設(shè)計(jì)把待傳輸?shù)臄?shù)據(jù)分為兩類,一類是控制命令類數(shù)據(jù),另一類是采集的數(shù)據(jù),即MPC8536同步單元需要傳送到PC后臺(tái)服務(wù)器的數(shù)據(jù)??刂泼铑悢?shù)據(jù)通過發(fā)送IoControl命令的方式進(jìn)行傳輸。采集的數(shù)據(jù)則通過DMA方式傳送,因?yàn)閷?duì)于高速數(shù)據(jù)流來說,需要速度更快,傳輸效率更高,DMA方式傳送能滿足性能要求,而且也保證了數(shù)據(jù)在傳輸過程中不丟失。
控制命令類數(shù)據(jù)的傳輸,操作系統(tǒng)檢測(cè)到硬件設(shè)備并加載相應(yīng)的驅(qū)動(dòng)程序后,應(yīng)用程序就可以通過DeviceIoControl發(fā)起一個(gè)device I/O control請(qǐng)求,控制命令類數(shù)據(jù)定義成device I/O control請(qǐng)求功能碼,通過這個(gè)請(qǐng)求即可發(fā)送各種控制命令類數(shù)據(jù),驅(qū)動(dòng)程序中EvtIoDeviceControl例程將接受并處理DeviceIoControl請(qǐng)求,DeviceIoControl可以通過參數(shù)傳送不同的功能請(qǐng)求碼,驅(qū)動(dòng)程序中根據(jù)不同的功能碼做不同的響應(yīng)處理,例如,啟動(dòng)/停止數(shù)據(jù)傳輸、復(fù)位設(shè)備、設(shè)置句柄等等,具體功能碼和用途見表1所示。
采集的數(shù)據(jù)傳輸,由于采集數(shù)量大,為了及時(shí)可靠的完成數(shù)據(jù)傳輸,采用DMA方式傳輸。DMA方式傳輸?shù)墓ぷ髁鞒倘缦拢河肳dfDmaTransactionInitializeUsingRequest函數(shù)初始化DMA傳輸,調(diào)用WdfDmaTransactionExecute啟動(dòng)DMA編程。在EvtProgramDmaDMA中對(duì)MPC8536的DMA寄存器進(jìn)行編程進(jìn)行數(shù)據(jù)傳輸。當(dāng)DMA傳輸中斷發(fā)生,在DPC例程中測(cè)試DMA是否結(jié)束,沒有結(jié)束則調(diào)用WdfDmaTransactionExecute函數(shù)繼續(xù)執(zhí)行DMA。若DMA傳輸結(jié)束則完成該I/O請(qǐng)求。同步單元中的MPC8536作為DMA的主控制器,當(dāng)緩沖區(qū)區(qū)中的采集數(shù)據(jù)達(dá)到一定數(shù)量后,MPC8536利用DMA方式將緩沖區(qū)中的數(shù)據(jù)直接寫到PC后臺(tái)服務(wù)器的內(nèi)存空間,并產(chǎn)生一個(gè)DMA中斷通知驅(qū)動(dòng)程序,驅(qū)動(dòng)程序收到中斷后調(diào)用中斷響應(yīng)例程來處理內(nèi)存空間的數(shù)據(jù)。PC后臺(tái)服務(wù)器中用于DMA讀寫的內(nèi)存空間由驅(qū)動(dòng)程序分配,應(yīng)用程序利用這段內(nèi)存空間直接與同步單元的MPC8536進(jìn)行DMA方式的數(shù)據(jù)傳輸。
為了提高驅(qū)動(dòng)程序和應(yīng)用程序之間的處理效率,驅(qū)動(dòng)程序采用事件方式與應(yīng)用程序進(jìn)行通信。應(yīng)用程序中用CreateEvent創(chuàng)建事件hEvent,調(diào)用DeviceIoControl函數(shù)將事件傳遞給驅(qū)動(dòng)程序,驅(qū)動(dòng)程序響應(yīng)該請(qǐng)求,從輸入緩沖區(qū)中取出這個(gè)事件句柄存在設(shè)備擴(kuò)展對(duì)象中。當(dāng)驅(qū)動(dòng)程序處理完DMA傳輸中斷后將該事件設(shè)置為信號(hào)狀態(tài),此時(shí)應(yīng)用程序就可以處理已經(jīng)傳送到PC后臺(tái)服務(wù)器內(nèi)存空間中的數(shù)據(jù)了。
PCI-E作為一種高性能的總線,已經(jīng)得到了廣泛的應(yīng)用,文章闡述了基于WDF的PCI-E驅(qū)動(dòng)程序開發(fā),經(jīng)測(cè)試在windows2003系統(tǒng)下驅(qū)動(dòng)程序運(yùn)行穩(wěn)定,在數(shù)據(jù)鏈路x1通道的條件下用DMA方式傳輸,數(shù)據(jù)率可以達(dá)到100MB/s,數(shù)據(jù)傳輸速率比較理想,滿足項(xiàng)目的要求,目前已經(jīng)成功運(yùn)用于某海上采油平臺(tái)的數(shù)據(jù)采集中,經(jīng)現(xiàn)場(chǎng)實(shí)際運(yùn)行驗(yàn)證,工作穩(wěn)定可靠。
[1]王齊.PCI Express體系結(jié)構(gòu)導(dǎo)讀[M].北京:機(jī)械工業(yè)出版社,2010.
[2]武安河.Windows設(shè)備驅(qū)動(dòng)程序WDF開發(fā)[M].北京:電子工業(yè)出版社,2009.
[3]MPC8536E PowerQUICC III.Integrated Processor Reference Manual Rev.0 10/2008.
[4]Microsoft Corporation.Architecture of the Windows Driver Foundation[EB/OL].2005.http://www.microsoft.com/whdc/driver/wdf/default.mspx1
[5]楊阿鋒,吳帥,劉凱.PCIe接口高速數(shù)據(jù)傳輸卡的驅(qū)動(dòng)程序開發(fā)[J].中國(guó)測(cè)試技術(shù),2008,3:67-68.