RT-Thread论坛
直播中

李娟

8年用户 1462经验值
私信 关注
[问答]

rtt usb-HID 现在收发数据在 bus hound 里面能看到,用USB调试助手只能发送数据,没法接收数据是怎么回事?


  • while(1)
  •     {
  •                 hiddev->parent.write(&hiddev->parent,5,sendBuff,sizeof(sendBuff));
  •                 ulog_hexdump("hiddev_send_data", 16, sendBuff, sizeof(sendBuff));
  •               rt_thread_mdelay(500);
  •         if(rt_mq_recv(&hiddev->hid_mq, &report, sizeof(report),RT_WAItiNG_FOREVER) < 0)
  •             continue;
  •         HID_Report_Received(&report);

  •     }


收发都正常,就是电脑端调试软件收不到数据

回帖(1)

莎莎miu~

2025-10-13 18:09:08

根据您描述的情况及提供的代码片段,问题可能出在接收数据回调机制未正确配置或处理上。以下是详细分析和解决方案:




问题根源分析




  1. 发送正常、接收异常  



    • Bus Hound 能捕获双向数据 → 设备端点配置正确,USB协议层通信正常。

    • USB调试助手只能发送 → 设备接收逻辑未正确响应主机数据。




  2. 代码缺失关键部分

    您的代码只展示了发送逻辑hiddev->parent.write),但未包含接收数据的回调处理,这是无法接收数据的直接原因。




  3. 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);
    }
}



关键检查点




  1. 端点匹配性  



    • 确保OUT端点的地址(如0x01)与rt_usb_hid_ep_read()调用的端点一致。




  2. 缓冲区生命周期  



    • 接收缓冲区(如rx_buff)必须是全局或静态变量,确保在回调期间有效。




  3. USB调试助手设置  



    • 选择正确的 OUT端点(如EP1 OUT)发送数据:
      USB调试助手设置

      (实际界面可能不同,但需指定OUT端点)




  4. HID报告描述符(可选)  



    • 如果主机要求特定报告格式,请在报告描述符中明确定义输入(Input)和输出(Output)用途。






调试建议




  1. 添加接收日志

    hid_rx_callback()中加入日志,确认是否触发回调:


    rt_kprintf("[HID] Received %d bytesn", size);



  2. 端点方向验证

    在Bus Hound中检查主机发送的数据是否确实发送到OUT端点(如EP1 OUT)。




  3. 备用工具测试

    使用libusbPyUSB编写简单脚本测试接收,排除调试工具兼容性问题。




完成上述步骤后,设备应能正常接收并处理主机下发的数据。如仍存在问题,请检查RT-Thread的USB HID驱动层日志(打开UCLASS_USBHOSTUCLASS_USBDEVICE调试选项)。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分