保定中力電力科技發(fā)展有限公司 石美傳
PCI-Express是一種最具發(fā)展前景的總線和接口標準,早在2001年的春季英特爾開發(fā)者論壇(IDF)上,Intel公布了第三代I/O互聯(lián)技術(3GIO),用以取代PCI總線和多種芯片的內部連接。2001年底,包括Intel、AMD、Dell、IBM等20多家業(yè)界主導公司起草了新技術的規(guī)范,對其正式命名為PCI Express,簡稱PCI-E,代表著下一代I/O接口標準。PCI-E采用與全雙工通信技術類似的雙通道傳輸模式,具有速度快、點對點串行傳輸,是兩端設備可以獨享帶寬,擴展靈活方便,支持熱插拔以及服務質量(QoS)的優(yōu)點。PCI-E總線具有極高的傳輸速率,規(guī)格從x1通道到x32通道,其中x1通道雙向傳輸速度為5Gbps,而PCI-E 3.0規(guī)范中x32通道雙向傳輸速度可達320Gbps,滿足目前絕大部分場合的需要。PCI-E設備連接到計算機系統(tǒng)必須有相應的驅動程序才能在計算機系統(tǒng)上正常工作。PCI-E驅動程序的優(yōu)劣直接關系到整個系統(tǒng)的性能和穩(wěn)定性,因此,設計和開發(fā)穩(wěn)定高效的PCI-E驅動程序具有重要意義。
在設計PCI-E驅動程序之前,先對要控制的硬件系統(tǒng)和工作流程做簡要的分析介紹。硬件系統(tǒng)的基本結構框圖如圖1所示。這是一套自行開發(fā)的基于PCI-E接口的分布式數(shù)據(jù)采集系統(tǒng),主要實現(xiàn)了分布式高速數(shù)據(jù)采集及傳輸。
圖1左側是基于FPGA的數(shù)據(jù)采集單元,采集單元不間斷采集實際運行數(shù)據(jù),數(shù)據(jù)同步單元將多個采集單元的數(shù)據(jù)匯總打包,然后通過PCI-E傳送到PC后臺服務器。數(shù)據(jù)同步單元與采集單元、PC后臺服務之間均采用PCI-E連接,傳輸介質為光纖。采集系統(tǒng)的核心是基于PowerPC處理器的數(shù)據(jù)同步單元,數(shù)據(jù)同步單元選用了FreeScale公司的MPC8536處理器,該處理器內部集成PCI-E、USB、以太網(wǎng)、內存等部件。用MPC8536配置與PC后臺服務器相連接的PCI-E總線接口,包括PCI-E接口寄存器、基地址寄存器、Memory空間。為了實現(xiàn)高速數(shù)據(jù)傳輸,本設計把MPC8536作為DMA主控制器,MPC8536自帶PCI-E有四路DMA通道,通過MPC8536來實現(xiàn)采集同步后的數(shù)據(jù)向PC后臺服務器的高速傳輸。
Jungo公司開發(fā)的WinDriver驅動程序開發(fā)軟件包,易于使用,不需要熟悉操作系統(tǒng)的內核知識及系統(tǒng)相關底層的東西,整個驅動程序中的所有函數(shù)都工作在用戶態(tài),所以該軟件包開發(fā)的驅動程序靈活和工作效率都很低。
NuMega公司開發(fā)的DriverStudio驅動程序開發(fā)軟件包,采用面向對象的方式,將驅動程序編寫所需的與內核訪問及對硬件的訪問封裝成類,加上驅動程序代碼生成向導DriverWizard等工具,簡化了驅動程序開發(fā)的難度,減少了工作量,靈活性也很好。但該軟件目前已經停止開發(fā),不支持Windows7、8等新版本的操作系統(tǒng)。
WDK(Windows Driver Kit)是Microsoft公司開發(fā)一種完全集成的驅動程序開發(fā)系統(tǒng),包括WDF、頭文件重構(Windows Vista和更高版本)、驗證程序和靜態(tài)分析工具。極大地簡化Windows驅動程序的開發(fā),利用WDF開發(fā)驅動程序具有代碼簡單,結構清晰,效率高,而且對整個體系結構有很好的理解和把握。本文采用WDK進行PCI-E的驅動程序開發(fā)。
WDF(Windows Driver Foundation)是微軟提出的下一代全新的驅動程序模型,是以WDM(Windows Driver Model)為基礎進行建模和封裝,完全基于面向對象技術實現(xiàn),支持屬性、方法和事件。提供了高度靈活、可擴展、可診斷的驅動程序框架。WDF框架管理了大部分與操作系統(tǒng)相關的交互,實現(xiàn)了公共的驅動程序功能,如電源管理、即插即用pnp等,降低了驅動程序開發(fā)的難度。WDF提供了兩個框架:KMDF內核模式驅動程序框架和UMDF用戶模式驅動程序框架。本文介紹的PCI-E驅動程序屬于KMDF內核模式。KMDF框架支持面向對象、事件驅動的驅動程序模型。它定義了一系列的對象用來表示設備、驅動、中斷等,每個對象有對應的屬性、方法和事件。驅動程序利用這些方法創(chuàng)建對象、設置屬性和響應事件。
WDF的對象模型是層次化的模型。WDFDRIVER對象是根對象,其他對象都是它的子對象。對于大多數(shù)對象,驅動程序在創(chuàng)建它們的時候可以指定父對象,如果沒有指定,則框架默認其父對象為WDFDRIVER對象。
WDF大大簡化了WDM中的pnp和電源管理的開發(fā)。WDF框架為設備停止、設備刪除、電源狀態(tài)切換等事件提供了適合的缺省行為,驅動程序本身不再糾纏于復雜的pnp和電源管理事件處理。此外,WDF還集成了請求隊列的支持,一個設備可以有多個請求隊列,每個請求隊列可以有一種模式。

