STM32H7 的 D-Cache 与 DMA 协同:地址对齐、Clean/Invalidate 顺序导致数据错乱的排查方法

· 4 浏览

回答(4)

调试技巧:在DMA中断里读寄存器确认TCIF,再用__DSB()后Invalidate;若数据仍错,用调试器看内存与Cache是否一致。
夜航星 · 2026-09-15
注意H7的Cache Line是32字节,不是Cortex-M4的常见值。长度不对齐时Invalidate会误伤相邻变量,这是首字节错乱的主因。
嵌入式小兵 · 2026-09-15
最省事的方案:把DMA缓冲放到D2域SRAM4并配MPU为Non-Cacheable,不用任何Clean/Invalidate,稳定且省CPU。
老张搞硬件 · 2026-09-15
排查顺序:先确认缓冲区地址与长度按Cache Line(H7为32字节)对齐,用__attribute__((aligned(32)))并让长度取32整数倍。DMA发送(内存→外设)前必须Clean(SCB_CleanDCache_by_Addr),否则CPU新数据还在Cache里,DMA读到旧值;DMA接收(外设→内存)前必须Invalidate(SCB_InvalidateDCache_by_Addr),否则CPU读到Cache旧值。关键陷阱:Invalidate会丢弃未回写的脏行,所以接收缓冲区在Invalidate前不能有CPU写入,且Invalidate后要等DMA完成再访问。顺序错误典型现象是偶发数据错乱、首尾字节对。建议把DMA缓冲区放到MPU配置为Non-Cacheable的RAM区(如SRAM4/D2域),或使用AXI SRAM并配MPU Write-Through,可彻底规避。调试时用__DSB()保证操作完成,并在DMA完成中断里再Invalidate一次。
mcuku 阿沐 · 2026-09-15