• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            旅途

            如果想飛得高,就該把地平線忘掉

            10分鐘完成一個USB驅動程序

            10分鐘完成一個USB驅動程序
            責任編輯:admin   更新日期:2005-8-6
            ??很多寫Windows Device Driver的開發人員基本上都是使用Windows DDK進行開發的。但是,現在也有不少人都開始借助一些輔助工具。筆者去年開始接觸到riverStudio,發現它真的是一個不錯的開發工具,不僅寫代碼的時候思路清晰,而且和DDK的結合很好。

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



            在驅動開發網上,經常看到有人詢問一些關于DriverStudio的使用的問題。我正好很有幸用它作了幾個驅動程序,包括VXD, KMD和WDM,稍微有點心得,因此想寫下來給大家作一個小小的參考。如果其中有錯誤,歡迎大家給我指出,謝謝。



            下面我就介紹一下用DriverStudio開發一個USB驅動程序的過程。這個USB設備有3個雙向端點,每個端點的配置如下:

            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

            我們的驅動程序需要實現的功能就是控制設備上的LED燈的亮和滅,以及通過Endpoint 2對設備進行讀寫。



            由于DriveStudio由幾個部分組成,我們寫這個驅動程序只要用到DriverWorks,因此下面我們就簡稱它為DW。在這里,我們假定讀者已經正確的安裝了DW,并且已經編譯好了各個庫文件。



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

            2. 從VC IDE的菜單"DriverStudio"中選擇"DriverWizard", 在如圖1所示的對話框中, 寫上項目名稱. 在這里, 我們將這個項目稱為: TEST, 所在的目錄為D:\TEST. 然后點按鈕"Next >".


            圖1

            3. 在接下來的這個對話框中(如圖2), 我們需要選擇驅動程序的類型. 由于USB設備驅動程序是WDM類型的, 所以我們選擇第二項并且點按鈕"Next >".


            圖2

            4. 在第3個對話框中(如圖3), 選擇我們的驅動程序所操作的總線類型. 這里, 我們選擇USB. 在USB Vendor ID和USB Product ID中填入USB設備的VID和PID. 假定我們的USB設備的VID和PID分別是16進制的0471和1801. 然后點按鈕"Next >". 關于VID和PID的規定請參考USB-IF的規范.


            圖3

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


            圖4


            圖5




            圖6


            圖7

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


            圖8

            7. 在如圖9所示的對話框中, 因為不需要給其他的驅動程序提供接口, 也不需要提供Flush功能, 所以不需要任何修改, 直接按"Next >"按鈕.


            圖9

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


            圖10

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


            圖11

            10. 對于如圖12的對話框, 我們直接按"Next >"按鈕. 這里是設置是否要將I/O請求排隊, 在這里, 我們不需要排隊.


            圖12

            11. 在如圖13所示的對話框中, 我們不需要創建任何注冊表項, 所以直接按"Next >"按鈕.


            圖13

            12. 如圖14所示的對話框, 是讓我們設置一些驅動程序的屬性, 比如接口, 緩沖區之類的. 一般的都可以使用缺省設置. 繼續按"Next >"按鈕.


            圖14

            13. 在如圖15所示的對話框中, 是讓我們給驅動程序增加一些IOCTL接口. 我們只增加一個如圖16所示的IOCTL來控制USB設備的LED燈. 然后按"Next >"按鈕.


            圖15


            圖16

            14. 在最后一個如圖17所示的對話框中, 可以設置一些驅動程序的屬性, 產生一個console測試程序. 按下"Finish"按鈕, 就結束了Wizard.


            圖17

            這樣, 我們就創建好了一個基本的驅動程序, 下面來看看還要做哪些工作才可以和我們的設備以及上層的應用程序通訊.



            把函數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;

            }

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



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



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



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

            posted on 2007-10-26 00:55 旅途 閱讀(1213) 評論(1)  編輯 收藏 引用 所屬分類: 驅動開發

            Feedback

            # re: 10分鐘完成一個USB驅動程序 2008-07-20 03:27 faning

            大哥你太強大了。我都感覺是在做夢。編寫操作系統。啊啊啊。我最近才領悟編程。也從匯編看看了。你博客我收藏了、。  回復  更多評論   

            国产精品激情综合久久| 午夜久久久久久禁播电影 | 久久精品国产只有精品2020| 欧美精品久久久久久久自慰| 国产精品久久久久久福利漫画| 日本免费久久久久久久网站| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 很黄很污的网站久久mimi色| 思思久久99热只有频精品66| 国产精品欧美久久久天天影视| 国产精品综合久久第一页 | 国产99久久久久久免费看| 伊色综合久久之综合久久| 精品久久久久久久| 女人高潮久久久叫人喷水| 久久久久国产一级毛片高清版| 伊人久久亚洲综合影院| 热久久这里只有精品| 综合网日日天干夜夜久久 | 精品久久人人做人人爽综合 | 国内精品久久久久影院亚洲| 久久综合综合久久狠狠狠97色88 | 亚洲AV成人无码久久精品老人| 久久精品国产一区二区| 丁香五月网久久综合| 亚洲国产精品一区二区久久hs| 国内精品久久久久久久久电影网| 久久精品中文字幕无码绿巨人| 国产成人精品综合久久久| 久久天天躁狠狠躁夜夜2020| 亚洲午夜精品久久久久久人妖| 国产成人无码久久久精品一| 久久人人爽人人爽人人片AV不 | 久久精品国产男包| 偷窥少妇久久久久久久久| 无码任你躁久久久久久老妇App| 美女久久久久久| 欧美精品国产综合久久| 久久久无码精品亚洲日韩京东传媒| 亚洲精品久久久www| 思思久久99热只有频精品66|