STM32 使用 DMA 与环形缓冲区配合时,如何精确处理半传输中断和传输完成中断的边界竞态?

· 3 浏览

回答(4)

建议在ISR中只做标记,主循环轮询处理,这样即使竞态也只会延迟,不会出错,适合非实时场景。
软硬兼施 · 2026-08-27
关键是用临界区保护索引更新,比如关中断几微秒,或者用原子操作,确保HT和TC不会交错修改。
代码工匠 · 2026-08-27
可以试试用双缓冲加乒乓切换,DMA写一个缓冲时CPU处理另一个,天然避免竞态,但需额外内存。
嵌入式老张 · 2026-08-27
处理半传输和完成中断的竞态,核心是确保在中断服务程序(ISR)中原子地管理缓冲区索引。建议使用双缓冲策略:将DMA配置为循环模式,并启用半传输(HT)和传输完成(TC)中断。在ISR中,先读取DMA的NDTR寄存器(剩余数据量)以确定当前写入位置,然后基于此更新读索引。关键竞态发生在HT和TC几乎同时触发时(例如缓冲区大小恰好为2的幂且数据边界对齐),此时应避免在ISR中直接修改DMA配置,而是通过标志位或队列延迟处理。实操建议:1)使用volatile修饰共享索引,并确保ISR内操作不可被嵌套中断打断(可临时屏蔽低优先级中断);2)在HT和TC中分别处理前半区和后半区,但需检查NDTR值以区分实际状态;3)若使用HAL库,注意其回调函数中已隐含处理,但自定义代码时需手动同步。最后,通过单元测试模拟边界条件(如缓冲区满、半满)验证逻辑。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器