STM32H7 的 D-Cache 开启后 DMA 数据错乱:Cache 一致性维护的三种正确做法与性能代价对比

· 3 浏览

回答(4)

别忘了SCB_EnableDCache后中断向量表和栈区也要考虑,MPU配置时把DMA描述符和缓冲区单独划一个region最稳妥。
硬件阿伟 · 2026-09-22
实测H7上手动Clean+Invalidate一次约几十个周期,1kHz小包传输时CPU占用可忽略;但若每包只有几字节,建议合并传输或改用MPU方案。
码农小陈 · 2026-09-22
补充一点:Invalidate操作会丢弃未回写的Cache行,若CPU在DMA写入期间碰过该缓冲区,数据会丢。接收缓冲区建议先Invalidate再交给DMA,或干脆用Non-Cacheable。
嵌入式老张 · 2026-09-22
STM32H7开启D-Cache后DMA数据错乱,本质是CPU与DMA看到的内存视图不一致:DMA直接访问SRAM,而CPU可能读到Cache中的旧数据,或写数据仍停留在Cache未回写到SRAM。三种正确做法:1) 使用MPU将DMA缓冲区配置为Write-Through或Non-Cacheable,一劳永逸,无需每次手动维护,代价是该区域CPU访问性能下降(Non-Cacheable最明显,Write-Through写性能受损)。2) 手动维护:发送前对缓冲区执行SCB_CleanDCache_by_Addr,接收后执行SCB_InvalidateDCache_by_Addr,注意地址和长度必须32字节对齐,且Invalidate前要确保CPU不再访问该缓冲区,否则可能丢数据。3) 使用带Cache维护的HAL回调或DMA双缓冲+Cache行对齐,把维护开销摊到流水线中。性能对比:MPU方案零运行时开销但牺牲该区域访问速度;手动维护每次传输增加几十到几百周期,频繁小包传输时开销显著;双缓冲适合高吞吐场景。推荐:固定DMA缓冲区用MPU配置,动态缓冲区用手动维护,并务必32字节对齐。
mcuku 阿沐 · 2026-09-22