利用Keil的Call Stack解決Hardfault問(wèn)題

一、問(wèn)題的由來(lái)

在調(diào)試STM32程序時(shí)卖漫,遇到了程序突然運(yùn)行到HardFault中斷的問(wèn)題。之前也遇到過(guò)類似的情況赠群,大多時(shí)憑借猜想解決問(wèn)題羊始,有時(shí)候不能夠很快的定位問(wèn)題來(lái)源。今天在調(diào)試時(shí)乎串,學(xué)到了一個(gè)有效的調(diào)試方法店枣,可以幫助我快速定位問(wèn)題點(diǎn)。
先貼出大神的博客:http://blog.sina.com.cn/s/blog_4aa25f130102v0m8.html

二叹誉、關(guān)于Hardfault

Cortex-M3/4的Fault異常是由于非法的存儲(chǔ)器訪問(wèn)(比如訪問(wèn)0地址、寫只讀存儲(chǔ)位置等)和非法的程序行為(比如除以0等)等造成的闷旧。常見的4種異常及產(chǎn)生異常的情況如下:
Bus Fault:在fetch指令长豁、數(shù)據(jù)讀寫、fetch中斷向量或中斷時(shí)存儲(chǔ)恢復(fù)寄存器棧情況下忙灼,檢測(cè)到內(nèi)存訪問(wèn)錯(cuò)誤則產(chǎn)生Bus Fault匠襟。
Memory Management Fault:訪問(wèn)了內(nèi)存管理單元(MPU)定義的不合法的內(nèi)存區(qū)域,比如向只讀區(qū)域?qū)懭霐?shù)據(jù)该园。
Usage Fault:檢測(cè)到未定義指令或在存取內(nèi)存時(shí)有未對(duì)齊酸舍。
Hard Fault:在調(diào)試程序過(guò)程中,這種異常最常見里初。上面三種異常發(fā)生任何一種異常都會(huì)引起Hard Fault啃勉,在上面的三種異常未使能的情況下,默認(rèn)發(fā)生異常時(shí)進(jìn)入Hard Fault中斷服務(wù)程序双妨。
需要注意的是淮阐,在默認(rèn)復(fù)位初始化時(shí),Hard Fault使能刁品,其它三者不使能泣特,因此當(dāng)程序中出現(xiàn)不合法內(nèi)存訪問(wèn)(一般是指針錯(cuò)誤引起)或非法的程序行為(一般就是數(shù)學(xué)里面常見的除0)時(shí)都將產(chǎn)生Hard Fault中斷。

三挑随、問(wèn)題分析

在網(wǎng)上查找相關(guān)資料状您,發(fā)現(xiàn)這種問(wèn)題主要有以下原因:
1 內(nèi)存溢出或者訪問(wèn)越界,通常為數(shù)組或結(jié)構(gòu)體訪問(wèn)越界兜挨。這個(gè)需要自己寫程序的時(shí)候規(guī)范代碼膏孟,遇到了需要慢慢排查。
2 堆棧溢出暑劝。增加堆棧的大小骆莹。
3 在uCos-III系統(tǒng)中,任務(wù)切換時(shí)要關(guān)中斷担猛。
4 沒有打開相應(yīng)的硬件模塊但操作了相應(yīng)的硬件而導(dǎo)致了錯(cuò)誤
5 Jlink的問(wèn)題幕垦,禁止用Jlink供電就可以了丢氢。在Jlink commander中輸入power off,
6程序在添加全局變量的時(shí)候會(huì)出現(xiàn)sprintf 輸出的浮點(diǎn)數(shù)不正常先改,因此盡量不用sprintf函數(shù)疚察。
7使用了非法的指針,比如說(shuō)空指針
u8 *p = null;
*p = 1; 把0地址的數(shù)據(jù)強(qiáng)制設(shè)置為1仇奶, 不錯(cuò)才怪
8使用 OS_ENTER_CRITICAL();
使用了 OS_ENTER_CRITICAL(); 卻忘了OS_EXIT_CRITICAL(); 退出臨界區(qū)
特別是在這個(gè)函數(shù)OS_ENTER_CRITICAL(); 調(diào)用了子函數(shù) 也有的這類情況貌嫡,很容易忘記關(guān)閉的這樣就造成了“死機(jī)現(xiàn)象”
因此如果調(diào)用的話 建議在函數(shù)中加入OS_CPU_SR cpu_sr = 0u;局部變量 在管理臨界區(qū) os的內(nèi)核程序也是這么用的 ,而且要注意该溯,臨界區(qū)一般用于全局變量的寫操作岛抄,時(shí)間要非常快的狈茉,任務(wù)中的變量可以不用添加 夫椭。

