如何在iMX6ULL开发板上避免挂起恢复后USB设备重置,以加速同VID/PID双设备的恢复过程?
哥们,我先给你捋明白为啥同VID/PID的双设备恢复会变慢:大概率是这俩设备没带唯一的硬件序列号,系统从挂起恢复时,没法靠VID/PID区分它们,只能通过重置设备重新枚举来确认身份,这就硬生生拖慢了恢复速度。下面给你几个针对iMX6ULL Debian系统的实操方案,你可以一步步试:
1. 先查设备有没有唯一序列号(最根本的解决办法)
系统恢复时能精准匹配设备的核心是唯一序列号,先确认你的设备有没有:
- 先通过
lsusb -t列出USB设备的拓扑结构,找到两个设备对应的总线路径(比如1-1.1和1-1.2) - 进入其中一个设备的sysfs节点,查看序列号:
cd /sys/bus/usb/devices/1-1.1/ # 替换成你的设备实际路径 cat serial
如果输出是空的,说明设备固件没带唯一序列号。要是能修改设备固件,给俩设备加上不同的唯一序列号,系统恢复时就能直接匹配,不会触发重置,这是最彻底的解决办法。
2. 给设备加「恢复时不重置」的内核豁免标记
如果没法改设备固件,那就让内核给这个VID/PID的设备开个绿灯,恢复时不执行重置:
方法A:修改内核源码(适合有内核编译环境的情况)
找到内核源码里的drivers/usb/core/quirks.c,在static const struct usb_device_id usb_quirk_list[]数组里加一行:
USB_DEVICE_QUIRK(0xXXXX, 0xYYYY, QUIRK_NO_RESET_RESUME),
把0xXXXX和0xYYYY换成你的设备实际VID和PID,然后重新编译iMX6ULL的内核,烧写到板子里就行。
方法B:通过模块参数设置(适合驱动是可加载模块的情况)
如果你的设备用的是通用驱动(比如usb-storage、usb-serial这类),可以给驱动模块加参数:
- 新建一个modprobe配置文件:
echo "options usb-storage no_reset_resume=1" > /etc/modprobe.d/usb-no-reset.conf
这里的usb-storage要替换成你的设备实际驱动名,然后重启系统,或者重新加载模块:
rmmod usb-storage modprobe usb-storage
3. 让USB Hub挂起时保持端口供电
要是USB Hub在挂起时切断了端口电源,设备会掉电,恢复时必须重新枚举。可以设置让Hub端口一直供电:
- 先通过
lsusb找到Hub的VID/PID(你的是USB2514,对应VID 0x0424,PID 0x2514) - 临时设置端口供电:
# 先找到Hub的设备路径,比如`1-1` echo on > /sys/bus/usb/devices/1-1/power/control
- 想让设置永久生效,就写个udev规则:
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="0424", ATTR{idProduct}=="2514", ATTR{power/control}="on"' > /etc/udev/rules.d/99-usb-hub-power.rules
这样Hub在系统挂起时不会切断端口电源,设备保持唤醒状态,恢复时就不用重置了。
4. 全局禁用USB恢复重置(谨慎使用)
如果上面的方法都不管用,可以试试全局禁用USB恢复时的重置,但这个操作副作用最大,会影响所有USB设备,可能导致部分依赖重置才能正常恢复的设备出问题:
- 在系统的bootargs里添加
usbcore.no_reset_resume=1,比如修改iMX6ULL的U-Boot环境变量:
setenv bootargs ${bootargs} usbcore.no_reset_resume=1 saveenv
重启后生效。
注意事项
- 所有操作前建议备份系统镜像,避免改崩了没法恢复
- 全局禁用重置的副作用最大,优先用设备级的豁免规则
- 测试每个方案后,都要验证挂起恢复流程,确认设备功能正常,同时恢复速度是否提升
备注:内容来源于stack exchange,提问作者jrosa

