基於WDF的PCI/PCIe介面卡Windows驅動程式(5)-如何為硬體移植驅動程式

來源:互聯網
上載者:User

標籤:翻譯   針對   nbu   不同   top   裝置資訊   val   位元組   編譯   

原文地址:http://www.cnblogs.com/jacklu/p/6139347.html

正如前幾篇部落格所說,使用WDF開發PCIe驅動程式是我本科畢業設計的主要工作。在讀研的兩年,我也分別為所在課題組移植了自己編寫的驅動程式,在Windows 32位和64位平台下的PXI、PXIe、PCI、PCIe板卡分別得到了驗證。

這篇文章根據自己最新編寫的驅動代碼(原始碼請找博主索取),主要講述如何為自己的硬體板卡移植驅動程式,並簡單講述如何使用Altera系列FPGA配置PCI IP核,然後對INF檔案作簡要描述,最後描述如何使用Qt編寫上位機軟體調用底層驅動。

準備去讀博了,這一篇將作為這個系列的完結,之後將把更多精力放到機器學習上來。 

1概述

所編寫的驅動代碼程式包括7個原始碼檔案,分別是Device.h, Driver.h, Public.h, Trace.h, Device.c,Driver.c, Queue.c。其中Device.h 定義了與硬體相關的地址位移;Public.h定義了DeviceIoControl 用到的使用者自訂命令字, 此標頭檔由上層應用程式和驅動程式共同使用;Queue.c定義了I/O回調常式,分別使用了read、write和I/O Control 三個隊列。 除了這三個檔案外, 不建議更改其他4個檔案的代碼。三個源檔案函數列表分別 1-1、1-2、1-3所示:

2驅動程式移植說明2.1 Public.h說明
  • 代碼中定義了GUID值,開發人員可以使用 VS2013 下的工具 GUIDGen.exe 產生 GUID值,該GUID標識驅動程式,應用程式根據這個GUID值來找到對應的驅動程式。
  • 代碼中定義了CTL_CODE, I/O 處理常式 DeviceIoControl 的第二個參數dwIoControlCode 就是由 CTL_CODE 宏定義的。 CTL_CODE 是一個用於建立一個唯一的32 位系統I/O控制碼的宏,這個控制碼包括4部分組成:DeviceType(裝置類型,高16位(16-31 位)),Access(訪問限制,14-15 位),Function(功能2-13位),Method(I/O訪問記憶體使用量方式)。CTL_CODE 定義中有一個Method域,該2域定義了驅動程式中擷取應用程式資料緩衝區的地址方式。 已經定義的 CTL_CODE 命令字說明如表 2-1 所示, 使用者可以根據格式自訂 CTL_CODE, 實現不同功能。

什麼是 CRA 寄存器組? 開啟 quartus 的 sopc builder,可以看到sopc架構 2-1 所示,在PCI IP核一欄中有 Control Register Access 寄存器組,位址範圍0x00000000-0x00003fff。 裡面關鍵的寄存器地址 2-2 所示。 通過讀黃色標識的寄存器,可以通過驅動程式調實驗證 PCI 核。 關於 CRA 寄存器組的配置說明會在 2.3 節詳細說明。

2.2 Device.h說明
  • 代碼對 FPGA 上硬體資源的位移地址進行宏定義,在 Altera 系列的 FPGA 裡,這些位移地址也叫 Avalon 地址, 在 sopc builder 可以自訂分配, 2-1 中的 Base和End 所示, “ 小鎖頭” 標誌表示地址鎖定, 點擊該標誌解鎖後可以自訂便宜地址。這些地址必須與驅動程式中所用的地址一一對應;
  • 代碼定義了裝置對象結構體, 對幾個重要的成員變數注釋如下:

  • 代碼對一些事件回調常式進行了說明, 一般不需要使用者進行二次修改;
2.3 Queue.c說明
  • 代碼是使用者需要針對功能開發的代碼。 以從應用程式向驅動程式寫入位移地址為例,即原代碼第 xx-xx 行 , 首先在 Public.h 檔案裡定義 IoControlCode 為qd41_IOCTL_WRITE_OFFSETADDRESS, 第 48-53 行為擷取應用程式輸入快取資料的指標( 代碼中為 inBuffer) , 通過指派陳述式將 inBuffer 指向的資料內容賦給裝置對象的成員變數 OffseAddressFromApp, 即完成了本功能;
  • 代碼定義了寫隊列功能, 對 DMA 的寫功能配置在此函數中完成。 Altera的 DMA IP 核共有 5 個寄存器, 2-3 所示。

  • 在配置 DMA 前需要配置 PCI CRA 寄存器, 使能 PCI 中斷, 配置 Avalon-PCI 地址轉換表, 如代碼所示;
  • 為什麼需要配置 Avalon-PCI 地址轉換表? 因為 PCI IP核一端是 PCI 匯流排,一端是Avalon匯流排,地址轉換過程圖 2-4 所示,類似MMU地址翻譯原理,不在贅述,此時需要把PC機獲得的DMA傳輸緩衝物理地址的高16位地址寫入地址轉換表;

  • 配置好 PCI 後就可以配置 DMA 控制寄存器了, 首先將狀態寄存器和控制寄存器清零,如代碼所示;
  • 然後將讀寫地址分別寫入讀寫寄存器, 注意PC機上的記憶體位址為低16位,而高16位要配置在 Avalon-PCI 地址轉換表中, 如代碼所示, 其中 0x20000 為 PCI IP核的 Avalon 地址, 2-1 所示;
  • 向長度寄存器寫入 DMA 傳輸長度(單位:位元組) , 如代碼所示;
  • 向控制寄存器寫入 DMA 控制字 0x8c, 即長度寄存器降低為0時傳輸完成, 使能DMA,32 位字傳輸, 如代碼所示;
