日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用DriverStudio开发USB驱动程序

發(fā)布時(shí)間:2025/3/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用DriverStudio开发USB驱动程序 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

很多寫Windows Device Driver的開發(fā)人員基本上都是使用Windows DDK進(jìn)行開發(fā)的。但是,現(xiàn)在也有不少人都開始借助一些輔助工具。筆者去年開始接觸到DriverStudio,發(fā)現(xiàn)它真的是一個(gè)不錯(cuò)的開發(fā)工具,不僅寫代碼的時(shí)候思路清晰,而且和DDK的結(jié)合很好。

??? 當(dāng)然,也有很多人覺得用DriverStudio不夠正宗,或者說不能很好的理解Windows Device Driver的架構(gòu)。我感覺這就有點(diǎn)像MFC和SDK的關(guān)系,關(guān)于這個(gè)問題在很多地方都有爭(zhēng)論,比如在萬千新聞組上,就討論了將近2個(gè)月。每個(gè)人都有自己的最愛,都有自己的習(xí)慣,只要你能把事情做好,我想用什么方法應(yīng)該都是一樣的。如果你已經(jīng)習(xí)慣了用DDK開發(fā),那完全還可以繼續(xù)用下去;如果你覺得DriverStudio不錯(cuò),那嘗試用一個(gè)可以給你按照OOP概念來編程的工具有什么不好呢?

????? 在驅(qū)動(dòng)開發(fā)網(wǎng)上,經(jīng)常看到有人詢問一些關(guān)于DriverStudio的使用的問題。我正好很有幸用它作了幾個(gè)驅(qū)動(dòng)程序,包括VXD, KMD和WDM,稍微有點(diǎn)心得,因此想寫下來給大家作一個(gè)小小的參考。如果其中有錯(cuò)誤,歡迎大家給我指出,謝謝。

下面我就介紹一下用DriverStudio開發(fā)一個(gè)USB驅(qū)動(dòng)程序的過程。這個(gè)USB設(shè)備有3個(gè)雙向端點(diǎn),每個(gè)端點(diǎn)的配置如下:

?????? EP??????? 類型??????? 地址 buffer(Bytes)
0 IN/OUT Control 0x80/0x00 16/16
1 IN/OUT Bulk 0x81/0x01 16/16
2 IN/OUT Bulk 0x82/0x02 64/64

????? 我們的驅(qū)動(dòng)程序需要實(shí)現(xiàn)的功能就是控制設(shè)備上的LED燈的亮和滅,以及通過Endpoint 2對(duì)設(shè)備進(jìn)行讀寫。

???? 由于DriveStudio由幾個(gè)部分組成,我們寫這個(gè)驅(qū)動(dòng)程序只要用到DriverWorks,因此下面我們就簡(jiǎn)稱它為DW。在這里,我們假定讀者已經(jīng)正確的安裝了DW,并且已經(jīng)編譯好了各個(gè)庫文件。

1. 首先,我們通過快捷方式“Setup DDK and Start MSVC“來啟動(dòng)VC IDE。這個(gè)快捷方式所指向的程序,會(huì)進(jìn)行一些必要的設(shè)置,然后再啟動(dòng)VC IDE,這樣我們的程序就可以使用DDK和DW的頭文件和庫了。

2. 從VC IDE的菜單"DriverStudio"中選擇"DriverWizard", 在如圖1所示的對(duì)話框中, 寫上項(xiàng)目名稱. 在這里, 我們將這個(gè)項(xiàng)目稱為: TEST, 所在的目錄為D:\TEST. 然后點(diǎn)按鈕"Next >".
?
圖1

3. 在接下來的這個(gè)對(duì)話框中(如圖2), 我們需要選擇驅(qū)動(dòng)程序的類型. 由于USB設(shè)備驅(qū)動(dòng)程序是WDM類型的, 所以我們選擇第二項(xiàng)并且點(diǎn)按鈕"Next >".
?
圖2

