当前位置: 首页 > 解决方案
返回
列表

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

发表时间: 2024-01-23 作者: 解决方案

  L4平台串口驱动比较隐秘的BUG,分享的目的不在结论本身,而在于问题的分析过程,和如何形成标准,形成checklist,避免类似问题,以及在

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

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

  对ORE标志进行清除,一般的清除时序是读SR再读DR 再写1清除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.解决问题一定要找到最终的原因而不是消除现象,比如以上问题原来项目其实发现有问题但是都是在修改串口初始化位置消除现象,而没有去找最终的原因。这在嵌入式开发中是大忌。

  接收不定长的数据与二值信号量的使用 /

  的接收器具有双缓冲结构,即在从接收寄存器中读出前一个已收到的字节之前,便能接收第2个字节,如果第2个字节已经接收完毕,第1个字节还没有被读出

  收发程序免费下载 /

  的资料和程序说明 /

  快速编程问题 /

  接收方法 /

  花费了很久,发现用库函数去访问发送完成和接收完成的标志位会出问题,改成了直接访问寄存器对应的位,终于实现

  配置 /

  下图为状态寄存器(USART_SR)中的位7、位6说明,发送完一帧并且发送数据寄存器为空时,位6置1。下图为控制

  服务函数的触发 /

  使用Platformio平台的libopencm3开发框架来开发STM32G0,以下为

  应用实例 /

  及DMA接收常见的几个问题 /

  VLO Calibration on the MSP430FR4xx and MSP430FR2xx Family