色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

記錄一次hard fault on handler的解決過(guò)程

冬至子 ? 來(lái)源:BruceTan ? 作者:BruceTan ? 2023-10-12 16:45 ? 次閱讀

背景

最近在做一個(gè)OTA的功能時(shí),遇到一個(gè)hard fault on handler的問(wèn)題,前前后后排查了將近2天,才將此問(wèn)題解決,因此做一個(gè)記錄,方便其它工程師,遇到此類問(wèn)題的時(shí)候有個(gè)參考。

環(huán)境

rt-thread v4.1.0
lwip2.1.2
cJSON-lastest
使能了posix的select和poll
CmBacktrace v1.3.0
使能了ulog組件

問(wèn)題和排查過(guò)程
最開始遇到問(wèn)題的時(shí)候,報(bào)以下錯(cuò)誤

psr: 0xa100000f
r00: 0xffffffff
r01: 0x2000def4
r02: 0xffffffff
r03: 0x7fffffff
r04: 0x00000000
r05: 0x20017f18
r06: 0x20000358
r07: 0xdeadbeef
r08: 0x00000000
r09: 0x00000001
r10: 0xdeadbeef
r11: 0xdeadbeef
r12: 0x00000000
lr: 0x08042ed9
pc: 0x08042ef8
hard fault on handler
bus fault:
SCB_CFSR_BFSR:0x82 PRECISERR SCB->BFAR:FFFFFFFF

使用CmBacktrace軟件包定位問(wèn)題

后來(lái)在論壇搜索相關(guān)的關(guān)鍵詞,有人推薦使用CmBacktrace軟件包,于是去安裝此軟件包,但是安裝了以后,報(bào)如下錯(cuò)誤

thread pri status sp stack size max used left tick error


rf_led 10 suspend 0x00000080 0x00000100 50% 0x0000000a 000
rf_send 10 suspend 0x000000a0 0x00000800 16% 0x00000009 000
rf_read 10 suspend 0x000000c0 0x00000200 39% 0x00000003 000
可以看到,CmBacktrace沒(méi)有打印完全,這時(shí)候我又去CmBacktrace的github倉(cāng)庫(kù),看有沒(méi)有人提相關(guān)的issue,發(fā)現(xiàn)是因?yàn)槲掖蜷_了ulog組件導(dǎo)致的,具體可以參考這個(gè)issue

Usage fault下沒(méi)輸出關(guān)鍵的call_stack信息

然后我按照鏈接,手動(dòng)修改CmBacktrace的打印宏定義為rt_kprintf,使用CmBacktrace的cmb_test的除零測(cè)試命令測(cè)試以后,可以正常打印了,這時(shí)候我太開心了,以為問(wèn)題基本上可以定位了,然而我發(fā)現(xiàn)我高興的還是太早了。

在cmb_test正常以后,當(dāng)我把問(wèn)題再次復(fù)現(xiàn)時(shí),CmBacktrace打印的信息,還是不全,和之前完全沒(méi)有變化!!!如下所示。

thread pri status sp stack size max used left tick error


rf_led 10 suspend 0x00000080 0x00000100 50% 0x0000000a 000
rf_send 10 suspend 0x000000a0 0x00000800 16% 0x00000009 000
rf_read 10 suspend 0x000000c0 0x00000200 39% 0x00000003 000

這就非常奇怪了,明明使用CmBacktrace的除零測(cè)試是OK的,為什么還是打印不正常呢?

使用PC和LR反推

看樣子是不能用CmBacktrace了,也許是我使用的姿勢(shì)不對(duì),也許是其他問(wèn)題,那就只能靠自己了。

我試著按照文章的方法去排查,結(jié)果發(fā)現(xiàn)復(fù)現(xiàn)問(wèn)題的時(shí)候,是在rtthread的timer里面,如下圖所示

1.jpg

這就讓我犯難了,這不會(huì)是rt-thread的問(wèn)題吧,rt-thread這么多年了,難道我一用就出問(wèn)題?

不破不立

不可能,絕對(duì)不可能,一定是我用的姿勢(shì)不對(duì),再換一個(gè)姿勢(shì)吧,不破不立,由于我的代碼是分模塊的,于是我就將自己感覺(jué)有問(wèn)題的模塊,一個(gè)一個(gè)注釋掉,如下圖所示,從后面往前面一個(gè)一個(gè)注釋,每注釋一個(gè)模塊,我就看看是否還會(huì)發(fā)生hardfualt

