《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 模擬設(shè)計(jì) > 設(shè)計(jì)應(yīng)用 > WinCE USB驅(qū)動(dòng)開(kāi)發(fā)
WinCE USB驅(qū)動(dòng)開(kāi)發(fā)
摘要: 隨著USB2.0設(shè)備的不斷增加,USB設(shè)備驅(qū)動(dòng)開(kāi)發(fā)在嵌入式開(kāi)發(fā)中變的越來(lái)越重要。WindowsCE支持USB2.0更是對(duì)這一波新技術(shù)浪潮產(chǎn)生巨大的推動(dòng)。近期我負(fù)責(zé)一個(gè)這樣的項(xiàng)目,在WinCE下開(kāi)發(fā)USB接口的外圍設(shè)備驅(qū)動(dòng)。
關(guān)鍵詞: 接口IC WinCE USB 驅(qū)動(dòng)
Abstract:
Key words :

  隨著USB2.0設(shè)備的不斷增加,USB設(shè)備驅(qū)動(dòng)開(kāi)發(fā)在嵌入式開(kāi)發(fā)中變的越來(lái)越重要。Windows CE支持USB 2.0更是對(duì)這一波新技術(shù)浪潮產(chǎn)生巨大的推動(dòng)。近期我負(fù)責(zé)一個(gè)這樣的項(xiàng)目,在WinCE下開(kāi)發(fā)USB接口的外圍設(shè)備驅(qū)動(dòng)。當(dāng)時(shí)做這個(gè)項(xiàng)目花費(fèi)了我相當(dāng)多的時(shí)間和精力,錯(cuò)走許多冤枉路使我精疲力盡。

  項(xiàng)目需求是在已調(diào)好的ARM9板子上開(kāi)發(fā)USB WiFi無(wú)線網(wǎng)卡的驅(qū)動(dòng)程序,具體要求是驅(qū)動(dòng)程序平臺(tái)是WinCE,CPU類型支持ARM構(gòu)架,要能比較方便地移植到X86;驅(qū)動(dòng)接口類型是USB2.0和Wlan 802.11b。后來(lái)因?yàn)檫B接效率一直有問(wèn)題,就東改西改,最后改的是一塌糊涂。幸好老板比較寬容,給了我充裕的時(shí)間和支持,這里將關(guān)于USB驅(qū)動(dòng)開(kāi)發(fā)的點(diǎn)滴理解與大家分享。

  1. 什么是WinCE設(shè)備驅(qū)動(dòng)程序?

  (1)從驅(qū)動(dòng)加載方式來(lái)區(qū)分

  在深入探討Windows CE所支持的外圍設(shè)備驅(qū)動(dòng)程序之前,先了解在WinCE平臺(tái)上使用的兩種設(shè)備:內(nèi)建設(shè)備和可安裝設(shè)備。因此,從驅(qū)動(dòng)加載方式來(lái)看WinCE可分為本機(jī)設(shè)備驅(qū)動(dòng)(Built-In Driver)、可加載驅(qū)動(dòng)(Loadable Driver)以及混合型驅(qū)動(dòng)。

 ?、俦緳C(jī)設(shè)備驅(qū)動(dòng)

  本機(jī)設(shè)備驅(qū)動(dòng)即Native Device Drivers。WinCE設(shè)計(jì)成可直接使用內(nèi)建設(shè)備,這些設(shè)備由本機(jī)驅(qū)動(dòng)過(guò)程控制,而本機(jī)驅(qū)動(dòng)程序又與WinCE的核心組件緊密相連。這些驅(qū)動(dòng)對(duì)應(yīng)的設(shè)備通常在系統(tǒng)啟動(dòng)時(shí),在GWES的進(jìn)程空間內(nèi)被加載,因此它們不是以獨(dú)立的DLL形式存在,也因此要求每一個(gè)本機(jī)驅(qū)動(dòng)程序都必須與稱為設(shè)備驅(qū)動(dòng)程序接口(DDI)的特定接口一致。

  本機(jī)設(shè)備是指整合進(jìn)平臺(tái)的設(shè)備,其中包括顯示、觸摸面板、音頻、串行埠、LED、電池和PC卡插座等。如果沒(méi)有這些本機(jī)設(shè)備整個(gè)系統(tǒng)就不能和用戶信息交流,例如觸摸面板和顯示等。本機(jī)驅(qū)動(dòng)程序一般設(shè)計(jì)為動(dòng)態(tài)鏈接庫(kù),但有兩個(gè)例外:電池和LED驅(qū)動(dòng)程序由于小而設(shè)計(jì)為靜態(tài)庫(kù)(當(dāng)建立CE圖像時(shí)與GWES模塊鏈接)。這些設(shè)備相應(yīng)的驅(qū)動(dòng)程序是在WinCE平臺(tái)開(kāi)發(fā)過(guò)程中由OEM開(kāi)發(fā)的,它們儲(chǔ)存在ROM或閃存內(nèi)。通常只有OEM才會(huì)對(duì)本機(jī)設(shè)備驅(qū)動(dòng)程序進(jìn)行修改,其它自由設(shè)備生產(chǎn)商只提供附加的硬件設(shè)備,對(duì)本機(jī)設(shè)備驅(qū)動(dòng)程序不會(huì)有過(guò)多涉及。

  ②可加載設(shè)備驅(qū)動(dòng)

  可加載設(shè)備是指可與平臺(tái)連接和分離的第三方接口設(shè)備,可由用戶隨時(shí)安裝和卸載。這種外圍設(shè)備的驅(qū)動(dòng)也被稱為流驅(qū)動(dòng),這些驅(qū)動(dòng)可以在系統(tǒng)啟動(dòng)時(shí)或者和啟動(dòng)后的任何時(shí)候由設(shè)備管理器動(dòng)態(tài)加載。通常這類驅(qū)動(dòng)是以DLL動(dòng)態(tài)鏈接庫(kù)的形式存在,系統(tǒng)加載后這些驅(qū)動(dòng)程序也只是以用戶態(tài)的角色運(yùn)行。可加載驅(qū)動(dòng)程序是通過(guò)文件操作API來(lái)從設(shè)備管理器和應(yīng)用程序獲得命令。在WinCE典型的可加載驅(qū)動(dòng)有:PCMCIA driver(PCMCIA.dll)、Serial driver(SERIAL.dll)、ATAFLASH driver(ATA.dll)、Ethernet driver(NE2000.dll,SMSC100FD.dll)。

  與本機(jī)驅(qū)動(dòng)程序不同的是,所有可加載流驅(qū)動(dòng)程序都共享一個(gè)公用接口。該接口由每個(gè)驅(qū)動(dòng)程序內(nèi)的10個(gè)功能或記錄點(diǎn)組成,這些功能與應(yīng)用程序所用的文件API中的功能匹配。因此,控制可加載設(shè)備的流接口驅(qū)動(dòng)程序一般由應(yīng)用程序存取,流接口驅(qū)動(dòng)程序由一個(gè)特殊文件來(lái)將設(shè)備功能展現(xiàn)給應(yīng)用程序的,該文件可被打開(kāi)、讀取、寫入和關(guān)閉。例如,用戶將一個(gè)GPS設(shè)備與平臺(tái)相連后,就可啟動(dòng)有GPS功能的應(yīng)用程序來(lái)存取并使用該設(shè)備。WinCE是使用已有的API來(lái)讓應(yīng)用程序存取這些驅(qū)動(dòng)程序,而不是建立新的API。

  (2)從驅(qū)動(dòng)程序?qū)哟紊戏诸?/p>

  一般可以分為獨(dú)立驅(qū)動(dòng)和層次型驅(qū)動(dòng)兩類。獨(dú)立驅(qū)動(dòng)程序是指將驅(qū)動(dòng)程序編寫成同時(shí)包含Model Device Driver(MDD)和Platform Dependent Driver(PDD)層的獨(dú)立驅(qū)動(dòng)。使用獨(dú)立驅(qū)動(dòng)的好處在于可以省去MDD和PDD層驅(qū)動(dòng)之間的信息傳遞,這一點(diǎn)在實(shí)時(shí)處理中非常重要。獨(dú)立驅(qū)動(dòng)的代碼包括中斷服務(wù)例程和平臺(tái)相關(guān)處理函數(shù)。另外,如果設(shè)備的操作和MDD驅(qū)動(dòng)層的接口描述相吻合,用獨(dú)立驅(qū)動(dòng)程序可以提高處理性能。

  層次型驅(qū)動(dòng)是指分為兩層,較上層的MDD和比較下層的PDD。MDD實(shí)現(xiàn)的是和平臺(tái)無(wú)關(guān)的功能,它描述了一個(gè)通用的驅(qū)動(dòng)程序框架;而PDD是和硬件以及平臺(tái)相關(guān)的代碼組成。MDD調(diào)用PDD中特定的接口來(lái)獲取硬件相關(guān)的信息。當(dāng)使用層次型驅(qū)動(dòng)的時(shí)候,一般只需要基于相近的樣列驅(qū)動(dòng)程序,針對(duì)特定的硬件只修改PDD程序,MDD建立的框架可繼續(xù)使用。但由于層次間接口的層層調(diào)用以及消息的傳遞,使得處理速度相對(duì)于獨(dú)立驅(qū)動(dòng)程序要慢。因此,在嵌入式實(shí)時(shí)要求苛刻的環(huán)境下,層次型驅(qū)動(dòng)顯得不是很適合。

  簡(jiǎn)單的說(shuō),獨(dú)立驅(qū)動(dòng)是把PDD與MDD寫在一起,沒(méi)有做嚴(yán)格的區(qū)分,通常這種驅(qū)動(dòng)比較簡(jiǎn)單,比如ATADISK。至于本機(jī)驅(qū)動(dòng)和加載式流驅(qū)動(dòng)是從驅(qū)動(dòng)與系統(tǒng)其它模塊(調(diào)用者)的接口形式上做的分類。所以,一個(gè)加載式驅(qū)動(dòng)程序可以是獨(dú)立的流式驅(qū)動(dòng),例如ATADISK;也可以是分層的流式驅(qū)動(dòng),例如OHCI。也就是說(shuō),獨(dú)立和分層是驅(qū)動(dòng)實(shí)現(xiàn)方式上的分類,而本機(jī)和加載流式則是驅(qū)動(dòng)模型上的分類。所謂本機(jī)驅(qū)動(dòng)就是操作系統(tǒng)有保留專門的接口,而加載流式驅(qū)動(dòng)是指編寫DLL文件導(dǎo)出各種流式接口函數(shù)的接口。

  2. USB加載式流接口驅(qū)動(dòng)要點(diǎn)分析

  為了支持不同類型的外圍設(shè)備,WinCE平臺(tái)提供了具有定制接口的流接口驅(qū)動(dòng)程序模型。因?yàn)榇蟛糠諹SB外圍設(shè)備由于功能性更適合流接口驅(qū)動(dòng)的結(jié)構(gòu),所以一般都采用加載式流接口驅(qū)動(dòng)程序模型來(lái)開(kāi)發(fā)USB設(shè)備驅(qū)動(dòng)程序。

 ?。?)USB系統(tǒng)結(jié)構(gòu)分析

  WinCE下USB系統(tǒng)軟件由兩層組成:較高USB設(shè)備驅(qū)動(dòng)程序?qū)雍洼^低的USB函數(shù)層。較低的USB函數(shù)層本身又由兩部分組成:較高的通用串行總線驅(qū)動(dòng)程序(USBD)模塊和較低的主控制器驅(qū)動(dòng)程序(HCD)模塊。通過(guò)HCD模塊功能和USBD模塊實(shí)現(xiàn)高層的USBD接口函數(shù),USB設(shè)備驅(qū)動(dòng)程序就能與外圍設(shè)備進(jìn)行通訊。

  在數(shù)據(jù)傳輸?shù)倪^(guò)程中,操作流程通常按下列的次序進(jìn)行:①USB設(shè)備驅(qū)動(dòng)程序進(jìn)行數(shù)據(jù)傳輸?shù)某跏蓟?,即通過(guò)USBD接口函數(shù)給USBD模塊發(fā)送數(shù)據(jù)傳輸?shù)恼?qǐng)求。②USBD模塊將該請(qǐng)求分成一些單獨(dú)的事務(wù)。③HCD模塊排出事務(wù)次序。④主控制器硬件執(zhí)行事務(wù)。這里需要提醒的是,所有的事務(wù)都是從主機(jī)發(fā)出的,外圍設(shè)備完全是被動(dòng)接受型的。

 ?。?)USB設(shè)備驅(qū)動(dòng)程序入口點(diǎn)函數(shù)

  從結(jié)構(gòu)分析我們可知,所有的USB設(shè)備驅(qū)動(dòng)程序必須在它們的DLL庫(kù)設(shè)置一定的入口點(diǎn)與USBD模塊進(jìn)行適當(dāng)?shù)慕换ァTO(shè)置入口點(diǎn)函數(shù)有兩個(gè)作用:一是使得 USBD 模塊能與外部設(shè)備交互;二是使得驅(qū)動(dòng)程序能創(chuàng)建和管理任何可能需要的注冊(cè)鍵。

  下面簡(jiǎn)要介紹相關(guān)函數(shù)的作用:USBDeviceAttach是當(dāng) USB 設(shè)備連接到主計(jì)算機(jī)時(shí)運(yùn)行,USBD模塊會(huì)調(diào)用這個(gè)函數(shù)初始化USB設(shè)備,取得USB設(shè)備信息和配置USB設(shè)備,并且申請(qǐng)必需的資源。USBInstallDrive是在第一次加載USB設(shè)備驅(qū)動(dòng)程序時(shí)首先被調(diào)用,它使得驅(qū)動(dòng)程序能創(chuàng)建需要的注冊(cè)鍵,用于將一個(gè)驅(qū)動(dòng)程序所需的注冊(cè)表信息寫入到HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers目錄下,例如設(shè)備名稱等。需要注意的是,USB設(shè)備驅(qū)動(dòng)程序不使用標(biāo)準(zhǔn)的注冊(cè)表函數(shù),而是使用RegisterClientDriverID()、RegisterClientSettings()函數(shù)來(lái)注冊(cè)相應(yīng)的設(shè)備信息。

  USBUninstallDriver是在用戶刪除USB設(shè)備驅(qū)動(dòng)程序時(shí)調(diào)用,負(fù)責(zé)刪除注冊(cè)鍵并釋放其它相關(guān)資源。它通過(guò)調(diào)用UnRegisterClientSettings()和UnRegisterClientDriverID()函數(shù)來(lái)刪除由驅(qū)動(dòng)程序的USBInstallDriver()函數(shù)創(chuàng)建的所有注冊(cè)鍵。因此,我們?cè)隍?qū)動(dòng)程序中就需要嚴(yán)格按照這三個(gè)函數(shù)的原型來(lái)實(shí)現(xiàn),否則就不能為設(shè)備管理器所識(shí)別。

  3.USB設(shè)備流接口驅(qū)動(dòng)的實(shí)現(xiàn)步驟

  從WinCE USB設(shè)備驅(qū)動(dòng)模型及結(jié)構(gòu)分析中,我們可以清晰的看到主機(jī)和外設(shè)之間的實(shí)現(xiàn)方式。在主機(jī)端,通過(guò)USBD模塊和HCD模塊使用默認(rèn)的PIPE訪問(wèn)一個(gè)通用的邏輯設(shè)備,實(shí)際上就是說(shuō)USBD和HCD是一組訪問(wèn)所有USB設(shè)備的邏輯接口,它們負(fù)責(zé)管理所有USB設(shè)備的連接、加載、移除、數(shù)據(jù)傳輸和通用配置。其中HCD是主機(jī)控制驅(qū)動(dòng),是為USBD提供底層的功能訪問(wèn)服務(wù),USBD是USB總線驅(qū)動(dòng),位于HCD的上層,利用HCD的服務(wù)提供較高層次的功能。因此,實(shí)現(xiàn)USB加載流驅(qū)動(dòng)程序大致需要完成以下步驟:

  (1)選擇代表設(shè)備的文件名前綴。前綴非常重要,設(shè)備管理器在注冊(cè)表中通過(guò)前綴來(lái)識(shí)別設(shè)備。同時(shí),在流接口命名時(shí)也將這個(gè)前綴作為入口點(diǎn)函數(shù)的前綴,如果設(shè)備前綴為XXX,那么流接口對(duì)應(yīng)為XXX_Close,XXX_Init等。

  (2)設(shè)置驅(qū)動(dòng)的各個(gè)入口點(diǎn)函數(shù)。所謂入口點(diǎn)是指提供給設(shè)備管理器的標(biāo)準(zhǔn)文件I/O接口。在生成一個(gè)DLL后,就用設(shè)備文件名前綴替換名字中的XXX。因此,每個(gè)加載式流接口驅(qū)動(dòng)程序必須實(shí)現(xiàn)XXX_Init()、XXX_IOControl()以及XXX_PowerUp()等一組標(biāo)準(zhǔn)的函數(shù),用來(lái)完成標(biāo)準(zhǔn)的文件I/O函數(shù)和電源管理等。

 ?。?)建立.DEF文件。當(dāng)設(shè)備管理器初始化USB設(shè)備編譯出來(lái)的流接口函數(shù)后,還必須建立一個(gè).def文件。DEF文件定義了DLL要導(dǎo)出的接口集,而且加載式流驅(qū)動(dòng)大多是以DLL形式存在的,所以應(yīng)將DLL和DEF的文件名統(tǒng)一起來(lái)。DEF文件告訴鏈接程序需要輸出什么樣的函數(shù),最后將驅(qū)動(dòng)程序編譯到內(nèi)核中去,這樣這個(gè)USB設(shè)備流接口驅(qū)動(dòng)程序就可以被應(yīng)用程序調(diào)用。

 ?。?)在注冊(cè)表中為驅(qū)動(dòng)程序建立表項(xiàng)。在注冊(cè)表中建立驅(qū)動(dòng)程序入口點(diǎn),這樣設(shè)備管理器才能識(shí)別和管理這個(gè)驅(qū)動(dòng)。此外,注冊(cè)表中還能存儲(chǔ)額外的信息,這些信息可以在驅(qū)動(dòng)運(yùn)行之后被使用到。

  在這次USB驅(qū)動(dòng)開(kāi)發(fā)過(guò)程中,錯(cuò)走許多冤枉路使我叫苦連天。我感受最深的是由于WinCE提供了通用串行總線驅(qū)動(dòng)程序(USBD)模塊、USBD接口函數(shù)全集、樣本主機(jī)控制器驅(qū)動(dòng)程序(HCD)模塊。所以,我們只需要根據(jù)USB設(shè)備硬件特性,利用USBD提供的不同函數(shù),實(shí)現(xiàn)流接口函數(shù)與外圍設(shè)備的交互。在沒(méi)有特別的情況下,我最大的收獲經(jīng)驗(yàn)是把這些公用的源程序照搬過(guò)來(lái),能極大的縮短開(kāi)發(fā)周期,從而能更快速地進(jìn)行嵌入式開(kāi)發(fā)。

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。