问题描述
之前由于想体验 rt-thread 的 winusb 于是将USB的协议栈从ST的官方库转到了rt_thread 的USB协议栈,在实现玩代码之后发现, python 的demo 能直接与设备通讯,但是子涵的SDK却不能使用,于是找了网上的测试工具 PortHelper.exe 也是无法交互,这边感觉还是协议配置方面有些问题
最后发现是报告描述符的差异导致的
USAGE_PAGE(1), 0x8c,
USAGE(1), 0x01,
COLLECTION(1), 0x01,
// REPORT_ID(1), HID_REPORT_ID_GENERAL,
REPORT_COUNT(1), RT_USB_DEVICE_HID_GENERAL_IN_REPORT_LENGTH,
USAGE(1), 0x03,
REPORT_SIZE(1), 0x08,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0xFF,
INPUT(1), 0x02,
REPORT_COUNT(1), RT_USB_DEVICE_HID_GENERAL_OUT_REPORT_LENGTH,
USAGE(1), 0x04,
REPORT_SIZE(1), 0x08,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0xFF,
OUTPUT(1), 0x02,
END_COLLECTION(0),
剔除这个报告描述字段,然后在发送的数据中发送内容剔除报告ID
struct hid_report
{
// rt_uint8_t report_id;
rt_uint8_t report[64]; // 之前数据是63个字节
rt_uint8_t size;
};
static rt_size_t _hid_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
struct hid_s *hiddev = (struct hid_s *)dev;
struct hid_report report;
if (hiddev->func->device->state == USB_STATE_CONFIGURED)
{
// report.report_id = pos; // 剔除报告描述符
rt_memcpy((void *)report.report,(void *)buffer,size);
report.size = size;
hiddev->ep_in->request.buffer = (void *)&report; // 直接发送报告的地址
hiddev->ep_in->request.size = (size+1) > 65 ? 65 : size+1;
hiddev->ep_in->request.req_type = UIO_REQUEST_WRITE;
// rt_kprintf("[%d] report_id:%d, size:%d\n", HAL_GetTick(),
// report.report_id, hiddev->ep_in->request.size);
rt_usbd_io_request(hiddev->func->device, hiddev->ep_in, &hiddev->ep_in->request);
return size;
}
return 0;
}
进过在修改之后就可以正常兼容之前的业务软件的,测试工具发送也是正常的 RT_USB_DEVICE_HID_GENERAL_OUT_REPORT_LENGTH 这个现在的长度是64 ,在rt_thread 中对这个长度做了限制只能是63,估计就是这个报告描述符中的 REPORT_ID 占了一个,所以才加的这个限制【全速的HID在之前的认知中数据长度一致是64字节的】