1.jpg

當(dāng)我把ota_init模塊注釋掉的時(shí)候,發(fā)現(xiàn)hardfualt沒(méi)了,這…這怎么可能呢,這個(gè)模塊我之前測(cè)試過(guò)的呀,跑了兩天都是正常的。

然后我發(fā)現(xiàn),設(shè)備每次出現(xiàn)hardfault的時(shí)候,系統(tǒng)的tick都是553600ms左右,如下所示,換算成分鐘也就是9分鐘這樣,9分鐘,9分鐘,9分鐘,9分鐘的時(shí)候還沒(méi)有出現(xiàn)hardfualt,我的ota模塊,是每10分鐘去服務(wù)器拉取一次做版本檢測(cè),這么說(shuō),是這里的問(wèn)題了?

| /

RT - Thread Operating System
/ | 4.1.0 build Jan 6 2023 17:42:12
2006 - 2022 Copyright by RT-Thread team
lwIP-2.1.2 initialized!
[4416] I/sal.skt: Socket Abstraction Layer initialize success.
[4574] I/rfid_config: reader.id : 4403061904001
[4579] I/rfid_config: reader.beep : 0
[4584] I/rfid_config: report.interval : 60
[4588] I/rfid_config: reader.power : 10
[4594] D/ota_module: ota_flag == ERASE_IAP_FLAG
msh />[4715] D/rfid_module: rfid_report tag
[65630] D/rfid_module: rfid_report tag
[126649] D/rfid_module: rfid_report tag
[187613] D/rfid_module: rfid_report tag
[248612] D/rfid_module: rfid_report tag
[309611] D/rfid_module: rfid_report tag
[370595] D/rfid_module: rfid_report tag
[430629] D/rfid_module: rfid_report tag
[491631] D/rfid_module: rfid_report tag
[552598] D/rfid_module: rfid_report tag
thread pri status sp stack size max used left tick error

tcp_ser 10 suspend 0x000001d8 0x00000800 25% 0x0000000a 000
udp_ser 10 suspend 0x00000228 0x00000400 53% 0x0000000a 000
rf_led 10 suspend 0x00000080 0x00000100 50% 0x0000000a 000
rf_send 10 suspend 0x000000a0 0x00000800 16% 0x00000003 000
rf_read 10 suspend 0x000000c0 0x00000200 37% 0x00000004 000
| /

RT - Thread Operating System
/ | 4.1.0 build Jan 6 2023 17:42:12
2006 - 2022 Copyright by RT-Thread team
lwIP-2.1.2 initialized!
[4416] I/sal.skt: Socket Abstraction Layer initialize success.
[4574] I/rfid_config: reader.id : 4403061904001
[4579] I/rfid_config: reader.beep : 0
[4584] I/rfid_config: report.interval : 60
[4588] I/rfid_config: reader.power : 10
[4594] D/ota_module: ota_flag == ERASE_IAP_FLAG
msh />[4716] D/rfid_module: rfid_report tag
[65642] D/rfid_module: rfid_report tag
[126601] D/rfid_module: rfid_report tag
[151604] D/rfid_module: rfid_report tag
[187619] D/rfid_module: rfid_report tag
[248596] D/rfid_module: rfid_report tag
[309616] D/rfid_module: rfid_report tag
[370621] D/rfid_module: rfid_report tag
[431620] D/rfid_module: rfid_report tag
[492616] D/rfid_module: rfid_report tag
[553600] D/rfid_module: rfid_report tag
thread pri status sp stack size max used left tick error


rf_led 10 suspend 0x00000080 0x00000100 50% 0x0000000a 000
rf_send 10 suspend 0x000000a0 0x00000800 16% 0x00000009 000
rf_read 10 suspend 0x000000c0 0x00000200 39% 0x00000003 000

于是我把OTA的時(shí)間改成每10秒一次,果然10秒以后,就出現(xiàn)了hardfault

峰回路轉(zhuǎn)

那么問(wèn)題很明確了,就是這個(gè)OTA模塊的問(wèn)題,于是我在OTA模塊里面打斷點(diǎn)排查,發(fā)現(xiàn)在socket里面,發(fā)送UDP數(shù)據(jù)包的時(shí)候,就出現(xiàn)了hardfault,如下所示

