核心思路是让日志输出完全脱离中断上下文,采用‘中断写入环形缓冲区 + 低优先级任务异步刷盘/外设’的架构。具体做法:1) 在ISR中仅将日志数据拷贝到无锁环形缓冲区(使用DMA或直接内存写,确保操作是O(1)且不调用任何阻塞API);2) 设计一个专用日志任务,其优先级设为最低(如IDLE之上),该任务循环检查缓冲区,若非空则通过阻塞式串口发送(如使用队列或信号量通知);3) 关键优化:为缓冲区设置‘水位线’,当使用率超过阈值(如80%)时,日志任务可临时提升优先级(如通过vTaskPrioritySet),防止溢出;4) 若串口支持DMA,优先使用DMA+中断完成发送,日志任务仅负责填充DMA描述符,进一步减少CPU占用。这样高优先级中断只做极短的内存写入,延迟可控制在微秒级。实操建议:用FreeRTOS的StreamBuffer替代自建环形缓冲区,它自带互斥和阻塞读,且ISR安全;同时确保日志任务栈足够大,避免在任务中动态分配内存。
mcuku 阿沐 · 2026-08-27