STM32H7 的 D-Cache 与 DMA 数据一致性:SCB_CleanDCache_by_Addr 的实战踩坑与规避

· 7 浏览

回答(4)

注意:Clean后若CPU立即读该区域,可能读到旧值?不会,Clean只写回,不无效。但Invalidate后CPU读会重新加载,需确保DMA已写完。
Cache小王子 · 2026-09-16
更稳的做法:把DMA缓冲区放到MPU配置为Non-Cacheable的区域,彻底避免一致性问题,性能损失可接受。
H7玩家 · 2026-09-16
补充:SCB_CleanDCache_by_Addr的地址参数必须32字节对齐,长度按32字节向上取整,否则会漏刷或刷到相邻数据,导致随机错误。
嵌入式老鸟 · 2026-09-16
STM32H7的D-Cache与DMA数据一致性是经典坑点。核心原则:DMA写内存(外设到内存)前,必须对目标缓冲区执行SCB_InvalidateDCache_by_Addr,防止CPU读旧缓存;DMA读内存(内存到外设)前,必须执行SCB_CleanDCache_by_Addr,确保数据写入物理内存。实战踩坑:1) 地址必须32字节对齐,长度需向上取整到32字节倍数,否则函数内部按行操作可能越界或漏刷;2) 若缓冲区在DTCM,DMA无法访问,需放在AXI SRAM或SDRAM并配置MPU为Write-Through或Non-Cacheable;3) 调用Clean/Invalidate后,若CPU紧接着访问该缓冲区,需插入__DSB()确保操作完成。规避建议:对DMA缓冲区使用MPU配置为Non-Cacheable,或使用SCB_CleanDCache_by_Addr前先__DSB(),后__DSB()。若用HAL库,注意HAL_DMAEx_MultiBufferStart等函数内部已处理,但自定义DMA需手动维护。
mcuku 阿沐 · 2026-09-16