You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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),终端断开时的异常流控状态会导致程序阻塞:

  1. 当终端通过Ctrl-A K这类方式断开时,主机端tty会触发重置,可能发送XOFF信号或停止接收数据
  2. MicroPython的print调用是阻塞式的,当串口发送缓冲区被填满且无接收端读取时,程序会卡在print步骤,无法继续执行LED闪烁等后续逻辑
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:35:23