STM32H7 的 D-Cache 开启后 DMA 数据错乱:地址对齐、Clean/Invalidate 顺序与 MPU 配置的完整排查路径

· 5 浏览

回答(4)

调试时先关 D-Cache 验证 DMA 本身正常,再开 Cache 定位一致性问题,可快速缩小范围。
硬件小工 · 2026-10-12
注意 SCB_InvalidateDCache_by_Addr 会丢弃未 clean 的写数据,接收缓冲区若被 CPU 写过,必须先 clean 再 invalidate。
H7调参侠 · 2026-10-12
优先用 MPU 把 DMA 缓冲区设为 Non-cacheable,比手动 clean/invalidate 更可靠,能避免漏调用和顺序错误。
嵌入式老鸟 · 2026-10-12
STM32H7 开 D-Cache 后 DMA 数据错乱,核心是缓存一致性问题。排查路径:1) 地址对齐:DMA 缓冲区必须按 Cache Line(32字节)对齐,用 __attribute__((aligned(32))) 或 ALIGN_32 定义,且大小补齐到32字节倍数,避免相邻数据被误 invalidate。2) Clean/Invalidate 顺序:CPU 写数据后、启动 DMA 发送前,对发送缓冲区执行 SCB_CleanDCache_by_Addr;DMA 接收完成后、CPU 读数据前,对接收缓冲区执行 SCB_InvalidateDCache_by_Addr。注意:invalidate 前若 CPU 可能写过该区域,必须先 clean 再 invalidate,否则丢数据。3) MPU 配置:将 DMA 缓冲区所在区域配置为 Device 或 Normal Non-Cacheable 内存,属性 TEX=1,C=0,B=0 或直接 Non-cacheable,并设置 XN 防执行。4) 验证:用 __DSB() 和 __ISB() 保证顺序,检查 DMA 是否访问了未对齐的栈变量。最稳妥方案:DMA 缓冲区放 Non-cacheable 区,或使用 D-cache 维护函数并严格对齐。
mcuku 阿沐 · 2026-10-12