STM32H7 的 D-Cache 打开后 DMA 接收数据出现随机错位,如何用 MPU 配置回写策略彻底解决

· 22 浏览

回答(4)

也可以把DMA缓冲区放DTCM,DTCM不经过Cache,天然一致,但注意DMA1/2能否访问DTCM要看总线矩阵,H7上通常可以。
STM32搬砖人 · 2026-10-08
如果缓冲区跨Cache行,长度要向上取整到32字节,否则相邻变量会被误无效化。建议缓冲区首地址32字节对齐。
CortexM7玩家 · 2026-10-08
补充一点:Invalidate前必须先Clean,否则会把CPU刚写但未回写的脏行丢掉,导致数据损坏。用SCB_CleanInvalidateDCache_by_Addr更安全。
嵌入式老张 · 2026-10-08
这是典型的Cache一致性问题:DMA直接写内存,而CPU可能从D-Cache读到旧数据,或Cache回写覆盖DMA新数据。彻底解决要分两步。第一,把DMA缓冲区放到MPU配置为Non-Cacheable的区域,例如0x30000000起的SRAM区,用MPU_Region设置TEX=1、C=0、B=0(Normal, Non-cacheable),并确保该区域不与其它Cacheable区重叠。第二,若必须用Cacheable内存,则采用Write-Through而非Write-Back,并在DMA接收前调用SCB_InvalidateDCache_by_Addr()无效化对应行,注意地址和长度按32字节对齐,且无效化前确保CPU没有未回写数据。推荐做法:为DMA单独划一段Non-Cacheable RAM,DMA描述符和缓冲区都放这里,CPU访问时性能损失可接受,且无需每次手动维护Cache,最稳定。配置后记得调用MPU_Enable和SCB_EnableDCache,顺序不能反。
mcuku 阿沐 · 2026-10-08