根据您描述的情况及提供的代码片段,问题可能出在接收数据回调机制未正确配置或处理上。以下是详细分析和解决方案:
问题根源分析
发送正常、接收异常
- Bus Hound 能捕获双向数据 → 设备端点配置正确,USB协议层通信正常。
- USB调试助手只能发送 → 设备接收逻辑未正确响应主机数据。
代码缺失关键部分
您的代码只展示了发送逻辑(hiddev->parent.write),但未包含接收数据的回调处理,这是无法接收数据的直接原因。
HID设备的接收机制
HID设备接收数据需满足:
- 配置 OUT端点(主机→设备)。
- 注册 接收回调函数,在数据到达时处理。
- 提前 提交接收缓冲区(类似
rt_usb_hid_ep_read())。
解决方案
步骤1:确认端点描述符配置
确保HID描述符中包含 OUT端点(方向:Host→Device):
// 示例:OUT端点描述符 (方向OUT, 中断传输)
static struct uep_descriptor hid_ep_out = {
.bLength = USB_DESC_LENGTH_ENDPOINT,
.bDescriptorType = USB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x01, // EP1 OUT (bit7=0表示OUT)
.bmAttributes = USB_EP_ATTR_INT,
.wMaxPacketSize = 64, // 根据实际修改
.bInterval = 0x0A,
};
步骤2:实现接收回调函数
添加数据接收完成时的回调处理:
/* 接收回调函数 */
static rt_err_t hid_rx_callback(rt_device_t dev, void *buffer, rt_size_t size) {
// 1. 打印接收到的数据
ulog_hexdump("hiddev_recv", 16, buffer, size);
// 2. 重新提交缓冲区等待下一次接收
rt_usb_hid_ep_read(dev, buffer, size);
return RT_EOK;
}
步骤3:初始化时注册回调并启动接收
在设备初始化阶段:
// 注册接收回调
rt_usb_hid_set_rx_complete(hiddev, hid_rx_callback);
// 分配缓冲区并启动接收
static rt_uint8_t rx_buff[64]; // 大小需匹配端点wMaxPacketSize
rt_usb_hid_ep_read(&hiddev->parent, rx_buff, sizeof(rx_buff));
步骤4:完整示例代码结构
/* HID设备接收处理示例 */
static struct rt_usb_hid_device hiddev;
static rt_uint8_t rx_buff[64]; // 接收缓冲区
/* 接收回调 */
static rt_err_t hid_rx_callback(rt_device_t dev, void *buffer, rt_size_t size) {
ulog_hexdump("RX Data", 16, buffer, size); // 打印数据
rt_usb_hid_ep_read(dev, buffer, size); // 重新提交缓冲区
return RT_EOK;
}
void hid_init() {
// ... 初始化HID描述符等
// 注册回调
rt_usb_hid_set_rx_complete(&hiddev, hid_rx_callback);
// 启动接收
rt_usb_hid_ep_read(&hiddev.parent, rx_buff, sizeof(rx_buff));
}
void main_thread() {
while (1) {
// 发送数据 (原始代码)
hiddev.parent.write(&hiddev.parent, 0, sendBuff, sizeof(sendBuff));
rt_thread_mdelay(500);
}
}
关键检查点
端点匹配性
- 确保OUT端点的地址(如
0x01)与rt_usb_hid_ep_read()调用的端点一致。
缓冲区生命周期
- 接收缓冲区(如
rx_buff)必须是全局或静态变量,确保在回调期间有效。
USB调试助手设置
- 选择正确的 OUT端点(如EP1 OUT)发送数据:

