當(dāng)前位置:首頁 > 公眾號精選 > TopSemic嵌入式
[導(dǎo)讀]一、HardFault產(chǎn)生原因和常規(guī)分析方法二、HardFault解決方法分析三、HardFault回溯的原理四、操作分析流程:心里明白徒手分析法CmBacktrace天龍大法五、總結(jié)一、HardFault產(chǎn)生原因和常規(guī)分析方法在嵌入式開發(fā)中,偶爾會遇到HardFault死機(jī)的異...

一、HardFault產(chǎn)生原因和常規(guī)分析方法

二、HardFault解決方法分析

三、HardFault回溯的原理

四、操作分析流程:

  1. 心里明白徒手分析法

  2. CmBacktrace 天龍大法

五、總結(jié)

一、HardFault產(chǎn)生原因和常規(guī)分析方法

在嵌入式開發(fā)中,偶爾會遇到Hard Fault死機(jī)的異常,常見產(chǎn)生Hard Fault的原因大致有以下幾類:

  • 數(shù)組越界和內(nèi)存溢出,譬如訪問數(shù)組時(shí),動態(tài)訪問的數(shù)組標(biāo)號超過數(shù)組長度或者動態(tài)分配內(nèi)存太小等;
  • 堆棧溢出,例如在使用中,局部變量分配過大,超過棧大小,也會導(dǎo)致程序跑飛;
  • 在外設(shè)時(shí)鐘開啟前,訪問對應(yīng)外設(shè)寄存器,例如Kinetis中未打開外設(shè)時(shí)鐘去配置外設(shè)的寄存器;
  • 不當(dāng)?shù)挠梅ú僮鳎绶菍R的數(shù)據(jù)訪問、除0操作(默認(rèn)情況下M3/M4/M7,除0默認(rèn)都不會觸發(fā)Fault,因?yàn)锳RM內(nèi)核CCR寄存器DIV_0_TRP位復(fù)位值為0,而對M0來說DIV_0_TRP位是reserved的,也不會產(chǎn)生Fault錯誤)、強(qiáng)行訪問受保護(hù)的內(nèi)存區(qū)域等;
出現(xiàn)Hardfault錯誤時(shí),問題比較難定位的原因在于此時(shí)代碼無法像正常運(yùn)行時(shí)一樣,在debug IDE的stack callback窗口能直接找到出錯時(shí)上一級的調(diào)用函數(shù),所以顯得無從下手。通常情況下我們都是通過在某個區(qū)間打斷點(diǎn),然后通過單步執(zhí)行去逐步縮小“包圍圈”去找到產(chǎn)生Hard Fault的代碼位置,接著再去推敲、猜測問題的原因。對于不是很復(fù)雜的程序,這種方法是有效的,但是當(dāng)用戶代碼量進(jìn)一步增大,再用這種單步 斷點(diǎn)去逐步縮小包圍圈的方式就很難查到問題點(diǎn),效率也很低。尤其是在有操作系統(tǒng)的應(yīng)用中,很多代碼的跳轉(zhuǎn)是由操作系統(tǒng)調(diào)度的,不是嚴(yán)格的順序執(zhí)行,所以很難依靠縮小包圍圈的方式去有效找到問題產(chǎn)生的點(diǎn),進(jìn)一步增加了定位到Hard Fault觸發(fā)原因的難度。

盡管本測試是針對NXP KW36芯片的,但該步驟和方法也適用于其他的Arm Cortex-M內(nèi)核MCU;

二、HardFault解決方法分析

筆者在實(shí)際支持客戶過程中也遇到這種困惑,網(wǎng)上的介紹資料比較零散,理論很多,很少詳細(xì)描述實(shí)戰(zhàn)操作的步驟,借助同事的點(diǎn)撥,摸索出兩種定位Hard Fault問題的方法,在實(shí)際使用中操作性也很強(qiáng),此處分別做一介紹。

  • 第一種:心里明白徒手分析法,就是在了解Hard Fault出錯原理以及程序調(diào)用壓棧出棧原理的基礎(chǔ)上(當(dāng)然按照本文的練就心法,心里不明白也可以),在Debug仿真模式下徒手去回溯分析CPU通用寄存器(LR/MSP/PSP/PC),然后結(jié)合調(diào)試IDE去定位到產(chǎn)生Hard Fault的代碼位置;
  • 第二種:CmBacktrace 天龍大法,該方法是朱天龍大神針對 ARM Cortex-M系列MCU開發(fā)的一套錯誤代碼自動追蹤、定位、錯誤原因自動分析的開源庫,已開源在Github上,該方法支持在非Debug模式下,自動分析定位到出錯的行號,無需了解復(fù)雜的壓棧出棧過程。
