STM32F4 系列在开启 D-Cache 后,DMA 与内存数据一致性问题的几种实用解法

STM32 · 潘东芯片应用 · 36 浏览

回答(4)

如果缓冲区频繁传输,建议用双缓冲加DMA中断,配合缓存维护,能减少CPU等待。但别忘关中断时处理缓存,否则数据错乱。
硬件控阿强 · 2026-08-27
杜博文智能硬件:FreeRTOS 任务优先级这个点很关键,我们上次死锁就是优先级配反了。
MPU配置时注意region大小要覆盖整个缓冲区,且优先级别设太高,否则可能影响其他外设。用CMSIS的MPU_ConfigRegion函数最省事。
码农小刘 · 2026-08-27
杜博文智能硬件:这个坑我们也踩过,后来发现是时钟配置的问题,照着这个改就好了。
我常用SCB_CleanDCache和Invalidate,但记得在DMA完成中断里先Invalidate再读数据,否则可能读到旧值。对齐问题很坑,建议统一用32字节对齐数组。
曹雪嵌入式软件 · 2026-08-27
★ 精华
针对STM32F4开启D-Cache后的DMA一致性问题,核心解法有三类:1) 使用MPU将DMA缓冲区配置为非缓存(强序或设备内存),这是最推荐的方式,通过MPU_ConfigRegion设置region属性为Normal, Non-Cacheable,确保CPU和DMA访问同一物理内存,避免缓存脏数据;2) 在DMA传输前后手动维护缓存,使用SCB_CleanDCache_by_Addr(DMA写内存前)和SCB_InvalidateDCache_by_Addr(DMA读内存后),注意地址需32字节对齐且长度按行对齐,否则可能破坏相邻数据;3) 使用DMA的存储器到存储器模式配合双缓冲,但仅适用于特定场景。实操建议:优先用MPU方案,因为它零性能开销且代码简洁;若必须用缓存维护,务必在中断或轮询中严格按序执行Clean/Invalidate,并考虑使用__ALIGNED(32)声明缓冲区。另外,检查DMA描述符和缓冲区是否在非缓存区域,避免混合使用。
杜博文智能硬件 · 2026-08-27