最近做了一個USB裝置的功能驅動,並對其速度的瓶頸做了一些分析,最後找到了影響此裝置的速度的主要原因。由於USB裝置的通用性,代碼的主體直接使用DDK提供的範例程式碼:Bluckusb。
1、 USB驅動結構圖
查看次數: 173
檔案大小: 16.8 KB" src="http://bbs.pediy.com/attachment.php?attachmentid=31655&d=1253583343" border="0" alt="名稱: USB裝置層次.JPG
查看次數: 173
檔案大小: 16.8 KB">
圖表 1:USB裝置階層
USB主控制器與其它I/O裝置一樣直接連接到系統匯流排上。作業系統與主控制器通訊使用I/O口或記憶體寄存器,通過普通的中斷訊號,系統可以接受主控制器的事件通知。主控制器串連一棵USB裝置樹。一種稱為hub的裝置作為其它裝置的連接點。多個hub能以菊鏈方式串連,可以串連到USB規範中定義的最大深度。其它裝置,如照相機、麥克風、鍵盤等等,直接連到hub上。為了精確地表達概念,USB使用術語function來描述非hub裝置。
2、 寫USB功能驅動需要瞭解的內容
a. 驅動編譯方法
各種入門書上都有介紹,用DDK的Dos環境編譯時間,錯誤資訊會在Dos介面顯示,如果這些資訊不能定位問題,可以到代碼目錄下找名字為buildxx的log檔案。
b. 驅動與裝置的關聯
驅動與裝置的關聯是靠INF檔案來指定的。簡單來說只要把DDK中提供的USB驅動樣本中的INF檔案中的VID_XXXX和PID_XXXX中的XXXX換成自己裝置的VID和PID值,[SourceDisksFiles]節中BULKUSB.sys 換成自己的驅動檔案名稱就可以使驅動和裝置關聯。更多INF檔案介紹可以參考相關介紹文檔。
c. 裝置自訂的命令
自訂的裝置,一般都會自訂一些控制命令,在寫驅動時,需要瞭解這些命令的作用,在調試時方便定位問題所在。
此處需要把IoControl命令和裝置命令區分開,IoControl命令是應用程式與驅動進行互動的命令,IoControl命令的產生與裝置沒有直接關係,可以隨意設定只要不與驅動的標準命令發生衝突就可以;裝置命令是在令牌階段使用,也即Setup包,裝置命令由硬體設計者要定義,裝置命令是主機和裝置通訊的第一步。
查看次數: 173
檔案大小: 17.7 KB" src="http://bbs.pediy.com/attachment.php?attachmentid=31656&d=1253583343" border="0" alt="名稱: SETUP令牌.JPG
查看次數: 173
檔案大小: 17.7 KB">
圖表 2:SETUP令牌的內容
d. USB驅動與裝置互動的方式
Windows中通過發送URB和USB裝置進行通訊備,各種函數代碼中的核心是構造URB,發送URB,Setup包(令牌包)中的資訊也被包含在URB中。為了方便構造URB,DDK提供了一組宏函數,使用宏函數可以很方便構造不同類型的URB,構造Setup包的宏為UsbBuildVendorRequest ,其中index,value,request在硬體中會用到。
3、 正確讀寫資料的關鍵點
USB裝置讀寫主要由是通過端點來進行,一個端點的資料流方向只能有一個IN或者OUT。端點存在於介面中,介面由配置時取得,配置主要在IRP_MJ_CREATE的Dispatch函數裡執行。配置、介面與端點的關係如所示。在DDK提供的Bulkusb的代碼中,PipeInfomation設定有問題,用fileObject儲存pipe handle沒有道理,需要改成用deviceExtension來儲存;UsbInterfaces中,Pipes數組至少有兩個元素,一個是寫資料時用的Handle,一個是讀資料時用的Handle,在我的裝置中Pipes[0]寫,Pipes[1]寫。
查看次數: 173
檔案大小: 23.2 KB" src="http://bbs.pediy.com/attachment.php?attachmentid=31657&d=1253583343" border="0" alt="名稱: USB配置.JPG
查看次數: 173
檔案大小: 23.2 KB">
圖表 3:USB裝置的配置、介面、端點
4、 調試驅動的工具
查看列印資訊,需要用DbgView;要跟蹤驅動代碼用Windbg,串口線進行雙機調試,調試前需要下載被調試機的符號檔案;測試並且查看USB讀寫資料,用Bus Hound,USBlyzer配合使用;驅動代碼編輯用Source Insight;代碼編譯直接用DDK提供的編譯環境即可。