兩者的區(qū)別在于:前者不需要額外添加代碼,缺點(diǎn)是只能在仿真狀態(tài)下調(diào)試,需要用戶對程序調(diào)用壓棧/出棧原理有清晰的理解,后者的唯一的缺點(diǎn)是需要適當(dāng)添加代碼,并稍微配置工程和打印輸出,優(yōu)點(diǎn)就太多了。首先,產(chǎn)品真機(jī)調(diào)試時(shí)可以斷開仿真器,并將錯誤信息輸出到控制臺上,甚至可以將錯誤信息使用 Easy Flash 的 Log 功能保存至 Flash 中,待設(shè)備死機(jī)后重啟依然能夠讀取上次的錯誤信息。這個功能真的是very very重要了,尤其在有些Hard Fault問題偶發(fā)的情況下,很多時(shí)候一天可能也復(fù)現(xiàn)不了一次問題,但借助CmBacktrace 天龍大法便可以輕松脫離仿真器get每一次錯誤,最后再配合 addr2line 工具進(jìn)行精確定位出錯代碼的行號,方便用戶進(jìn)行后續(xù)的精確分析。

三、HardFault回溯的原理

為了找到Hard Fault 的原因和觸發(fā)的代碼段,就需要深刻理解當(dāng)系統(tǒng)產(chǎn)生異常時(shí) MCU 的處理過程: 當(dāng)處理器接收一個異常后,芯片硬件會自動將8個通用寄存器組中壓入當(dāng)前棧空間里(依次為 xPSR、PC、LR、R12以及 R3~R0),如果異常發(fā)生時(shí),當(dāng)前的代碼正在使用PSP,則上面8個寄存器壓入PSP,否則就壓入MSP。那問題來了,如何找到這個??臻g的地址呢?答案是SP, 但是前面提到壓棧時(shí)會有MSP和PSP,如何判斷觸發(fā)異常時(shí)使用的MSP還是PSP呢?答案是LR。到此確定完SP后,用戶便可以通過堆棧找到觸發(fā)異常的PC 值,并與反匯編的代碼對比就能得到哪條指令產(chǎn)生了異常。

總結(jié)下來,總體思路就是:首先通過LR判斷出異常產(chǎn)生時(shí)當(dāng)前使用的SP是MSP還是PSP,接著通過SP去得到產(chǎn)生異常時(shí)保存的PC值,最后與反匯編的代碼對比就能得到哪條指令產(chǎn)生了異常。

回到前面的第二個問題,如何通過LR判斷當(dāng)前使用的MSP還是PSP呢?參見如下圖,當(dāng)異常產(chǎn)生時(shí),LR 會被更新為異常返回時(shí)需要使用的特殊值(EXC_RETURN),其定義如下,其高 28 位置 1,第 0 位到第3位則提供了異常返回機(jī)制所需的信息,可見其中第 2 位標(biāo)示著進(jìn)入異常前使用的棧是 MSP還是PSP。


四、操作分析流程:

理解了以上的Hard Fault回溯的原理,下面按以上提到的兩種思路來實(shí)操一下。

1. ?心里明白徒手分析法

前面提到,為了清晰的展現(xiàn)這個過程以及每個參數(shù)之間的關(guān)系,盡量把整個流程按照順序整理到一張圖中,如下圖1。示例中使用的是KW36 temp_sensor_freeRTOS例子(什么例子不重要,該方法也適用于其他的MCU系列),在main函數(shù)中通過非對齊地址訪問故意制造Hard Fault錯誤,代碼如圖中序號1,當(dāng)程序試圖訪問讀取非對齊地址0xCCCC CCCC位置時(shí)程序就會跳入到Hard Fault Handler中,那具體是如何通過堆棧分析定位到出錯代碼是在n=*p這一行呢?具體步驟如下:


Step1:判斷SP是MSP還是PSP,找出SP地址。在產(chǎn)生Hard Fault異常后,首先在序號2中選擇“ CPU register”,不要使用默認(rèn)的 “CPU register ”,否則默認(rèn)只會顯示MSP,不會顯示PSP。然后查看序號3中LR寄存器的值表示判斷當(dāng)前程序使用堆棧為MSP主進(jìn)程或PSP子進(jìn)程堆棧,顯然LR=0xFFFFFFF9 的bit2=0,表示使用的是主棧,于是得到SP=序號4中的SP_main=0x20005620;

Step2:找出PC地址。如序號5演示,打開memory串口,輸入SP的地址可以找到異常產(chǎn)生前壓棧的8個寄存器,依次為 xPSR、PC、LR、R12以及 R3~R0,序號6中便可以找到出錯前PC的地址位0x00008a06;

