引言
USB,全稱是Universal Serial Bus(通用串行總線),它是一些PC大廠商,如Microsoft、Intel、康柏等為了解決日益增加的PC外設(shè)與有限的主板插槽和端口之間的矛盾而制定的一種串行通信的標(biāo)準(zhǔn),自1995年在Comdex上亮相以來至今已廣泛地為各PC廠家所支持?,F(xiàn)在生產(chǎn)的PC幾乎都配備了USB接口,Microsft的Windows98、NT以及MacOS、Linux、FreeBSD等流行操作系統(tǒng)都增加了對(duì)USB的支持。 它有以下主要優(yōu)點(diǎn): ·速度快。USB有高速和低速兩種方式,主模式為高速模式,速率為12Mbps,另外為了適應(yīng)一些不需要很大吞吐量和很高實(shí)時(shí)性的設(shè)備,如鼠標(biāo)等,USB還提供低速方式,速率為1.5Mb/s。 ·設(shè)備安裝和配置容易。安裝USB設(shè)備不必再打開機(jī)箱,加減已安裝過的設(shè)備完全不用關(guān)閉計(jì)算機(jī)。所有USB設(shè)備支持熱插拔,系統(tǒng)對(duì)其進(jìn)行自動(dòng)配置,徹底拋棄了過去的跳線和撥碼開關(guān)設(shè)置。 ·易于擴(kuò)展。通過使用Hub擴(kuò)展可撥接多達(dá)127個(gè)外設(shè)。標(biāo)準(zhǔn)USB電纜長度為3m(5m低速)。通過Hub或中繼器可以使外設(shè)距離達(dá)到30m。 ·能夠采用總線供電。USB總線提供最大達(dá)5V電壓、500mA電流。 ·使用靈活。USB共有4種傳輸模式:控制傳輸(control)、同步傳輸(Synchronization)、中斷傳輸(interrupt)、批量傳輸(bulk),以適應(yīng)不同設(shè)備的需要。 WDM驅(qū)動(dòng)程序的介紹 設(shè)備驅(qū)動(dòng)程序就是控制硬件設(shè)備的一組函數(shù)。在Windows環(huán)境下,如果要處理硬件中斷,實(shí)現(xiàn)DMA操作,就一定要用到設(shè)備驅(qū)動(dòng)程序,開發(fā)即插即用(PnP)設(shè)備(如USB接口設(shè)備、PCI接口卡)更是這樣。 WDM(Win32 Driver Model)是Microsoft公司力推的全新的驅(qū)動(dòng)程序模式,它的應(yīng)用平臺(tái)是Windows 98/Me/2000操作系統(tǒng),不久的將來,在Windows平臺(tái)上,WDM將成為主流的驅(qū)動(dòng)模式。 WDM驅(qū)動(dòng)程序是分層的,不同層上的驅(qū)動(dòng)程序有不同的優(yōu)先級(jí)。另外,WDM還引入了功能設(shè)備對(duì)象FDO(Function Device Object)與物理設(shè)備對(duì)象PDO(Physical Device Object)兩個(gè)新類來描述硬件,一個(gè)PDO對(duì)應(yīng)一個(gè)真實(shí)的硬件。一個(gè)硬件只允許有一個(gè)PDO,卻可以擁有多個(gè)FDO,在驅(qū)動(dòng)程序中直接操作的不是硬件而是相應(yīng)的PDO和FDO。 WDM不是通過驅(qū)動(dòng)程序名稱,而是通過一個(gè)128位的全局唯一標(biāo)識(shí)符(GUID)實(shí)現(xiàn)驅(qū)動(dòng)程序的識(shí)別。在應(yīng)用程序與WDM驅(qū)動(dòng)程序通信方面,系統(tǒng)為每一個(gè)用戶請(qǐng)求打包形成一個(gè)I/O請(qǐng)求包(IRP)結(jié)構(gòu),并將其發(fā)送到驅(qū)動(dòng)程序,并通過識(shí)別IRP中的PDO來區(qū)別是發(fā)送給哪一個(gè)設(shè)備的。內(nèi)核通常通過發(fā)送IRP來運(yùn)行驅(qū)動(dòng)程序的代碼。WDM驅(qū)動(dòng)程序完全支持即插即用。 一個(gè)WDM驅(qū)動(dòng)程序的功能模塊可由以下幾個(gè)部分組成: ·驅(qū)動(dòng)程序初始化。 ·創(chuàng)建和刪除設(shè)備。 ·處理Win32程序打開和關(guān)閉句柄的請(qǐng)求。 ·處理Win32程序輸入/輸出請(qǐng)求。 ·實(shí)現(xiàn)對(duì)設(shè)備的串行化訪問。 ·訪問硬件。 ·取消I/O請(qǐng)求。 ·超時(shí)I/O請(qǐng)求。 ·調(diào)用其他驅(qū)動(dòng)程序。 ·處理電源管理請(qǐng)求。 ·使用Windows管理診斷(WMI)向系統(tǒng)管理員報(bào)告。 ·處理一個(gè)可熱插拔的設(shè)備被加入或刪除的情況。 WDM驅(qū)動(dòng)程序有一個(gè)主要的初始化入口點(diǎn),即一個(gè)稱為DriverEntry的例程,它有一個(gè)標(biāo)準(zhǔn)的函數(shù)原型,當(dāng)WDM驅(qū)動(dòng)程序被裝入時(shí),內(nèi)核調(diào)用DriverEntry例程。所有對(duì)各種IRP的處理例程都在此入口函數(shù)中做出定義。 大多數(shù)的WDM設(shè)備對(duì)象,都是在即插即用管理器調(diào)用AddDevice例程入口點(diǎn)被創(chuàng)建的。插入新設(shè)備后,當(dāng)系統(tǒng)找到由安裝信息所指示的驅(qū)動(dòng)程序時(shí),這個(gè)例程調(diào)用在此之后,一系列的即插即用IRP被發(fā)送到驅(qū)動(dòng)程序,設(shè)備驅(qū)動(dòng)程序可進(jìn)行相應(yīng)的功能處理。 開發(fā)WDM驅(qū)動(dòng)程序有兩種方法,一種利用微軟提供的98DDK和2000DDK驅(qū)動(dòng)程序開發(fā)包,另外一種是專用驅(qū)動(dòng)程序開發(fā)工具,如Compuware Numega公司的DriverStudio,KRF, Tech公司的WinDriver。后者給出驅(qū)動(dòng)程序的框架,并對(duì)DDK中操作進(jìn)行封裝,因此減少了開發(fā)時(shí)間,提高了效率。我們選用了DriverStudio開發(fā)工具開發(fā)USB驅(qū)動(dòng)程序。 USB 啟動(dòng)的過程 在介紹USB程序設(shè)計(jì)之前,我們需要先了解它的啟動(dòng)過程。 USB系統(tǒng)主要由主控制器(Host Controller)、USB Hub 和USB外設(shè)(Peripherals Node)組成系統(tǒng)拓?fù)浣Y(jié)構(gòu),如圖1所示。 在應(yīng)用程序可以與一個(gè)USB設(shè)備通信之前,主機(jī)需要知道設(shè)備支持哪些傳輸類型和終端,主機(jī)也必須分配一個(gè)地址給設(shè)備,主機(jī)通過一個(gè)被稱為枚舉的信息交換來完成這些工作 。枚舉過程:集線器的一個(gè)任務(wù)就是檢測設(shè)備的連接與斷開,每個(gè)集線器都有一個(gè)中斷流程來通知主機(jī)報(bào)告這些事情。在系統(tǒng)啟動(dòng)的時(shí)候,主機(jī)查詢它的根集線器來了解有哪些設(shè)備已經(jīng)連接上了,包括其他集線器和連接到這些集線器的設(shè)備。在啟動(dòng)后,主機(jī)持續(xù)周期性地查詢了解是否有設(shè)備連接或斷開。 圖1:USB總線的拓樸結(jié)構(gòu) 圖2:軟件結(jié)構(gòu)框圖 一旦發(fā)現(xiàn)一個(gè)新設(shè)備,主機(jī)發(fā)送一系列的請(qǐng)求給這個(gè)設(shè)備的集線器,使這個(gè)集線器在主機(jī)和這個(gè)設(shè)備之間建立一個(gè)通信渠道。然后主機(jī)試圖枚舉這個(gè)設(shè)備,枚舉是使得主機(jī)的設(shè)備驅(qū)動(dòng)程序能與這個(gè)設(shè)備通信的最基本的信息交換 。這個(gè)過程由如下動(dòng)作組成:分配一個(gè)地址給設(shè)備,從設(shè)備讀取描述數(shù)據(jù),分配和載入一個(gè)設(shè)備驅(qū)動(dòng)程序以及從接收到的數(shù)據(jù)中選擇一個(gè)配置。然后設(shè)備就被配置完畢,并且準(zhǔn)備好使用它的配置中支持的任何終端來傳輸數(shù)據(jù)。 主機(jī)的枚舉是通過給終端0發(fā)送包含標(biāo)準(zhǔn)USB請(qǐng)求的控制傳輸。所有的USB設(shè)備必須支持控制傳輸、標(biāo)準(zhǔn)USB請(qǐng)求和終端0。對(duì)一個(gè)成功的枚舉來說,設(shè)備必須對(duì)每一個(gè)請(qǐng)求響應(yīng)并返回請(qǐng)求的信息。 從用戶的角度看,枚舉應(yīng)該是不可見和自動(dòng)的,除了一些情況下如申明發(fā)現(xiàn)一個(gè)新設(shè)備和是否成功配置這個(gè)新設(shè)備的窗口,有時(shí)在第一次使用時(shí),用戶需要提供一個(gè)有INF文件和設(shè)備驅(qū)動(dòng)程序的磁盤。 當(dāng)枚舉結(jié)束時(shí),Windows把新的設(shè)備加入到控制面板的設(shè)備管理器顯示中。應(yīng)依次單擊"開始"菜單(Start menu)->設(shè)置(Settings)->控制面板(Control Pannel)->設(shè)備管理器(Device Manager),在設(shè)備管理器可以看到新加的設(shè)備。當(dāng)一個(gè)用戶斷開一個(gè)外設(shè)的連接時(shí),Windows自動(dòng)地從這個(gè)顯示中移掉這個(gè)設(shè)備。 在一個(gè)USB的外設(shè)中,外設(shè)的程序代碼包含了主機(jī)將請(qǐng)求的信息,并且程序代碼必須能識(shí)別和響應(yīng)這些信息的請(qǐng)求。在Windows不需要編寫枚舉的程序,因?yàn)閃indows自動(dòng)處理枚舉過程。Windows將查找一個(gè)被稱為INF文件的特殊文本文件,這個(gè)文件會(huì)告訴Windows哪個(gè)驅(qū)動(dòng)程序適合這個(gè)設(shè)備。 USB接口軟件結(jié)構(gòu) USB接口軟件結(jié)構(gòu)如圖2所示。PC機(jī)底層驅(qū)動(dòng)程序包括HUB驅(qū)動(dòng)、總線類驅(qū)動(dòng)和主機(jī)控制器驅(qū)動(dòng),它們負(fù)責(zé)處理總線枚舉、電源管理,以及USB事務(wù)的其它方面,這些驅(qū)動(dòng)不需要編程者開發(fā),Windows操作系統(tǒng)提供這類驅(qū)動(dòng)程序。編程者需要開發(fā)的程序?yàn)椋篣SB控制器固件程序,控制器的接收應(yīng)用程序,設(shè)備功能驅(qū)動(dòng)程序, PC機(jī)應(yīng)用程序。 USB控制器固件程序?qū)崿F(xiàn)設(shè)備的枚舉以及端點(diǎn)與主機(jī)的通信??刂破鞯慕邮諔?yīng)用程序接收主機(jī)下載的文件。 設(shè)備功能驅(qū)動(dòng)程序?yàn)閼?yīng)用程序和底層驅(qū)動(dòng)程序之間提供接口。當(dāng)一個(gè)應(yīng)用程序啟動(dòng)一個(gè)API調(diào)用后,Windows把調(diào)用傳遞給設(shè)備驅(qū)動(dòng)程序,設(shè)備驅(qū)動(dòng)程序把請(qǐng)求傳遞到底層驅(qū)動(dòng)程序,底層驅(qū)動(dòng)程序?qū)τ布M(jìn)行相應(yīng)的操作。PC機(jī)應(yīng)用程序功能是實(shí)現(xiàn)主機(jī)文件的下載。 USB驅(qū)動(dòng)程序的介紹 USB驅(qū)動(dòng)程序的編寫必須采用WDM驅(qū)動(dòng)程序。對(duì)于USB設(shè)備來說,其驅(qū)動(dòng)程序可分為USB底層驅(qū)動(dòng)程序和USB功能驅(qū)動(dòng)程序。USB底層驅(qū)動(dòng)程序由操作系統(tǒng)提供,它位于USB功能驅(qū)動(dòng)程序的下面,負(fù)責(zé)與實(shí)際的硬件打交道,實(shí)現(xiàn)繁瑣的底層通信。USB功能驅(qū)動(dòng)程序由設(shè)備開發(fā)者編寫,位于USB底層驅(qū)動(dòng)程序的上面,不與實(shí)際的硬件打交道,而是通過向USB底層驅(qū)動(dòng)程序發(fā)送包含URB(USB Request Block,USB 請(qǐng)求塊)的IRP(I/O Request Packet,I/O請(qǐng)求包),來實(shí)現(xiàn)對(duì)USB設(shè)備信息的發(fā)送和接收。采用這種分層驅(qū)動(dòng)程序的設(shè)計(jì)方法有兩個(gè)優(yōu)點(diǎn):(1)多個(gè)USB設(shè)備可以通過USB底層驅(qū)動(dòng)程序來協(xié)調(diào)它們的工作;(2)編寫分層驅(qū)動(dòng)程序較之編寫單一驅(qū)動(dòng)程序相對(duì)簡單,且可以節(jié)省內(nèi)存和資源,不易出錯(cuò)。 若應(yīng)用程序想對(duì)設(shè)備進(jìn)行I/O操作,它需調(diào)用Windows API函數(shù) ,I/O管理器將此請(qǐng)求構(gòu)造成一個(gè)合適的I/O請(qǐng)求包IRP并把它傳遞給USB功能驅(qū)動(dòng)程序。USB功能驅(qū)動(dòng)程序接收到這個(gè)IRP以后,根據(jù)IRP中包含的具體操作代碼,構(gòu)造相應(yīng)USB請(qǐng)求塊并把此URB放到一個(gè)新的IRP中,然后把此IRP傳遞USB底層驅(qū)動(dòng)程序,USB底層驅(qū)動(dòng)程序根據(jù)IRP中所含的URB執(zhí)行響應(yīng)的操作(如從USB設(shè)備讀取數(shù)據(jù)),并把操作結(jié)果返還給USB功能驅(qū)動(dòng)程序。USB功能驅(qū)動(dòng)程序接收到此IRP后,將操作結(jié)果通過IRP返還給I/O管理器,最后I/O管理器將此IRP操作結(jié)果返還給應(yīng)用程序,至此應(yīng)用程序?qū)SB設(shè)備的一次I/O操作完成。 USB功能驅(qū)動(dòng)程序除負(fù)責(zé)處理應(yīng)用程序的I/O請(qǐng)求外,還要處理PnP請(qǐng)求(如設(shè)備啟動(dòng)請(qǐng)求IRP_MN_START_DEVICE,設(shè)備刪除IRP_MN_REMOVE_DEVICE等)。通過對(duì)這些PnP請(qǐng)求的處理,USB功能驅(qū)動(dòng)程序可支持設(shè)備的熱插拔和即插即用功能。 INF文件的介紹 INF文件含有安裝一個(gè)WDM設(shè)備驅(qū)動(dòng)程序需要的所有必要的信息,包括要復(fù)制的文件列表、要?jiǎng)?chuàng)建的注冊(cè)表項(xiàng)、設(shè)備的ID和兼容ID等。INF文件是一個(gè)文本文件,它由節(jié)組成,每一節(jié)從節(jié)名稱開始,后面是節(jié)內(nèi)容。 當(dāng)發(fā)現(xiàn)新的設(shè)備時(shí)(系統(tǒng)啟動(dòng)時(shí),在安裝熱插拔設(shè)備時(shí),或者從控制面板安裝新設(shè)備時(shí)),就調(diào)用Windows的"添加新設(shè)備向?qū)?執(zhí)行。這個(gè)向?qū)呙杷锌捎玫腎NF文件,試圖找到合適的驅(qū)動(dòng)程序。Windows首先選擇硬件ID匹配的設(shè)備的INF文件,否則它選擇其兼容ID與設(shè)備ID最佳匹配的INF文件,若仍未找到提示用戶選擇驅(qū)動(dòng)程序INF文件。然后根據(jù)INF文件的指令安裝驅(qū)動(dòng)程序,驅(qū)動(dòng)程序可執(zhí)行文件被復(fù)制到正確的位置,通常是Windows System32\Drivers目錄,然后創(chuàng)建各種注冊(cè)表項(xiàng),驅(qū)動(dòng)程序被裝入內(nèi)存,并執(zhí)行它的DirverEntry例程。對(duì)新的設(shè)備調(diào)用AddDevice例程,給設(shè)備分配I/O,DMA,中斷等資源(USB設(shè)備不需要分配資源),啟動(dòng)設(shè)備,然后正常的I/O操作就可以繼續(xù)進(jìn)行。使用后的INF文件復(fù)制到Windows INF子目錄。 USB功能驅(qū)動(dòng)程序開發(fā) 系統(tǒng)中USB驅(qū)動(dòng)程序的開發(fā)采用Compuware Numega公司的DriverStudio開發(fā)工具。DriverStudio是一個(gè)大的開發(fā)工具包,它包含VtoolsD、softICE和DriverWorks等開發(fā)工具。Driver Wizard是DriverWorks創(chuàng)建WDM框架程序的工具,而DriverWorks又是DriverStudio的工具之一。在DriverWorks安裝之前,需要先安裝Windows 98 DDK或Windows 2000 DDK。系統(tǒng)中采用Driver Wizard創(chuàng)建一個(gè)WDM程序框架。 在Driver Wizard創(chuàng)建驅(qū)動(dòng)程序框架時(shí),開發(fā)者需要提供設(shè)備的類型,驅(qū)動(dòng)程序支持的功能,從注冊(cè)表中裝載的參數(shù),接口方式,緩沖方式和電源管理方式等內(nèi)容。通過Driver Wizard生成驅(qū)動(dòng)程序?yàn)殚_發(fā)者提供基本的框架 ,針對(duì)具體的設(shè)備,開發(fā)者只需修改較少的代碼就可以實(shí)現(xiàn)相應(yīng)的功能。 PC機(jī)應(yīng)用程序的實(shí)現(xiàn) 1、應(yīng)用程序?qū)SB驅(qū)動(dòng)程序的訪問 在Windows中,Win32應(yīng)用程序調(diào)用WDM的Win32函數(shù)有五個(gè):CreateFile(),ReadFile(),WriteFile(),DeviceIocontrol(),CloseHandle()。 (1)打開一個(gè)WDM設(shè)備 應(yīng)用程序打開一個(gè)WDM設(shè)備驅(qū)動(dòng)程序,用的是CreateFile()函數(shù),它的第一個(gè)參數(shù)不是一個(gè)WDM文件名,而是一個(gè)符號(hào)鏈接名。符號(hào)鏈接名的獲得需要調(diào)用SetupDiGetClassDevs,SetupDiEnumDeviceInterfaces,SetupDiGetDeviceInterfaceDetail三個(gè)函數(shù)。SetupDiGetClassDevs打開指定GUID的設(shè)備的"設(shè)備信息集",SetupDiEnumDeviceInterfaces取出感興趣的設(shè)備實(shí)例的信息,SetupDiGetDeviceInterfaceDetail獲得實(shí)例的符號(hào)鏈接名。最后調(diào)用CreateFile()函數(shù)獲得設(shè)備的句柄,這樣它就能夠調(diào)用Win32函數(shù),這將產(chǎn)生對(duì)應(yīng)于此設(shè)備對(duì)象的IRP。 (2)關(guān)閉一個(gè)WDM設(shè)備 WDM允許多個(gè)應(yīng)用程序打開同一個(gè)設(shè)備,它為每個(gè)應(yīng)用程序創(chuàng)建一個(gè)設(shè)備對(duì)象。當(dāng)其中的一個(gè)應(yīng)用程序調(diào)用CloseHandle()函數(shù),驅(qū)動(dòng)程序首先收到"清除"IRP,驅(qū)動(dòng)程序應(yīng)當(dāng)在"清除"例程中清除和此設(shè)備對(duì)象有關(guān)的待處理的IRP。然后關(guān)閉IRP,關(guān)閉設(shè)備對(duì)象。 (3)ReadFile()、WriteFile()和DeviceIoControl函數(shù)的調(diào)用 這些調(diào)用都產(chǎn)生一個(gè)請(qǐng)求,產(chǎn)生IRP請(qǐng)求包傳遞給驅(qū)動(dòng)程序,實(shí)現(xiàn)對(duì)設(shè)備的讀、寫和一些特定的操作。 2、PC機(jī)應(yīng)用程序下載數(shù)據(jù)文件 PC機(jī)應(yīng)用程序通過Win32函數(shù)實(shí)現(xiàn)將音頻文件下載到目標(biāo)板,為了減少讀取下載文件的時(shí)間,在內(nèi)存開辟1M空間。先讀1M大小的文件到內(nèi)存,下載完后再將剩余的文件讀入內(nèi)存。在下載文件過程中,傳輸?shù)臄?shù)據(jù)可能有錯(cuò)誤,為了解決這個(gè)問題,采用了重傳機(jī)制,即若沒有收到EP7212確認(rèn)''$''字符或收到其他的字符,將重傳該512個(gè)字節(jié)塊,直到成功為止。程序下載的流程如圖3所示。 |
|