STM32H7 的 Cache 与 DMA 一致性:Clean/Invalidate 的边界条件与踩坑复盘

· 2 浏览

回答(4)

推荐用SCB_InvalidateDCache_by_Addr前先Clean,避免Invalidate时把未写回的脏数据丢弃。或者直接配置MPU将DMA缓冲区设为Write-Through模式。
Cache小王子 · 2026-09-18
实测踩坑:用HAL库的HAL_DMA_Start_IT后立即Invalidate,结果DMA还没写完就清Cache,数据全丢。务必在DMA完成回调里做Invalidate。
H7调试员 · 2026-09-18
补充:若使用STM32H7的MDMA或BDMA,同样需注意Cache一致性,且BDMA只能访问D3域SRAM,该区域默认非Cache,可简化处理。
嵌入式老鸟 · 2026-09-18
STM32H7的Cache与DMA一致性核心是:DMA访问的内存区域必须保证CPU Cache与物理内存同步。关键边界条件:1) 发送方向(CPU写,DMA读):在启动DMA前对数据区执行Clean操作(如SCB_CleanDCache_by_Addr),确保Cache中脏数据写回内存;2) 接收方向(DMA写,CPU读):在DMA完成中断后、CPU读取数据前,对数据区执行Invalidate操作(SCB_InvalidateDCache_by_Addr),丢弃Cache中可能过时的行;3) 若缓冲区跨Cache行(32字节对齐),必须按行对齐地址和长度,否则会误伤相邻数据。常见坑:在DMA传输过程中调用Invalidate会导致数据丢失;使用非对齐地址或长度引发HardFault;忘记在DMA启动前Clean导致发送旧数据。建议:将DMA缓冲区放在非Cache区域(如通过MPU配置)或使用DTCM RAM(CPU可直接访问,但DMA无法访问DTCM,需注意),或严格遵循Clean/Invalidate时序,并利用__DSB()和__ISB()保证指令顺序。
mcuku 阿沐 · 2026-09-18