1.jpg

這會(huì)是數(shù)組越界導(dǎo)致的嗎?于是我開始排查在這個(gè)udp發(fā)送函數(shù)前面的代碼,仔細(xì)排查以后,沒(méi)發(fā)現(xiàn)有數(shù)組越界的現(xiàn)象。線索又?jǐn)嗔恕?怎么辦呢?我左思右想,問(wèn)題就出現(xiàn)在這,到底是什么原因?

柳暗花明

udp發(fā)送,udp發(fā)送,會(huì)不會(huì)是這個(gè)線程爆棧了,于是我瞟了一眼這個(gè)線程的棧大小,哎喲我去,512字節(jié)。

thread = rt_thread_create("ota", ota_thread, RT_NULL, 512, 10, 10);
那我就改一下吧,改1024試試,果然,正常了….松了一口氣…

原來(lái)這個(gè)線程的棧是1024字節(jié)的,后面我使用ps命令看了這個(gè)線程棧的利用率還很低,于是我改成了512字節(jié),這也就是說(shuō),為什么我之前測(cè)試了2天這個(gè)模塊都是正常的,現(xiàn)在卻不行了。因?yàn)槲沂褂胮s命令的時(shí)候,那會(huì)才運(yùn)行了幾分鐘,看到的線程棧利用率是沒(méi)有調(diào)用udp發(fā)送函數(shù)的,也就是說(shuō),那會(huì)看到的棧利用率,是不準(zhǔn)的,那時(shí)候我去減小它,肯定就容易出問(wèn)題了

當(dāng)系統(tǒng)正常以后,我再次去ps,發(fā)現(xiàn)線程實(shí)際的棧利用率是92%,如下所示(前面的ps是沒(méi)有調(diào)用udp函數(shù)之前的,后面的ps是調(diào)用udp函數(shù)以后的,這時(shí)候的棧我設(shè)置的大小是1024),也就是說(shuō),512字節(jié),肯定是不夠的,甚至1024都快爆了,還得增大。

thread pri status sp stack size max used left tick error

ota 10 suspend 0x0000007c 0x00000400 32% 0x00000005 000
sys_led 10 suspend 0x0000007c 0x00000100 48% 0x0000000a 000
tshell 20 running 0x00000094 0x00001000 13% 0x00000003 000
tcpip 10 suspend 0x000000d0 0x00002000 07% 0x00000014 000
etx 12 suspend 0x00000094 0x00000400 14% 0x00000010 000
erx 12 suspend 0x00000094 0x00000400 56% 0x00000010 000
sys work 23 suspend 0x00000060 0x00000800 53% 0x0000000a 000
tidle0 31 ready 0x00000048 0x00000100 45% 0x00000009 000
timer 4 suspend 0x00000064 0x00000200 24% 0x00000009 000
main 10 suspend 0x00000084 0x00000800 33% 0x0000000e 000
msh />
msh />
msh />
msh />
msh />[14598] D/udp_module: send success
[14628] D/ota_module: ota_flag == ERASE_IAP_FLAG
ps
thread pri status sp stack size max used left tick error

ota 10 suspend 0x0000007c 0x00000400 92% 0x00000001 000
sys_led 10 suspend 0x0000007c 0x00000100 48% 0x0000000a 000
tshell 20 running 0x0000020c 0x00001000 13% 0x00000007 000
tcpip 10 suspend 0x000000d0 0x00002000 07% 0x00000014 000
etx 12 suspend 0x00000094 0x00000400 14% 0x00000010 000
erx 12 suspend 0x00000094 0x00000400 56% 0x00000010 000
sys work 23 suspend 0x00000060 0x00000800 53% 0x0000000a 000
tidle0 31 ready 0x00000058 0x00000100 45% 0x00000018 000
timer 4 suspend 0x00000064 0x00000200 24% 0x00000009 000
main 10 suspend 0x00000084 0x00000800 33% 0x0000000e 000

總結(jié)

