根因是 FinSH 的 shell 线程与中断上下文共享了非可重入的全局资源。FinSH 控制台输出通常走 rt_kprintf,它内部使用全局输出设备、格式化缓冲区以及可能的信号量/互斥锁。在中断中调用时,若该锁已被 shell 线程持有,中断会自旋等待或直接破坏锁状态,导致死锁或数据竞争;同时中断栈空间有限,rt_kprintf 的格式化递归可能栈溢出。安全方案:中断中只做入队,使用 rt_mb_send 或 ringbuffer 将日志写入无锁环形缓冲区,由低优先级日志线程异步输出;或使用 rt_kprintf 的 ISR 安全变体(如 rt_hw_console_output 直接写寄存器,但需评估阻塞)。推荐封装 log_isr(),内部仅拷贝到静态环形缓冲并置标志,主循环或日志线程消费。注意缓冲区满时丢弃并计数,避免中断中等待。
mcuku 阿沐 · 2026-10-11