在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁 > 博客 > 見鬼,過年回來后板子就 hardfault 了?

            見鬼,過年回來后板子就 hardfault 了?

            發(fā)布人:魚鷹談單片機(jī) 時間:2022-03-19 來源:工程師 發(fā)布文章

            快一個月沒有更新了,回家之前給自己安排了很多任務(wù),然后回到家之后電腦就沒有打開過,啥也沒干,不知道有多少人回家后的狀態(tài)和魚鷹是一樣的~~


            回來之后,準(zhǔn)備搞個腳本,自動讀取芯片 ID、修改頭文件 ID、自動編譯、下載。


            折騰了一晚上,讀取 ID 是搞定了,但是發(fā)現(xiàn)有個板子讀取 ID 后下載進(jìn)去發(fā)現(xiàn)直接 hardfault 了,可自己年前的時候明明代碼沒動、板子沒動,年前都是沒問題的啊。


            想不通,反正還有其他板子,直接換一塊,下載進(jìn)去,完全運(yùn)行正常。因?yàn)樘砹?,就暫時不管它。


            第二天晚上,還是沒想明白,本想不管的,想想反正沒事情,不如深入研究一下,萬一下次遇到這種問題,那不是很快就能定位了嘛。


            第一步,打開錯誤窗口(怎么打開的,自己看往期系列文章吧):

            圖片

            可以看出,總線錯誤,IMPRECISERR 、STKERR 置位(下面的是 BKPT 是人為給出, FORCED 是因?yàn)楸緛硎强偩€錯誤,但因?yàn)闆]有開啟該中斷,直接上訪成了 Hardfault,所以真正來說,這次異常應(yīng)該由總線異常中斷處理的)。


            突然想起年前好像也發(fā)生類似的事情,因?yàn)楫?dāng)時程序能正常運(yùn)行,換板子后不能運(yùn)行,立馬就想到了是芯片差異導(dǎo)致,改了代碼就好了;而現(xiàn)在時間過去太久,把這事情忘記了,就鬧了這一出(當(dāng)時解決問題太快,也沒深入研究,就沒有多少印象了)。


            其實(shí)這種事情很多工程師估計(jì)都遇到過,本來一個程序需要內(nèi)存 RAM 40 K,在一塊板子運(yùn)行的好好的,換一塊就不行,然后發(fā)現(xiàn)芯片實(shí)際只有 20K。


            一般建工程選芯片型號的時候,就會規(guī)定好 ROM、RAM大小,只要能正常編譯通過,問題都不大,但萬一搞錯了,就可能遇到魚鷹的情況了。

            圖片


            工程選擇 STM32F103RET6,實(shí)際芯片 STM32F103RCT6,內(nèi)存一個 64 K,一個 48K,偏偏我這個工程內(nèi)存用量接近滿了(如果 RAM 在 48  K 以內(nèi)即使下載了也是沒有問題的),程序也能正常下載,但運(yùn)行之后立刻 Hardfault 伺候。


            很多人遇到這個錯誤,束手無策,實(shí)際上掌握方法,并不是很難的事情。今天魚鷹教大家一步步排查定位這個錯誤,大家遇到了其他錯誤,也可以按魚鷹的思路解決。

            首先,《權(quán)威指南》肯定要有,然后就是在線調(diào)試了。


            從前面的錯誤信息可以了解到這是一個總線錯誤,但是我們看到地址這一欄,發(fā)現(xiàn)并不像有效地址(是否有效可以看 BFARVALID 是否置位),所以先不管它:

            圖片


            就看那兩個打鉤的位置啥意思了。看看《Cortex-M3 權(quán)威指南》咋說的:

            圖片


            了解這些就差不多了。


            此時,我們就要通過在線調(diào)試的方式定位錯誤代碼的位置了,畢竟上面的內(nèi)容只是給我們一個排查方向,但具體怎么解決還看代碼情況。


            通過單步運(yùn)行(代碼量大的話,可以用二分法排查),并且追蹤到匯編級別的代碼發(fā)現(xiàn),在即將運(yùn)行下面代碼時 LDR,[pc, #76],直接跳轉(zhuǎn)到了 Hardfault:



            PUSH {r4,lr}   // 執(zhí)行完成LDR,[pc, #76]  // 未執(zhí)行

            執(zhí)行 PUSH {r4,lr}  前,未報(bào)錯(黃色光標(biāo)位置代表即將執(zhí)行但未執(zhí)行的代碼

            圖片


            執(zhí)行后報(bào)錯,但是還沒有運(yùn)行到 hard fault (單步調(diào)試,芯片可能還沒反應(yīng)過來 -_-):

            圖片


            當(dāng)想單步執(zhí)行 LDR,[pc, #76] 時,直接進(jìn)入了 Hardfault 中斷:

            圖片


            這樣問題就很明確了,PUSH {r4,lr}  執(zhí)行有問題,這個和前面從權(quán)威指南中得到的信息是一致的。


            那么為什么壓棧操作會導(dǎo)致問題?


            此時我們可以看左邊的寄存器,壓棧前 0x2000F338 ,壓棧后 0x2000F330。


            如果對這個數(shù)據(jù)不敏感,可能不知道這個值超出了 48 K (49152,0xC000)范圍,沒那么快定位。


            沒關(guān)系,我們可以繼續(xù)看右邊魚鷹給出的內(nèi)存窗口,壓榨后 0x2000F330 和 0x2000F334 的值應(yīng)該和 R4、LR 值一一對應(yīng),實(shí)際上并沒有(先減 4,再賦值,圖片打開后很清晰,認(rèn)真分析)。


            于是很容易可以得出壓棧失敗的結(jié)論,進(jìn)而得出內(nèi)存訪問問題,從而發(fā)現(xiàn)芯片型號不對導(dǎo)致。


            后面魚鷹又查了英文版《Cortex M3與M4權(quán)威指南.pdf》,更詳細(xì)了一些:

            圖片

            IMPRECISERR   bit 解釋了:訪問無效內(nèi)存空間。

            圖片


            如此一來,hardfault 問題就順利解決了 ^_^ ^_^


            工作時間久了,這種問題很容易遇到,那么我們的代碼是否能自動根據(jù)某個寄存器來識別芯片型號,從而確定大小,繼而拒絕運(yùn)行呢?


            魚鷹發(fā)現(xiàn)在用 MDK 更新  ST-LINK 固件的時候,它居然知道我芯片型號的準(zhǔn)確容量大小(RAM 不行),從而拒絕下載,ST-LINK Utility 也是,就不知道它是通過讀取哪個寄存器得到這些信息的了,有知道的道友不如留言分享一下。


            圖片


            *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。

            萬能遙控器相關(guān)文章:萬能遙控器代碼


            波段開關(guān)相關(guān)文章:波段開關(guān)原理


            電容式接近開關(guān)相關(guān)文章:電容式接近開關(guān)原理
            電機(jī)保護(hù)器相關(guān)文章:電機(jī)保護(hù)器原理
            接近開關(guān)相關(guān)文章:接近開關(guān)原理


            關(guān)鍵詞: 單片機(jī)

            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