文獻標識碼: A
文章編號: 0258-7998(2014)04-0126-04
在高科技研究以及工業、醫療、交通、航空等眾多領域中,對高幀率和高分辨率的圖像數據需求逐漸加大,例如航天和軍工中高速物體運動軌跡的捕捉、3D動漫、視頻定位和測量、高速公路交通監控等。然而,連續的高幀率和高分辨率圖像采集將產生巨大的數據量,例如以10 f/s幀率傳輸分辨率為4 928 V×3 280H的視頻圖像時,總線上的數據速率高達1.23 Gb/s;以500 f/s幀率傳輸分辨率為640 V×480 H的視頻圖像時,總線上的數據速率也高達1.18 Gb/s。為了實現1 Gb/s以上的傳輸速度且滿足實時性和長距離傳輸的要求,選用光纖技術和PCI Express(簡稱PCI-E)總線技術設計了PCI-E總線光纖接口卡。
光纖具有頻帶寬、傳輸距離長、損耗低、抗干擾能力強等優點[1],適用于大量數據的遠程傳輸。PCI-E總線采用了串行點對點通信技術,使傳輸速率大幅度提高,PCI-E 1.0標準的單通道單向速率高達2.5 Gb/s,且最大支持32通道[2]。PCI-E 3.0標準單通道單向速率可達8 Gb/s,是傳輸高速、大數據量總線的首選,具有研究和應用價值。
本文基于Spartan-6芯片設計的PCI Express光纖接口卡的驅動程序,完成的功能有:(1)驅動程序對光纖接口卡硬件資源的獲取; (2)光纖接口卡能夠將大量數據及時發送到計算機內存中; (3)合理的中斷機制能夠滿足處理高速圖像的需要; (4)計算機可以向光纖接口卡發送參數命令。
1 PCI Express接口卡的硬件結構
PCI Express接口卡基于Xilinx公司的Spartan-6 LTX系列FPGA設計,完成圖像數據收發、數據緩存以及PCI-E協議等工作,并將采集到的圖像數據通過PCI-E總線傳輸給計算機。Spartan-6 LTX系列FPGA內部包含一個PCI-E端點硬核,完整實現了PCI-E1.0標準協議中的數據鏈路層和物理層的功能,可以完成1鏈路的PCI-E總線傳輸[3]。光纖接口卡采用單片高性能FPGA設計,具有系統集成度高、硬件設計簡潔且便于擴展的特點。末端利用計算機對采集的圖像進行顯示、存儲以及回放等操作。PCI Express接口卡的硬件結構如圖1所示。
利用ISE中的IP核生成工具CORE Generator對PCIE端點硬核進行定制:設備ID采用默認值,Vendor ID = 0x10EE,Device ID = 0x0007,這是驅動程序識別該硬件的廠商號和設備號; 基址寄存器的類型選擇為Memory,開辟一個32 位尋址的1 KB大小的存儲器空間;中斷設置為采用INTA的傳統中斷類型。
基址寄存器設計是實現接口卡功能關鍵內容,按照偏移地址將1 KB的存儲器空間劃分成功能不同的寄存器,部分定義如表1所示。
2 PCI Express接口卡的驅動程序
2.1 開發工具Windows DDK簡介
Windows DDK是微軟提供的驅動程序開發工具包,包括了設備驅動開發的文檔、頭文件和庫文件、調試工具和程序示例。先將Windows DDK導入VC++軟件開發工具,然后用C語言編寫驅動程序代碼,編譯后再用Windows DDK中的調試軟件調試,生成可執行的驅動程序。使用Windows DDK能夠開發出真正意義上的核心態驅動程序,它所開發的驅動程序效率也是最高的,但必須詳細了解操作系統的內核工作方式,開發難度較大[4]。
常用開發工具還有WinDriver和DriverStudio,為了獲得最大的驅動程序效率,選擇采用Windows DDK來設計PCI Express接口卡的驅動程序。
2.2 WDM啟動程序的結構
通常WDM驅動程序都是基于分層的結構設計,由功能驅動函數、總線驅動程序和過濾器驅動程序三部分組成。完成一個設備的操作,至少要有兩個驅動設備共同完成[5],一個是總線驅動程序生成的物理設備對象(PDO),另一個是功能驅動程序生成的功能設備對象(FDO)。
Windows XP系統檢測到PCI-E接口卡插入主板卡槽時,總線驅動會自動創建出一個PDO。但是PDO不能單獨操作設備,還需要將實現功能的FDO掛載在總線驅動生成的PDO上,即相當于功能驅動程序掛載到了指定的硬件設備上[6],實現驅動程序對硬件設備的控制。
2.3 接口卡發送數據
為了提高接口卡的傳輸效率,采用DMA的傳輸方式將圖像數據通過PCI-E總線發送到計算機。在DMA傳輸過程中,PCI-E接口卡作為DMA傳輸的主控器,數據的傳輸速度基本由PCI-E總線的傳輸速度決定[7]。
2.3.1 獲取接口卡的資源信息
接口卡發送圖像數據之前,驅動程序要將DMA傳輸的目標地址以及數據負載的大小發送給接口卡,驅動程序需要先獲取接口卡上的硬件資源,如接口卡端點內存的物理地址等。
首先根據設備類型和設備擴展的大小,利用函數IoCreateDevice生成并初始化一個FDO;其次利用函數IoAttachDeviceToDeviceStack將生成的FDO附加在系統生成的PDO上;然后向PDO轉發一個IRP_MN_START_DEVICE類型的I/O 請求包(IRP),PDO會根據設備的類型自動枚舉該設備的所有資源。為了使FDO能夠得到底層PDO處理IRP的結果,需要同時將一個同步事件發送給底層PDO。PDO處理完IRP后立刻激發同步事件,通知FDO查詢此次IRP的結果; PDO完成了對IRP_
MN_START_DEVICE命令的響應后,將獲取到的接口卡設備資源存儲在IRP中名為IO_STACK_LOCATION結構的設備堆棧中[8],流程如圖2所示。
利用函數IoGetCurrentIrpStackLocation可以獲得該IO_STACK_LOCATION結構,主要包含接口卡的中斷信息、端點內存寄存器資源以及接口卡的物理地址等設備硬件資源。
2.3.2 分配內存空間并實現乒乓操作
為了盡可能提高計算機內存資源利用率,驅動程序分配的內存空間大小與每次DMA傳輸的圖像數據大小需保持一致。先利用函數IoGetDmaAdapter獲取一個DMA適配器,包含了開辟內存空間的函數AllocateCommonBuffer,調用此函數獲得一段指定大小的連續物理內存,保存物理內存的邏輯地址作為DMA傳輸的目標地址。
預先在計算機中分配了多塊內存空間,使計算機可以在處理一塊寫滿了圖像數據的內存緩沖區的同時,用另一塊閑置的內存緩沖區接收DMA傳輸的圖像數據,從而實現乒乓操作,提高傳輸效率[9]。
接收到DMA傳輸開始的指令后,PCI-E接口卡會根據分配好的內存空間地址和設定好的DMA傳輸負載長度,不斷地向計算機發送帶有圖像數據的TLPs數據包[10]。每次DMA傳輸結束后,驅動程序都會根據是否希望繼續進行DMA傳輸選擇輪轉一塊新的內存地址發送給接口卡或者釋放相關資源。DMA傳輸操作流程圖如圖3所示。
2.4 驅動程序的中斷處理
驅動程序接收到PCI-E接口卡產生的中斷信號,表明PCI-E接口卡已經向計算機指定的內存空間完成了一次DMA傳輸,要通知應用層程序對內存中的數據進行訪問,完成顯示、存儲等功能。先利用函數IoConnectInterrupt將中斷例程與設備產生的中斷信號綁定。根據計算機中斷優先級的規則,硬件中斷會得到操作系統的優先響應[11]。
計算機操作系統檢測到PCI-E接口卡的中斷信號來臨時,立即進入中斷服務例程(ISR)。由于接口卡采用的傳統中斷是一種電平中斷信號,還需要驅動程序在ISR中進一步完成對中斷來源的判斷和清除中斷的操作。
采用同步事件方式實現中斷信號的同步處理,先在應用程序中定義一個與驅動程序共享的同步事件,并通過DeviceIoControl函數把該事件句柄傳遞給驅動程序,等待事件觸發之后再進行讀數據操作。驅動程序根據所傳遞的這個事件句柄創建一個相應的內核事件[12]。中斷發生時驅動程序調用KeSetEvent函數將同步事件設置為激發態,通知應用程序中斷已經發生。盡量減少ISR程序的運行時間,將激發同步事件的動作設計發生在擁有較低中斷等級的延遲過程調用例程(DPC)中[13]。中斷處理流程如圖4所示。
2.5 驅動程序向接口卡發送指令
指令發送可以分為兩個子過程,首先應用程序與驅動程序實現交互,然后驅動程序再根據交互獲得的參數,修改PCI-E接口卡端點內存中寄存器的值[14]。
用函數IoRegisterDeviceInterface將一個名為GUID的128位二進制數字標識符與PDO綁定在一起。應用程序利用函數OpenDeviceByGuid獲取被綁定的驅動程序的設備句柄,再利用這個設備句柄和函數DeviceIoControl完成應用程序與驅動程序之間的通信與交互。DeviceIoControl函數可以將指定字節數量的數據傳入驅動程序,同時也可以接收驅動程序返回的數據。
下面舉例給出一個發送光纖相機幀的行大小的參數指令代碼:
#define IOCTL_LINE CTL_CODE (// 定義控制碼
FILE_DEVICE_UNKNOWN,//對象類型0x828,//驅動程序定義的IOCTL碼METHOD_BUFFERED, //操作模式FILE_
ANY_ACCESS) // 訪問權限
hDevice = OpenDeviceByGuid(// 打開驅動
(LPGUID) &GuidDriver); //接口卡設備句柄
ULONG value=0; //初始化輸出緩沖區
value = (m_Line<<16)|0x03; //光纖相機幀的行大小
DeviceIoControl (//發送相機參數命令到驅動程序
hDevice, //上文打開設備后返回的句柄
IOCTL_LINE //控制代碼名稱
&value //輸入緩沖區地址
sizeof(value) //輸入緩沖區大小
NULL,//返回緩沖區地址
NULL 0 //返回緩沖區大小為0
&nOutput // 記錄返回的數據大小
NULL)// 默認為NULL
…
switch (ioStack->Parameters.DeviceIoControl
.IoControlCode) // 驅動程序獲取IOCTL碼
case IOCTL_LINE: // 驅動程序接收到命令
address=(ULONG)deviceExtension->
MemoryStart[FPGA]+LINE; //設定PIO傳輸的目標地址
WRITE_REGISTER_ULONG((PULONG)address,
*pBuffer); //寫接口卡寄存器
應用層將相機參數和指令一同發送給了驅動程序,驅動程序利用在獲取PCI-E接口卡硬件資源時,保存接口卡物理地址和端點內存的寄存器偏移地址,完成對寄存器中數據的修改,實現對前端相機的控制。
利用FPGA內的計數器不斷產生數據,使PCI-E接口卡不停地進行DMA傳輸。應用程序使用QueryPerformanceFrequency獲取處理器頻率,使用QueryPerformanceCounter查詢定時器計數值。經多次反復測試,系統實際最大有效傳輸速度為1.5 Gb/s,高于利用DriverStudio工具開發的驅動程序實現的720 Mb/s有效傳輸速度[15]。
PCI-E總線采用8b/10b編碼, 因此使用1.0標準的PCI-E總線的理論有效輸速度為2.0 Gb/s[16],分析實際有效傳輸速度沒能達到理論值的原因是: (1)驅動程序基于Windows XP系統設計,該操作系統不支持MSI中斷方式,在響應DMA傳輸的傳統中斷時會占用一定時間; (2)發起DMA傳輸前需要設置FPGA內相關寄存器,這也需要一定的時間。
經安裝光纖相機后測試,能夠清晰、流暢地顯示圖像大小為1 280 H×720 V、幀率為120 f/s、傳輸速率為842 Mb/s的圖像數據。驅動程序工作穩定,并且可滿足多種數據類型的傳輸。
參考文獻
[1] 吳德明.光纖通信原理與技術[M].北京:科學出版社, 2004.
[2] 王齊.PCI Express體系結構導讀[M].北京:機械工業出版社,2010.
[3] XILINX. Xilinx solutions guide for PCI express user guide [EB/OL].[2009-09-16]. Http://www.xilinx.com/.
[4] 李忠輝,張志文.PCI設備驅動程序的開發和應用[J].西安工業學院學報,2005,25(1):8-11.
[5] 張帆,史彩成. Windows驅動開發技術形式詳解[M]. 北京:電子工業出版社,2008.
[6] 蹇紅梅,居錦武,王蘭英. Windows設備驅動程序的開發[J]. 四川理工學院學報(自然科學版), 2007(4):11-13.
[7] 席華偉.基于Verilog語言的DMA控制器的設計與仿真[D]. 西安:西安電子科技大學,2007.
[8] 武安河.Windows 2000/XP WDM設備驅動程序開發[M]. 北京:電子工業出版社,2003.
[9] 何柳,陳勇,吳斌.PCI/PCI-E高速實時DMA傳輸驅動設計[J].電子技術應用,2012,38(11):143-145.
[10] 董永吉,陳庶樵,李玉峰,等.Xilinx PCI-Express核總線接口設計與實現[J].電子技術應用,2011,37(8):135-138.
[11] 田澤, 劉娟, 王琦卉.基于WDM的PCIE驅動設計和實現[J]. 軟件導刊,2010,9(4):9-10.
[12] 司剛,付少鋒,周利華.WDM驅動程序中設備事件通知技術研究[J].計算機技術與發展,2006,16(4):144-146.
[13] 梁國龍,何昕,魏仲慧,等.PCIE數據采集系統的驅動程序開發[J].計算機工程與應用,2009,45(31):63-65.
[14] Peng Yu, Li Bo, Liu Datong, et al. A High Speed DMA transaction method for PCI express devices[J]. Journal of Electronic Science and Technology of China, 2009,7(4):380-384.
[15] 王維,蔣景宏,劉垚.基于PCI Express總線光纖采集卡WDM驅動程序設計[J].計算機測量與控制,2013,21(1):272-275.
[16] PCI-SIG. PCI Express card electromechanical specification revision 1.0[S].2002.