Pi Pico W(MicroPython):如何通过UART启用CTRL+C功能?
解决Pi Pico W通过DupTerm(UART/WebREPL)无法用CTRL+C终止无限循环的问题
核心原因
MicroPython的sys.dupterm()默认仅复制普通输入输出到附加通道(UART/WebREPL),不会将CTRL+C(ASCII 0x03)这类控制字符转发到主REPL的中断处理逻辑。USB CDC能触发中断是因为它直接绑定了底层的VM中断信号,而DupTerm通道没有这个默认机制。
可行解决方案
1. 自定义DupTerm包装类,捕获CTRL+C并触发中断
通过包装UART/WebREPL的输入对象,在读取数据时检测CTRL+C字符,主动触发KeyboardInterrupt中断:
import micropython import sys from machine import UART # 预分配紧急异常缓冲区,避免中断时无法抛出异常 micropython.alloc_emergency_exception_buf(100) def trigger_ctrl_c(_): raise KeyboardInterrupt class DupTermCtrlWrapper: def __init__(self, stream): self.stream = stream def read(self, n): data = self.stream.read(n) if data and b'\x03' in data: # 调度触发中断,避免在read函数中直接抛出异常导致死锁 micropython.schedule(trigger_ctrl_c, None) return data # 转发其他必要方法 def write(self, data): return self.stream.write(data) # 初始化UART并设置包装后的DupTerm uart0 = UART(0, baudrate=9600, tx=0, rx=1) sys.dupterm(DupTermCtrlWrapper(uart0))
说明:WebREPL的处理逻辑类似,只需将UART实例替换为WebREPL的流对象即可。
2. 硬件触发中断方案
如果软件方案不稳定,可通过GPIO外接按钮触发中断,强制终止循环:
import micropython from machine import Pin micropython.alloc_emergency_exception_buf(100) def force_interrupt(pin): raise KeyboardInterrupt # 配置GPIO2为输入,上拉电阻,按下按钮时触发下降沿中断 reset_btn = Pin(2, Pin.IN, Pin.PULL_UP) reset_btn.irq(trigger=Pin.IRQ_FALLING, handler=force_interrupt)
使用:当设备陷入无限循环时,按下外接按钮即可触发KeyboardInterrupt,等效于CTRL+C。
3. 定制MicroPython固件(进阶)
如果需要长期稳定的解决方案,可以修改MicroPython源码,让DupTerm通道自动处理CTRL+C:
- 在
py/dupterm.c的dupterm_read函数中,检测到0x03字符时,调用mp_keyboard_interrupt()触发主REPL中断。 - 重新编译并烧录定制固件到Pi Pico W。
内容的提问来源于stack exchange,提问作者mostek
相关产品推荐
相关产品推荐

