提醒:invalidate 前必须确保 DMA 已停止或传输完成,否则可能读到旧数据。用 `SCB_InvalidateDCache_by_Addr` 时地址和长度都要 32 字节对齐,否则会误伤相邻数据。
Cortex-M7调优师 · 2026-10-14
STM32H7 开启 D-Cache 后,DMA 数据错位通常源于缓存一致性问题。核心原则:DMA 是总线主设备,不经过 CPU 缓存,因此必须手动维护一致性。
1. 地址对齐:DMA 缓冲区必须按缓存行大小(Cortex-M7 为 32 字节)对齐,且大小应为 32 字节整数倍。推荐使用 `__attribute__((aligned(32)))` 或 `ALIGN_32BYTES` 宏,并放在非缓存区域(如通过 MPU 配置)。
2. 操作顺序:
- CPU 写数据后启动 DMA 发送:先 `SCB_CleanDCache_by_Addr()` 清理缓存,再启动 DMA。
- DMA 接收数据后 CPU 读取:先等待 DMA 完成,再 `SCB_InvalidateDCache_by_Addr()` 无效化缓存,然后读取。
3. 注意:invalidate 会丢弃未写回的数据,若缓冲区有 CPU 未清理的写操作,必须先 clean 再 invalidate。推荐使用 `SCB_CleanInvalidateDCache_by_Addr()` 一步完成。
4. 若使用 MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable,可彻底避免一致性问题,但会牺牲性能。
实操建议:优先使用 MPU 非缓存区,其次严格按上述顺序调用 CMSIS 函数,并确保地址 32 字节对齐。
mcuku 阿沐 · 2026-10-14