表1 DeviceIoControl功能碼及用途簡介

圖1 采集系統(tǒng)結構圖

圖2 驅動程序整體框圖
最簡單的是WdfIoQueueDispatchSerial模式,在這種模式下,請求隊列將請求串行化后再處理;而WdfIoQueueDispatchParallel模式則自動在每個請求到來時調用相應的回調函數(shù);最后WdfIoQueueDispatchManual模式允許驅動程序手工分發(fā)請求,類似于WDM的工作方式。
第一次加載驅動程序時調用DriverEntry例程,DriverEntry是WDF驅動程序的標準入口函數(shù),DriverEntry例程負責驅動程序和框架的初始化。在DriverEntry例程中主要創(chuàng)建驅動程序對象WDFDRIVER和設置EvtDeviceAdd例程地址,驅動程序對象WDFDRIVER代表PCI-E驅動程序。
PCI-E驅動程序整體框體如圖2所示,驅動程序初始化后,當PnP管理器檢測到新的PCI-E硬件設備時,PnP管理器根據(jù)安裝驅動程序時inf文件中的設備識別號和廠商識別號找到相應的設備驅動,然后調用在DriverEntry例程中設置的EvtDeviceAdd對應的回調例程。完成PCI-E設備驅動程序的初始化。初始化過程主要完成創(chuàng)建設備對象、創(chuàng)建I/O隊列、設備GUID接口、初始化中斷處理、創(chuàng)建DMA操作對象,并設置各種事件的回調處理例程,如即插即用、電源管理、I/O處理等等。在該例程中創(chuàng)建設備對象作為目標I/O設備,并將該設備對象附著到設備堆棧中。驅動程序還將完成設備內存空間的獲取及轉換,這點非常重要,因為這將直接影響驅動程序工作時的正確性和穩(wěn)定性,具體過程是通過調用EvtDevicePrepareHardware例程獲取設備的內存的物理地址和長度,部分代碼如下:

