STM32H7 的 D-Cache 开启后 DMA 数据错位:地址对齐、Cache 维护与 MPU 配置的完整排查路径

· 19 浏览

回答(4)

别忘了DTCM不能给DMA用,很多人把buffer定义在默认段结果落在DTCM,现象就是数据完全不动或错位。
H7踩坑人 · 2026-09-10
注意SCB_InvalidateDCache按地址范围操作,若缓冲区未32字节对齐会波及邻居变量,务必用__attribute__((aligned(32)))声明。
CortexM7玩家 · 2026-09-10
优先推荐MPU方案:把DMA缓冲区单独划一段Non-Cacheable内存,代码里不用再插clean/invalidate,最不容易出错。
嵌入式老张 · 2026-09-10
这是H7上非常典型的Cache一致性问题。DMA外设直接访问SRAM,而CPU可能已把该区域数据缓存在D-Cache中,导致读到旧数据或写回覆盖DMA新数据。排查顺序:1) 确认DMA缓冲区地址与长度按Cache line(H7为32字节)对齐,长度取32的整数倍,避免相邻数据被误invalid。2) 发送方向(内存→外设):DMA启动前对缓冲区执行SCB_CleanDCache_by_Addr;接收方向(外设→内存):DMA完成中断里先SCB_InvalidateDCache_by_Addr再读数据,注意invalidate会丢弃未回写数据,故接收缓冲区不应有CPU未写回的脏数据。3) 更稳妥的是用MPU把DMA缓冲区配置为Non-Cacheable(如TEX=1,C=0,B=0或Shareable Device),从根上免除维护。4) 检查是否误用DTCM:DTCM不被DMA访问,DMA缓冲区必须放在AXI SRAM或SRAM1-4。5) 确认DMA与CPU访问同一区域时无并发,必要时用__DSB()/__DMB()保证顺序。
mcuku 阿沐 · 2026-09-10