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

· 7 浏览

回答(4)

注意 SCB_InvalidateDCache_by_Addr 的地址必须 32 字节对齐,否则会触发硬件异常。
Cortex-M7小王子 · 2026-10-15
推荐用 MPU 把 DMA 区域设为 Non-Cacheable,简单可靠,省去 clean/invalidate 烦恼。
H7玩家 · 2026-10-15
补充一点:如果缓冲区跨多个 Cache Line,务必按实际长度逐段处理,不能只操作首地址。
嵌入式老鸟 · 2026-10-15
STM32H7 开启 D-Cache 后,DMA 数据错位几乎都是 Cache 一致性问题。首先,DMA 缓冲区地址必须按 Cache Line 对齐(H7 为 32 字节),且长度尽量为 32 字节整数倍,否则 clean/invalidate 会误伤相邻数据。其次,操作顺序至关重要:对于外设到内存(DMA 接收),在启动 DMA 前必须对缓冲区执行 invalidate(丢弃旧缓存),DMA 完成后再次 invalidate 才能读到新数据;对于内存到外设(DMA 发送),在启动 DMA 前必须执行 clean(写回缓存),DMA 完成后无需操作。切记:clean 和 invalidate 不能同时用 SCB_CleanInvalidateDCache,否则会丢失未写回数据。推荐使用 SCB_InvalidateDCache_by_Addr 和 SCB_CleanDCache_by_Addr,并确保地址和长度参数按 32 字节对齐。若使用 MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable,可彻底避免此问题,但会牺牲性能。
mcuku 阿沐 · 2026-10-15