Raspberry Pico W断开UART终端后MicroPython程序冻结求助
Raspberry Pi Pico W MicroPython程序断开终端后冻结问题排查与解决
问题现象
- 部署了包含LED闪烁+print计数功能的
main.py,USB供电时程序运行正常 - 通过
screen /dev/ttyACM0 115200连接终端时,LED持续闪烁,能正常接收计数输出 - 按
Ctrl-A K断开screen后,约15秒LED停止闪烁,程序冻结;重新连接终端后程序恢复,但计数增长远慢于实际时长 - 移除代码中的
print语句后,断开终端程序不再冻结 - 测试picocom时:
Ctrl-A Ctrl-Q断开仍会触发冻结,Ctrl-A Ctrl-X断开则正常(后者不执行tty重置操作) - 对应功能的C语言版本程序无此问题;提升
print的输出频率或内容量会更快触发冻结
原因分析
MicroPython的USB CDC串口实现默认启用了软件流控(XON/XOFF),终端断开时的异常流控状态会导致程序阻塞:
- 当终端通过
Ctrl-A K这类方式断开时,主机端tty会触发重置,可能发送XOFF信号或停止接收数据 - MicroPython的
print调用是阻塞式的,当串口发送缓冲区被填满且无接收端读取时,程序会卡在print步骤,无法继续执行LED闪烁等后续逻辑 - C语言版本无此问题,是因为C代码通常会将串口配置为非阻塞模式,或不依赖主机端的流控状态
解决方案
1. 设置串口为非阻塞输出
直接操作USB CDC串口对象,将输出设为非阻塞模式,避免缓冲区满时阻塞程序:
import machine import time from usb_cdc import console # 配置USB CDC串口为非阻塞模式 console.setblocking(False) led = machine.Pin('LED', machine.Pin.OUT) count = 0 while True: led.toggle() try: # 尝试写入数据,缓冲区满时抛出OSError,直接忽略即可 console.write(f"Count: {count}\n") except OSError: pass count += 1 time.sleep(0.5)
2. 禁用USB CDC软件流控
在boot.py中添加配置,关闭USB CDC的XON/XOFF流控:
import usb_cdc # 启用CDC并禁用软件流控 usb_cdc.enable(console=True, data=True, flow_ctrl=usb_cdc.FLOW_CTRL_NONE)
修改后重启Pico W,串口输出将不再受流控信号影响而阻塞。
3. 使用正确的终端断开方式
如果必须保留阻塞式print,选择不会触发tty重置的断开操作:
- 使用picocom时,用
Ctrl-A Ctrl-X断开终端 - 使用screen时,通过
Ctrl-A :输入quit命令退出,而非Ctrl-A K
4. 升级MicroPython固件
你当前使用的是2022年的不稳定版固件,官方后续版本针对USB CDC的流控逻辑有修复优化,建议升级至最新稳定版(如v1.22及以上)。
内容的提问来源于stack exchange,提问作者Ciro Santilli OurBigBook.com
相关产品推荐
相关产品推荐

