一个隐秘的串口中断BUG案例分享

发布者:chunying最新更新时间:2024-06-19 来源: elecfans关键字:串口中断  BUG 手机看文章 扫描二维码
随时随地手机看文章

一. 前言

本文分享一个STM32L4平台串口驱动比较隐秘的BUG,分享的目的不在结论本身,而在于问题的分析过程,和如何形成标准,形成checklist,避免类似问题,以及在嵌入式开发中的思想。


二.问题描述

在某个项目代码时发现以下问题, 串口中断处理函数中,只对IDLE和RXNE标志进行了处理,而对溢出标志没有处理。 根据手册描述如果使能接收非空中断即RXNEIE=1时,则有ORE标识溢出时也会进入中断,该标志需要手动清除,如果不清除则会反复进入中断。项目中是使能接收非空中断的即RXNEIE=1。

图片

图片

三.问题验证

在中断服务函数中打断点,然后串口调试助手输入1个字符,进入中断处理函数

图片

此时ORE为0,RXN=1表示收到数据无溢出。

然后串口调试助手中输入多个数据,然后再运行程序。

图片

再次进入中断,此时ORE置位,由于没有对ORE标志清除,所以会一直进中断,导致程序运行异常。

四.修改

对ORE标志进行清除,一般的清除时序是读SR再读DR 再写1清除ORE标志。

图片

再进行上述测试,ORE在每次中断后都会清除,不再会出现该情况。

图片

图片

正确的处理应该如下:即只要有任何标志则清除相应的标志。

图片

五.总结

1.中断服务函数一般要清除所有的标志,而不是只清除自己关心的标志。但是要考虑可能会清掉别人没有处理掉的标志,所以具体问题具体分析。

2.中断服务函数清标志一定要按照手册要求时序,有些是写0清除,有些是写1清除,有些是先读状态寄存器再读数据寄存器清除等等。

3.一定要考虑异常,一般情况下没有异常不代表任何情况没有异常,温度等环境改变则可能偶然的异常变为必然的错误。

4.一定要测试异常,实际该问题可以测试。比如结合仿真器白盒测试,也可以比如模拟RX引脚一直拉低模拟异常,生成任意PWM波形到RX引脚模拟干扰数据,模拟大负载等进行黑盒测试

5.如果串口是先初始化使能,然后启动Freertos时才使能中断,那么使能中断前可能就已经有溢出ORE错误了。这个问题是随机的,出现概率小,一出现就会导致系统不能启动的假象,如果RX引脚浮空,或者上电瞬间有干扰,或者高低温等环境因素改变导致RX引脚出现干扰数据的概率增加,则可能导致每次启动都失败原项目从代码注释来看初始化位置修改过了,应该就是遇到过这个问题改的,但是系统启动前还进行了一大段外设初始化也需要考虑除了串口外其他外设是否有该问题。

6.不排除该问题与之前的接上串口导致不能启动等问题相关,并且有高温等可能更容易出现的情况,实际高温应该跟波特率无关,而可能是高温更容易产生干扰数据等。

7.对于使用RTOS的系统,不要在OsStart之前初始化驱动使能外设,因为一般OsStart之前都是不使能中断的,OsStart之前使能外设则再使能中断的一刹那可能会出现未预料的中断导致异常。

从原项目代码注释来看应该是遇到过这个问题后面改了,使能接收改到了初始化任务中。

图片

但是从原项目代码来看main函数之后,系统启动之前还是进行了太多的处理,甚至进行了文件系统的操作等,这种处理比较危险,建议除了系统启动必要的初始化其他的都放在初始化任务重初始化。

图片

如系统启动前只进行底层系统必要初始化然后创建shell任务,其他初始化都在shell任务中进行。

图片

7.解决问题一定要找到根本原因而不是消除现象,比如上述问题原来项目其实发现有问题但是都是在修改串口初始化位置消除现象,而没有去找根本原因。这在嵌入式开发中是大忌。


关键字:串口中断  BUG 引用地址:一个隐秘的串口中断BUG案例分享

上一篇:如何转化十六进制字符串
下一篇:单片机开启TFTP服务器的方法

推荐阅读最新更新时间:2026-03-18 11:17

