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