用WdfCmResourceListGetCount函數(shù)獲取配置資源的個數(shù),用WdfCmResourceListGetDescriptor函數(shù)獲取該資源的描述符,其類型屬性包括CmResourceTypeMemory(存儲器)、CmResource-TypePort(IO端口)、CmResourceTypeInterrupt(中斷)等,對于存儲器地址,用MmMapIoSpace將物理地址轉換成系統(tǒng)內核模式地址,并將該內核模式地址保存到設備擴展對象中供以后使用,
數(shù)據(jù)傳輸是驅動程序和同步單元MPC8536的Memory之間進行的數(shù)據(jù)傳輸,本設計把待傳輸?shù)臄?shù)據(jù)分為兩類,一類是控制命令類數(shù)據(jù),另一類是采集的數(shù)據(jù),即MPC8536同步單元需要傳送到PC后臺服務器的數(shù)據(jù)。控制命令類數(shù)據(jù)通過發(fā)送IoControl命令的方式進行傳輸。采集的數(shù)據(jù)則通過DMA方式傳送,因為對于高速數(shù)據(jù)流來說,需要速度更快,傳輸效率更高,DMA方式傳送能滿足性能要求,而且也保證了數(shù)據(jù)在傳輸過程中不丟失。
控制命令類數(shù)據(jù)的傳輸,操作系統(tǒng)檢測到硬件設備并加載相應的驅動程序后,應用程序就可以通過DeviceIoControl發(fā)起一個device I/O control請求,控制命令類數(shù)據(jù)定義成device I/O control請求功能碼,通過這個請求即可發(fā)送各種控制命令類數(shù)據(jù),驅動程序中EvtIoDeviceControl例程將接受并處理DeviceIoControl請求,DeviceIoControl可以通過參數(shù)傳送不同的功能請求碼,驅動程序中根據(jù)不同的功能碼做不同的響應處理,例如,啟動/停止數(shù)據(jù)傳輸、復位設備、設置句柄等等,具體功能碼和用途見表1所示。
采集的數(shù)據(jù)傳輸,由于采集數(shù)量大,為了及時可靠的完成數(shù)據(jù)傳輸,采用DMA方式傳輸。DMA方式傳輸?shù)墓ぷ髁鞒倘缦拢河肳dfDmaTransactionInitializeUsingRequest函數(shù)初始化DMA傳輸,調用WdfDmaTransactionExecute啟動DMA編程。在EvtProgramDmaDMA中對MPC8536的DMA寄存器進行編程進行數(shù)據(jù)傳輸。當DMA傳輸中斷發(fā)生,在DPC例程中測試DMA是否結束,沒有結束則調用WdfDmaTransactionExecute函數(shù)繼續(xù)執(zhí)行DMA。若DMA傳輸結束則完成該I/O請求。同步單元中的MPC8536作為DMA的主控制器,當緩沖區(qū)區(qū)中的采集數(shù)據(jù)達到一定數(shù)量后,MPC8536利用DMA方式將緩沖區(qū)中的數(shù)據(jù)直接寫到PC后臺服務器的內存空間,并產生一個DMA中斷通知驅動程序,驅動程序收到中斷后調用中斷響應例程來處理內存空間的數(shù)據(jù)。PC后臺服務器中用于DMA讀寫的內存空間由驅動程序分配,應用程序利用這段內存空間直接與同步單元的MPC8536進行DMA方式的數(shù)據(jù)傳輸。
為了提高驅動程序和應用程序之間的處理效率,驅動程序采用事件方式與應用程序進行通信。應用程序中用CreateEvent創(chuàng)建事件hEvent,調用DeviceIoControl函數(shù)將事件傳遞給驅動程序,驅動程序響應該請求,從輸入緩沖區(qū)中取出這個事件句柄存在設備擴展對象中。當驅動程序處理完DMA傳輸中斷后將該事件設置為信號狀態(tài),此時應用程序就可以處理已經傳送到PC后臺服務器內存空間中的數(shù)據(jù)了。
PCI-E作為一種高性能的總線,已經得到了廣泛的應用,文章闡述了基于WDF的PCI-E驅動程序開發(fā),經測試在windows2003系統(tǒng)下驅動程序運行穩(wěn)定,在數(shù)據(jù)鏈路x1通道的條件下用DMA方式傳輸,數(shù)據(jù)率可以達到100MB/s,數(shù)據(jù)傳輸速率比較理想,滿足項目的要求,目前已經成功運用于某海上采油平臺的數(shù)據(jù)采集中,經現(xiàn)場實際運行驗證,工作穩(wěn)定可靠。
[1]王齊.PCI Express體系結構導讀[M].北京:機械工業(yè)出版社,2010.
[2]武安河.Windows設備驅動程序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ù)傳輸卡的驅動程序開發(fā)[J].中國測試技術,2008,3:67-68.