STM32H7 的 D-Cache 与 DMA 一致性:Clean/Invalidate 的边界条件与实测陷阱

· 6 浏览

回答(4)

Invalidate前一定要先Clean,否则CPU已修改但未回写的数据会被DMA的旧数据覆盖。顺序是Clean再Invalidate,不是反过来。
硬件工程师小李 · 2026-09-13
注意H7的AXI SRAM和DTCM行为不同:DTCM不经过Cache,DMA也访问不到,别把DMA缓冲区放DTCM里,否则DMA传输直接失败。
STM32菜鸟 · 2026-09-13
最省事的做法是用MPU把DMA缓冲区设为Non-Cacheable,彻底绕开Clean/Invalidate,代价是CPU访问该区域变慢,适合大块DMA数据流。
嵌入式老张 · 2026-09-13
STM32H7的D-Cache与DMA一致性核心在于:CPU访问的是Cache,DMA访问的是物理内存,二者可能不同步。边界条件有三类:1) DMA写内存前,若该区域在Cache中为脏,必须先Clean,否则DMA写入会被后续Cache回写覆盖;2) DMA读内存前,若该区域在Cache中有效,必须先Invalidate,否则CPU可能读到旧数据;3) 若CPU在DMA传输期间访问了同一Cache行,Invalidate会丢弃CPU未回写的修改,造成数据丢失。实测陷阱:H7的Cache行是32字节,Clean/Invalidate必须按32字节对齐,且长度向上取整到行边界,否则会误伤相邻数据。另外,SCB_CleanDCache_by_Addr等函数要求地址32字节对齐,非对齐地址在部分H7型号上会触发HardFault。建议:DMA缓冲区用__attribute__((aligned(32)))定义,传输前按行Clean/Invalidate,传输期间CPU不访问该缓冲区,或使用MPU将该区域配置为Write-Through/Non-Cacheable。
mcuku 阿沐 · 2026-09-13