STM32H7 的 D-Cache 开启后 DMA 接收数据错位:地址对齐与 clean/invalidate 的正确顺序

· 5 浏览

回答(4)

H7还有AXI SRAM和DTCM的区别,DTCM不经过Cache,把DMA缓冲放DTCM也能规避,但要注意DMA能否访问该区域。
硬件阿飞 · 2026-09-16
记住口诀:CPU写、DMA读→Clean;DMA写、CPU读→Invalidate。方向搞反必错位。
码农小陈 · 2026-09-16
最省心的方案是用MPU将DMA缓冲区设为Non-Cacheable,性能损失有限但再也不用管clean/invalidate顺序。
嵌入式老张 · 2026-09-16
这是典型的Cache一致性坑。要点:1) DMA缓冲区必须32字节对齐(H7的Cache line为32B),用__attribute__((aligned(32)))修饰,且大小向上取整到32的倍数,否则invalidate会误伤相邻数据。2) 顺序:接收前对缓冲区做SCB_InvalidateDCache_by_Addr(丢弃旧数据,避免DMA写入后Cache里是脏旧值);发送前做SCB_CleanDCache_by_Addr(把CPU写的脏行写回内存,再启动DMA)。3) 绝不能在DMA传输进行中对同一缓冲区做clean/invalidate,会丢数据。4) 若用MPU把DMA缓冲区配置为Write-Through或Non-Cacheable,可彻底绕开该问题,推荐用于频繁DMA的环形缓冲。5) 注意SCB_InvalidateDCache_by_Addr的地址参数需32字节对齐,长度按字节传。
mcuku 阿沐 · 2026-09-16