You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

STM32F4XX写Flash时UART中断仍出现OVERRUN错误的求助

解决STM32F4 Flash写入时UART OVERRUN错误的思路

你已经按照AN3969和AN4808完成了向量表重定位、UART中断移至RAM的操作,但仍出现OVERRUN错误,咱们可以从以下几个方向排查和优化:


1. 确保RAM函数的所有依赖都在RAM中

你提到RAM函数使用的变量和调用的函数都需要在RAM,但可能有遗漏:

  • 检查UART中断服务例程(ISR)中用到的全局/静态变量(比如uart_1_send_bufferuart_1_recv_write_pos)是否也被放在RAM中(可以用__attribute__((section(".data")))或者通过链接脚本确保它们在.data段)。
  • 确认ISR里调用的所有辅助函数/宏(比如GPIO_SETGPIO_CLR)如果是库函数,是否也标记为RAMFUNC。如果是直接操作寄存器的宏则没问题,但如果调用了Flash中的函数,会导致ISR执行时触发Flash访问,在Flash操作期间被停滞。

2. 验证向量表重定位是否真正生效

向量表没正确移到RAM的话,中断还是会从Flash取指令,导致Flash操作时无法响应:

  • 在代码中读取SCB->VTOR寄存器的值,确认它指向SRAM的起始地址(比如0x20000000 + VECT_TAB_OFFSET)。如果值还是Flash的起始地址0x08020000,说明重定位失败。
  • 检查Reset Handler中复制向量表的代码是否正确执行:可以在复制完成后添加断点,对比Flash和SRAM中的向量表内容是否一致。

3. 优化UART中断的响应和执行效率

STM32F4的UART没有硬件FIFO,只有1字节接收寄存器,任何微小的延迟都可能导致OVERRUN:

  • 简化ISR逻辑:把ISR里的非必要操作(比如LED状态翻转)移到主循环,ISR只做最核心的工作——读取UART数据、写入缓冲区,以及处理发送缓冲区的字节。
  • 确认中断优先级配置:确保UART中断的优先级足够高(通过NVIC_SetPriority配置),避免被其他低优先级中断抢占,延长响应时间。同时要确认USART_CR1中的OREIE位已开启,保证OVERRUN错误能触发中断及时处理。
  • 增大软件缓冲区:适当扩大uart_1_recv_buffer的大小,给主循环处理数据多留一点缓冲空间。

4. 优化Flash操作的时长

Flash操作的时间越长,UART数据丢失的概率越高:

  • 优化EEPROM仿真的操作:如果使用AN3969的EEPROM仿真,尽量使用页编程/擦除代替字节操作,减少Flash操作的次数和总时长。
  • 检查Flash等待周期:确认RCC->CFGR中的FLASH_LATENCY配置与当前系统时钟匹配,避免因等待周期不足导致Flash操作变慢。

5. 改用DMA接收UART数据

这是解决这类实时性冲突最有效的方案之一:

  • STM32F4的DMA是独立于CPU的外设,即使CPU因Flash操作停滞,DMA仍能自动将UART接收的数据传输到RAM缓冲区(DMA访问SRAM和UART外设不需要经过Flash总线)。
  • 配置UART的DMA接收模式后,只需在DMA传输完成一半或全部时触发中断,批量处理数据,完全避免了CPU实时响应UART接收的压力。

内容的提问来源于stack exchange,提问作者Julian Poidevin

火山引擎 最新活动