windows USB HID通信 读写日记

  • Post author:
  • Post category:其他


自己做了个USB Dongle,在android下通信正常;在windows下通信不正常。操作采用异步通信。

本文件为调试过程记录。

查阅过的文章:


Windows与自定义USB HID设备通信说明_顺其自然~的博客-CSDN博客_hidd_setfeature

通过CreateFile打开设备成功。

设备描述符

static const u8 sHIDReportDesc[] = {
    0x06,0x00,0xFF,             //USAGE_PAGE (Vendor Defined Page 1)
    0x09,0x01,              //USAGE (Vendor Usage 1)
    0xA1,0x01,              //COLLECTION (Application)
  //   0x85,0x01,
    0x19,0x01,              //(Vendor Usage 1)
    0x29,0x08,              //(Vendor Usage 1)
    0x15,0x00,              //LOGICAL_MINIMUM (0)
    0x26,0xFF,0x00,             //LOGICAL_MAXIMUM (255)
    0x75,0x08,              //REPORT_SIZE (8)
    0x95,0x20,              //REPORT_COUNT (64)

    0x81,0x02,              //INPUT (Data,Var,Abs)
   // 0x85,0x02,
    0x19,0x01,              //(Vendor Usage 1)
    0x29,0x08,              //(Vendor Usage 1)
   // 0x15,0x00,              //LOGICAL_MINIMUM (0)
   // 0x26,0xFF,0x00,             //LOGICAL_MAXIMUM (255)
   // 0x75,0x08,              //REPORT_SIZE (8)
   // 0x95,0x20,              //REPORT_COUNT (64)
    0x91,0x02,              //OUTPUT (Data,Var,Abs)

    0xC0                    // END_COLLECTION
};

创建设备,分开句柄,没试过使用同一个句柄。

m_stHidDev.hReadHandle =CreateFile(m_stHidDev.strDevPathName, 
											GENERIC_READ,
									FILE_SHARE_READ| FILE_SHARE_WRITE,
									NULL,
									OPEN_EXISTING,
									FILE_ATTRIBUTE_NORMAL,//|FILE_FLAG_OVERLAPPED,
									NULL); 
                    if(m_stHidDev.hReadHandle!=INVALID_HANDLE_VALUE)
							 {
								TRACE("读访问打开设备成功");
								//m_strDataInfo+="读访问打开设备成功\r\n";
							}
							else
							{
								TRACE("读访问打开设备失败");
								//m_strDataInfo+="读访问打开设备失败\r\n";
							}
							m_stHidDev.hWriteHandle = CreateFile(m_stHidDev.strDevPathName,
								GENERIC_WRITE,
								FILE_SHARE_READ | FILE_SHARE_WRITE,
								NULL,
								OPEN_EXISTING,
								FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED,
								NULL);
							//m_stHidDev.hWriteHandle = m_stHidDev.hReadHandle;
							if (m_stHidDev.hWriteHandle != INVALID_HANDLE_VALUE)
							{
								
								
							}
							else
							{
								UINT32 u32LastError = GetLastError();
								TRACE("写访问打开设备失败:%d\r\n", u32LastError);
								continue;
							}

读取设备

i32Ret=ReadFile(pHidDev->hReadHandle,
                        u8Buffer,/*pHidDev->u8ReadReportBuffer,*/
                                                    33,
                                                    &Length,
                                                    &(pHidDev->ReadOverlapped));    

写设备,采用可变长度。

i32Ret = WriteFile(pHidDev->hWriteHandle,
                        u8Buffer,
                        u8BufLen,//7--old 跳舞毯//REPORT_PACKET_SIZE,
                        &Length,                        
                        &(pHidDev->WriteOverlapped));

问题1:

u8BufLen为可变长度,写数据不可写入,报参数错误(87)。

解决方案:

通过BUS Bound查,无数据写入。

看别的文章说要写入report ID,又进行尝试。在描述符中增加report ID,还是87错误。

最后解决办法:写入长度参数错误,必须为1+报告描述符中的out的长度。第一个字节深圳过填0,1,2都可以(注意,我的描述符是没有report ID的)。后面的字节为要写入的数据。

此修改后,数据写入正常,BusBound抓到对点的设备节点有out事件,数据与写入数据一致。

i32Ret = WriteFile(pHidDev->hWriteHandle,
						u8Buffer,
						33,//7--old 跳舞毯//REPORT_PACKET_SIZE,
						&Length,						
						&(pHidDev->WriteOverlapped));

问题2:

读出数据卡死,不产生Overlapped事件。

解决方案:

通过BusBound抓数据,母设备的Endpoint上有数据,但对应的HID设备节点无数据。根据问题1,怀疑也是数据长度的问题,将dongle设备的程序进行修改,无论设备上传数据为多少字节,后面都上传32个字节(与报告描述符的输入长度一致),

事情产生成功,注意,读出的数据长度应该为1+报告描述符中的IN的长度。

buffer中第一个字节为报告ID,后面的字节你实际上传的数据,注意不论你描述符是否有报告ID,他都将可以读出来报告ID。

报告ID为0。

注意不定长度的传输在Android USB HID通信中没有问题,Android的通过是通过USB的Interface, Endpoint来进行通信,Windows通信是通过最终的描述符产生的设备节点进行通讯。



版权声明:本文为delin11原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。