STM32H7在cache下的串口DMA
DMA使用的memory空间使能了Cache的话,空间要做32位字节对齐。同时为了保持数据一致性
1、AXI RAM空间MPU直接设置为WT模式。
2、DMA接收后,使用函数SCB_InvalidateDCache_by_Addr做接收缓冲区无效化。
MPU配置
.sct文件ram分配
LR_IROM1 0x08000000 0x00200000 ; load region size_region
{
ER_IROM1 0x08000000 0x00200000 ; load address = execution address
{
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00020000 ; RW data
{
.ANY (+RW +ZI)
}
RW_IRAM2 0x24000000 0x00080000
{
*(.RAM_D2)
}
}
MPU配置为WT或者WB,使能cache
void bsp_Init(void)
{
MPU_Config();
CPU_CACHE_Enable();
}
static void MPU_Config( void )
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes as WT for SRAM */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
// MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;//配置为WT
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
static void CPU_CACHE_Enable(void)
{
/* ʹÄÜ I-Cache */
SCB_EnableICache();
/* ʹÄÜ D-Cache */
SCB_EnableDCache();
}
接收DMA数据
分配变量32位对齐
#define ALIGN_32BYTES(buf) __align(32) buf //32位对齐
ALIGN_32BYTES(__attribute__((section (".RAM_D2"))) uint8_t aRxBuffer[5]) = "ARM";
若使能了cache为WB,则需要在接收和发送数据之前将Cache对应区域无效化
一般下面是放在中断里面,或者中断置位,在任务里面去读写,下面这段话的意思是设置新的接收,并将接收到的发送回去。
SCB_InvalidateDCache_by_Addr ((uint32_t *)aRxBuffer, 5);
HAL_UART_Transmit_DMA(&UartHandle, aRxBuffer, 5);
HAL_UART_Receive_DMA(&UartHandle, aRxBuffer, 5);