在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

ES32F36xx芯片發生HardFault異常時的函數調用關系及問題定位

東軟載波微電子 ? 來源:東軟載波微電子 ? 2023-06-20 09:30 ? 次閱讀

Part1引言

Cortex-M3微控制器因其功能強大、性價比高以及易用性好,在嵌入式體系結構中得到了廣泛應用。然而,在實際開發過程中,如果程序很大或運行很久后可能會遇到HardFault異常。為了快速有效地解決HardFault異常,本文將討論定位HardFault問題的方法。

Part2常見引發HardFault原因

  1. 訪問非法內存地址:編程中處理指針時可能導致訪問未定義的內存地址,特別是在數組越界、非法指針解引用等情況下。
  2. 疊棧溢出:程序運行過程中如果棧溢出,會導致棧上數據錯誤,從而引發異常。
  3. 寄存器未正確初始化:寄存器配置和使用不正確,可能導致硬件異常。
  4. 除0運算:當程序試圖執行除0運算時,可能發生硬件故障異常。
  5. 總線錯誤:外設總線通信發生錯誤,可能引起硬件故障。

Part3軟件觸發HardFault異常

ES32F36xx是Cortex-M3內核,當被除數為0時,硬件將觸發一個異常,導致系統進入Hard Fault異常狀態。這種情況下,處理器不能正常運行,并且不能恢復,直到硬件或軟件采取措施使得系統回到正常狀態。在ES32_SDK中,ES32F36xx 的KEY_LED_ADC例程中增加如下程序:

