• <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>

            旅途

            如果想飛得高,就該把地平線(xiàn)忘掉

            10分鐘完成一個(gè)USB驅(qū)動(dòng)程序

            10分鐘完成一個(gè)USB驅(qū)動(dòng)程序
            責(zé)任編輯:admin   更新日期:2005-8-6
            ??很多寫(xiě)Windows Device Driver的開(kāi)發(fā)人員基本上都是使用Windows DDK進(jìn)行開(kāi)發(fā)的。但是,現(xiàn)在也有不少人都開(kāi)始借助一些輔助工具。筆者去年開(kāi)始接觸到riverStudio,發(fā)現(xiàn)它真的是一個(gè)不錯(cuò)的開(kāi)發(fā)工具,不僅寫(xiě)代碼的時(shí)候思路清晰,而且和DDK的結(jié)合很好。

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



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



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

            EP 類(lèi)型 地址 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燈的亮和滅,以及通過(guò)Endpoint 2對(duì)設(shè)備進(jìn)行讀寫(xiě)。



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



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

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


            圖1

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


            圖2

            4. 在第3個(gè)對(duì)話(huà)框中(如圖3), 選擇我們的驅(qū)動(dòng)程序所操作的總線(xiàn)類(lèi)型. 這里, 我們選擇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. 在接下來(lái)的對(duì)話(huà)框中(如圖4), 我們需要加入Endpoint 1和Endpoint 2的定義. 由于在USB中規(guī)定Endpoint 0是必須存在的, 所以我們不需要對(duì)Endpoint 0進(jìn)行定義. 點(diǎn)"Add..."按鈕, 彈出一個(gè)如圖5所示的對(duì)話(huà)框. 我們將它修改成如圖6所示. 其中, 按照USB的規(guī)定, 對(duì)于端點(diǎn), 它的地址是1; 按照前面說(shuō)明的設(shè)備的特點(diǎn), Endpoint 1的最大的包大小為16字節(jié), 因此在"Max Transer Size"中填入16; Endpoint Name可以通過(guò)"Suggest Name"得到. 按照這些原則, 繼續(xù)設(shè)置其他的配置, 以使對(duì)話(huà)框4變成如圖7所示. 接下來(lái), 繼續(xù)按"Next >"按鈕.


            圖4


            圖5




            圖6


            圖7

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


            圖8

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


            圖9

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


            圖10

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


            圖11

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


            圖12

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


            圖13

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


            圖14

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


            圖15


            圖16

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


            圖17

            這樣, 我們就創(chuàng)建好了一個(gè)基本的驅(qū)動(dòng)程序, 下面來(lái)看看還要做哪些工作才可以和我們的設(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燈的,它是通過(guò)USB Vendor Request來(lái)向設(shè)備傳送的。其中,request=1的時(shí)候表示讓LED亮,request=0的時(shí)候讓LED滅。它是通過(guò)DeviceIoControl由上層應(yīng)用程序傳下來(lái)。



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



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



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

            posted on 2007-10-26 00:55 旅途 閱讀(1235) 評(píng)論(1)  編輯 收藏 引用 所屬分類(lèi): 驅(qū)動(dòng)開(kāi)發(fā)

            Feedback

            # re: 10分鐘完成一個(gè)USB驅(qū)動(dòng)程序 2008-07-20 03:27 faning

            大哥你太強(qiáng)大了。我都感覺(jué)是在做夢(mèng)。編寫(xiě)操作系統(tǒng)。啊啊啊。我最近才領(lǐng)悟編程。也從匯編看看了。你博客我收藏了、。  回復(fù)  更多評(píng)論   

            久久狠狠爱亚洲综合影院| 久久综合给合久久狠狠狠97色69| 亚洲日韩欧美一区久久久久我 | 久久伊人亚洲AV无码网站| 久久久久亚洲精品中文字幕| 国产99久久久国产精品小说| 中文字幕久久波多野结衣av| 国内精品久久久久久99蜜桃| 久久精品亚洲欧美日韩久久 | 国内精品久久九九国产精品| 三级韩国一区久久二区综合| 久久99国产精品久久99| 狠狠色噜噜色狠狠狠综合久久| 欧美日韩中文字幕久久伊人| 亚洲伊人久久成综合人影院 | 久久无码一区二区三区少妇| 久久国产亚洲精品| 2020久久精品亚洲热综合一本| 青青草原综合久久| 久久精品免费一区二区| 99久久精品国产毛片| 国产午夜福利精品久久| 久久婷婷五月综合色奶水99啪| 久久婷婷人人澡人人爽人人爱 | 一本一道久久a久久精品综合| 国内精品伊人久久久久| 久久最近最新中文字幕大全| 曰曰摸天天摸人人看久久久| 亚洲国产婷婷香蕉久久久久久| 久久天天躁狠狠躁夜夜av浪潮 | 亚洲国产香蕉人人爽成AV片久久 | 色综合久久久久综合99| 青青草原精品99久久精品66| 久久精品九九亚洲精品天堂| 久久五月精品中文字幕| 人妻无码αv中文字幕久久琪琪布| 久久久www免费人成精品| 国产成人无码精品久久久久免费| 亚洲中文字幕伊人久久无码| 四虎国产永久免费久久| 2019久久久高清456|