結(jié)合本項(xiàng)目的實(shí)際情況,我認(rèn)為內(nèi)存訪問(wèn)錯(cuò)誤的概率最大氯庆。

四蹭秋、排查過(guò)程

通過(guò)學(xué)習(xí)大神的文章,本次排查問(wèn)題主要利用了MDK中的Call Stack窗口堤撵。

1 在stm32f10x_it.c中仁讨,添加軟件斷點(diǎn),一旦調(diào)試時(shí)出現(xiàn)Hard Fault則會(huì)在停在斷點(diǎn)處实昨。

image.png

2調(diào)出Call Stack

image.png

3運(yùn)行程序洞豁,直到出現(xiàn)bug

image.png

如上圖所示,Call Stack記錄了出現(xiàn)異常前屠橄,單片機(jī)調(diào)用的一些函數(shù)族跛,從下到上,很像是飛機(jī)的黑匣子锐墙。
可以看到礁哄,我的程序運(yùn)行到了0x08004F40地址后,直接跳到了HardFault溪北。而這個(gè)地址的上一步執(zhí)行了Data_frame_parsing這個(gè)函數(shù)桐绒。首先定位到出錯(cuò)的地址,右鍵單擊那個(gè)地址之拨,選擇“Show Caller Code”就可以定位過(guò)去茉继。


image.png

定位到了這一行,對(duì)一個(gè)內(nèi)存地址進(jìn)行拷貝操作蚀乔,由于源地址和目標(biāo)地址都是在堆空間上malloc
出來(lái)的烁竭,于是我很快想到會(huì)不會(huì)是在拷貝前,由于某種原因源地址被free掉了吉挣,所以出現(xiàn)了內(nèi)存訪問(wèn)錯(cuò)誤派撕?


image.png

于是跑到這個(gè)函數(shù)調(diào)用的地方婉弹,果然發(fā)現(xiàn)緊跟著這個(gè)函數(shù)下面有一個(gè)free。于是改成了
while(Data_frame_parsing(p_wifi_rcv_frame) != 0);
free(p_wifi_rcv_frame);
大意就是等程序運(yùn)行完终吼,再釋放內(nèi)存空間镀赌。于是再仿真。际跪。商佛。發(fā)現(xiàn)依然進(jìn)了Hardfault。

然后我發(fā)現(xiàn)姆打,數(shù)據(jù)幀里有點(diǎn)不對(duì)勁良姆。


image.png

表示數(shù)據(jù)幀長(zhǎng)的這個(gè)字節(jié),居然是0x00幔戏!
然后我馬上意識(shí)到歇盼,我申請(qǐng)的這段內(nèi)存空間大小,是根據(jù)data_len這個(gè)成員的值來(lái)確定的评抚。
由于某種原因(通信丟包)這個(gè)地方寫入了0,于是申請(qǐng)的空間大小就是0伯复,之后再來(lái)訪問(wèn)這段內(nèi)存慨代,肯定就出錯(cuò)了!

確定了問(wèn)題啸如,接下來(lái)修改代碼侍匙。
在申請(qǐng)內(nèi)存空間之前,先判斷一下這個(gè)數(shù)叮雳,是不是在一個(gè)合理的范圍之內(nèi)想暗,如果是,就分配空間帘不,如果不是说莫,就說(shuō)明數(shù)據(jù)幀出問(wèn)題了,直接跳出寞焙。


