如何通过USB设备描述符让主机默认将USB设备power/control设为on?
解决方案
核心结论
可以通过调整USB设备描述符引导主机减少自动挂起行为,但更可靠的方式是结合udev规则直接持久化设置power/control为on。
一、调整USB设备描述符
修改V-USB中的设备描述符,重点调整以下字段:
1. 设备电源属性(bmAttributes)
在USB设备描述符的bmAttributes字段中开启**远程唤醒(Remote Wakeup)**位:
- USB 2.0规范中,
bmAttributes的位6对应远程唤醒功能,设为1表示设备支持唤醒主机;位5设为0表示设备为总线供电(符合你的散热器场景)。 - 最终
bmAttributes的值应设为0x40(二进制01000000)。 - 主机识别到设备支持远程唤醒后,通常会放宽自动挂起策略,避免误挂起需要唤醒主机的设备。
2. 设备类/子类/协议
如果上述调整效果有限,可以尝试将设备类设为Linux内核默认不会自动挂起的类型:
- 例如设为
0x09(Hub类),但需注意模拟Hub可能带来的其他行为影响; - 或保留自定义类(
0xFF),同时确保描述符中明确标注设备需要持续供电的特性。
二、主机端udev规则持久化设置
仅靠描述符可能无法完全覆盖Linux的USB电源管理策略,因此推荐通过udev规则强制设置:
- 创建udev规则文件:
/etc/udev/rules.d/99-usb-cooler.rules - 写入以下内容(替换为你的设备VID和PID):
SUBSYSTEM=="usb", ATTRS{idVendor}=="0123", ATTRS{idProduct}=="4567", ATTR{power/control}="on" - 重新加载udev规则:
sudo udevadm control --reload-rules && sudo udevadm trigger
此后每次插拔设备,系统都会自动将/sys/bus/usb/devices/xxx/power/control设为on,无需手动操作。
三、排除不可行方案
你提到的发送dummy数据模拟通信确实不可行:若主机未读取数据,设备的USB发送缓冲区会很快溢出,导致通信异常甚至设备断开连接,因此不建议采用。
补充说明
你已实现的通过SoF数据包检测主机挂起的功能不受上述调整影响:当主机真正进入挂起状态时,SoF数据包停止发送,设备仍能正常进入休眠;而主机正常运行时,设备不会被自动挂起,保持工作状态。
内容的提问来源于stack exchange,提问作者Bogdan Mircea
相关产品推荐
相关产品推荐

