TeenyUSB
TeenyUSB copied to clipboard
composite 示例程序修改为只有一个 HID 设备后,suspend & resume 后的第二次 SET_IDLE 设备端无应答
对应提交: 当前最新提交 9cd8bda1518068d3fbd1e6173ce4e3c76d8e787a (Nov 27, 2020) 对应项目: sample/composite/composite.uvprojx
问题描述:
composite 示例项目的原始程序可正常工作,但修改为只有一个 HID 设备后,在 PC 向设备发送 suspend 和 resume 请求后,第二次 SET_IDLE 请求设备端响应不正常。如果设备插入到了 USB Hub 而不是 Root Hub 上,后续 PC 发送 HID 数据设备端也没有响应。
复现步骤:
- 使用附件 composite_hid_only_modified_files.zip 中的文件覆盖 sample/composite 目录下的原有文件,编译下载到 STM32F072C8T6/CBT6 中
- 将设备插入到连接到 PC 的 USB Hub 上 (若只看 SET_IDLE 请求的问题,插到 Root Hub 的接口上也可以)
- 在 PC 识别到 USB HID 设备后,等待 10s 左右。打开 USB HID 调试工具 (我使用的是“单片机多功能调试助手”),查找和打开该 USB 设备,尝试发送数据。
- 在第 3 步中点击查找后,PC 就应该向设备发出了 suspend & resume 后的第二次 SET_IDLE 请求,抓包可以看到此事物没有来自设备的应答。
附件:
composite_hid_only_modified_files.zip - composite 示例项目修改后的文件
composite_sample_captured_packets.zip - 使用 USB Packet Viewer 工具所抓的包:
- composite_sample_01_original_on_usb_hub.upv:
使用原有 composite 示例程序,设备接在 USB Hub 上时所抓的包。PC 识别到设备后,一直有通信,未 suspend, 整体正常 - composite_sample_02_hid_only_on_usb_hub.upv:
使用修改为只有一个 HID 设备后的 composite 示例程序,设备接在 USB Hub 上时所抓的包。14s 处在 suspend & resume 后 PC 发送的第二次 SET_IDLE 请求未收到应答,USB Packet Viewer 显示这些事物的状态为 incomplete。25s 处的后续 PC 端发送 HID 数据的包解析出来也不正常。 - composite_sample_03_hid_only_on_root_hub.upv:
使用程序和 composite_sample_02_hid_only_on_usb_hub.upv 相同,但设备直接接在 Root Hub 上。16s 处的 SET_IDLE 仍然为 incomplete 状态,但从 16.837s 处的 Get Descriptor 请求开始恢复正常,HID 数据可正常发送。 - composite_sample_02_hid_only_on_usb_hub_device_info.txt 和 composite_sample_03_hid_only_on_root_hub_device_info.txt:
使用 UsbTreeView 工具查看到的,在插入到 USB Hub 和 Root Hub 时的设备信息。一个主要区别是,在插入到 USB Hub 时 Power State 为 D0 (supported: D0, D2, D3, wake from D0, wake from D2), 插入到 Root Hub 时 Power State 为 D0 (supported: D0, D3, wake from D0)。
另外我自己的项目用的还是 0.2_old_style 版本的文件,为了提交问题就用 master 分支的最新版本测试了一下,两个版本在这个问题上的现象一样。
我这里再附一个对我手头一个正常的 USB HID 设备抓的包,使用的是 STM32CubeMX 生成的 Custom HID Device 代码。 我对 USB 协议不太熟悉,从抓包结果中看 2.280s 后应该也 suspend 了,但之后 18s 处的 SET_IDLE 请求和后续的通信都正常。
我自己在 Keil 中调试,设备上电后枚举过程中能正常进入 tusb_hid_device_request() 函数,但 suspend & resume 后 PC 第二次发 SET_IDLE 和之后的其他 setup 请求时,就一直没有进入过 tusb_hid_device_request() 函数。
感谢你反馈的问题,TeenyUSB的电源管理部分没有进行过测试。根据你反馈的问题很有可能是设备收到resume信号后没有正确地配置芯片工作模式导致的。