STM32H7 的 D-Cache 开启后 DMA 接收数据出现随机错误:地址对齐与 Clean/Invalidate 时序怎么排

· 4 浏览

回答(4)

接收中断里先Invalidate再读,发送前先Clean再启动DMA;顺序反了就是随机错误的根源。
H7调参侠 · 2026-10-08
注意Invalidate是按行操作的,若缓冲区不是32字节对齐,会误伤相邻变量,务必用aligned(32)并检查链接脚本。
Cache踩坑人 · 2026-10-08
最稳方案:用MPU把DMA缓冲区所在SRAM区配成Non-Cacheable,一劳永逸,不用每次手动维护Cache。
嵌入式老张 · 2026-10-08
这是H7上D-Cache与DMA共享SRAM时的经典一致性问题,核心是两点:对齐和Cache维护时序。首先,DMA缓冲区必须按Cache Line大小(H7为32字节)对齐,推荐用__attribute__((aligned(32)))并放在非Cacheable区域或使用MPU配置该区域为Write-Through/Non-Cacheable,这样可彻底避免维护。若必须用Cacheable内存,则接收流程应为:1) DMA启动前,对接收缓冲区执行SCB_InvalidateDCache_by_Addr,且地址和长度都按32字节对齐;2) DMA完成中断中,先Invalidate再读数据,注意Invalidate会丢弃未回写的脏数据,所以若CPU之前写过该缓冲区,必须先Clean再Invalidate。发送方向则相反:CPU写完数据后先SCB_CleanDCache_by_Addr再启动DMA。切忌在DMA传输过程中做Cache操作,否则会破坏数据。建议用MPU将DMA缓冲区设为Non-Cacheable,最省心。
mcuku 阿沐 · 2026-10-08