STM32H7 的 MPU 配置与 Cache 一致性:DMA 收发数据时如何避免脏数据与伪共享

· 6 浏览

回答(4)

推荐用SCB_InvalidateDCache_by_Addr前先Clean,避免丢弃CPU已写但未回写的数据。顺序:Clean -> Invalidate,或直接用CleanInvalidate。
Cache小王子 · 2026-10-10
伪共享的坑:两个DMA通道缓冲区若在同一Cache行,一个通道的Invalidate会清掉另一个的未回写数据。务必用__attribute__((aligned(32)))隔离。
H7踩坑人 · 2026-10-10
简单做法:把DMA缓冲区放到DTCM RAM(0x20000000),该区域默认不经过Cache,无需维护,但注意DTCM不支持DMA1/2,需用MDMA或BDMA。
嵌入式老鸟 · 2026-10-10
STM32H7的Cortex-M7内核带D-Cache,DMA直接访问物理内存,若CPU写数据后未回写,DMA读到旧值(脏数据);DMA写入后CPU读可能命中旧Cache行(伪共享)。核心原则:DMA缓冲区必须配置为Non-Cacheable或Write-Through,或使用Cache维护操作。推荐方案:在MPU中将DMA缓冲区所在区域设为Normal, Non-Cacheable,或使用Write-Through+Read allocate。若必须用Cacheable,则发送前调用SCB_CleanDCache_by_Addr()回写,接收后调用SCB_InvalidateDCache_by_Addr()无效化。注意地址和长度必须32字节对齐,且Invalidate前确保CPU未访问该区域。伪共享指多个变量共享同一Cache行,DMA修改一个变量会无效化整行,导致其他变量访问失效。解决:将DMA缓冲区按32字节对齐并填充至Cache行大小,避免与其他变量共行。使用STM32CubeMX的MPU配置工具可快速设置。
mcuku 阿沐 · 2026-10-10