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

· 10 浏览

回答(4)

实测发现,在 DMA 传输完成中断里立即 Invalidate 接收缓冲区,若中断优先级高于 Cache 维护操作,可能引发总线冲突,建议在中断中只置标志,主循环处理。
夜风 · 2026-09-12
注意 H7 的 AXI SRAM 和 DTCM 差异:DTCM 不被 DCache 缓存,DMA 也无法访问,别把 DMA 缓冲区放 DTCM。
STM32小王子 · 2026-09-12
MPU 配置 DMA 缓冲区为 Non-Cacheable 最省心,但会牺牲 CPU 访问性能。若缓冲区小且访问频繁,可接受;大缓冲区建议用 Clean/Invalidate 手动维护。
嵌入式老鸟 · 2026-09-12
STM32H7 的 DCache 与 DMA 一致性核心在于:DMA 访问的是物理内存,而 CPU 可能读到 Cache 中的旧数据。正确操作分方向:CPU 写内存后启动 DMA 发送,必须对发送缓冲区执行 Clean(写回),确保数据落到 SRAM;DMA 接收数据前,若该缓冲区可能被 Cache 缓存,必须先 Invalidate(无效化),否则 CPU 后续读取会命中旧 Cache 行。边界条件:1) 缓冲区地址和长度必须按 Cache 行大小(H7 为 32 字节)对齐,否则 Clean/Invalidate 会误伤相邻数据;2) Invalidate 前必须确保 CPU 没有未写回的脏数据,否则会丢失;3) 多缓冲区或链表描述符需逐块处理。实测陷阱:使用 SCB_InvalidateDCache_by_Addr 时,若地址未对齐,函数内部会向上向下取整,可能把其他变量所在行无效化,导致随机错误。建议 DMA 缓冲区用 __attribute__((aligned(32))) 并放在非缓存区域(如通过 MPU 配置为 Write-Through 或 Non-Cacheable),或使用 SCB_CleanInvalidateDCache_by_Addr 一步到位。调试时先关闭 DCache 验证逻辑,再开启并检查对齐。
mcuku 阿沐 · 2026-09-12