ARMv7嵌入式Linux串口COM冻结,仅Ctrl+C可恢复的排查咨询
终端进程状态排查:Ctrl+C能恢复输出,说明问题出在终端接收进程而非硬件死锁。冻结时执行
ps aux | grep /dev/ttySx(替换为你的实际串口号,如ttyUSB0),查看进程状态是否为D(不可中断睡眠)或T(暂停);再用strace -p <进程PID>跟踪系统调用,确认进程卡在哪个操作上(如read/write阻塞)。用户态输出缓冲区同步问题:std::cout默认与C stdio流同步,多进程并发输出时易引发缓冲区竞争。可在每个C++应用中关闭同步:
std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr);,并在每次输出后手动调用std::cout.flush();(或用std::endl替代\n),避免缓冲区堆积导致输出阻塞。内核驱动与流控异常:检查内核日志(
dmesg -w),看冻结前后是否有UART相关报错(如uart: port error、锁竞争提示);用stty -F /dev/ttySx -a查看当前流控设置,尝试关闭硬件流控:stty -F /dev/ttySx -crtscts,排除流控异常导致的驱动阻塞。终端信号与控制模式异常:Ctrl+C发送的SIGINT能恢复,说明终端进程可能被误发的信号(如SIGSTOP)暂停,或终端控制模式被篡改。排查系统中是否有监控/调试进程向终端进程发送异常信号;同时检查是否有应用调用
tcsetattr修改termios参数,导致终端进入raw等异常模式引发阻塞。核内锁竞争排查:双核场景下多进程并发写串口可能触发内核驱动锁竞争。冻结时执行
lsof /dev/ttySx列出所有打开串口的进程,再用cat /proc/locks查看内核锁持有状态,确认是否存在串口相关锁的等待阻塞。硬件与电源管理排查:检查USB串口设备的电源管理设置,执行
cat /sys/bus/usb/devices/<设备路径>/power/control,若为auto则设置为on禁用自动休眠;尝试更换串口线或测试其他端口,排除硬件接触不良的小概率问题。
内容的提问来源于stack exchange,提问作者Almog Stern