一个隐秘的串口中断BUG案例分享
一. 前言 本文分享一个STM32L4平台串口驱动比较隐秘的BUG,分享的目的不在结论本身,而在于问题的分析过程,和如何形成标准,形成checklist,避免类似问题,以及在嵌入式开发中的思想。 二.问题描述 在某个项目代码时发现以下问题, 串口中断处理函数中,只对IDLE和RXNE标志进行了处理,而对溢出标志没有处理。 根据手册描述如果使能接收非空中断即RXNEIE=1时,则有ORE标识溢出时也会进入中断,该标志需要手动清除,如果不清除则会反复进入中断。项目中是使能接收非空中断的即RXNEIE=1。 三.问题验证 在中断服务函数中打断点,然后串口调试助手输入1个字符,进入中断处理函数 此时ORE为0,RXN=1表示
[单片机]
一个隐秘的<font color='red'>串口</font><font color='red'>中断</font><font color='red'>BUG</font>案例分享
STM32F207串口DMA模式(串口中断bug稳定性)
使用DMA操作UART4: 一、DMA映射表 见下表: UART4的发送 UART4_TX 在Stream4。 UART4的接收 UART4_RX在Stream2。 他们在Channel_4。 二、程序代码 unsigned char btDMARecbuf ;// DMA接收数据地址 unsigned char btDMASendbuf ;//DMA发送数据地址 // 初始化 void UartDMA() { //定义中断结构体 NVIC_InitTypeDef NVIC_InitStructure ; //定义IO初始化结构体 GPIO_InitTypeDef GPIO_InitStructure
[单片机]
STM32F207<font color='red'>串口</font>DMA模式(<font color='red'>串口</font><font color='red'>中断</font><font color='red'>bug</font>稳定性)
STM32 HAL库的定时器中断回调函数跟串口中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {      //添加回调后的程序逻辑  if (htim- Instance == htim2.Instance) //判断是否定时器2 { } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {      //添加回调后的程序逻辑 if(huart- Instance == USART1) //判断是否串口1 { } } 中断回调函数是在某个中断发生完成之后调用的,在用Cubem
[单片机]
STM32 HAL库的定时器<font color='red'>中断</font>回调函数跟<font color='red'>串口</font><font color='red'>中断</font>回调函数
STM32 HAL库关于串口中断烧录程序后可以正常运行
1、情景描述: 最近在做一个项目,X86的上位机通过串口控制MCU,使用串口中断接收上位机数据时,MCU在上电的情况下烧录程序,可以正常接收上位机的数据,在断电重启后,一直进入不了中断回调函数,上电的情况是X86上电,MCU也同时上电。 2、原因分析: 造成这个的原因是因为硬件上电的时候,因为X86跟MCU是同时上电的,上电后会把串口的电平拉高,这个高电平触发了MCU的串口中断,导致MCU的串口中断误以为接收到了一个数据,例如 HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_buff, 5) 这里,上电后MCU误以为接收了一个数据,还剩下4个数据没有接收,然后上位机每次发送5个数据过来后M
[单片机]
STM32 HAL库关于<font color='red'>串口</font><font color='red'>中断</font>烧录程序后可以正常运行
基于GD32F310使用串口的空闲中断完成不定长数据的接收
我们在单片机开发中,经常会用到串口,这时候我可以通过使用DMA,减少CPU的占用。使用串口的空闲中断可以完成不定长数据的接受。所以本次我们从基础的外设移植开始完成此款板子的体验。 首先看下板子吧。 板子整体还是GD一贯风格,还是白色板子,这次由于芯片的管脚较小,目前所以引出方式变了。把可以用的IO都引出了。 本次我们使用串口0进行测试,此测试完成后我们也可以非常方便的移植到串口1上。 我在其基础上移植了新的开发模板,主要导入我们的外设库和CMSIS库即可。例程上我使用了一个闪烁LED灯的例子。 主循环中我们就两个任务,一个是点灯,一个是完成串口接收和发送。 在串口初始话的时候需要主要下,我们使能了串口的中断后,还需要打
[单片机]
基于GD32F310使用<font color='red'>串口</font>的空闲<font color='red'>中断</font>完成不定长数据的接收
STM32入门编程总结4 (中断+串口
系统异常中断与外部中断统称为中断,复位中断的优先级最高, NVIC(NestedVectored Interrupt Controller)嵌套向量中断控制器,调整各个中断的优先级,中断优先级 =抢占优先级(1-4bit)+子优先级(0、1)如果两个中断的抢占优先级与子优先级参数一致,则按照中断向量表里的顺序区分优先级。GPIO的中断,EXTI(External interrupt/event controller)外部中断/事件(event)控制器,外部中断为用户自定义中断内容(用户编写程序发生中断后要干啥事儿),外部事件为具体对应外设自动执行,EXTI 0-15总共16个,GPIO A-G当中的pin尾数与EXTI尾数对应
[单片机]
STM32入门编程总结4 (<font color='red'>中断</font>+<font color='red'>串口</font>)
STM32串口中断应用实例
本文将介绍如何使用STM32F4的串口接收中断,通过串口助手模拟 上位机 发送指令、STM32F4串口中断接收到指令后根据指令选择开关LED小灯。 1.运用到的资源、工具: 1.1开发板 芯片 STM32F407,USART3串口 驱动电路 、 LED驱动 电路 1.2编译工具:MDK- ARM V5( keil 5) 1.3辅助工具:STM32CubeMX 2. 硬件 设计 2.1原理图 3.软件设计 3.1功能架构:串口调试助手向USART3发送1时,使LED1点亮; 发送0时,使LED1熄灭; 串口接收使用接收中断来提高程序运行时的效率、避免程序不断轮询查看串口是否接收到1或0的指令 3.2STM32cubeMX配
[单片机]
STM32<font color='red'>串口</font><font color='red'>中断</font>应用实例
如何使用带FIFO的串口来减少接收中断次数
本文介绍如何使用带FIFO的串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法;之后介绍一种特殊的串口数据发送方法,可在避免使用串口发送中断的情况下,提高系统的响应速度。 1、概述 在此之前,先来列举一下传统串口数据收发的不足之处: 每接收一个字节数据,产生一次接收中断。不能有效的利用串口硬件FIFO,减少中断次数。 应答数据采用等待发送的方法。由于串行数据传输的时间远远跟不上CPU的处理时间,等待串口发送完当前字节再发送下一字节会造成CPU资源浪费,不利于系统整体响应(在1200bps下,发送一字节大约需要10ms,如果一次发送几十个字节数据,CPU会长时间处于等待状态)。 应答数据采用中断发送。增加
[单片机]
如何使用带FIFO的<font color='red'>串口</font>来减少接收<font color='red'>中断</font>次数
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved