STM32 使用 DMA 与环形缓冲区配合时,如何精确计算并避免数据覆盖导致的丢包问题?

· 1 浏览

回答(4)

如果数据量大,考虑使用双缓冲(DMA双缓冲模式),一个缓冲在DMA写入时,另一个供应用读取,彻底消除覆盖风险。
硬件工程师阿强 · 2026-08-27
建议在DMA中断里只更新索引,不处理数据;应用层轮询或使用信号量通知,避免中断中做耗时操作导致丢数据。
码农小刘 · 2026-08-27
用环形缓冲区时,记得把缓冲区大小设为2的幂,这样索引取模可以用位与操作(如size-1),计算更快更安全。
嵌入式老张 · 2026-08-27
精确计算并避免丢包的关键在于维护好读/写指针和缓冲区状态标志。建议使用无符号整数(如uint16_t)表示读写索引,通过减法(写索引-读索引)计算已用空间,避免指针回绕时的溢出问题。同时,在DMA传输完成中断中更新写索引,在应用层读取时更新读索引,确保索引更新与DMA操作同步。为避免覆盖,需保证写索引不会追上读索引,即预留至少一个字节的空闲空间(环形缓冲区容量-1),并在写索引即将追上读索引时暂停DMA或丢弃新数据。实操上,可配置DMA为循环模式,并利用半传输/传输完成中断分别处理前半和后半缓冲区,配合双缓冲或乒乓缓冲进一步提高效率。此外,建议使用内存屏障(__DMB)确保索引更新顺序,并在读取数据前检查缓冲区非空。
mcuku 阿沐 · 2026-08-27