//B函數
voidB_Function(void)
{
printf_e("EnterBfunction
");
C_Function(0);
printf_e("ExitBfunction
");
}
//A函數
voidA_Function(void)
{
printf_e("EnterAfunction
");
B_Function();
printf_e("ExitAfunction
");
}
//C函數
intC_Function(intval)
{
return100/val;
}
//D函數
voidD_Function(void)
{
printf_e("EnterDfunction
");
C_Function(1);
printf_e("ExitDfunction
");
}
//TestDebug函數
voidTestDebug(void)
{
//使能除0異常
volatileint*CCR=(volatileint*)0xE000ED14;
*CCR|=(1<4);

A_Function();
D_Function();
}
//主函數
intmain(void)
{
uart_stdio_init();

TestDebug();
while(1);
}

如圖 1所示,工程文件中,User選項中增加“fromelf -a -c --output=all.dis .objout.axf“,生成匯編文件。

52ee25b6-0f02-11ee-962d-dac502259ad0.png

圖1 MDK工程生成匯編文件配置

Part4HardFault異常函數調用關系及問題定位

上述程序運行過程中會發生hardfault異常,發生hardfault異常瞬間,程序立刻中止運行,硬件自動保存“調用者保存寄存器“的值到棧,同時跳轉到異常向量表執行異常處理函數。如圖 2所示為發生異常瞬間,硬件自動保存xPSR、ReturnAddress、LR、R12、R3、R2、R1及R0寄存器。

5306ff82-0f02-11ee-962d-dac502259ad0.png

圖2 處理器進入異常時的棧幀

硬件僅保存了部分寄存器,為了保存發生異常瞬間所有寄存器值,程序跳轉到中斷向量處需要執行如下的匯編代碼:

;getcurrentcontext
TSTlr,#0x04;if(!EXC_RETURN[2])
ITEEQ
;[2]=0==>Z=1,getfaultcontextfromhandler
MRSEQr0,msp
;[2]=1==>Z=0,getfaultcontextfromthread
MRSNEr0,psp

STMFDr0!,{r4-r11};pushr4-r11register
STMFDr0!,{lr};將EXC_RETURN值壓棧

TSTlr,#0x04;if(!EXC_RETURN[2])
ITEEQ
;R0為棧值,作為hw_hardfault_exception函數首個參數
MSREQmsp,r0
;[2]=1==>Z=0,getfaultcontextfromthread
MSRNEpsp,r0

;再次將EXC_RETURN值壓棧
PUSH{lr}
;跳轉至hw_hardfault_exception函數
BLhw_hardfault_exception
POP{lr}
ORRlr,lr,#0x04
BXlr
ENDP

上述匯編代碼的主要功能是獲取棧(SP)地址,并將R4 ~ R11壓棧,跳轉執行hw_hardfault_exception函數。壓棧后棧中的數據情況如圖 3所示:

533019da-0f02-11ee-962d-dac502259ad0.png

圖3 hardfault異常瞬間棧中完整寄存器

Return Address是發生異常指令點,LR是發生異常指令所在函數的下一條指令地址。在hw_hardfault_exception函數中將棧中的寄存器值都通過串口打印出來。

voidhw_hardfault_exception(structexception_info*exception_info)
{
uint32_t*app_sp=NULL;
inti=0;
/*sp指向發生hardfault前棧地址*/
app_sp=(uint32_t*)(exception_info+1);/*context+16*4*/

printf_e("psr:0x%08x
",exception_info->psr);
printf_e("r00:0x%08x
",exception_info->r0);
printf_e("r01:0x%08x
",exception_info->r1);
printf_e("r02:0x%08x
",exception_info->r2);
printf_e("r03:0x%08x
",exception_info->r3);
printf_e("r04:0x%08x
",exception_info->r4);
printf_e("r05:0x%08x
",exception_info->r5);
printf_e("r06:0x%08x
",exception_info->r6);
printf_e("r07:0x%08x
",exception_info->r7);
printf_e("r08:0x%08x
",exception_info->r8);
printf_e("r09:0x%08x
",exception_info->r9);
printf_e("r10:0x%08x
",exception_info->r10);
printf_e("r11:0x%08x
",exception_info->r11);
printf_e("r12:0x%08x
",exception_info->r12);
printf_e("lr:0x%08x
",exception_info->lr);
printf_e("pc:0x%08x
",exception_info->pc);

printf_e("stacks:
");

for(i=0;i%08x",*app_sp);
app_sp++;
++i;
if(i%16==0)
printf_e("
");
}
printf_e("
");
while(1);
}

在hw_hardfault_handler函數中打印出了所有相關寄存器,如圖 4所示:

534e5b84-0f02-11ee-962d-dac502259ad0.png

圖4 發生異常時棧數據

從打出來的返回地址值(PC)為0x00000644,在生成的all.dis匯編文件搜索該地址,如圖 5所示,該地址是C_Function函數中的一個除法指令,R0寄存器值除以R1寄存器值,并將結果存放R0中。R0為0x64,確認R1寄存器值即可。

536ed5b2-0f02-11ee-962d-dac502259ad0.png

圖5 發生hardfault異常瞬間執行的指令

圖 4中,LR的值為0x0000060f,all.dis無法搜索到該地址。由于Cortex-M3使用的是Thumb指令集,bit0置位指示該地址地址指令是Thumb指令。bit0復位,搜索0x0000060e,如圖 6所示,該地址在B_Function函數中。B_Function函數調用了C_Function函數,R0為傳遞的參數0。由此可知,圖 5中,R1的除數值0,故程序會發生hardfault異常。

5390e8be-0f02-11ee-962d-dac502259ad0.png

圖6 B_Function函數的匯編代碼

圖 6中,調用C_Function函數前,R4和LR寄存器被壓入了棧中。即圖 7中,LR的值為0x000005D1,R4的值為0xe000ed14。

53b699ce-0f02-11ee-962d-dac502259ad0.png

圖 7 B_Function函數壓棧值

如圖 8所示,在all.dis文件搜索0x000005D0地址在A_Function函數中,在執行A_Function函數前,對R4和LR進行了壓棧。A_Function函數調用了B_Function函數。

53dbee18-0f02-11ee-962d-dac502259ad0.png

圖 8 A_Function函數匯編代碼

如圖 9所示,A_Function函數壓入的R4值為0xe000ed14,LR值為0x000006a1。

53ed5522-0f02-11ee-962d-dac502259ad0.png

圖 9 A_Function函數壓棧值

如圖 10,在all.dis文件中,搜索0x000006a0,發現該地址在TestDebug函數中,且該函數將R4和LR壓入棧中。

54129eae-0f02-11ee-962d-dac502259ad0.png

圖 10 TestDebug函數匯編代碼

如圖 11所示,A_Function函數壓入的R4值為0xe0001c18,LR值為0x00001ab9。

543cebdc-0f02-11ee-962d-dac502259ad0.png

圖 11 TestDebug函數壓棧值

如圖 12所示,在all.dis文件中,搜索0x00001ab8,該地址在main函數中。

5464664e-0f02-11ee-962d-dac502259ad0.png

圖 12 main函數的匯編代碼

至此,如圖 13所示為發生hardfault異常時函數的調用關系,在C_Function函數中,被除數為0是導致進入hardfault異常的原因。

547da280-0f02-11ee-962d-dac502259ad0.png

圖 13 發生hardfault時的函數調用關系


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 微控制器
    +關注

    關注

    48

    文章

    7557

    瀏覽量

    151446
  • 芯片
    +關注

    關注

    455

    文章

    50832

    瀏覽量

    423817
  • 函數
    +關注

    關注

    3

    文章

    4332

    瀏覽量

    62640

原文標題:工程師筆記 | ES32F36xx芯片發生HardFault異常時的函數調用關系及問題定位

文章出處:【微信號:東軟載波微電子,微信公眾號:東軟載波微電子】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    【轉載】快速追蹤和定位產生HardFault原因的方法

    AN0028—快速追蹤和定位產生HardFault原因的方法概述在使用ARM Cortex-M 系列 MCU時(如AT32 MCU),有時會出現程序運行異常。當通過編譯器在debug模式查原因
    發表于 08-17 09:44

    靈動微課堂 (第173講) | HardFault定位方法和步驟

    根據上述的定位手段可以查找是哪一種情況造成的異常,在編程過程中需要避免出現上述異常情況,但是在惡劣復雜的環境下,可能會小概率觸發HardFault中斷,可以在
    發表于 07-02 15:20

    STM32F101xx和STM32F103xx固件函數

    STM32F101xx和STM32F103xx固件函數庫函數使用說明手冊,開發必備工具!
    發表于 10-29 11:10 ?58次下載

    S32K1XX調試--快速定位HardFault

    1、背景程序運行,發現程序跑飛到HardFault,但不清楚為什么會跑到HardFault中斷處理函數去。2、分析要想知道為什么會跑到HardFault_Handler中去,就很有必要
    發表于 12-03 15:21 ?5次下載
    S32K1<b class='flag-5'>XX</b>調試--快速<b class='flag-5'>定位</b><b class='flag-5'>HardFault</b>

    ES32F36xx USB例程應用筆記

    電子發燒友網站提供《ES32F36xx USB例程應用筆記.pdf》資料免費下載
    發表于 09-22 11:02 ?2次下載
    <b class='flag-5'>ES32F36xx</b> USB例程應用筆記

    ES32F36xx Bootloader應用筆記

    電子發燒友網站提供《ES32F36xx Bootloader應用筆記.pdf》資料免費下載
    發表于 09-22 11:01 ?0次下載
    <b class='flag-5'>ES32F36xx</b> Bootloader應用筆記

    ES32F36xx應用筆記

    電子發燒友網站提供《ES32F36xx應用筆記.pdf》資料免費下載
    發表于 09-22 10:59 ?2次下載
    <b class='flag-5'>ES32F36xx</b>應用筆記

    ES022 STM32F05xx,STM32F107xx勘誤手冊

    ES022 STM32F05xx,STM32F107xx勘誤手冊
    發表于 11-23 20:31 ?0次下載
    <b class='flag-5'>ES</b>022 STM32<b class='flag-5'>F05xx</b>,STM32<b class='flag-5'>F107xx</b>勘誤手冊

    ES0022_STM32F105xx和STM32F107xx單片機的局限性

    ES0022_STM32F105xx和STM32F107xx單片機的局限性
    發表于 11-23 20:36 ?0次下載
    <b class='flag-5'>ES0022_STM32F105xx</b>和STM32<b class='flag-5'>F107xx</b>單片機的局限性

    ES0321_STM32F496xx和STM32F4A6xx單片機的局限性

    ES0321_STM32F496xx和STM32F4A6xx單片機的局限性
    發表于 11-23 20:36 ?0次下載
    <b class='flag-5'>ES0321_STM32F496xx</b>和STM32<b class='flag-5'>F4A6xx</b>單片機的局限性

    ES0321_STM32F469xx和STM32F479xx單片機的局限性

    ES0321_STM32F469xx和STM32F479xx單片機的局限性
    發表于 11-23 20:37 ?0次下載
    <b class='flag-5'>ES0321_STM32F469xx</b>和STM32<b class='flag-5'>F479xx</b>單片機的局限性

    AT32講堂009 | 基于CmBacktrace庫,如何快速追蹤和定位產生HardFault的原因

    概述在使用ARMCortex-M系列MCU時(如AT32MCU),有時會出現程序運行異常。當通過編譯器在debug模式查原因時,會發現程序跑到HardFault_Handler函數中,產生
    的頭像 發表于 06-15 10:44 ?3873次閱讀
    AT32講堂009 | 基于CmBacktrace庫,如何快速追蹤和<b class='flag-5'>定位</b>產生<b class='flag-5'>HardFault</b>的原因

    ES32F36xx芯片發生HardFault異常時的函數調用關系及問題定位

    ES32F36xx芯片發生HardFault異常時的函數調用
    的頭像 發表于 11-06 17:13 ?780次閱讀
    <b class='flag-5'>ES32F36xx</b><b class='flag-5'>芯片</b><b class='flag-5'>發生</b><b class='flag-5'>HardFault</b><b class='flag-5'>異常</b>時的<b class='flag-5'>函數</b><b class='flag-5'>調用</b><b class='flag-5'>關系</b>及問題<b class='flag-5'>定位</b>

    一個地址未對齊引起的HardFault異常

    一個地址未對齊引起的 HardFault 異常
    的頭像 發表于 09-18 10:57 ?824次閱讀
    一個地址未對齊引起的<b class='flag-5'>HardFault</b><b class='flag-5'>異常</b>

    python函數函數之間的調用

    函數函數之間的調用 3.1 第一種情況 程序代碼如下: def x ( f ): def y (): print ( 1 ) return y def
    的頭像 發表于 10-04 17:17 ?600次閱讀
    主站蜘蛛池模板: 97久草| 久久婷婷激情| 国产成人精品一区二区三区| 国产综合在线视频| 西西人体www303sw大胆高清| 午夜操一操| 一区二区三区视频在线观看| 日本不卡视频一区二区三区| 久久在线播放| 亚洲狠狠综合久久| 午夜精品福利在线观看| 日本xxxx色视频在线观看免| 美女艹逼视频| va在线| 奇米影视777狠狠狠888不卡 | 亚1州区2区三区4区产品| 色偷偷888欧美精品久久久| 久久看片网| 婷婷六月丁香午夜爱爱| 亚a在线| 午夜爽爽| 毛片其地| 亚洲午夜视频| 国产精品1区2区3区| 亚洲一区二区欧美| 亚洲一区二区电影| 欧美3d动漫网站| 91色吧| 波多野结衣一级毛片| 欧美高清a| 色噜噜在线视频| 国产三级免费观看| 天天干天天操天天舔| 五月婷婷俺也去开心| 在线看av的网址| 女性一级全黄生活片免费看| 在线免费午夜视频| 色涩在线| 香蕉爱爱网| 国模大尺度在线| 免费国产午夜高清在线视频|