使用了網(wǎng)絡(luò)的線程,一定要將線程棧開大一點(diǎn),512字節(jié)肯定是不夠的,最少1536字節(jié)以上
使用ps命令打印出來(lái)的線程棧最大使用率,是在代碼運(yùn)行過(guò)一段時(shí)間以后,才準(zhǔn)的,比如我的代碼中,udp發(fā)送數(shù)據(jù)是在系統(tǒng)啟動(dòng)10分鐘以后才運(yùn)行到,所以我在前面幾分鐘的時(shí)候使用的ps命令看,ota線程是沒(méi)有爆棧的,只有在運(yùn)行到這個(gè)網(wǎng)絡(luò)發(fā)送數(shù)據(jù)的代碼,這個(gè)棧才會(huì)溢出。

因此如果有一些代碼不是立即運(yùn)行的,在調(diào)試的時(shí)候,可以把這個(gè)時(shí)間提前,盡量讓系統(tǒng)上電以后,把所有的代碼都能跑一遍,這樣對(duì)于一些跑了一段時(shí)間才出現(xiàn)棧溢出的問(wèn)題,比較容易復(fù)現(xiàn),容易復(fù)現(xiàn)也就容易解決。

或者可以在調(diào)試代碼的時(shí)候,可以把線程棧設(shè)置大一些,讓代碼先能夠正常跑起來(lái),然后跑個(gè)幾天,再去ps一下看看棧的最大利用率,幾天以后所有的代碼、流程應(yīng)該基本上都跑過(guò)一遍了,這時(shí)候的棧利用率才是比較準(zhǔn)的,這時(shí)候才去優(yōu)化這個(gè)棧大小,會(huì)比較合適。

在遇到hardfault的時(shí)候,不要怕,用工具不行,我們就手動(dòng)一個(gè)一個(gè)模塊去排查,把問(wèn)題的范圍縮小,盡管耗費(fèi)的時(shí)間會(huì)長(zhǎng)一點(diǎn),但是總會(huì)定位到問(wèn)題的。