4. 在第3個(gè)對(duì)話框中(如圖3), 選擇我們的驅(qū)動(dòng)程序所操作的總線類型. 這里, 我們選擇USB. 在USB Vendor ID和USB Product ID中填入U(xiǎn)SB設(shè)備的VID和PID. 假定我們的USB設(shè)備的VID和PID分別是16進(jìn)制的0471和1801. 然后點(diǎn)按鈕"Next >". 關(guān)于VID和PID的規(guī)定請(qǐng)參考USB-IF的規(guī)范.
?
圖3

5. 在接下來的對(duì)話框中(如圖4), 我們需要加入Endpoint 1和Endpoint 2的定義. 由于在USB中規(guī)定Endpoint 0是必須存在的, 所以我們不需要對(duì)Endpoint 0進(jìn)行定義. 點(diǎn)"Add..."按鈕, 彈出一個(gè)如圖5所示的對(duì)話框. 我們將它修改成如圖6所示. 其中, 按照USB的規(guī)定, 對(duì)于端點(diǎn), 它的地址是1; 按照前面說明的設(shè)備的特點(diǎn), Endpoint 1的最大的包大小為16字節(jié), 因此在"Max Transer Size"中填入16; Endpoint Name可以通過"Suggest Name"得到. 按照這些原則, 繼續(xù)設(shè)置其他的配置, 以使對(duì)話框4變成如圖7所示. 接下來, 繼續(xù)按"Next >"按鈕.
?
圖4
?
圖5
?
圖6
?
圖7

6. 在如圖8所示的對(duì)話框中, 可以填入我們需要的Driver Class的名字和文件名. 一般我們不需要更改. 繼續(xù)按"Next >"按鈕.
?
圖8

7. 在如圖9所示的對(duì)話框中, 因?yàn)椴恍枰o其他的驅(qū)動(dòng)程序提供接口, 也不需要提供Flush功能, 所以不需要任何修改, 直接按"Next >"按鈕.
?
圖9

8. 在如圖10所示的對(duì)話框中, 我們選擇給端點(diǎn)2產(chǎn)生BULK Read的代碼, 并且按"Next >"按鈕. DW會(huì)給我們產(chǎn)生一套對(duì)端點(diǎn)2進(jìn)行讀的代碼, 不用修改, 就可以直接使用.
?
圖10

9. 在如圖11所示的對(duì)話框中, 我們選擇給端點(diǎn)2產(chǎn)生BULK Write的代碼, 并且按"Next "按鈕. 這樣, DW也會(huì)給我們產(chǎn)生一套對(duì)端點(diǎn)2進(jìn)行寫的代碼, 不用修改, 就可以直接使用.
?
圖11

10. 對(duì)于如圖12的對(duì)話框, 我們直接按"Next >"按鈕. 這里是設(shè)置是否要將I/O請(qǐng)求排隊(duì), 在這里, 我們不需要排隊(duì).
?
圖12

11. 在如圖13所示的對(duì)話框中, 我們不需要?jiǎng)?chuàng)建任何注冊(cè)表項(xiàng), 所以直接按"Next >"按鈕.
?
圖13

12. 如圖14所示的對(duì)話框, 是讓我們?cè)O(shè)置一些驅(qū)動(dòng)程序的屬性, 比如接口, 緩沖區(qū)之類的. 一般的都可以使用缺省設(shè)置. 繼續(xù)按"Next >"按鈕.
?
圖14

13. 在如圖15所示的對(duì)話框中, 是讓我們給驅(qū)動(dòng)程序增加一些IOCTL接口. 我們只增加一個(gè)如圖16所示的IOCTL來控制USB設(shè)備的LED燈. 然后按"Next >"按鈕.
?
圖15
?
圖16

14. 在最后一個(gè)如圖17所示的對(duì)話框中, 可以設(shè)置一些驅(qū)動(dòng)程序的屬性, 產(chǎn)生一個(gè)console測(cè)試程序. 按下"Finish"按鈕, 就結(jié)束了Wizard.
?
圖17

