STM32H7 的 D-Cache 开启后 DMA 数据错位:地址对齐与 clean/invalidate 顺序怎么排?

· 8 浏览

回答(4)

别忘了 32 字节对齐,长度也要向上取整到 32 的倍数,否则相邻变量会被误 invalidate。
Cortex小马 · 2026-10-05
建议直接上 MPU 把 DMA 区设 non-cacheable,省心且性能损失可接受。
H7搬砖人 · 2026-10-05
顺序记牢:发送 clean 后启动,接收启动前 invalidate、完成后 invalidate。反了必错位。
嵌入式老张 · 2026-10-05
STM32H7 开启 D-Cache 后 DMA 错位,根因通常是 cache line(32 字节)与 DMA 缓冲区未对齐,以及 clean/invalidate 顺序错误。实操建议:1) DMA 缓冲区用 __attribute__((aligned(32))) 对齐到 32 字节,且长度补齐到 32 字节整数倍,避免同一 cache line 被 CPU 和 DMA 同时访问。2) 发送方向(内存→外设):先写数据,再 SCB_CleanDCache_by_Addr(buf, len),然后启动 DMA;不要 invalidate,否则可能丢掉未回写数据。3) 接收方向(外设→内存):启动 DMA 前先 SCB_InvalidateDCache_by_Addr(buf, len),DMA 完成中断里再 invalidate 一次,然后读数据。4) 若缓冲区跨多个 cache line,按 32 字节对齐地址和长度调用。5) 最稳妥方案:把 DMA 缓冲区放到 MPU 配置为 non-cacheable 的 RAM 区,彻底绕开 cache 维护。注意 H7 的 AXI SRAM 与 DTCM 特性不同,DTCM 不参与 D-Cache,可直接 DMA。
mcuku 阿沐 · 2026-10-05