3應用程式如何調用驅動程式3.1 GUID說明

GUID( Globally Unique Identifier) 是微軟推出的通用唯一識別碼, 通過使用某個特定的演算法( 比如根據時間或地點等資訊) 產生一組128 位位元,來標識某一個實體,比如硬碟上的一張圖片。 GUID 廣泛應用於微軟的產品中, 用於識別介面、檔案等對象。開發人員可以使用 VS2013 下的工具 GUIDGen.exe 產生 GUID 值, 該 GUID 標識驅動程式, 應用程式根據這個 GUID 值來找到對應的驅動程式。

應用程式總體流程設計為: 首先通過 Win32API 函數 CreateFile 開啟裝置, 然後調用DeviceIoControl 函數與驅動程式通訊,即讀寫資料,當應用程式退出時,調用CloseHandle函數關閉裝置。

應用程式根據底層設定的 GUID 擷取裝置路徑, 從而與指定裝置建立串連: 首先調用SetupDiGetClassDevs 函數獲得符合傳入參數 GUID 的裝置資訊集合 hDevInfo; 然後根據裝置資訊集合 hDevInfo 和 GUID 調用 SetupDiEnumDeviceInterfaces 函數枚舉裝置資訊集合中的裝置,並輸出裝置介面資料資訊 DeviceInterfaceData ; 再 根 據 hDevInfo和 DeviceInterfaceData 調用 SetupDiGetDeviceInterfaceDetail函數得到儲存裝置介面詳細資料DeviceInterfaceDetailData 的緩衝區大小 ,接著為其開闢空間 , 最後再調用一次SetupDiGetDeviceInterfaceDetail 函數獲得裝置介面詳細資料 pDeviceInterfaceDetailData; 最後根據裝置介面詳細資料的裝置介面路徑 pDeviceInterfaceDetailData->DevicePath 調用CreateFile 函數來建立裝置控制代碼。

3.2 應用程式如何開啟裝置

在測試程式 Source.c 的代碼第 62-70 行,完成開啟裝置控制代碼功能, 不需要使用者改動。

3.3 應用程式如何讀裝置

成功開啟裝置後, 調用 DeviceIoControl 即可通過 IOControl 隊列與驅動程式通訊, 以讀32bit 資料為例, 首先向驅動程式寫入需要讀的儲存單元地址, 如代碼第 257-272 行所示,然後向驅動程式傳入讀資料緩衝 outBuffer, 如代碼第 274-289 所示, 即可獲得FPGA 上對應位移地址的資料。

3.4 應用程式如何寫裝置

成功開啟裝置後, 調用 DeviceIoControl 即可通過 IOControl 隊列與驅動程式通訊, 以寫32bit 資料為例, 首先向驅動程式寫入需要寫的儲存單元地址, 如代碼第 303-317 行所示,然後向驅動程式傳入縮寫資料緩衝 inBuffer, 如代碼第 322-336 所示, 即可將資料寫入 FPGA上對應位移地址的記憶體單元。

3.5 應用程式如何對裝置進行DMA傳輸

通過Win32API 函數ReadFile和WriteFile對裝置控制代碼進行檔案讀寫操作, 在核心驅動中會調用驅動程式的 qd41EvtIoRead和qd41EvtIoWrite,實際的DMA配置在這兩個驅動回調常式中實現, ReadFile和WriteFile 只是完成了資料從使用者層到核心層的搬運。詳細代碼在第 340-378 行,不再贅述。

4 INF檔案與如何調用Qt編寫上位機軟體調用底層驅動

我把C語言編寫的應用程式每一個獨立的控制命令編譯成一個可執行檔,這樣Qt可以在新的進程中調用 C 程式編寫的命令字讀寫程式。使用Qt 封裝好的進程類 QProcess, 使用其成員函數 start 即可調用一個外部程式。

基於WDF的PCI/PCIe介面卡Windows驅動程式(5)-如何為硬體移植驅動程式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.