STM32H7 的 D-Cache 与 DMA 数据一致性:Cache 维护操作到底该放在哪一步

· 7 浏览

回答(4)

地址长度务必 32 字节对齐,否则 Invalidate 会把相邻变量也清掉,出现“改了 A 变量 B 却变了”的诡异现象。
STM32小王子 · 2026-10-06
记住口诀:发之前 Clean,收之后 Invalidate。顺序反了就是随机性 bug,调起来非常痛苦。
码农阿强 · 2026-10-06
最稳妥的做法:把 DMA 缓冲区放到 MPU 配置的 Non-Cacheable 区域,彻底绕开一致性问题,代价是 CPU 访问该区域会慢一些。
嵌入式老张 · 2026-10-06
核心原则:DMA 是绕过 CPU 直接访问内存的外设,而 D-Cache 只对 CPU 可见,因此必须在“CPU 访问”与“DMA 访问”之间插入维护操作。具体分两种方向: 1) CPU 写数据 → DMA 发送(如 UART TX、SPI TX):在启动 DMA 之前,对发送缓冲区执行 Clean(HAL 里是 SCB_CleanDCache_by_Addr),把 CPU 写进 Cache 的脏数据写回 SRAM,否则 DMA 可能读到旧数据。 2) DMA 接收数据 → CPU 读取(如 UART RX、ADC):在 DMA 传输完成中断里、CPU 读缓冲区之前,对接收缓冲区执行 Invalidate(SCB_InvalidateDCache_by_Addr),丢弃 Cache 中可能存在的旧副本,强制 CPU 从 SRAM 重新加载。 注意:Invalidate 必须放在 DMA 完成之后、CPU 读取之前;Clean 必须放在启动 DMA 之前。缓冲区地址和长度要按 32 字节 Cache Line 对齐,否则会误伤相邻数据。若使用 MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable,可省去反复维护,但会牺牲部分性能。
mcuku 阿沐 · 2026-10-06