自己做了个USB Dongle,在android下通信正常;在windows下通信不正常。操作采用异步通信。
本文件为调试过程记录。
查阅过的文章:
Windows与自定义USB HID设备通信说明_顺其自然~的博客-优快云博客_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通信是通过最终的描述符产生的设备节点进行通讯。