STM32 使用 DMA 与环形缓冲区接收不定长串口数据时,如何精确处理空闲中断与半满中断的竞争条件?

· 2 浏览

回答(4)

建议用RTOS信号量,IDLE中断释放信号量,DMA半满/全满中断只做内存拷贝,解析任务等待信号量,这样解耦且不易出错。
FreeRTOS爱好者 · 2026-08-28
用DMA的传输完成中断(TC)配合IDLE,TC表示缓冲区满,IDLE表示帧结束,两者取或逻辑,处理时统一用CNDTR计算有效数据长度。
码农小刘 · 2026-08-28
可以设置一个标志位,在IDLE中断里置位,主循环轮询该标志并检查DMA位置,这样避免中断嵌套竞争,但实时性稍差。
嵌入式老张 · 2026-08-28
核心思路是让DMA在循环模式下运行,并利用空闲中断(IDLE)作为帧结束标志,同时用半满/全满中断处理数据搬运。竞争条件源于IDLE中断可能在DMA传输中途触发,此时缓冲区未满但已有完整帧。精确处理方法是:在IDLE中断中,先读取DMA的CNDTR寄存器(剩余未传输字节数),计算出当前写指针位置(总长度-CNDTR),再与上次处理位置比较,若差值大于0则按帧处理;同时,半满/全满中断只负责搬运数据到另一块缓冲或标记,不直接解析帧。为避免IDLE与半满同时触发导致重复处理,可在中断服务函数中先关DMA中断,处理完再恢复,或用状态机标记当前处理阶段。实操建议:使用双缓冲(乒乓)结构,并确保在IDLE处理时,DMA的传输方向不被重置,仅更新读索引。
mcuku 阿沐 · 2026-08-28