
1. 问题STM32H743开启D-cache以后如果使用DMA会导致数据错乱。2. 原因DMA访问的是RAM, 实际的数据可能还在D-cache中没有与RAM同步。3. 解决方法3.1 使用前同步DMA发送前将cache中的数据写会RAMSCB_CleanDCache_by_Addr()DMA接收数据后cache获取RMA的数据SCB_InvalidateDCache_by_Addr()详情//用于将 D-Cache 数据回写到 SRAM 里面SCB_CleanDCache_by_Addr((uint32_t*)buf,len);//用于重新从 SRAM 获取数据, 丢弃 D-Cache 当前数据SCB_InvalidateDCache_by_Addr((uint32_t*)buf,len);//写回数据到 SRAM, 并重新获取 D-Cache数据SCB_CleanInvalidateDCache_by_Addr((uint32_t*)buf,len);3.2 MPU方式推荐通过MPU关闭一块SRAM的Cache功能例如以0x30000000为首地址的128KSRAM1为什么不用0x24000000(AXI SRAM)这一块因为这块ram的速度快关闭Cache太浪费。DMA使用到的内存需要定义到关闭Cache的内存范围内步骤1. 开启MPU并设置voidMPU_Config(void){MPU_Region_InitTypeDef MPU_InitStruct{0};/* Disables the MPU */HAL_MPU_Disable();/** Initializes and configures the Region and the memory to be protected */MPU_InitStruct.EnableMPU_REGION_ENABLE;MPU_InitStruct.NumberMPU_REGION_NUMBER0;MPU_InitStruct.BaseAddress0x30000000;MPU_InitStruct.SizeMPU_REGION_SIZE_128KB;MPU_InitStruct.SubRegionDisable0x0;MPU_InitStruct.TypeExtFieldMPU_TEX_LEVEL0;MPU_InitStruct.AccessPermissionMPU_REGION_FULL_ACCESS;MPU_InitStruct.DisableExecMPU_INSTRUCTION_ACCESS_ENABLE;MPU_InitStruct.IsShareableMPU_ACCESS_SHAREABLE;MPU_InitStruct.IsCacheableMPU_ACCESS_NOT_CACHEABLE;MPU_InitStruct.IsBufferableMPU_ACCESS_NOT_BUFFERABLE;HAL_MPU_ConfigRegion(MPU_InitStruct);/* Enables the MPU */HAL_MPU_Enable(MPU_HFNMI_PRIVDEF);}2. Keil工程设置Linker3 STM32H743_DMA.sct;STM32H743IITx;Flash2MB;AXISRAM(D1)512KB;SRAM1SRAM2SRAM3(D2)288KB LR_IROM10x080000000x00200000{ER_IROM10x080000000x00200000{*.o(RESET,First)*(InRoot$$Sections).ANY(RO)};普通RW/ZI变量 RW_RAM_D10x240000000x00080000{.ANY(RWZI)};DMA专用区域 RW_DMA0x300000000x00048000{*(.dma_buffer)}}4. 使用#define__DMA_RAM\__attribute__((section(.dma_buffer)))\__attribute__((aligned(32)))//注意这里buf需要是全局变量或static变量__DMA_RAMuint8_tbuf[512]{0};//buf在0x30000000 sram段//备注这里赋初值可能没作用。例如下面两行代码赋的初值不起效果__DMA_RAMuint8_tbuf[512]{123};static__DMA_RAMuint8_tbuf[512]{1,2,3};3.3 D-Cache 的透写模式缺点 会损失一些性能因为每次都要从从Cache写会数据。/** * brief 使能 STM32H7 的 L1-Cache, 同时开启 D cache 的强制透写 * param 无 * retval 无 */voidsys_cache_enable(void){SCB_EnableICache();/* 使能 I-Cache,函数在 core_cm7.h 里面定义 */SCB_EnableDCache();/* 使能 D-Cache,函数在 core_cm7.h 里面定义 */SCB-CACR|12;/* 强制 D-Cache 透写,如不开启透写,实际使用中可能遇到各种问题 */}