STM32H755ZIT6 Cortex-M4核USART+DMA接收帧错误问题排查
STM32H755ZIT6 M4核USART+RTS+DMA接收帧错误问题
核心问题
在STM32H755ZIT6的Cortex-M4核上使用USART+仅RTS+DMA(非循环模式,外设到内存,DMA1 Stream0)接收数据时出现Framing Error(帧错误),相同代码在M7核上运行正常。帧错误表示接收端未在预期时间识别到停止位。
相关代码
// u8* dma_rx_buffer_ = (u8*)((u32)0x24000000); // u8* dma_rx_buffer_ = (u8*)((u32)0x38000000); u8* dma_rx_buffer_ = (u8*)((u32)0x30000000); int main(void) { //SCB_InvalidateDCache_by_Addr((u32*)dma_rx_buffer_, 14); error = HAL_UART_Receive_DMA(&usart2_dma_, dma_rx_buffer_, 14); }
注:M4核无法使用SCB_InvalidateDCache_by_Addr函数。
链接脚本配置
M7核Flash.ld
MEMORY { RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K }
M4核Flash.ld
MEMORY { FLASH (rx) : ORIGIN = 0x08100000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x10000000, LENGTH = 288K //RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K //RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K }
已尝试的操作
- 在M4核的Flash.ld中添加RAM_D1和RAM_D2,并通过以下方式定义缓冲区:
无效果。__attribute__ ((section(".RAM_D2"))) __attribute__ ((aligned (32))) u8* dma_rx_buffer_; - 查阅DMA相关文档,未找到解决方案。
- 测试不同RAM地址(RAM_D1、RAM_D2、RAM_D3)作为缓冲区,得到的数据不同,但均出现帧错误。
- 配置MPU区域,代码如下,但使用RAM_D1、RAM_D2或RAM_D3均无效果:
/* Disable fault exceptions */ SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; /* Disable the MPU and clear the control register*/ MPU->CTRL = 0; MPU->CTRL = MPU_PRIVILEGED_DEFAULT | MPU_CTRL_ENABLE_Msk; SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; __DSB(); __ISB(); MPU->RNR = MPU_REGION_NUMBER8; //MPU->RBAR = 0x24000000; //MPU->RBAR = 0x38000000; MPU->RBAR = 0x30000000; MPU->RASR = ((uint32_t)MPU_INSTRUCTION_ACCESS_ENABLE << MPU_RASR_XN_Pos) | ((uint32_t)MPU_REGION_FULL_ACCESS << MPU_RASR_AP_Pos) | ((uint32_t)MPU_TEX_LEVEL0 << MPU_RASR_TEX_Pos) | ((uint32_t)MPU_ACCESS_SHAREABLE << MPU_RASR_S_Pos) | ((uint32_t)MPU_ACCESS_CACHEABLE << MPU_RASR_C_Pos) | ((uint32_t)MPU_ACCESS_BUFFERABLE << MPU_RASR_B_Pos) | ((uint32_t)0x00 << MPU_RASR_SRD_Pos) | ((uint32_t)MPU_REGION_SIZE_32B << MPU_RASR_SIZE_Pos) | ((uint32_t)MPU_REGION_ENABLE << MPU_RASR_ENABLE_Pos);
疑问
请问我哪里操作有误?
解答
1. MPU配置错误
当前MPU配置存在两个关键问题:
- 缓存属性不匹配:DMA直接访问的内存区域必须配置为非缓存,否则M4核的缓存会和DMA写入的数据不一致,打乱传输时序引发帧错误。你设置了
MPU_ACCESS_CACHEABLE,这是错误的。 - 区域大小不匹配:RAM_D2长度为288KB,你设置的
MPU_REGION_SIZE_32B仅覆盖32字节,大部分RAM_D2地址未被MPU规则覆盖。
修改后的MPU配置代码:
/* Disable fault exceptions */ SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; /* Disable the MPU and clear the control register*/ MPU->CTRL = 0; MPU->RNR = MPU_REGION_NUMBER8; // 配置RAM_D2区域(0x30000000,512KB覆盖整个288KB范围) MPU->RBAR = 0x30000000 | MPU_RBAR_VALID_Msk; MPU->RASR = ((uint32_t)MPU_INSTRUCTION_ACCESS_ENABLE << MPU_RASR_XN_Pos) | ((uint32_t)MPU_REGION_FULL_ACCESS << MPU_RASR_AP_Pos) | ((uint32_t)MPU_TEX_LEVEL0 << MPU_RASR_TEX_Pos) | ((uint32_t)MPU_ACCESS_SHAREABLE << MPU_RASR_S_Pos) | ((uint32_t)MPU_ACCESS_NOT_CACHEABLE << MPU_RASR_C_Pos) | // 改为非缓存 ((uint32_t)MPU_ACCESS_BUFFERABLE << MPU_RASR_B_Pos) | ((uint32_t)0x00 << MPU_RASR_SRD_Pos) | ((uint32_t)MPU_REGION_SIZE_512KB << MPU_RASR_SIZE_Pos) | // 匹配RAM_D2的范围 ((uint32_t)MPU_REGION_ENABLE << MPU_RASR_ENABLE_Pos); MPU->CTRL = MPU_PRIVILEGED_DEFAULT | MPU_CTRL_ENABLE_Msk; SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; __DSB(); __ISB();
2. 缓冲区定义错误
你使用u8* dma_rx_buffer_指针指向RAM_D2地址,但指针本身可能被分配到M4的私有RAM,且未在RAM_D2中实际分配缓冲区空间。正确做法是直接定义数组,并通过section属性分配到RAM_D2:
__attribute__ ((section(".RAM_D2"))) __attribute__ ((aligned (32))) u8 dma_rx_buffer_[14];
同时修改M4的Flash.ld,添加RAM_D2的section映射:
MEMORY { FLASH (rx) : ORIGIN = 0x08100000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x10000000, LENGTH = 288K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K } SECTIONS { /* 保留原有SECTION配置,新增以下内容 */ .RAM_D2 : { . = ALIGN(32); *(.RAM_D2) . = ALIGN(32); } > RAM_D2 }
3. 内存访问权限问题
STM32H7的M4核默认只能访问自身私有RAM(0x10000000)和部分共享外设区域,需确保:
- M7核已配置AXI总线,允许M4核访问RAM_D2区域(通过
RCC->AXI3SMENR等寄存器启用)。 - M4核的MPU规则正确覆盖RAM_D2,且权限设置为全访问。
4. RTS流控时序问题
帧错误可能源于RTS信号时序不匹配,检查:
- USART的RTSE位(流控使能)是否正确置位。
- RTS引脚的复用功能和输出模式是否配置正确(复用推挽输出,根据需求配置上下拉)。
- USART的波特率、数据位、停止位配置与发送端完全一致。
内容的提问来源于stack exchange,提问作者user3473485
相关产品推荐
相关产品推荐

