本文轉自公眾號,歡迎關注
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.解決問題一定要找到根本原因而不是消除現象,比如上述問題原來項目其實發現有問題但是都是在修改串口初始化位置消除現象,而沒有去找根本原因。這在嵌入式開發中是大忌。
審核編輯:湯梓紅
-
嵌入式
+關注
關注
5082文章
19104瀏覽量
304793 -
中斷
+關注
關注
5文章
898瀏覽量
41470 -
串口
+關注
關注
14文章
1551瀏覽量
76421 -
函數
+關注
關注
3文章
4327瀏覽量
62569 -
BUG
+關注
關注
0文章
155瀏覽量
15665
發布評論請先 登錄
相關推薦
評論