1. 引言
STM32 G0 系列產品具有豐富的外設和強大的處理性能以及良好的低功耗特性,被廣泛用于各類工業產品中,包括一些需要低功耗需求的應用。
2.問題描述
用戶使用STM32G0B1 作為汽車多媒體音響控制器的控制芯片,用來作為收音機頻道存貯和各種檢測控制。在實驗室條件下模擬汽車頻繁打火的情形進行測試,連續工作72 小時實驗中,進入STOP 模式后,會出現無法再繼續運行的情況(屏幕沒有顯示輸出,外部中斷無反應)。
3. 問題重現
通常調查問題時采取調試監控的方式。但是用戶產品是在檢測外部掉電時,測外部電壓(汽車ACC 電源,轎車12V)下降后,立刻進入低功耗模式,然后通過RTC 和外部中斷(PC13 下降沿觸發即汽車打火上電)喚醒MCU 繼續工作。
那么既然是已經進入低功耗模式,并且在幾十個小時內才會出現故障,通常的用ST-LINK 在線調試方式顯然很困難重現問題,即使幸運的遇到了故障,也很容易錯過引起故障的代碼部分,看到了現象卻無法定位。
在此種情況下,正面分析出問題的可能性極小,況且用戶代碼量超過200k。這時候采用排除法不失為一種可行的辦法。通過增加測試樣本數量,進行并行測試提高定位效率。
圖1 是為了方便說明問題,模擬用戶關鍵程序。主要是進入STOP 前后外設的處理,來復現故障現象。
圖1 模擬ACC掉電喚醒程序
在經過一段時間的實驗,并從增加和減少該段代碼的排除中,最后驗證并定位到下面的代碼引起故障發生。
圖2 定位到引起的故障代碼
反復分析我們可以看到,在進入STOP前,用戶需要停止ADC和DMA。但是在停止DMA時,用戶程序直接停掉DMA的時鐘。從函數名稱上看,是從其他軟件直接搬過來,并且誤以為是DMA的默認初始化動作。
圖3 DMA正確的停止方式
查詢參考手冊,停止循環模式的DMA應該從外設停止開始,而不是簡單粗暴的停止DMA時鐘。而且,在程序順序上客戶是先停止了DMA的時鐘然后才去停止ADC的DMA請求。顯然,當DMA開始工作時,突然停止時鐘會使DMA和總線處于一個不確定階段狀態,因此才有極低概率發生喚醒故障。
到此已經找到了發生的原因,按說應該找到了前因后果。但奇怪的是無意中發現振蕩器的波形比較奇怪,并不符合低功耗模式。
圖 4 外部振蕩器HSE 波形
在發生故障狀態時發現外部震蕩器還在持續震蕩,因此判定此時并非進入低功耗模式。利用IAR編譯器以HOT PLUG的方式連接調試與觀測。
通過調試界面可以看到,代碼會不停的進入DMA中斷。
圖5 故障模式下的調試
圖6 代碼進入循環過程
奇怪的是每次并沒有看到DMA的寄存器內容,原因是已經關閉了DMA外設的時鐘。所以無法看到任何狀態標志。退出中斷時在C語言下就無法單步調試了。切換到匯編界面下,可以看到代碼可以繼續運行到系統時鐘配置函數,但是在配置函數中的除法部分進入了循環,然后又發生了DMA中斷,并且循環沒有出來。
顯然,正常的調試手段已顯示出邏輯的不正常。
4.小結
至此,情況已經明了。由于軟件在進入低功耗前試圖關閉ADC加DMA工作,沒有按照手冊的規范,通過外設停止的方式關閉,而是簡單粗暴的關閉DMA時鐘,導致總線和運行邏輯出錯,無法繼續執行。
外部看起來像是進入低功耗模式后,外部中斷觸發沒有執行,芯片沒有喚醒,實際上是DMA進入了不正常的循環中斷方式導致了系統卡在循環代碼下。
芯片的外設功能強大,每種外設運行的方式也不相同,因此停止外設時需根據外設特點以及參考手冊的建議來實施,切不可按自己想象的方式執行,這樣引起隱蔽的偶發故障就很難去定位解決了。
此外ST已經建立好完整強大的生態系統,按照cube 軟件庫的規范編寫調用驅動函數可以避免少走類似的彎路。
來源:STM32單片機
免責聲明:本文為轉載文章,轉載此文目的在于傳遞更多信息,版權歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權問題,請聯系小編進行處理
審核編輯 黃宇
-
STM32
+關注
關注
2270文章
10896瀏覽量
355757 -
dma
+關注
關注
3文章
560瀏覽量
100551
發布評論請先 登錄
相關推薦
評論