中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. 新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 如何編寫Windows CE.net的usb驅動程序

        如何編寫Windows CE.net的usb驅動程序

        作者: 時間:2011-02-25 來源:網絡 收藏

        隨著USB設備的普及,擺在開發(fā)人員面前的驅動開發(fā)任務也是越來越繁重了,特別是對于一些開發(fā)廠商來講,由于設備所采用的操作系統(tǒng)不同,相應的硬件接口也是不一樣的,開發(fā)相關的USB 驅動程序更是難上加難。Windows CE.NET 是微軟推出的功能強大的操作系統(tǒng),國內采用此操作系統(tǒng)的廠商已經很多了,本文就以windows ce.net為例,簡單介紹一下如何開發(fā)windows ce.net下的USB驅動程序。
          首先要熟悉一些USB的基本概念,當然最好把USB 1.1的協(xié)議看一遍,(當然現(xiàn)在2。0的協(xié)議都已經有了)http://www.usb.org上可以下載,我記得好像有個中文版的,翻譯的還可以,http://www.driverdevolep.com上有的,具體位置記不太清楚了,中文版的協(xié)議可以快速翻一邊,了解一些基本的概念,但是設計到一些關鍵性的東西最好還是看英文版的心里比較清楚些。
          這里我就不介紹USB的基本協(xié)議了,假設用戶已經熟悉了USB設備的一些基本的概念,并且對Winows CE.NET的開發(fā)有一定的了解。
          下面簡略介紹一下Windows CE.NET中USB設備驅動開發(fā)的一些基礎知識。
          Windows CE.NET 的USB系統(tǒng)軟件分為兩層: USB Client設備驅動程序和底層的Windows CE實現(xiàn)的函數(shù)層。USB設備驅動程序主要負責利用系統(tǒng)提供的底層接口配置設備,和設備進行通訊。底層的函數(shù)提本身又由兩部分組成,通用串行總線驅動程序(USBD)模塊和較低的主控制器驅動程序(HCD)模塊。HCD負責最最底層的處理,USBD模塊實現(xiàn)較高的USBD函數(shù)接口。USB設備驅動主要利用 USBD接口函數(shù)和他們的外圍設備打交道。
          USB設備驅動程序主要和USBD打交道,所以我們必須詳細的了解USBD提供的函數(shù)。
          主要的傳輸函數(shù)有:
          AbourtTransfer   IssueControlTransferCloseTransfer    IssueInterrupTransferGetIsochResult   IssueIsochTransferGetTransferStatus  IstransferCompleteIssueBulkTransfer  IssueVendorTransfer主要的用于打開和關閉USBD和USB設備之間的通信通道的函數(shù)有:
          AbortPipeTransfers  ClosePipeIsDefaultPipeHalted  IsPipeHaltedOpenPipe       ResetDefaultPipeResetPipe相應的打包函數(shù)接口有:
          GetFrameLength   GetFrameNumber   ReleaseFrameLengthControlSetFrameLength   TakeFrameLengthControl取得設置設備配置函數(shù):
          ClearFeature   SetDescriptorGetDescriptor  SetFeatureGetInterface   SetInterfaceGetStatus    SyncFrame與USB進行交互的實現(xiàn)方法相關的多任務函數(shù):
          FindInterface         RegisterClientDeviceIdGetDeviceInfo         RegisterClientSettingsGetUSBDVersion         RegisterNotificationRoutineLoadGenericInterfaceDriver   TranslateStringDescrOpenClientRegisterKey     UnRegisterNotificationRoutine常見的Windows CE.NET下USB的設備驅動程序的編寫有以下幾種方法:
          ● 流式接口函數(shù)這種驅動程序主要呈現(xiàn)流式函數(shù)接口,主要輸出XXX_Init,XXX_Deinit,XXX_Open,XXX_Close,XXX_Open,XXX_Close,XXX_Read,XXX_Write,XXX_Seek, XXX_IOControl,XXX_PowerUp,XXX_PowerDown等流式接口,注意上述的幾個接口一定都要輸出,另外XXX必須為三個字符,否則會出錯。但是此類的驅動程序不是通過設備管理接口來加載的,所以必須手工的調用RegisterDevice()和 DeregisterDevice()函數(shù)來加載和卸載驅動程序。用戶可以將此類的設備作為標準的文件來操作,只要調用相應的文件操作就可以和驅動程序打交道。
          ● 使用現(xiàn)有的Window CE.NET的應用程序接口此類設備主要是利用Windows CE.NET中已經有了現(xiàn)成的函數(shù)接口,例如USB Mass Storage Disk,它主要利用現(xiàn)有的Windows CE.Net中已經有的可安裝文件系統(tǒng)接口,呈現(xiàn)給系統(tǒng)可用的文件系統(tǒng),對于用戶來講,它是透明的,用戶僅僅感覺在操作一個文件夾。
          ● 創(chuàng)建指定到特定的USBD的用戶指定的API這種方法在USBD呈現(xiàn)設備時不需要任何限制,主要是特制的提供API給用戶,一般不太常見。
          USB設備驅動程序必須輸出的函數(shù)有:
          ● USBDeviecAttach當USB設備連接到計算機上時,USBD模塊就會調用此函數(shù),這個函數(shù)主要用于初始化USB設備,取得USB設備信息,配置USB設備,并且申請必需的資源。
          ● USBInstallDriver主要用于創(chuàng)建一個驅動程序加載所需的注冊表信息,例如讀寫超時,設備名稱等。
          ● USBUninstallDriver主要用于釋放驅動程序所占用的資源,以及刪除USBInstallDriver函數(shù)創(chuàng)建的注冊表等。
          上述的三個函數(shù)接口是所有的USB驅動程序必須提供的,缺一不可。
          另外比較重要的是USB設備驅動程序的注冊表配置,一般的USB設備驅動程序的注冊表配置在HKEY_LOCAL_MACHINEDriversUSB LoadClients下,每個驅動程序的子鍵都有Group1_IDGroup2_IDGroup3_IDDriverName格式,如果注冊表信息與USB設備信息符合,USBD就會加載此驅動程序。否則設備的子鍵應該由供應商,設備類和協(xié)議信息通過下劃線組成。
          具體的配置舉個例子:
          例如你有個PDA設備,它具有一個USB接口,它的供應廠商ID假設為0x0888,設備ID為0x0999,沒有使用特殊的協(xié)議,那么它的加載注冊表應該寫為:
          [HKEY_LOCAL_MACHINEDriversUSBLoadClients2184_2457DefaultDefaultPDA] "DLL"="pdausb.dll"需要注意的是注冊表構成都是十進制數(shù)值來標識的,注意一下十進制和十六進制的轉換。
          再舉個USB鼠標的例子,USB鼠標是標準的HID設備,它的協(xié)議為:InterfaceClassCode為3(HID類), InterfaceSubclassCode為1(引導接口類),InterfaceProtocolCode為2(鼠標協(xié)議類),所以它的注冊如下:
          [HKEY_LOCAL_MACHINEDriversUSBLoadClientsDefaultDefault3_1_2USBMouse] "DLL"="usbmouse.dll"到此為止,我們可以看出,其實驅動開發(fā)無非做兩件事情,一件是和硬件打交道,另外一件是和操作系統(tǒng)打交道。舉個簡單的例子,例如:我們需要開發(fā)一個USB鼠標驅動程序,我們就需要了解USB鼠標硬件上是怎么發(fā)送數(shù)據(jù)的?操作系統(tǒng)怎么才能得到鼠標的控制事件?其實USB鼠標是有一個中斷PIPE的,用于傳送鼠標產生的數(shù)據(jù),Windwos CE.NET中有個接口函數(shù)叫做mouse_event(),專門用于產生鼠標事件,但是它是不關心具體什么硬件的,甚至我們自己在應用程序中調用這個函數(shù)都可以實現(xiàn)模擬鼠標,對應的有個keybd_event(),用于產生鍵盤事件,知道了這個就好辦多了,只要將相應的數(shù)據(jù)轉換一下,調用一下 mouse_event()即可例如我們有個USB Mouse設備,設備信息描述如下:
          Device Descriptor:
          bcdUSB: 0x0100bDeviceClass: 0x00bDeviceSubClass: 0x00bDeviceProtocol: 0x00bMaxPacketSize0: 0x08 (8)idVendor: 0x05E3 (Genesys Logic Inc.)idProduct: 0x0001bcdDevice: 0x0101iManufacturer: 0x00iProduct: 0x01iSerialNumber: 0x00bNumConfigurations: 0x01ConnectionStatus: DeviceConnectedCurrent Config Value: 0x01Device Bus Speed: LowDevice Address: 0x02Open Pipes: 1Endpoint Descriptor:
          bEndpointAddress: 0x81Transfer Type: InterruptwMaxPacketSize: 0x0003 (3)bInterval: 0x0A可以看出上述設備有一個中斷PIPE,包的最大值為3??赡苡腥藛柹鲜龅闹翟趺吹玫降?,win2k 的DDK中有個usbview的例程,編譯一下,將你的USB設備插到PC機的USB口中,運行usbview.exe即可看得相應的設備信息。
          有了這些基本信息,就可以編寫USB設備了,首先聲明一下,下面的代碼取自微軟的USB鼠標樣本程序,版權歸微軟所有,此處僅僅借用來描述一下USB鼠標驅動的開發(fā)過程,讀者如需要引用此代碼,需要得到微軟的同意。
          首先,必須輸出USBD要求調用的三個函數(shù),首先到設備插入到USB端口時,USBD會調用USBDeviceAttach()函數(shù),相應的代碼如下:
          extern "C" BOOLUSBDeviceAttach(USB_HANDLE hDevice, // USB設備句柄LPCUSB_FUNCS lpUsbFuncs, // USBDI的函數(shù)集合LPCUSB_INTERFACE lpInterface, // 設備接口描述信息LPCWSTR szUniqueDriverId, // 設備ID描述字符串。
          LPBOOL fAcceptControl, // 返回TRUE,標識我們可以控制此設備, 反之表示不能控制DWORD dwUnused){*fAcceptControl = FALSE;// 我們的鼠標設備有特定的描述信息,要檢測是否是我們的設備。
          if (lpInterface == NULL)return FALSE;// 打印相關的USB設備接口描述信息。
          DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: 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));// 初試數(shù)據(jù)USB鼠標類,產生一個接受USB鼠標數(shù)據(jù)的線程CMouse * pMouse = new CMouse(hDevice, lpUsbFuncs, lpInterface);if (pMouse == NULL)return FALSE;if (!pMouse->Initialize()){delete pMouse;return FALSE;}
          // 注冊一個監(jiān)控USB設備事件的回調函數(shù),用于監(jiān)控USB設備是否已經拔掉。
          (*lpUsbFuncs->lpRegisterNotificationRoutine)(hDevice,USBDeviceNotifications, pMouse);*fAcceptControl = TRUE;return TRUE;}
          第二個函數(shù)是 USBInstallDriver()函數(shù),一些基本定義如下:
          const WCHAR gcszRegisterClientDriverId[] = L"RegisterClientDriverID";const WCHAR gcszRegisterClientSettings[] = L"RegisterClientSettings";const WCHAR gcszUnRegisterClientDriverId[] = L"UnRegisterClientDriverID";const WCHAR gcszUnRegisterClientSettmngs[] = L"UnRegisterClientSettings";const WCHAR gcszMouseDriverId[] = L"Generic_Sample_Mouse_Driver";函數(shù)接口如下:
          extern "C" BOOLUSBInstallDriver(LPCWSTR szDriverLibFile) // @parm [IN] - Contains client driver DLL name{BOOL fRet = FALSE;HINSTANCE hInst = LoadLibrary(L"USBD.DLL");// 注冊USB設備信息if(hInst){LPREGISTER_CLIENT_DRIVER_ID pRegisterId = (LPREGISTER_CLIENT_DRIVER_ID)GetProcAddress(hInst, gcszRegisterClientDriverId);LPREGISTER_CLIENT_SETTINGS pRegisterSettings =(LPREGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,gcszRegisterClientSettings);if(pRegisterId pRegisterSettings){USB_DRIVER_SETTINGS DriverSettings;DriverSettings.dwCount = sizeof(DriverSettings);// 設置我們的特定的信息。
          DriverSettings.dwVendorId = USB_NO_INFO;DriverSettings.dwProductId = USB_NO_INFO;DriverSettings.dwReleaseNumber = USB_NO_INFO;DriverSettings.dwDeviceClass = USB_NO_INFO;DriverSettings.dwDeviceSubClass = USB_NO_INFO;DriverSettings.dwDeviceProtocol = USB_NO_INFO;DriverSettings.dwInterfaceClass = 0x03; // HIDDriverSettings.dwInterfaceSubClass = 0x01; // boot deviceDriverSettings.dwInterfaceProtocol = 0x02; // mousefRet = (*pRegisterId)(gcszMouseDriverId);if(fRet){fRet = (*pRegisterSettings)(szDriverLibFile,gcszMouseDriverId, NULL, DriverSettings);if(!fRet){//BUGBUG unregister the Client Driver’s ID}
          }
          }
          else{RETAILMSG(1,(TEXT("!USBMouse: Error getting USBD function pointersrn")));}
          FreeLibrary(hInst);}
          return fRet;}
          上述代碼主要用于產生USB設備驅動程序需要的注冊表信息,需要注意的是:USB設備驅動程序不使用標準的注冊表函數(shù),而是使用RegisterClientDriverID()和RegisterClientSettings來注冊相應的設備信息。
          另外一個函數(shù)是USBUninstallDriver()函數(shù),具體代碼如下:
          extern "C" BOOLUSBUnInstallDriver(){BOOL fRet = FALSE;HINSTANCE hInst = LoadLibrary(L"USBD.DLL");if(hInst){LPUN_REGISTER_CLIENT_DRIVER_ID pUnRegisterId =(LPUN_REGISTER_CLIENT_DRIVER_ID)GetProcAddress(hInst, gcszUnRegisterClientDriverId);LPUN_REGISTER_CLIENT_SETTINGS pUnRegisterSettings =(LPUN_REGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,gcszUnRegisterClientSettings);if(pUnRegisterSettings){USB_DRIVER_SETTINGS DriverSettings;DriverSettings.dwCount = sizeof(DriverSettings);// 必須填入與注冊時相同的信息。
          DriverSettings.dwVendorId = USB_NO_INFO;DriverSettings.dwProductId = USB_NO_INFO;DriverSettings.dwReleaseNumber = USB_NO_INFO;DriverSettings.dwDeviceClass = USB_NO_INFO;DriverSettings.dwDeviceSubClass = USB_NO_INFO;DriverSettings.dwDeviceProtocol = USB_NO_INFO;DriverSettings.dwInterfaceClass = 0x03; // HIDDriverSettings.dwInterfaceSubClass = 0x01; // boot deviceDriverSettings.dwInterfaceProtocol = 0x02; // mousefRet = (*pUnRegisterSettings)(gcszMouseDriverId, NULL,DriverSettings);}
          if(pUnRegisterId){BOOL fRetTemp = (*pUnRegisterId)(gcszMouseDriverId);fRet = fRet ? fRetTemp : fRet;}
          FreeLibrary(hInst);}
          return fRet;}
          此函數(shù)主要用于刪除USBInstallDriver()時創(chuàng)建的注冊表信息,同樣的它使用自己的函數(shù)接口UnRegisterClientDriverID()和UnRegisterClientSettings()來做相應的處理。
          另外一個需要處理的注冊的監(jiān)控通知函數(shù)USBDeviceNotifications():
          extern "C" BOOL USBDeviceNotifications(LPVOID lpvNotifyParameter, DWORD dwCode,LPDWORD * dwInfo1, LPDWORD * dwInfo2, LPDWORD * dwInfo3,LPDWORD * dwInfo4){CMouse * pMouse = (CMouse *)lpvNotifyParameter;switch(dwCode){case USB_CLOSE_DEVICE:
          //刪除相關的資源。
          delete pMouse;return TRUE;}
          return FALSE;}
          USB鼠標的類的定義如下:
          class CMouse{public:
          CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,LPCUSB_INTERFACE lpInterface);~CMouse();BOOL Initialize();private:
          // 傳輸完畢調用的回調函數(shù)static DWORD CALLBACK MouseTransferCompleteStub(LPVOID lpvNotifyParameter);// 中斷處理函數(shù)static ULONG CALLBACK CMouse::MouseThreadStub(PVOID context);DWORD MouseTransferComplete();DWORD MouseThread();BOOL SubmitInterrupt();BOOL HandleInterrupt();BOOL m_fClosing;BOOL m_fReadyForMouseEvents;HANDLE m_hEvent;HANDLE m_hThread;USB_HANDLE m_hDevice;USB_PIPE m_hInterruptPipe;USB_TRANSFER m_hInterruptTransfer;LPCUSB_FUNCS m_lpUsbFuncs;LPCUSB_INTERFACE m_pInterface;BOOL m_fPrevButton1;BOOL m_fPrevButton2;BOOL m_fPrevButton3;// 數(shù)據(jù)接受緩沖區(qū)。
          BYTE m_pbDataBuffer[8];};具體實現(xiàn)如下:
          // 構造函數(shù),初始化時調用CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,LPCUSB_INTERFACE lpInterface){m_fClosing = FALSE;m_fReadyForMouseEvents = FALSE;m_hEvent = NULL;m_hThread = NULL;m_hDevice = hDevice;m_hInterruptPipe = NULL;m_hInterruptTransfer = NULL;m_lpUsbFuncs = lpUsbFuncs;m_pInterface = lpInterface;m_fPrevButton1 = FALSE;m_fPrevButton2 = FALSE;m_fPrevButton3 = FALSE;memset(m_pbDataBuffer, 0, sizeof(m_pbDataBuffer));}
          // 析構函數(shù),用于清除申請的資源。
          CMouse::~CMouse(){// 通知系統(tǒng)去關閉相關的函數(shù)接口。
          m_fClosing = TRUE;// Wake up the connection thread again and give it time to die.
          if (m_hEvent != NULL){// 通知關閉數(shù)據(jù)接受線程。
          SetEvent(m_hEvent);if (m_hThread != NULL){DWORD dwWaitReturn;dwWaitReturn = WaitForSingleObject(m_hThread, 1000);if (dwWaitReturn != WAIT_OBJECT_0){TerminateThread(m_hThread, DWORD(-1));}
          CloseHandle(m_hThread);m_hThread = NULL;}
          CloseHandle(m_hEvent);m_hEvent = NULL;}
          if(m_hInterruptTransfer)(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);if(m_hInterruptPipe)(*m_lpUsbFuncs->lpClosePipe)(m_hInterruptPipe);}
          // 初始化USB鼠標驅動程序BOOL CMouse::Initialize(){LPCUSB_DEVICE lpDeviceInfo = (*m_lpUsbFuncs->lpGetDeviceInfo)(m_hDevice);// 檢測配置:USB鼠標應該只有一個中斷管道if ((m_pInterface->lpEndpoints[0].Descriptor.bmAttributes USB_ENDPOINT_TYPE_MASK) != USB_ENDPOINT_TYPE_INTERRUPT){RETAILMSG(1,(TEXT("!USBMouse: EP 0 wrong type (%u)!rn"),m_pInterface->lpEndpoints[0].Descriptor.bmAttributes));return FALSE;}
          DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: EP 0:MaxPacket: %u, Interval: %urn"),m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,m_pInterface->lpEndpoints[0].Descriptor.bInterval));m_hInterruptPipe = (*m_lpUsbFuncs->lpOpenPipe)(m_hDevice,m_pInterface->lpEndpoints[0].Descriptor);if (m_hInterruptPipe == NULL) {RETAILMSG(1,(TEXT("Mouse: Error opening interrupt pipern")));return (FALSE);}
          m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);if (m_hEvent == NULL){RETAILMSG(1,(TEXT("USBMouse: Error on CreateEvent for connect eventrn")));return(FALSE);}
          // 創(chuàng)建數(shù)據(jù)接受線程m_hThread = CreateThread(0, 0, MouseThreadStub, this, 0, NULL);if (m_hThread == NULL){RETAILMSG(1,(TEXT("USBMouse: Error on CreateThreadrn")));return(FALSE);}
          return(TRUE);}
          // 從USB鼠標設備中讀出數(shù)據(jù),產生相應的鼠標事件。
          BOOL CMouse::SubmitInterrupt(){if(m_hInterruptTransfer)(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);// 從USB鼠標PIPE中讀數(shù)據(jù)m_hInterruptTransfer = (*m_lpUsbFuncs->lpIssueInterruptTransfer)(m_hInterruptPipe, MouseTransferCompleteStub, this,USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK, // 表示讀數(shù)據(jù)min(m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,sizeof(m_pbDataBuffer)),m_pbDataBuffer,NULL);if (m_hInterruptTransfer == NULL){DEBUGMSG(ZONE_ERROR,(L "!USBMouse: Error in IssueInterruptTransferrn"));return FALSE;}
          else{DEBUGMSG(ZONE_TRANSFER,(L"USBMouse::SubmitInterrupt,Transfer:0x%Xrn",m_hInterruptTransfer));}
          return TRUE;}
          // 處理鼠標中斷傳輸?shù)臄?shù)據(jù)BOOL CMouse::HandleInterrupt(){DWORD dwError;DWORD dwBytes;DWORD dwFlags = 0;INT dx = (signed char)m_pbDataBuffer[1];INT dy = (signed char)m_pbDataBuffer[2];BOOL fButton1 = m_pbDataBuffer[0] 0x01 ? TRUE : FALSE;BOOL fButton2 = m_pbDataBuffer[0] 0x02 ? TRUE : FALSE;BOOL fButton3 = m_pbDataBuffer[0] 0x04 ? TRUE : FALSE;if (!(*m_lpUsbFuncs->lpGetTransferStatus)(m_hInterruptTransfer, dwBytes,dwError)){DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error in GetTransferStatus(0x%X)rn"),m_hInterruptTransfer));return FALSE;}
          else{DEBUGMSG(ZONE_TRANSFER,(TEXT("USBMouse::HandleInterrupt, hTransfer 0x%X complete (%u bytes, Error:%X)rn"),m_hInterruptTransfer,dwBytes,dwError));}
          if (!SubmitInterrupt())return FALSE;if(dwError != USB_NO_ERROR){DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error 0x%X in interrupt transferrn"),dwError));return TRUE;}
          if(dwBytes 3){DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Invalid byte cnt %u from interrupt transferrn"),dwBytes));return TRUE;}
          if(dx || dy)dwFlags |= MOUSEEVENTF_MOVE;if(fButton1 != m_fPrevButton1){if(fButton1)dwFlags |= MOUSEEVENTF_LEFTDOWN;elsedwFlags |= MOUSEEVENTF_LEFTUP;}
          if(fButton2 != m_fPrevButton2){if(fButton2)dwFlags |= MOUSEEVENTF_RIGHTDOWN;elsedwFlags |= MOUSEEVENTF_RIGHTUP;}
          if(fButton3 != m_fPrevButton3){if(fButton3)dwFlags |= MOUSEEVENTF_MIDDLEDOWN;elsedwFlags |= MOUSEEVENTF_MIDDLEUP;}
          m_fPrevButton1 = fButton1;m_fPrevButton2 = fButton2;m_fPrevButton3 = fButton3;DEBUGMSG(ZONE_EVENTS,(TEXT("USBMouse event: dx:%d, dy:%d, dwFlags:0x%X (B1:%u, B2:%u, B3:%u)rn"),dx,dy,dwFlags,fButton1,fButton2,fButton3));// 通知系統(tǒng)產生鼠標事件if (m_fReadyForMouseEvents)mouse_event(dwFlags, dx, dy, 0, 0);elsem_fReadyForMouseEvents = IsAPIReady(SH_WMGR);return TRUE;}
          DWORD CALLBACK CMouse::MouseTransferCompleteStub(LPVOID lpvNotifyParameter){CMouse * pMouse = (CMouse *)lpvNotifyParameter;return(pMouse->MouseTransferComplete());}
          // 數(shù)據(jù)傳輸完畢回調函數(shù)DWORD CMouse::MouseTransferComplete(){if (m_hEvent)SetEvent(m_hEvent);return 0;}
          ULONG CALLBACK CMouse::MouseThreadStub(PVOID context){CMouse * pMouse = (CMouse *)context;return(pMouse->MouseThread());}
          // USB鼠標線程DWORD CMouse::MouseThread(){DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: Worker thread startedrn")));SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);if (SubmitInterrupt()){while (!m_fClosing){WaitForSingleObject(m_hEvent, INFINITE);if (m_fClosing)break;if ((*m_lpUsbFuncs->lpIsTransferComplete)(m_hInterruptTransfer)){if (!HandleInterrupt())break;}
          else{RETAILMSG(1,(TEXT("!USBMouse: Event signalled, but transfer not completern")));// The only time this should happen is if we get an error on the transferASSERT(m_fClosing || (m_hInterruptTransfer == NULL));break;}
          }
          }
          RETAILMSG(1,(TEXT("USBMouse: Worker thread exitingrn")));return(0);}
          看到了沒有,其實USB的驅動程序編寫就這么簡單,類似的其他設備,例如打印機設備,就有Bulk OUT PIPE,需要Bulk傳輸,那就需要了解一下IssueBulkTransfer()的應用。當然如果是開發(fā)USB Mass Storage Disk的驅動,那就需要了解更多的協(xié)議,例如Bulk-Only Transport協(xié)議等。
          微軟的Windows CE.NET的Platform Build中已經帶有USB Printer和USB Mass Storage Disk的驅動的源代碼了,好好研究一下,你一定回受益非淺的。

        linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


        評論


        相關推薦

        技術專區(qū)

        關閉