|
|
我来修这个热插拔问题。大概率是程序打开 /dev/ttyACM0 后,USB 拔出再插入时旧 fd 没有及时重连,或者 2 秒无帧后没有主动关闭重扫。我要在串口线程里加“长时间无有效帧则关闭当前端口并重新扫描”。
现场现象确认了:USB 重插后内核有时会变成 /dev/ttyACM1,现在又回到 /dev/ttyACM0;程序需要在无数据/读错误时主动关闭旧串口并重新扫描所有 ttyACM*。我现在加自动重连逻辑并部署。
先修复一个潜在误重连点:刚打开串口后可能要等几秒才有第一帧,不能 3 秒就断;我改成 8 秒无有效帧才重连。
已部署自动重连版。现在需要你实际拔插一次 USB 串口,我这边会等 20 秒后检查是否自动重新打开新枚举的 /dev/ttyACM0 或 /dev/ttyACM1,并恢复收帧。
自动重连逻辑已经生效了,但检查发现它现在会反复重开同一个 /dev/ttyACM0;如果热插拔后真实数据口变成 /dev/ttyACM1,程序可能还会优先打开旧的 /dev/ttyACM0。我继续改成:某个口 8 秒无有效帧就临时跳过该口,自动尝试下一个 ttyACM/ttyUSB。
现在看到自动重连已经在跑,但重开 /dev/ttyACM0 后仍然没有恢复收帧。下一步不是单纯重扫端口,而是串口重新打开时要重新拉起 DTR/RTS 控制线;USB CDC 设备热插拔后常见问题就是设备枚举了,但没有重新进入发送状态。我继续加这个处理。
我现在的结论先说清:程序侧已经能检测“无帧超时”并反复重连,也重新拉了 DTR/RTS,但设备端仍没有恢复发数据。也就是说问题不只是旧 fd 没关闭,可能是 USB 设备热插拔后枚举成功但发送端没重新启动。我继续做设备侧验证:直接看 /dev/ttyACM0 是否有原始数据,如果没有,就加 USB 端口软复位/重新枚举兜底。
DTR/RTS 已加,但当前 /dev/ttyACM0 仍然没有任何原始数据,手工 dd 读也是 0 字节。这说明热插拔后 USB 枚举还在,但发送端没有恢复输出。我要再加一个兜底:连续多次重连仍无帧时,对 USB 设备做一次软复位/重新枚举,然后再打开串口。
我找到 USB sysfs 路径了:当前串口对应 usb4/4-1/4-1:1.0/tty/ttyACM0。继续加程序内兜底:连续 3 次“打开成功但 8 秒无帧”后,自动对这个 USB 设备执行一次 unbind/bind 软复位,再重新扫描串口。
我继续把“连续无帧后 USB 软复位”这一版编译部署。这个兜底会在打开串口但连续多次 8 秒无帧时,对对应 USB 设备做 unbind/bind,然后重新枚举再打开。
|
|