這樣, 我們就創(chuàng)建好了一個(gè)基本的驅(qū)動(dòng)程序, 下面來看看還要做哪些工作才可以和我們的設(shè)備以及上層的應(yīng)用程序通訊.

把函數(shù)NTSTATUS TESTDevice::TEST_IOCTL_LED_Handler(KIrp I)改成如下面的樣子:

NTSTATUS TESTDevice::TEST_IOCTL_LED_Handler(KIrp I)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;

t << "Entering TESTDevice::TEST_IOCTL_LED_Handler, " << I << EOL;

__try

{

// TODO: Verify that the input parameters are correct

// If not, return STATUS_INVALID_PARAMETER

if(I.IoctlOutputBufferSize() || !I.IoctlBuffer() ||

(I.IoctlInputBufferSize() != sizeof(UCHAR)))

__leave;

// TODO: Handle the the ZBUARD_IOCTL_LED_ON request, or

// defer the processing of the IRP (i.e. by queuing) and set

// status to STATUS_PENDING.

PURB pUrb = m_Lower.BuildVendorRequest(

NULL, // transfer buffer

0, // transfer buffer size

0, // request reserved bits

(UCHAR)(*(PUCHAR)I.IoctlBuffer()), // request. 1 = LED_ON, 0 = LED_OFF

0 // Value

);

// transmit

status = m_Lower.SubmitUrb(pUrb, NULL, NULL, 5000L);

}

__finally

{

// TODO: Assuming that the request was handled here. Set I.Information

// to indicate how much data to copy back to the user.

I.Information() = 0;

I.Status() = status;

}

return status;

}

這個(gè)函數(shù)是控制LED燈的,它是通過USB Vendor Request來向設(shè)備傳送的。其中,request=1的時(shí)候表示讓LED亮,request=0的時(shí)候讓LED滅。它是通過DeviceIoControl由上層應(yīng)用程序傳下來。

再看看讀寫部分,經(jīng)過檢查NTSTATUS TESTDevice::Read(KIrp I)和NTSTATUS TESTDevice::Write(KIrp I)可以發(fā)現(xiàn),DW已經(jīng)給我們寫好了讀寫的代碼,我們可以直接使用了。這些代碼就是在上面的第8和第9步中產(chǎn)生的代碼。

最后,修改編譯一下DriverStudio產(chǎn)生的測(cè)試程序Test_TEST程序,我們就可以通過命令行來測(cè)試我們的驅(qū)動(dòng)程序了。對(duì)于LED的控制,我們可以直觀的在設(shè)備上看到,但對(duì)于讀寫的操作就需要和firmware程序配合,這已經(jīng)超出了本文的范圍,不在這里討論了。

通過上面的講解,我們可以看到有了DriverStudio,就可以快速的產(chǎn)生一個(gè)驅(qū)動(dòng)程序,然后在里面作一些小的改動(dòng)就可以使用了。即使是寫一個(gè)比較復(fù)雜的USB驅(qū)動(dòng)程序,我們也可以不用管一些系統(tǒng)的IRP處理,只要專注于我們自己的特定應(yīng)用就可以了。而且它把一個(gè)驅(qū)動(dòng)程序概括成幾個(gè)類的概念,并且DW還附帶有一些很有用的STL類,在VC IDE里面有了一個(gè)很清晰直觀的表示。這樣,對(duì)一些從上層應(yīng)用轉(zhuǎn)向驅(qū)動(dòng)程序的開發(fā)人員,或者一些對(duì)C++/OOP很熟悉但不太了解系統(tǒng)內(nèi)核的開發(fā)人員,都比較容易上手。即使對(duì)于推崇直接用DDK編程的人來說,通過閱讀DriverStudio附帶的源代碼,也可以對(duì)驅(qū)動(dòng)程序的開發(fā)有一個(gè)更加深入的了解


總結(jié)

以上是生活随笔為你收集整理的用DriverStudio开发USB驱动程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。