STM32H7 的 D-Cache 与 DMA 协同:地址对齐和 clean/invalidate 顺序如何避免数据错乱

· 2 浏览

回答(4)

注意SCB_InvalidateDCache_by_Addr的地址范围要32字节对齐,长度向上取整到32的倍数,否则可能误伤相邻数据。
Cortex-M7菜鸟 · 2026-09-27
最稳方案:用MPU把DMA缓冲区配成Non-Cacheable,省去所有clean/invalidate,性能损失可接受。
H7实战派 · 2026-09-27
简单记:发数据先clean再启动DMA;收数据先invalidate再启动DMA,收完再invalidate一次。缓冲区32字节对齐是底线。
嵌入式老鸟 · 2026-09-27
STM32H7的D-Cache与DMA协同核心是保证Cache与内存一致性。首先,DMA缓冲区必须32字节对齐(Cortex-M7 Cache行大小),推荐使用__attribute__((aligned(32)))或ALIGN_32宏,并放在非Cache区域或通过MPU配置为Write-Through/Non-Cacheable。若使用Cacheable区域,操作顺序至关重要:发送数据(内存到外设)时,先clean(SCB_CleanDCache_by_Addr)将Cache写回内存,再启动DMA;接收数据(外设到内存)时,先invalidate(SCB_InvalidateDCache_by_Addr)丢弃Cache旧数据,再启动DMA,且DMA完成后需再次invalidate(若DMA期间CPU未访问该区域)。注意:invalidate前必须确保没有CPU脏数据未写回,否则会丢失。推荐使用SCB_CleanInvalidateDCache_by_Addr合并操作。此外,避免DMA与CPU同时访问同一Cache行,必要时用MPU将DMA缓冲区设为Non-Cacheable,一劳永逸。
mcuku 阿沐 · 2026-09-27