詳解WinCE下USB Host驅動開發_第1頁
詳解WinCE下USB Host驅動開發_第2頁
詳解WinCE下USB Host驅動開發_第3頁
詳解WinCE下USB Host驅動開發_第4頁
詳解WinCE下USB Host驅動開發_第5頁
已閱讀5頁,還剩2頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、WinCE下所有的驅動都是以DLL的形式,被device.exe進程加載的,所以每個驅動程序中都要實現DllEntry函數。 在注冊表的HKEY_LOCAL_MACHINEDriversUSBLoadClients鍵下保存了USB Host的驅動程序信息。當我們第一次插入USB設備時。因為不存在這樣的信息,所以系統會彈出一個“ 未能識別的USB設備”的對話框,要求用戶輸入驅動程序的名稱。該名稱就是USB Host驅動DLL的文件名。在輸入了名稱后,系統會自動調用該DLL的USBInstallDriver函數。該函數 負責向注冊表添加USB Host驅動的信息,以便再次插入設備時,能夠識別該US

2、B設備。其原型如下: BOOL USBInstallDriver(LPCWSTR szDriverLibFile; 其中szDriverLibFile就是輸入的DLL文件名稱。返回TRUE表示注冊成功。 在向注冊表注冊USB Host信息時,不能使用普通的注冊表函數,只能使用USBD提供的注冊函數。 BOOL RegisterClientDriverID(LPCWSTR szUniqueDriverId; BOOL RegisterClientSettings(LPCWSTR szDriverLibFile, LPCWSTR szUniqueDriverId, LPCWSTR erved, L

3、PCUSB_DRIVER_SETTINGS lpDriverSettings; 這兩個函數在USBD.DLL中,可以通過動態方式調用,也可以通過靜態方式調用。 動態方式如下: HINSTANCE hInst = LoadLibrary(LUSBD.DLL; if(hInst LPREGISTER_CLIENT_DRIVER_ID lpRegisterClientId = (LPREGISTER_CLIENT_DRIVER_IDGetProcAddress( hInst, LRegisterClientDriverID; if(!lpRegisterClientId return FALSE;

4、LPREGISTER_CLIENT_SETTINGS lpRegisterClientSetting = (LPREGISTER_CLIENT_SETTINGSGetProcAddress( hInst, LRegisterClientSettings; if(!lpRegisterClientSetting return FALSE; else return FALSE; 此后,就可以通過lpRegisterClientId和lpRegisterClientSetting函數指針調用這些函數,最后記得要FreeLibrary。 靜態方式: 在.cpp源文件中加入 #pragma commen

5、t(lib,usbd.lib 并在source文件的TARGETLIBS變量中加入$(_SYSGENOAKROOTlib$(_CPUINDPATHusbd.lib 如此一來,就可以直接使用這兩個函數了。 1 BOOL RegisterClientDriverID(LPCWSTR szUniqueDriverId 該函數注冊USB Host驅動程序的ID。 2 BOOL RegisterClientSettings(LPCWSTR szDriverLibFile, LPCWSTR szUniqueDriverId, LPCWSTR erved, LPCUSB_DRIVER_SETTINGS lp

6、DriverSettings 該函數負責注冊驅動程序的信息。 szDriverLibFile 設置為USBInstallDriver函數傳入的DLL驅動程序名稱。 szUniqueDriverId 設置為調用RegisterClientDriverID注冊的驅動程序ID。 erved 設置為NULL lpDriverSettings 該參數是一個USB_DRIVER_SETTINGS結構體。其聲明如下: typedef struct DWORD dwCount; DWORD dwVendorId; DWORD dwProductId; DWORD dwReleaseNumber; DWORD

7、dwDeviceClass; DWORD dwDeviceSubClass; DWORD dwDeviceProtocol; DWORD dwInterfaceClass; DWORD dwInterfaceSubClass; DWORD dwInterfaceProtocol; USB_DRIVER_SETTINGS; Count為結構體大小,其他項對應USB描述符。 其中除Count外的各字段,如果不設置具體的值,可以設置為USB_NO_INFO。 這個結構體中的信息講反應到注冊表的HKEY_LOCAL_MACHINEDriversUSBLoadClients鍵下,用于在USB設備插入時,

8、查找USB驅動。下面以一個例子說明: BOOL USBInstallDriver(LPCWSTR szDriverLibFile RETAILMSG(1,(TEXT(USBInstallDriverrn; RETAILMSG(1,(TEXT(USBInstallDriver:%srn, szDriverLibFile; BOOL fRet = FALSE; USB_DRIVER_SETTINGS DriverSettings; DriverSettings.dwCount = sizeof(DriverSettings; DriverSettings.dwVendorId = 0x10C4;

9、DriverSettings.dwProductId = 0x0003; DriverSettings.dwReleaseNumber = USB_NO_INFO; DriverSettings.dwDeviceClass = USB_NO_INFO; DriverSettings.dwDeviceSubClass = USB_NO_INFO; DriverSettings.dwDeviceProtocol = USB_NO_INFO; DriverSettings.dwInterfaceClass = 0; DriverSettings.dwInterfaceSubClass = 0; Dr

10、iverSettings.dwInterfaceProtocol = 0; fRet = RegisterClientDriverID(LUSBTest; if (fRet fRet = RegisterClientSettings( szDriverLibFile, LUSBTest, NULL, &DriverSettings; if(!fRet RETAILMSG(1,(TEXT(RegisterClientSettings errorrn; else RETAILMSG(1,(TEXT(RegisterClientDriverID errorrn; return fRet; 在WinC

11、E中,將設置信息分為了三組,每組3個值, 第一組: dwVendorId、dwProductId、dwReleaseNumber 第二組: dwDeviceClass、dwDeviceSubClass、dwDeviceProtocol 第三組: dwInterfaceClass、dwInterfaceSubClass、dwInterfaceProtocol 如果注冊成功,將會在HKEY_LOCAL_MACHINEDriversUSBLoadClients鍵下出現 “第一組第二組第三組注冊IDDLL”這樣的建,鍵值為DLL驅動名稱。其中每組又是由三個值中間加下劃線組成。如果有一個值設置為USB_

12、NO_INFO,則鍵名不包括該值。如果整個組中每個值都設置成USB_NO_INFO,則鍵名為Default。 據上面的例子,在我的系統下,將會生成如下鍵名: HKEY_LOCAL_MACHINEDriversUSBLoadClients4292_3Default0_0_0USBTestDLL = MyUSBTest (我的驅動程序為MyUSBTest.dll 當用戶插入USB設備時,它會讀取USB設備的描述符,根據描述符中的值在注冊表中查找驅動程序名稱。 現在假設,我們要WinCE只支持USB鍵盤,另外我們自己實現一個USB鼠標驅動程序。如果不加注意,我們的USB鼠標驅動程序將不能被調用。原因

13、正是在于這個查找USB設備驅動的過程。WINCE提供的USBHID驅動程序的注冊表信息是 HKEY_LOCAL_MACHINEDriversUSBLoadClientsDefaultDefault3Hid_ClassDLL = USBHID.DLL 其中第三組信息只使用了dwInterfaceClass,而USB鍵盤和USB鼠標只有dwInterfaceProtocol不同。所以,一個3概括了所有的HID,當我們的USB鼠標插入系統后,將會調用USBHID.DLL驅動程序處理,但是它只包括鍵盤的驅動,沒有 鼠標的驅動,所以鼠標不能使用。要想使得自定義的USB鼠標可以使用,則將第三組的值都設置上

14、,如下: HKEY_LOCAL_MACHINEDriversUSBLoadClientsDefaultDefault3_1_1Hid_ClassDLL = USBHID.DLL 如此一來,當值為3_1_2的鼠標插入后,因為找不到對應的鍵值,將提示要求我們輸入USB鼠標的驅動。 當用戶需要卸載USB Host設備驅動時,將會調用USBUnInstallDriver函數 BOOL USBUnInstallDriver(; 它與USBInstallDriver類似,不過是調用如下兩個函數 UnRegisterClientSettings BOOL UnRegisterClientSettings(L

15、PCWSTR szUniqueDriverId, LPCWSTR szReserved, LPCUSB_DRIVER_SETTINGS lpDriverSettings; BOOL UnRegisterClientDriverID(LPCWSTR szUniqueDriverId; 其中szUniqueDriverId是注冊時,使用的ID,szReserved保留,故設置為NULL,lpDriverSettings則是驅動程序設置信息。 例程如下: BOOL USBUnInstallDriver( RETAILMSG(1,(TEXT(USBUninstallDriverrn; BOOL fRe

16、t = FALSE; USB_DRIVER_SETTINGS DriverSettings; DriverSettings.dwCount = sizeof(DriverSettings; DriverSettings.dwVendorId = 0x10C4; DriverSettings.dwProductId = 0x0003; DriverSettings.dwReleaseNumber = USB_NO_INFO; DriverSettings.dwDeviceClass = USB_NO_INFO; DriverSettings.dwDeviceSubClass = USB_NO_I

17、NFO; DriverSettings.dwDeviceProtocol = USB_NO_INFO; DriverSettings.dwInterfaceClass = 0; DriverSettings.dwInterfaceSubClass = 0; DriverSettings.dwInterfaceProtocol = 0; fRet = UnRegisterClientSettings(LUSBTest, NULL, &DriverSettings; if(fRet fRet = UnRegisterClientDriverID(LUSBTest; if(!fRet RETAILM

18、SG(1,(TEXT(UnRegisterClientDriverID errorrn; else RETAILMSG(1,(TEXT(UnRegisterClientSettings errorrn; return fRet; 其中DriverSettings必須與USBInstallDriver的DriverSettings一致。 回到原來的流程,WinCE注冊表中已經包含了驅動信息,WinCE系統自動查找注冊表,在找到設備對應鍵值的DLL后,將會調用該DLL的USBDeviceAttach函數。 BOOL USBDeviceAttach( USB_HANDLE hDevice, LPCU

19、SB_FUNCS lpUsbFuncs, LPCUSB_INTERFACE lpInterface, LPCWSTR szUniqueDriverId, LPBOOL fAcceptControl, DWORD dwUnused hDevice 設備句柄,操作USB設備時,需要使用該句柄 lpUsbFuncs 指向一個包含各種USB操作的函數指針 lpInterface USB接口信息,這里需要注意的是,如果在DriverSettings里dwInterfaceClass、dwInterfaceSubClass、dwInterfaceProtocol設置為USB_NO_INFO,則該指針為NU

20、LL szUniqueDriverId 注冊設備ID fAcceptControl 該值被賦值為TRUE,表示該驅動能操作該設備。如果不能操作該設備,則“未能識別的USB設備”對話框會再次出現,要求用戶輸入驅動程序名稱 dwUnused 未使用 在該函數內,主要是做一些檢查,判斷是否能驅動設備,還有就是注冊USB事件通知回調函數,以 及激活流驅動。對于檢查部分,這里不再詳細說明。 首先,介紹一下激活流驅動。 流驅動為應用程序提供了一個訪問設備的接口,利用該接口可以像訪問文件一樣訪問設備。USB設備同樣可以使用該接口來為應用程序提供支持。在注冊表的 HKEY_LOCAL_MACHINEDrive

21、rsBuiltIn鍵下,保存了各種WinCE內建流驅動程序的入口。這些驅動通過device.exe在系統啟動時被激活。像USB這樣的設備,只有插入時,才存在流 驅動接口,所以我們需要手動激活流驅動。激活流驅動的函數是: HANDLE ActivateDevice(LPCWSTR lpszDevKey, DWORD dwClientInfo; lpszDevKey 字符串指明了流驅動所在注冊表的鍵。獲悉流驅動的人都知道,流驅動在注冊表中必須包含兩個鍵Prefix和Dll。 流驅動中所有接口函數都有類似XXX_的前綴,而這個Prefix則指明XXX對應的字符串,如Prefix為COM,則流驅動包含

22、如COM_Open、COM_Close、COM_Write、COM_Read這樣接口函數。Dll則說明了這些函數所在的動態鏈接庫。 在我的例子中存在如下的注冊表鍵: HKEY_LOCAL_MACHINEDriversUSBClientDriversUSBTest Prefix=TST Dll=MyUSBTest.dll 通過dwClientInfo,可以把參數間接傳給驅動的XXX_init。我們可以把hDevice、lpUsbFuncs、lpInterface這樣信息放置在一個結構體中,通過該函數傳遞給流驅動使用。 USB通知回調函數,可以用來判斷各種USB事件的發生,如USB拔出。當發生事件

23、后,系統會根據注冊的回調函數做相應的處理,在USB設備拔出后,所要做的事情,就是卸載流驅動,并釋放占用的各種資源。 注冊回調函數是一個包含在lpUsbFuncs中的函數指針: LPUN_REGISTER_NOTIFICATION_ROUTINE lpUnRegisterNotificationRoutine 該函數的聲明如下: typedef BOOL (* LPREGISTER_NOTIFICATION_ROUTINE( USB_HANDLE hDevice, LPDEVICE_NOTIFY_ROUTINE lpNotifyRoutine, LPVOID lpvNotifyParameter

24、 ; hDevice 設備句柄 lpNotifyRoutine 回調函數 lpvNotifyParameter 傳遞給回調函數的參數 在回調函數中卸載流驅動使用 BOOL DeactivateDevice(HANDLE hDevice; 其中,hDevice 傳入ActivateDevice時返回的句柄。 下面是具體的示例: typedef struct DWORD dwSize; USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs, LPCUSB_INTERFACE lpInterface, HANDLE hStreamDevice; TESTUSBINF

25、O, PTESTUSBINFO; /回調函數 extern C BOOL USBDeviceNotifications( LPVOID lpvNotifyParameter, DWORD dwCode, LPDWORD *dwInfo1, LPDWORD *dwInfo2, LPDWORD *dwInfo3, LPDWORD *dwInfo4 if (dwCode = USB_CLOSE_DEVICE PTESTUSBINFO pDrv = (PDRVCONTEXT lpvNotifyParameter; DeactivateDevice(pDrv-hStreamDevice; /卸載流驅動

26、LocalFree(pDrv; /釋放資源 RETAILMSG(1,(TEXT(Free Driver Resources!rn; return TRUE; BOOL USBDeviceAttach( USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs, LPCUSB_INTERFACE lpInterface, LPCWSTR szUniqueDriverId, LPBOOL fAcceptControl, DWORD dwUnused RETAILMSG(1,(TEXT(USBDeviceAttachrn; *fAcceptControl = FALSE

27、; /顯示USB設備的一些信息 if(lpInterface != NULL RETAILMSG(1,(TEXT(usbserialhost: DeviceAttach, IF %u, #EP:%u, Class:%u, Sub:%u, Prot:%urn, lpInterface-Descriptor.bInterfaceNumber, lpInterface-Descriptor.bNumEndpoints, lpInterface-Descriptor.bInterfaceClass, lpInterface-Descriptor.bInterfaceSubClass, lpInterface-Descriptor.bInterfaceProtocol; RETAILMSG(1,(TEXT(Endpoint 1:%urn, lpInterface-lpEndpoints0.Descriptor.bmAttributes; RETAILMSG(1,(TEXT(Endpoint 2:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論