本文转自公众号,欢迎关注
https://mp.weixin.qq.com/s/uzaGLFTDBAn8wyR84yaiIw
一. 前言
本文分享一个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.解决问题一定要找到根本原因而不是消除现象,比如上述问题原来项目其实发现有问题但是都是在修改串口初始化位置消除现象,而没有去找根本原因。这在嵌入式开发中是大忌。
审核编辑:汤梓红
-
嵌入式
+关注
关注
5068文章
19008浏览量
302900 -
中断
+关注
关注
5文章
895浏览量
41382 -
串口
+关注
关注
14文章
1543浏览量
76156 -
函数
+关注
关注
3文章
4303浏览量
62408 -
BUG
+关注
关注
0文章
155浏览量
15649
发布评论请先 登录
相关推荐
评论