本文轉(zhuǎn)自公眾號,歡迎關(guān)注
https://mp.weixin.qq.com/s/uzaGLFTDBAn8wyR84yaiIw
一. 前言
本文分享一個(gè)STM32L4平臺串口驅(qū)動比較隱秘的BUG,分享的目的不在結(jié)論本身,而在于問題的分析過程,和如何形成標(biāo)準(zhǔn),形成checklist,避免類似問題,以及在嵌入式開發(fā)中的思想。
二.問題描述
在某個(gè)項(xiàng)目代碼時(shí)發(fā)現(xiàn)以下問題, 串口中斷處理函數(shù)中,只對IDLE和RXNE標(biāo)志進(jìn)行了處理,而對溢出標(biāo)志沒有處理。 根據(jù)手冊描述如果使能接收非空中斷即RXNEIE=1時(shí),則有ORE標(biāo)識溢出時(shí)也會進(jìn)入中斷,該標(biāo)志需要手動清除,如果不清除則會反復(fù)進(jìn)入中斷。項(xiàng)目中是使能接收非空中斷的即RXNEIE=1。
三.問題驗(yàn)證
在中斷服務(wù)函數(shù)中打斷點(diǎn),然后串口調(diào)試助手輸入1個(gè)字符,進(jìn)入中斷處理函數(shù)
此時(shí)ORE為0,RXN=1表示收到數(shù)據(jù)無溢出。
然后串口調(diào)試助手中輸入多個(gè)數(shù)據(jù),然后再運(yùn)行程序。
再次進(jìn)入中斷,此時(shí)ORE置位,由于沒有對ORE標(biāo)志清除,所以會一直進(jìn)中斷,導(dǎo)致程序運(yùn)行異常。
四.修改
對ORE標(biāo)志進(jìn)行清除,一般的清除時(shí)序是讀SR再讀DR 再寫1清除ORE標(biāo)志。
再進(jìn)行上述測試,ORE在每次中斷后都會清除,不再會出現(xiàn)該情況。
正確的處理應(yīng)該如下:即只要有任何標(biāo)志則清除相應(yīng)的標(biāo)志。
五.總結(jié)
1.中斷服務(wù)函數(shù)一般要清除所有的標(biāo)志,而不是只清除自己關(guān)心的標(biāo)志。但是要考慮可能會清掉別人沒有處理掉的標(biāo)志,所以具體問題具體分析。
2.中斷服務(wù)函數(shù)清標(biāo)志一定要按照手冊要求時(shí)序,有些是寫0清除,有些是寫1清除,有些是先讀狀態(tài)寄存器再讀數(shù)據(jù)寄存器清除等等。
3.一定要考慮異常,一般情況下沒有異常不代表任何情況沒有異常,溫度等環(huán)境改變則可能偶然的異常變?yōu)楸厝坏腻e誤。
4.一定要測試異常,實(shí)際該問題可以測試。比如結(jié)合仿真器白盒測試,也可以比如模擬RX引腳一直拉低模擬異常,生成任意PWM波形到RX引腳模擬干擾數(shù)據(jù),模擬大負(fù)載等進(jìn)行黑盒測試。
5.如果串口是先初始化使能,然后啟動Freertos時(shí)才使能中斷,那么使能中斷前可能就已經(jīng)有溢出ORE錯誤了。這個(gè)問題是隨機(jī)的,出現(xiàn)概率小,一出現(xiàn)就會導(dǎo)致系統(tǒng)不能啟動的假象,如果RX引腳浮空,或者上電瞬間有干擾,或者高低溫等環(huán)境因素改變導(dǎo)致RX引腳出現(xiàn)干擾數(shù)據(jù)的概率增加,則可能導(dǎo)致每次啟動都失敗原項(xiàng)目從代碼注釋來看初始化位置修改過了,應(yīng)該就是遇到過這個(gè)問題改的,但是系統(tǒng)啟動前還進(jìn)行了一大段外設(shè)初始化也需要考慮除了串口外其他外設(shè)是否有該問題。
6.不排除該問題與之前的接上串口導(dǎo)致不能啟動等問題相關(guān),并且有高溫等可能更容易出現(xiàn)的情況,實(shí)際高溫應(yīng)該跟波特率無關(guān),而可能是高溫更容易產(chǎn)生干擾數(shù)據(jù)等。
7.對于使用RTOS的系統(tǒng),不要在OsStart之前初始化驅(qū)動使能外設(shè),因?yàn)橐话鉕sStart之前都是不使能中斷的,OsStart之前使能外設(shè)則再使能中斷的一剎那可能會出現(xiàn)未預(yù)料的中斷導(dǎo)致異常。
從原項(xiàng)目代碼注釋來看應(yīng)該是遇到過這個(gè)問題后面改了,使能接收改到了初始化任務(wù)中。
但是從原項(xiàng)目代碼來看main函數(shù)之后,系統(tǒng)啟動之前還是進(jìn)行了太多的處理,甚至進(jìn)行了文件系統(tǒng)的操作等,這種處理比較危險(xiǎn),建議除了系統(tǒng)啟動必要的初始化其他的都放在初始化任務(wù)重初始化。
如系統(tǒng)啟動前只進(jìn)行底層系統(tǒng)必要初始化然后創(chuàng)建shell任務(wù),其他初始化都在shell任務(wù)中進(jìn)行。
7.解決問題一定要找到根本原因而不是消除現(xiàn)象,比如上述問題原來項(xiàng)目其實(shí)發(fā)現(xiàn)有問題但是都是在修改串口初始化位置消除現(xiàn)象,而沒有去找根本原因。這在嵌入式開發(fā)中是大忌。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19123瀏覽量
305147 -
中斷
+關(guān)注
關(guān)注
5文章
898瀏覽量
41495 -
串口
+關(guān)注
關(guān)注
14文章
1554瀏覽量
76510 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4331瀏覽量
62605 -
BUG
+關(guān)注
關(guān)注
0文章
155瀏覽量
15669
發(fā)布評論請先 登錄
相關(guān)推薦
評論