1. 程式人生 > >STM32F030 中斷太頻繁導致宕機

STM32F030 中斷太頻繁導致宕機

最近在忙一個專案,使用了STM32F030的微控制器,定時器用系統定時器,每10us中斷一次。在程式少的時候,沒有發現宕機情況,但是隨著功能的豐富,經常出現宕機問題,具體表現為while(1)迴圈無法執行,但是中斷函式正常或者按鍵不起作用,程式直接跑分。這時我認為是宕機,即程式跑分,但是有時中斷正常,這就證明程式依然正常執行,可能是其它原因造成。

首先,我懷疑是I2C讀寫DSP出錯,於是遮蔽掉DSP初始化,剛開始正常,多開機幾次就又不正常了,所以排除寫DSP。

接著,我懷疑讀Flash出錯,也發現模擬時,有時讀Flash,就假死在那兒,於是就又把讀Flash遮蔽掉,發現程式又正常了許多,但是多開機幾次就又出現假死,所以又排除寫Flash。但是模擬時,卻說發現程式假死在一些初始化時的延時函式裡。於是我仔細檢查延時函式是否出錯,發現沒有錯誤,這就導致很奇怪了。

然後,我把優化等級調到-O3,發現出現了局部變數沒有初始化就被使用和陣列越界的情況(程式是拷貝別人的,沒有仔細檢查),以為這次可以解決了,在修改掉Bug後,程式假死改善了許多,但是很不幸,多級開關機後,發現程式又假死了,問題還不在這裡,不過順便解決了兩個Bug。

最後,在同事的幫助下,開始檢查系統定時器的中斷函式,發現中斷是每10us觸發一次,並且在10us的中斷函式裡有呼叫了好幾個函式,並且還有對IO口的操作,所以很有可能是由於中斷過於頻繁,系統被拖死了,導致不停的進入中斷(這次中斷還沒有執行完成,下一次中斷事件就產生了),導致while(1)迴圈根本沒有時間執行,就出現了之前的假死現象。於是,在把中斷時間改為1ms後,並把函式的操作放在了50ms的中斷函式裡處理,假死問題得以解決。

總結:

1、微控制器不能把中斷設定的太頻繁,否則可能會消耗掉過多的MCU資源,導致while(1)執行的很慢,系統執行出現問題。

      微控制器會隨著溫度的升高,速度回稍微變慢,這也是為什麼程式在中斷太頻繁時,有時執行正常,有時又不正常的原因。

      中斷函式裡最好不要放函式呼叫,比較耗費時間,如果確實要用,就快進快出,並且不能在低於1ms的中斷函式裡呼叫函式。

      中斷函式裡最好不要操作IO口,檢測IO口的狀態可以,但是最好不要寫IO口,否則可能會消耗掉過多的MCU資源,導致系統假死。

      區域性變數一定要記得在定義時初始化,否則可能會出現不初始化就使用,導致系統異常;陣列一定要仔細檢查是否可能會出現越界,如果越界了怎麼處理,要有保護措施。

2、從發現問題,到解決問題,用了將近兩天的時間,不能不說這是一種浪費。首先,在發現問題後,沒有先做深入的分析,而是不停的懷疑這裡有問題,而沒有用“證據”來證明其一定有問題,這不說一種好的解決問題的思路。其次,在沒有串列埠列印時,沒有第一時間把串列埠焊好,又是自己獨自摸索懷疑,增加了除錯的難度。最後,對微控制器的執行速度沒有大致的概念,以為8M晶振倍頻到48M,微控制器速度非常快了,但是沒有考慮到多週期指令和C程式碼翻譯成彙編再翻譯成機器碼後,會增加20%~30%的程式碼量,綜合考慮,跑一次while(1)迴圈大概需要幾毫秒的時間(中等規模程式碼,且沒有任何延時)。