image.png

再編譯储狭,運(yùn)行!OK了捣郊!再也沒有出現(xiàn)過(guò)Hardfault錯(cuò)誤辽狈。

五、總結(jié)

這個(gè)故事告訴我們呛牲。在寫一個(gè)程序的時(shí)候刮萌,對(duì)輸入的參數(shù)進(jìn)行合法性的檢查,是非常重要的娘扩,可以省去很多不必要的麻煩着茸。
在遇到Hardfault錯(cuò)誤時(shí)壮锻,可以用一個(gè)很直觀的方式觀察到是哪里出現(xiàn)了問(wèn)題,可以幫助我們快速的定位錯(cuò)誤元扔。解決bug躯保!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市澎语,隨后出現(xiàn)的幾起案子途事,更是在濱河造成了極大的恐慌,老刑警劉巖擅羞,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尸变,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡减俏,警方通過(guò)查閱死者的電腦和手機(jī)召烂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)娃承,“玉大人奏夫,你說(shuō)我怎么就攤上這事±荩” “怎么了酗昼?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)梳猪。 經(jīng)常有香客問(wèn)我麻削,道長(zhǎng),這世上最難降的妖魔是什么春弥? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任呛哟,我火速辦了婚禮,結(jié)果婚禮上匿沛,老公的妹妹穿的比我還像新娘扫责。我一直安慰自己,他們只是感情好俺祠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布公给。 她就那樣靜靜地躺著,像睡著了一般蜘渣。 火紅的嫁衣襯著肌膚如雪淌铐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天蔫缸,我揣著相機(jī)與錄音腿准,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吐葱,可吹牛的內(nèi)容都是我干的街望。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼弟跑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼灾前!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起孟辑,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤哎甲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后饲嗽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炭玫,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年貌虾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吞加。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尽狠,死狀恐怖衔憨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袄膏,我是刑警寧澤巫财,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站哩陕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赫舒。R本人自食惡果不足惜悍及,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望接癌。 院中可真熱鬧心赶,春花似錦、人聲如沸缺猛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荔燎。三九已至耻姥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間有咨,已是汗流浹背琐簇。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留座享,地道東北人婉商。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓似忧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親丈秩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盯捌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 計(jì)算機(jī)英語(yǔ)(編程詞匯大全) application 應(yīng)用程式 應(yīng)用、應(yīng)用程序 application framew...
    朱森閱讀 595評(píng)論 0 1
  • 隨著越來(lái)越多的用戶將生產(chǎn)應(yīng)用遷移到云平臺(tái)蘑秽,一些傳統(tǒng) IT 的運(yùn)維功能也相應(yīng)的需要改變饺著,例如監(jiān)控,備份等等筷狼。我們希望...
    ITknight閱讀 1,327評(píng)論 0 0
  • 一個(gè)人埂材,一杯水塑顺,一曲音樂,一顆還微微還為你跳動(dòng)的心俏险。 最不喜歡聽見你說(shuō)‘對(duì)不起’严拒,那三個(gè)字中的絕對(duì),比任何話都傷人...
    莫非仙閱讀 647評(píng)論 0 4
  • 01 我曾經(jīng)好多次向她約稿竖独,讓她寫他們之間的故事裤唠,可她始終不肯,直到前幾天莹痢,我們聊天再說(shuō)起這些往事种蘸,她突然哽咽了,...
    于湙遠(yuǎn)閱讀 552評(píng)論 0 1
  • 已經(jīng)日更了28天竞膳,卻因?yàn)橛齼褐苡浐讲t,全軍覆沒,挫敗感肯定很強(qiáng)烈坦辟,但愿賭服輸刊侯,大不了從頭再來(lái),這才是王道锉走。 我的目標(biāo)是...
    方土令閱讀 74評(píng)論 0 0