見鬼,過年回來后板子就 hardfault 了?
快一個月沒有更新了,回家之前給自己安排了很多任務,然后回到家之后電腦就沒有打開過,啥也沒干,不知道有多少人回家后的狀態(tài)和魚鷹是一樣的~~
回來之后,準備搞個腳本,自動讀取芯片 ID、修改頭文件 ID、自動編譯、下載。
折騰了一晚上,讀取 ID 是搞定了,但是發(fā)現有個板子讀取 ID 后下載進去發(fā)現直接 hardfault 了,可自己年前的時候明明代碼沒動、板子沒動,年前都是沒問題的啊。
想不通,反正還有其他板子,直接換一塊,下載進去,完全運行正常。因為太晚了,就暫時不管它。
第二天晚上,還是沒想明白,本想不管的,想想反正沒事情,不如深入研究一下,萬一下次遇到這種問題,那不是很快就能定位了嘛。
第一步,打開錯誤窗口(怎么打開的,自己看往期系列文章吧):
可以看出,總線錯誤,IMPRECISERR 、STKERR 置位(下面的是 BKPT 是人為給出, FORCED 是因為本來是總線錯誤,但因為沒有開啟該中斷,直接上訪成了 Hardfault,所以真正來說,這次異常應該由總線異常中斷處理的)。
突然想起年前好像也發(fā)生類似的事情,因為當時程序能正常運行,換板子后不能運行,立馬就想到了是芯片差異導致,改了代碼就好了;而現在時間過去太久,把這事情忘記了,就鬧了這一出(當時解決問題太快,也沒深入研究,就沒有多少印象了)。
其實這種事情很多工程師估計都遇到過,本來一個程序需要內存 RAM 40 K,在一塊板子運行的好好的,換一塊就不行,然后發(fā)現芯片實際只有 20K。
一般建工程選芯片型號的時候,就會規(guī)定好 ROM、RAM大小,只要能正常編譯通過,問題都不大,但萬一搞錯了,就可能遇到魚鷹的情況了。
工程選擇 STM32F103RET6,實際芯片 STM32F103RCT6,內存一個 64 K,一個 48K,偏偏我這個工程內存用量接近滿了(如果 RAM 在 48 K 以內即使下載了也是沒有問題的),程序也能正常下載,但運行之后立刻 Hardfault 伺候。
很多人遇到這個錯誤,束手無策,實際上掌握方法,并不是很難的事情。今天魚鷹教大家一步步排查定位這個錯誤,大家遇到了其他錯誤,也可以按魚鷹的思路解決。
首先,《權威指南》肯定要有,然后就是在線調試了。
從前面的錯誤信息可以了解到這是一個總線錯誤,但是我們看到地址這一欄,發(fā)現并不像有效地址(是否有效可以看 BFARVALID 是否置位),所以先不管它:
就看那兩個打鉤的位置啥意思了??纯础禖ortex-M3 權威指南》咋說的:
了解這些就差不多了。
此時,我們就要通過在線調試的方式定位錯誤代碼的位置了,畢竟上面的內容只是給我們一個排查方向,但具體怎么解決還看代碼情況。
通過單步運行(代碼量大的話,可以用二分法排查),并且追蹤到匯編級別的代碼發(fā)現,在即將運行下面代碼時 LDR,[pc, #76],直接跳轉到了 Hardfault:
PUSH {r4,lr} // 執(zhí)行完成LDR,[pc, #76] // 未執(zhí)行
執(zhí)行 PUSH {r4,lr} 前,未報錯(黃色光標位置代表即將執(zhí)行但未執(zhí)行的代碼):
執(zhí)行后報錯,但是還沒有運行到 hard fault (單步調試,芯片可能還沒反應過來 -_-):
當想單步執(zhí)行 LDR,[pc, #76] 時,直接進入了 Hardfault 中斷:
這樣問題就很明確了,PUSH {r4,lr} 執(zhí)行有問題,這個和前面從權威指南中得到的信息是一致的。
那么為什么壓棧操作會導致問題?
此時我們可以看左邊的寄存器,壓棧前 0x2000F338 ,壓棧后 0x2000F330。
如果對這個數據不敏感,可能不知道這個值超出了 48 K (49152,0xC000)范圍,沒那么快定位。
沒關系,我們可以繼續(xù)看右邊魚鷹給出的內存窗口,壓榨后 0x2000F330 和 0x2000F334 的值應該和 R4、LR 值一一對應,實際上并沒有(先減 4,再賦值,圖片打開后很清晰,認真分析)。
于是很容易可以得出壓棧失敗的結論,進而得出內存訪問問題,從而發(fā)現芯片型號不對導致。
后面魚鷹又查了英文版《Cortex M3與M4權威指南.pdf》,更詳細了一些:
IMPRECISERR bit 解釋了:訪問無效內存空間。
如此一來,hardfault 問題就順利解決了 ^_^ ^_^
工作時間久了,這種問題很容易遇到,那么我們的代碼是否能自動根據某個寄存器來識別芯片型號,從而確定大小,繼而拒絕運行呢?
魚鷹發(fā)現在用 MDK 更新 ST-LINK 固件的時候,它居然知道我芯片型號的準確容量大小(RAM 不行),從而拒絕下載,ST-LINK Utility 也是,就不知道它是通過讀取哪個寄存器得到這些信息的了,有知道的道友不如留言分享一下。
*博客內容為網友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。
萬能遙控器相關文章:萬能遙控器代碼
波段開關相關文章:波段開關原理
電容式接近開關相關文章:電容式接近開關原理 電機保護器相關文章:電機保護器原理 接近開關相關文章:接近開關原理