Step3:找出代碼行數(shù)。如序號7演示,打開匯編窗口,在“go to”串口輸入PC地址,便可以找到具體出錯時(shí)代碼的位置,如序號8演示,可以發(fā)現(xiàn),輕松愉快的找到了導(dǎo)致Hard Fault的非對齊訪問的代碼行;

2. CmBacktrace 天龍大法

Step1: 從天龍大神的Github下載CmBacktrace的源代碼包,拷貝cm_backtrace目錄下的4個文件以及cmb_fault.s文件到KW36 IAR工程中,如下圖序號2標(biāo)識,并添加應(yīng)的搜索路徑;

Step2: 根據(jù)應(yīng)用修改cmb_cfg.h的配置,需要配置的選項(xiàng)包括print打印信息的重定義,是否需要支持OS,OS的類型(RTT、uCOS以及FreeRTOS),ARM內(nèi)核的類型,打印輸出語言類型等;本實(shí)例中使用了錯誤信息中文打印以及FreeRTOS,所以配置如下圖序號2標(biāo)識。


Step3: 修改FreeRTOS的task.c文件增加以下3個函數(shù),否則在編譯時(shí)會報(bào)錯提示這3個函數(shù)無定義。最簡單的做法就是直接使用CmBacktrace源代碼包的task.c替代KW36 SDK中的task.c文件。

Step4: 在啟動FreeRTOS啟動任務(wù)調(diào)度前初始化CmBacktrace庫以及配置信息,并在startup子任務(wù)中編寫故意制造錯誤的代碼,代碼如下。


Step5: 配置打印信息的輸出位置,建議的做法是輸出到物理串口,可以方便的離線分析記錄log, 但實(shí)驗(yàn)中為了簡化以及通用(有些時(shí)候硬件設(shè)計(jì)上可能沒有留硬件串口),直接把打印信息輸出到IAR的Terminal IO進(jìn)行顯示(Kinetis SDK如何修改代碼,使能打印信息輸出到IAR的Terminal IO的做法詳見另外一篇文檔)。

Step6: 運(yùn)行代碼,觀察打印結(jié)果,可以看到打印信息中包含出錯的任務(wù)名稱、出錯前的任務(wù)壓棧的8個通用寄存器名稱和內(nèi)容,從圖中可以一目了然的找出出錯的PC指針,如果進(jìn)一步去結(jié)合匯編代碼可以清晰的看到其能夠準(zhǔn)確定位到代碼出錯的位置。


Step7: 盡管在Step6中結(jié)合匯編找到了出錯的代碼行,但是前面吹過的一個牛逼還未實(shí)現(xiàn),就是使用CmBacktrace 可以支持不掛仿真器debug狀態(tài)下找到出錯的代碼行,那具體如何操作呢?答案其實(shí)在Step 5的打印信息中已經(jīng)揭曉“查看更多函數(shù)調(diào)用棧信息,請運(yùn)行:addr2line -e CmBacktrace.out -a -f 00005f12 0000dda4 ”。

于是拷貝工程的.out文件到\tools\addr2line\win64目錄下,在cmd命令行中執(zhí)行以上命令,結(jié)果如下圖的上半部分,可以看到出錯的任務(wù)是startup_task,出錯的文件是fsl_os_abstraction_free_rtos.c,出錯行號是135。結(jié)合截圖的下半部分的代碼去看,完全驗(yàn)證了這三個點(diǎn)。


到此,使用CmBacktrace大法不輕松但很愉悅的定位到問題點(diǎn)了。

五、總結(jié):

對于Hard Fault問題,通過以上兩種辦方法可以有效的找到問題點(diǎn),為后續(xù)進(jìn)一步分析定位問題指明方向。徒手分析法比較簡單,不需要額外添加代碼,缺點(diǎn)是只能在仿真狀態(tài)下調(diào)試,需要用戶對程序調(diào)用壓棧/出棧原理有清晰的理解。CmBacktrace 天龍大法則支持離線調(diào)試分析,但繁瑣點(diǎn)在于需要移植代碼,并配置工程和打印輸出,尤其在Hard Fault問題偶發(fā)(很多時(shí)候一天可能也復(fù)現(xiàn)不了一次問題)以及只有離線狀態(tài)下才能復(fù)現(xiàn)問題的情況下,使用CmBacktrace 的方法去定位問題是非常高效的。至于如何將錯誤信息使用 Easy Flash 的 Log 功能保存至 Flash 中,待設(shè)備死機(jī)后重啟依然能夠讀取上次的錯誤信息部分,時(shí)間關(guān)系筆者沒有深入研究,有興趣的可以嘗試實(shí)現(xiàn)。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