最后我想,如果rt-thread可以在棧溢出的時(shí)候,自動(dòng)檢測(cè)并且定位出來(lái)就好了,比如我這個(gè)ota的線程棧溢出了,rt-thread就告訴我,xxxx線程棧溢出啦,你得開辟大一點(diǎn),就好了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • OTA
    OTA
    +關(guān)注

    關(guān)注

    7

    文章

    578

    瀏覽量

    35196
  • LwIP協(xié)議棧
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    7347
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1285

    瀏覽量

    40089
  • UDP通信
    +關(guān)注

    關(guān)注

    0

    文章

    21

    瀏覽量

    1901
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【經(jīng)驗(yàn)】飛思卡爾工程師教你如何定位Kinetis MCU Hard Fault 異常

    看到有朋友遇到Hard Fault 異常錯(cuò)誤,特地找到篇飛思卡爾工程師寫的片經(jīng)驗(yàn)帖,定位Hard F
    發(fā)表于 01-31 22:06

    記錄一次STM32H743 CANFD調(diào)試過(guò)程中的一次BUG

    記錄一次STM32H743 CANFD調(diào)試過(guò)程中的一次BUG
    發(fā)表于 08-13 06:30

    通過(guò)SPI往SD卡寫數(shù)據(jù)出現(xiàn)bus hard_fault該怎樣去解決這個(gè)問(wèn)題呢

    ???難道是系統(tǒng)時(shí)鐘不穩(wěn)定么,設(shè)備測(cè)試一次,大約需要寫卡2.5w,有概率會(huì)出現(xiàn)這個(gè)bug,但出現(xiàn)一次hard_fault就裂開了。請(qǐng)各位老師支支招,萬(wàn)分感謝
    發(fā)表于 08-15 11:29

    記錄一次hard fault on handler的解決過(guò)程

    背景最近在做個(gè)OTA的功能時(shí),遇到個(gè)hard fault on handler的問(wèn)題,前前后后排查了將近2天,才將此問(wèn)題解決,因此做
    發(fā)表于 02-09 14:36

    新手求助刪掉某行LOG_I會(huì)導(dǎo)致hard fault on handler

    : 0x0806128d pc: 0x08061290 hard fault on handler usage fault: SCB_CFSR_UFSR:0x01 UNDEFINSTR
    發(fā)表于 05-17 10:14

    程序在運(yùn)行段時(shí)間后報(bào)In Hard Fault Handler錯(cuò)誤怎么解決?

    各位大神,我的程序在運(yùn)行段時(shí)間后報(bào)In Hard Fault Handler錯(cuò)誤, In Hard F
    發(fā)表于 06-13 08:22

    M0516LDE老是進(jìn)入Hard_Fault_Handler的原因?怎么解決?

    M0516 LDE,老是進(jìn)入Hard_Fault_Handler
    發(fā)表于 06-27 08:57

    程序在運(yùn)行段時(shí)間后報(bào)In Hard Fault Handler錯(cuò)誤的原因?怎么解決?

    各位大神,我的程序在運(yùn)行段時(shí)間后報(bào)In Hard Fault Handler錯(cuò)誤, In Hard F
    發(fā)表于 06-28 06:02

    程序在運(yùn)行段時(shí)間后報(bào)In Hard Fault Handler錯(cuò)誤的原因?

    各位大神,我的程序在運(yùn)行段時(shí)間后報(bào)In Hard Fault Handler錯(cuò)誤, In Hard F
    發(fā)表于 08-28 07:45

    一次過(guò)程的等值電路

    一次過(guò)程的等值電路 圖 一次過(guò)程的等值電路 在電動(dòng)機(jī)端子上安裝阻抗匹配器可
    發(fā)表于 07-18 11:24 ?1699次閱讀
    <b class='flag-5'>一次</b>波<b class='flag-5'>過(guò)程</b>的等值電路

    鬼魅樣的 Hard Fault

    STM32 鬼魅樣的 Hard Fault
    發(fā)表于 12-07 17:53 ?0次下載

    使用指針調(diào)用函數(shù)產(chǎn)生 Hard Fault

    使用指針調(diào)用函數(shù)產(chǎn)生 Hard Fault
    發(fā)表于 12-07 17:52 ?0次下載

    stm32h743外部RAM非字節(jié)對(duì)齊訪問(wèn),引起的hard fault

    stm32h743外部RAM非字節(jié)對(duì)齊訪問(wèn),引起的hard fault
    發(fā)表于 12-09 09:21 ?5次下載
    stm32h743外部RAM非字節(jié)對(duì)齊訪問(wèn),引起的<b class='flag-5'>hard</b> <b class='flag-5'>fault</b>

    單片機(jī)硬錯(cuò)誤排查方法

    \PROCIMPORT hard_fault_handler_cTST LR, #4ITE EQMRSEQ R0, MSPMRSNE R0, PSPB hard_fault_handler_cENDP2、然后把 hard_fault_h
    發(fā)表于 12-16 16:54 ?0次下載
    單片機(jī)硬錯(cuò)誤排查方法

    STM32H750上使用PCROP后導(dǎo)致Hard Fault

    電子發(fā)燒友網(wǎng)站提供《STM32H750上使用PCROP后導(dǎo)致Hard Fault.pdf》資料免費(fèi)下載
    發(fā)表于 09-20 09:10 ?11次下載
    STM32H750上使用PCROP后導(dǎo)致<b class='flag-5'>Hard</b> <b class='flag-5'>Fault</b>
    主站蜘蛛池模板: 久久精品久久久久| 日本护士hd| 国产69精品久久久久人妻刘玥| 污污内射在线观看一区二区少妇 | thermo脱色摇床安卓下载| 青青青久久久| 九九热这里都是精品| 第一次处破女18分钟免费| 亚洲精品无夜久久久久久久久| 欧美日韩1区| 久久无码人妻AV精品一区| 国产精品成人影院| YELLOW视频在线观看最新 | 丰满的美女射精动态图| 在线a亚洲视频| 翁熄性放纵交换300章| 女女破视频在线观看| 精品国产乱码久久久久久免费流畅 | 小小水蜜桃免费影院| 久久精品国产亚洲AV蜜臀| 国产精品第八页| 成人免费观看国产高清| 2017必看无码作品| 用快播看黄的网站| 亚洲zooz人禽交xxxx| 天美传媒在线观看完整高清| 欧美亚洲曰韩一本道| 男女午夜性爽快免费视频不卡| 黄网13区| 国内精品蜜汁乔依琳视频| 国产产一区二区三区久久毛片国语| WWW国产精品内射老师| 中文字AV字幕在线观看| 伊人久久大香线蕉综合色啪| 亚洲AV电影天堂男人的天堂| 我的奶头被客人吸的又肿又红| 日本亚欧热亚洲乱色视频| 欧美多人群p刺激交换电影| 蜜臀AV熟女人妻中文字幕| 久久精品国产在热亚洲| 精品久久伦理中文字幕|