(实际界面可能不同,但需指定OUT端点)
HID报告描述符(可选)
- 如果主机要求特定报告格式,请在报告描述符中明确定义输入(Input)和输出(Output)用途。
调试建议
添加接收日志
在hid_rx_callback()中加入日志,确认是否触发回调:
rt_kprintf("[HID] Received %d bytesn", size);
端点方向验证
在Bus Hound中检查主机发送的数据是否确实发送到OUT端点(如EP1 OUT)。
备用工具测试
使用libusb或PyUSB编写简单脚本测试接收,排除调试工具兼容性问题。
完成上述步骤后,设备应能正常接收并处理主机下发的数据。如仍存在问题,请检查RT-Thread的USB HID驱动层日志(打开UCLASS_USBHOST和UCLASS_USBDEVICE调试选项)。
根据您描述的情况及提供的代码片段,问题可能出在接收数据回调机制未正确配置或处理上。以下是详细分析和解决方案:
问题根源分析
发送正常、接收异常
- Bus Hound 能捕获双向数据 → 设备端点配置正确,USB协议层通信正常。
- USB调试助手只能发送 → 设备接收逻辑未正确响应主机数据。
代码缺失关键部分
您的代码只展示了发送逻辑(hiddev->parent.write),但未包含接收数据的回调处理,这是无法接收数据的直接原因。
HID设备的接收机制
HID设备接收数据需满足:
- 配置 OUT端点(主机→设备)。
- 注册 接收回调函数,在数据到达时处理。
- 提前 提交接收缓冲区(类似
rt_usb_hid_ep_read())。
解决方案
步骤1:确认端点描述符配置
确保HID描述符中包含 OUT端点(方向:Host→Device):
// 示例:OUT端点描述符 (方向OUT, 中断传输)
static struct uep_descriptor hid_ep_out = {
.bLength = USB_DESC_LENGTH_ENDPOINT,
.bDescriptorType = USB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x01, // EP1 OUT (bit7=0表示OUT)
.bmAttributes = USB_EP_ATTR_INT,
.wMaxPacketSize = 64, // 根据实际修改
.bInterval = 0x0A,
};
步骤2:实现接收回调函数
添加数据接收完成时的回调处理:
/* 接收回调函数 */
static rt_err_t hid_rx_callback(rt_device_t dev, void *buffer, rt_size_t size) {
// 1. 打印接收到的数据
ulog_hexdump("hiddev_recv", 16, buffer, size);
// 2. 重新提交缓冲区等待下一次接收
rt_usb_hid_ep_read(dev, buffer, size);
return RT_EOK;
}
步骤3:初始化时注册回调并启动接收
在设备初始化阶段:
// 注册接收回调
rt_usb_hid_set_rx_complete(hiddev, hid_rx_callback);
// 分配缓冲区并启动接收
static rt_uint8_t rx_buff[64]; // 大小需匹配端点wMaxPacketSize
rt_usb_hid_ep_read(&hiddev->parent, rx_buff, sizeof(rx_buff));
步骤4:完整示例代码结构
/* HID设备接收处理示例 */
static struct rt_usb_hid_device hiddev;
static rt_uint8_t rx_buff[64]; // 接收缓冲区
/* 接收回调 */
static rt_err_t hid_rx_callback(rt_device_t dev, void *buffer, rt_size_t size) {
ulog_hexdump("RX Data", 16, buffer, size); // 打印数据
rt_usb_hid_ep_read(dev, buffer, size); // 重新提交缓冲区
return RT_EOK;
}
void hid_init() {
// ... 初始化HID描述符等
// 注册回调
rt_usb_hid_set_rx_complete(&hiddev, hid_rx_callback);
// 启动接收
rt_usb_hid_ep_read(&hiddev.parent, rx_buff, sizeof(rx_buff));
}
void main_thread() {
while (1) {
// 发送数据 (原始代码)
hiddev.parent.write(&hiddev.parent, 0, sendBuff, sizeof(sendBuff));
rt_thread_mdelay(500);
}
}
关键检查点
端点匹配性
- 确保OUT端点的地址(如
0x01)与rt_usb_hid_ep_read()调用的端点一致。
缓冲区生命周期
- 接收缓冲区(如
rx_buff)必须是全局或静态变量,确保在回调期间有效。
USB调试助手设置
- 选择正确的 OUT端点(如EP1 OUT)发送数据:

(实际界面可能不同,但需指定OUT端点)
HID报告描述符(可选)
- 如果主机要求特定报告格式,请在报告描述符中明确定义输入(Input)和输出(Output)用途。
调试建议
添加接收日志
在hid_rx_callback()中加入日志,确认是否触发回调:
rt_kprintf("[HID] Received %d bytesn", size);
端点方向验证
在Bus Hound中检查主机发送的数据是否确实发送到OUT端点(如EP1 OUT)。
备用工具测试
使用libusb或PyUSB编写简单脚本测试接收,排除调试工具兼容性问题。
完成上述步骤后,设备应能正常接收并处理主机下发的数据。如仍存在问题,请检查RT-Thread的USB HID驱动层日志(打开UCLASS_USBHOST和UCLASS_USBDEVICE调试选项)。
举报