STM32H7 的 D-Cache 与 DMA 一致性:MPU 配置与 clean/invalidate 的正确顺序

· 3 浏览

回答(4)

还要注意 SCB_InvalidateDCache_by_Addr 和 SCB_CleanDCache_by_Addr 的调用时机,别在 DMA 传输过程中去操作,否则会破坏正在传输的数据。中断里处理要格外小心。
Cortex小王子 · 2026-09-19
最省心的方案其实是把 DMA 缓冲区直接放到 MPU 配置为 Non-cacheable 的 SRAM 区域,比如用 D2 SRAM 并单独配 MPU region,这样完全不用管 clean/invalidate,代码也简单。
H7搬砖工 · 2026-09-19
补充一点:invalidate 是按 cache line(32字节)操作的,如果缓冲区没对齐,可能把相邻变量也 invalidate 掉,导致数据丢失。建议缓冲区用 __attribute__((aligned(32))) 对齐。
嵌入式老张 · 2026-09-19
STM32H7 的 D-Cache 与 DMA 一致性问题,核心是:DMA 访问的是物理内存,而 CPU 可能读到 Cache 里的旧数据,或 DMA 读到尚未写回内存的新数据。正确做法分两种场景。 1)DMA 读内存(外设→内存,如 ADC 采集):DMA 写完后,CPU 读之前,必须 invalidate 对应缓冲区,丢弃 Cache 中可能存在的旧行。注意:invalidate 前要确保该缓冲区没有 CPU 未写回的脏数据,否则会丢数据。 2)DMA 写内存(内存→外设,如 UART 发送):CPU 写完数据后、启动 DMA 前,必须 clean(写回)该缓冲区,保证 DMA 读到的是最新数据。 顺序口诀:发送先 clean 再启动 DMA;接收先等 DMA 完成再 invalidate。 MPU 配置建议:把 DMA 缓冲区所在区域配成 Normal, Non-cacheable 或 Write-Through,可从根本上避免一致性问题,代价是性能略降。若必须用 Cacheable,则严格按上述 clean/invalidate 顺序操作,并注意 32 字节 Cache line 对齐,避免相邻数据被误 invalidate。
mcuku 阿沐 · 2026-09-19