核心原则: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