STM32F4 系列在开启 D-Cache 后,DMA 与 CPU 访问同一内存区域时出现数据不一致,如何通过 MPU 配置或内存屏障指令正确解决?

· 3 浏览

回答(4)

补充:内存屏障指令在Cortex-M4上需要包含core_cm4.h,使用__DMB()也可,但DSB更严格,确保所有存储操作完成。
硬件调试员 · 2026-08-27
补充:如果使用FreeRTOS,注意任务切换时也可能触发Cache一致性问题,建议在DMA中断中调用Cache维护函数,并关闭调度器保护临界区。
RTOS小能手 · 2026-08-27
补充:MPU配置时,注意设置区域大小和子区域,确保覆盖整个DMA缓冲区,且MPU优先级要高于默认配置,否则可能不生效。
嵌入式老张 · 2026-08-27
在STM32F4上开启D-Cache后,DMA与CPU共享内存的数据不一致,核心原因是DMA绕过Cache直接访问物理内存,而CPU可能命中Cache中的旧数据。解决思路有两种:一是将共享内存区域配置为MPU的“非缓存(Non-cacheable)”或“写透(Write-through)”属性,确保CPU访问直接穿透Cache到内存,与DMA保持一致。具体操作:使用MPU_ConfigRegion()配置该区域为Normal memory, Non-cacheable(或Write-through, no write allocate),并确保MPU使能且优先级覆盖该区域。二是若必须使用Cache,则在DMA操作前后使用内存屏障指令:DMA写内存后,执行__DSB()和__ISB(),并调用SCB_CleanDCache_by_Addr()(若CPU先写)或SCB_InvalidateDCache_by_Addr()(若CPU后读)来同步Cache。注意:STM32F4的D-Cache是写回(Write-back)策略,因此CPU写后需Clean,DMA写后需Invalidate。实操建议:优先采用MPU配置为Non-cacheable,简单可靠;若追求性能,则用屏障+Cache维护函数,并确保DMA描述符和缓冲区地址对齐到32字节。
mcuku 阿沐 · 2026-08-27