Windows主機端與自定義USBHID設備通信詳解_第1頁
Windows主機端與自定義USBHID設備通信詳解_第2頁
Windows主機端與自定義USBHID設備通信詳解_第3頁
Windows主機端與自定義USBHID設備通信詳解_第4頁
Windows主機端與自定義USBHID設備通信詳解_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

WindowsUSBHID設備通信詳解(2009-06-1223:19)Windows說明:以下結論都是基于WindowsXP HID自定義設備,對于標準設備,譬如USB鼠標和鍵盤,由于操作系統(tǒng)對其獨占,很多操作未必能正確執(zhí)行。WindowsAPICreateFileReadFileWriteFileDDK的內(nèi)容:HidD_SetFeatureHidD_GetFeatureHidD_SetOutputReportHidD_GetInputReport其中,CreateFile用于翻開設備;ReadFile、HidD_GetFeature、HidD_GetInputReport用于設備到主機方向的數(shù)據(jù)通信;WriteFile、、HidD_SetOutputReport用于主機到設備方向的數(shù)據(jù)通信。鑒于函數(shù),明白了這四個函數(shù),其它的可以類推之。幾個常見錯誤會得到以下常見錯誤:6: 句柄無效23: 數(shù)據(jù)錯誤〔循環(huán)冗余碼檢查〕87: 參數(shù)錯誤1784: buffer無效主機端設備枚舉程序流程函數(shù)使用說明CreateFile(devDetail->DevicePath, //設備路徑GENERIC_READ|GENERIC_WRITE, //訪問方式FILE_SHARE_READ|FILE_SHARE_WRITE,//共享模式NULL,OPEN_EXISTING, //文件不存在時敗式翻開

FILE_FLAG_OVERLAPPED, 〕模NULL);在這里,CreateFileHID設備,其中設備路徑通過函數(shù)SetupDiGetInterfaceDeviceDetail取得。CreateFile有以下幾點需要留意:訪問方式:假設是系統(tǒng)獨占設備,例如鼠標、鍵盤等等,應將此參數(shù)0,否則后續(xù)函數(shù)操作將失敗〔HidD_GetAttributes〕;也就是MSDN上關于此參數(shù)的說明:Ifthisparameteriszero,theapplicationcanqueryfileanddeviceattributeswithoutaccessingthedevice.ThisisusefulifanapplicationwantstodeterminethesizeofafloppydiskdriveandtheformatsitsupportswithoutrequiringafloppyinthedriveItcanalsobeusedtotestforthefile”sordirectory”sexistencewithoutopeningitforreadorwriteaccess。 模式:此參數(shù)并不會在此處表現(xiàn)出明顯的意義,它主要是WriteFile,ReadFile有影響。假設這里設置為重疊〔異步〕模WriteFile,ReadFile時也應當使用重疊〔異步〕模式,WriteFile,ReadFile的最終一個參數(shù)不能為空并不代表就是此參數(shù)不正確,更多的信息將在具體表達這兩個函數(shù)時指0WriteFile,ReadFile操作會在數(shù)據(jù)處理完成之后才返回,否則堵塞在函數(shù)內(nèi)部。ReadFile(hDev, recvBuffer, //用于接收數(shù)據(jù)的bufferIN_REPORT_LEN, //要讀取數(shù)據(jù)的長度&recvBytes, //實際收到的數(shù)據(jù)的字節(jié)數(shù)&ol); //異步模式ReadFileHIDIN以下幾點要留意:1、ReadFileHID設備與主機之間的中INReadFile打交道。實際上主時機在最大間隔時間〔由設備的端點描述符來指定〕內(nèi)輪詢設備,發(fā)出中斷IN傳輸?shù)膽┣蟆!白x取”即意味著從某個bufferbuffer就是HID設備驅(qū)動中的bufferHidD_SetNumInputBuffers來轉(zhuǎn)變。在XP32〔個報告〕。假設設備不支持中斷IN傳輸,那么是無法使用此函數(shù)來得到預期結果的。實際上這種狀況不行能在HID中消滅,由于協(xié)議指明白至少要有一個中斷IN端點。、IN_REPORT_LEN代表要讀取的數(shù)據(jù)的長度〔實際的數(shù)據(jù)正文+一個byte的報告這里是一個常數(shù)主要是由于設備固件的信息我是完全知道的,固然知道要讀取多少數(shù)據(jù)〔也就是報告的長度〕;不過也可以通過另外的函數(shù)〔HidD_GetPreparsedData 先取得報告的長度,這里不做具體爭論。由于很難想象在不了解固件信息的狀況下來做自定義設備的HID通信在實際應用中一般來說就是固件與PC程序匹配著來開發(fā)此參數(shù)假設設置過大,recvBytes參數(shù)中會輸出實際讀到的長度;假設設1784〔buffer無效。CreateFile時的設置相對應,否則會返回87號錯誤〔參數(shù)錯誤〕。假設不需要異步模式,此參NULL。在這種狀況下,ReadFile會始終等待直到數(shù)據(jù)讀取成功,所以會堵塞住程序的當前過程。WriteFile(hDev, 值reportBuf, //存有待發(fā)送數(shù)據(jù)bufferOUT_REPORT_LEN, //待發(fā)送數(shù)據(jù)的長度&sendBytes, //實際收到的數(shù)據(jù)的字節(jié)數(shù)&ol); //異步模式WriteFile后,設備會接收到輸OUTWriteFile會通過中OUTSetReport懇求通過掌握管道來傳輸?!矊嶋H的數(shù)據(jù)正文+byte的報告ID〕。假設大于實際報告的長度,則使用實際報告長度;假設小1784號錯誤〔buffer無效〕。IDID指示的必需是輸〕。這種狀況可能簡潔被程序員無視,結果不知錯誤號所反映的是什么,網(wǎng)上也常常有類似疑問的帖子。順便指出,輸入報告、輸入報告、特征報告這些報告類型,是反映HID設備的報告描述符中。后文將做舉例爭論。4CreateFile時的設〕。假設不需要異步模式,NULL。在這種狀況下,WriteFile會始終等待直到數(shù)據(jù)讀取成功,所以會堵塞住程序的當前過程。HidD_SetFeature(hDev, 回值reportBuf, 送數(shù)據(jù)bufferFEATURE_REPORT_LEN); //buffer的長度HidD_SetOutputReport(hDev, 的返回值reportBuf, //bufferOUT_REPORT_LEN); //buffer的長度HidD_SetFeature發(fā)送一個特征報告HidD_SetOutputReport輸出報告給設備。留意以下幾點:1、跟WriteFilereportBuf[0]ID,并且和各自適合的類型相對應。也就是說,HidD_SetFeature只能發(fā)送特征報IDID。下狀況:報告ID與固件描述的不符。傳入的buffer長度少于固件描述的報告的長度。〔非官方文檔〕,只要是驅(qū)動程序?qū)┣鬅o反響,都會產(chǎn)生此錯誤。常見錯誤匯總HIDReadFileErrorCode6(handleisinvalid)傳入的句柄無效ErrorCode87(參數(shù)錯誤)createfile時聲明白異步方式,但是讀取時按同步讀取。ErrorCode1784(buffer無效):傳參時傳入的“讀取buffer長度”與實際的報告長度不符。HIDWriteFileErrorCode6(handleisinvalid)傳入的句柄無效ErrorCode87〔參數(shù)錯誤〕CreateFile時聲明的同步/WriteFile時傳入的不同。與固件中定義的不全都〔bufferID〕ErrorCode1784(buffer無效)傳參時傳入的“寫入buffer長度”與實際的報告長度不符。HidD_SetFeatureHidD_SetOutputReportErrorCode1(incorrectfunction)〔輸入、輸出、特征〕ErrorCode6(handleisinvalid)傳入的句柄無效ErrorCode23〔數(shù)據(jù)錯誤〔循環(huán)冗余碼檢查〕〕與固件中定義的不相符〔bufferID〕〔報告正文+1byte,1byte為ID〕〔非官方文檔〕,只要是驅(qū)動程序不承受此懇求〔對懇求無反響〕,都會產(chǎn)生此錯誤報告描述符及數(shù)據(jù)通信程序例如〔由于是匯編代碼,所以不必留意其語法,僅需留意表中的每個1個字節(jié)〕:_ReportDescriptor: //報告描述符.dw0x06, 0x00,0xff //用法頁.dw0x09, 0x01 用法(1).dw0xa1, 0x01 //集合開頭.dw0x85, 0x01 //ID(1).dw0x09, 0x01 用法(1).dw0x15, 0x00 //規(guī)律最小值(0).dw0x26, 0xff,0x0 //規(guī)律最大值(255).dw0x75, 0x08 //報告大小(8).dw0x95, 0x07 //報告計數(shù)(7).dw0x81, 0x06 //輸入〔數(shù)據(jù),變量,相對值〕.dw0x09, 0x01 (1).dw0x85, 0x03 //ID〔3〕.dw0xb1, 0x06 //特征〔數(shù)據(jù),變量,相對值〕.dw0x09, 0x01 (1).dw0x85, 0x02 //ID〔2〕.dw0xb1, 0x06 //特征〔數(shù)據(jù),變量,相對值〕.dw0x09, 0x01 用法(1).dw0x85, 0x04 //ID〔4〕.dw0x91, 0x06 //輸出〔數(shù)據(jù),變量,相對值〕.dw 0xc0 //結合完畢_ReportDescriptor_End:412,特征報告4〔ID〕7個字節(jié)〔加ID8個字節(jié)〕。下面用一個簡潔的例如來描述PC端與USBHID設備進展通信的一般方法。#defineUSB_VID0xFC0#defineUSB_PID0x420HANDLEOpenMyHIDDevice(intoverlapped);voidHIDSampleFunc{HANDLE hDev;BYTE recvDataBuf[8];BYTE reportBuf[8];DWORD bytes;hDev=OpenMyHIDDevice(0);//翻開設備,不使用重疊〔異步〕方式;if(hDev==INVALID_HANDLE_VALUE)return;reportBuf[0]=4;//ID4memset(reportBuf,0,8);reportBuf[1]=1;if(!WriteFile(hDevreportBuf8&bytesNULL//寫入數(shù)據(jù)到設備return;讀取設備發(fā)給主機的數(shù)據(jù)}HANDLEOpenMyHIDDevice(intoverlapped){HANDLE GUID hidGuid;HidD_GetHidGuid(&hidGuid);HDEVINFOhDevInfo=SetupDiGetClassDevs(&hidGuid,NULL,NULL,(DIGCF_PRESENT|DIGCF_DEVICEINTERFACE));if(hDevInfo==INVALID_HANDLE_VALUE){returnINVALID_HANDLE_VALUE;}SP_DEVICE_INTERFACE_DATAdevInfoData;devInfoData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);intdeviceNo=0;SetLastError(NO_ERROR);while(GetLastError!=ERROR_NO_MORE_ITEMS){if(SetupDiEnumInterfaceDevice(hDevInfo,0,&hidGuid,deviceNo,&devInfoData)){ULONGrequiredLength=0;SetupDiGetInterfaceDeviceDetail(hDevInfo,&devInfoData,NULL,0,&requiredLength,NULL);PSP_INTERFACE_DEVICE_DETAIL_DATAdevDetail=(SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(requiredLength);devDetail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);if(!SetupDiGetInterfaceDeviceDetail(hDevInfo,&devInfoData,devDetail,requiredLength,NULL,NULL)){free(devDetail);SetupDiDestroyDeviceInfoList(hDevInfo);returnINVALID_HANDLE_VALUE;}if(overlapped){hidHandle=CreateFile(devDetail->DevicePath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);}else{hidHandle=CreateFile(devDetail->DevicePath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);}free(devDetail);if(hidHandle==INVALID_HANDLE_VALUE){SetupDiDestroyDeviceInfoList(hDevInfo);free(devDetail);returnINVALID_HANDLE_VALUE;}_HIDD_ATTRIBUTEShidAttributes;if(!HidD_GetAttributes(hidHandle,&hidAttributes)){CloseHandle(hidHandle);SetupDiDestroyDeviceInfoList(hDevInfo);returnINVALID_HANDLE_VALU

溫馨提示

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

評論

0/150

提交評論