久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4451|回復: 0
打印 上一主題 下一主題
收起左側

飛思卡爾工程師教你如何定位Kinetis MCU Hard Fault 異常

[復制鏈接]
跳轉到指定樓層
樓主
ID:94349 發表于 2015-11-9 14:57 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
看到有朋友遇到Hard Fault異常錯誤,特地找到一篇飛思卡爾工程師寫的一片經驗帖,定位Hard Fault 異常。

Kinetis MCU 采用 Cortex-M4 的內核,該內核的 Fault 異常可以捕獲非法的內存訪問和非法的編程行為。Fault異常能夠檢測到以下幾類非法行為:
·       總線Fault:  在取址、數據讀/寫、取中斷變量、進入/退出中斷時寄存器堆棧操作(入棧/出棧)時檢測到內存訪問錯誤。
·       存儲器管理 Fault:檢測到內存訪問違反了內存保護單元(MPU, MemoryProtection Unit)定義的區域。
·       用法Fault:  檢測到未定義的指令異常,未對其的多重加載/存儲內存訪問。如果使能相應控制位,還可以檢測出除數為零以及其他未對齊的內存訪問。

·       硬Fault:  如果上述的總線 Fault、存儲器管理Fault、用法 Fault 的處理程序不能被執行(例如禁能了總線 Fault、存儲器管理Fault、用法Fault的異常或者在這些異常處理程序中又出現了新的Fault)則觸發硬Fault。
      MQX 操作系統啟動的時候會安裝上默認的異常中斷處理函數,當系統異常時會產生一個“unexpected”中斷,內核就會自動調用異常處理函數,同時也將運行用戶自定義的處理函數,來實現特殊故障的定位方法。
     默認情況下,MQX把出現異常的任務掛起,避免故障進一步擴大。通過TAD 任務感知調試插件的Tasksummary 功能,我們可以觀察到出現異常的任務情況。
開發人員在調試期間,需要弄清楚系統異常觸發了哪類Fault,由什么原因觸發了Fault 以及定位觸發Fault的代碼。在這種情況下,可以利用自定義的Fault 中斷處理程序來分析
Fault 出錯原因。
    為了解釋所述的 Fault中斷處理程序的原理,這里重述一下當系統產生異常時 MCU 的處理過程:
·       有一個壓棧的過程,若產生異常時使用PSP(進程棧指針),就壓入到 PSP 中,若產生異常時使用MSP(主棧指針),就壓入MSP 中。
·       會根據處理器的模式和使用的堆棧,設置LR 的值(當然設置完的LR 的值再壓棧)。
·       異常保存,硬件自動把 8個寄存器的值壓入堆棧(8 個寄存器依次為 xPSR、PC、LR、R12以及R3~R0)。如果異常發生時,當前的代碼正在使用PSP,則上面8 個寄存器壓入PSP; 否則就壓入MSP。
     當系統產生異常時,我們需要兩個關鍵寄存器值,一個是 PC ,一個是 LR (鏈接寄存器),通過LR找到相應的堆棧,再通過堆棧找到觸發異常的PC 值。將產生異常時壓入棧的 PC值取出,并與反匯編的代碼對比就能得到哪條指令產生了異常。
      這里解釋一下關于 LR寄存器的工作原理。如上所述,當 Cortex-M4處理器接受了一個異常后,寄存器組中的一些寄存器值會被自動壓入當前棧空間里,這其中就包括鏈接寄存器(LR )。這時的 LR會被更新為異常返回時需要使用的特殊值(EXC_RETURN)。關于
EXC_RETURN的定義如下,其為 32 位數值,高 28 位置 1,第 0 位到第三位則提供了異常返回機制所需的信息,如下表所示。可見其中第 2位標示著進入異常前使用的棧是 MSP還是PSP。在異常處理過程結束時,MCU 需要根據該值來分配 SP的值。這也是本方法中用來判斷所使用堆棧的原理,其實現方法可以從后面_init_hardfault_isr 中看到。
  另外,我們可以利用 MQX 的控制臺串口輸出Fault 異常信息來幫助調試。編寫Fault處理程序時,將啟動代碼中默認的Fault 處理程序跟換成自己需要的Fault處理程序。需要注意的是,由于是在中斷中進行打印輸出,MQX的控制臺串口只能使用POLL輪詢模式的驅動,不能使用中斷模式的驅動。
    用戶可以編寫自定義的硬Fault 處理程序_int_hardfault_isr,修改 MQX的中斷向量定義vector.c,把里面的DEFAULT_VECTOR 代碼段換成下面的代碼。當系統出現硬Fault異常時,將會調用自定義的Fault處理_int_hardfault_isr函數。在這個函數,我們可以通過StackTrace-back 回溯出現問題的代碼。
我們可以在_int_hardfault_isr函數里將出現異常時的寄存器、堆棧、狀態寄存器等信息打印出來。如果系統出現異常時,一般情況都會通過串口控制臺打印出LR,PC的值。然后根據編譯器生成的map文件,找到出現問題的具體函數。
    從上圖的串口輸出我們可以看到PC 和 LR 寄存器值,PC 的值為0x56c6,我們根據匯編代碼可以找到出現問題的指令。從而大大縮小了查找出現問題的范圍,可以幫助開發人員快速定位問題的根本原因。

附錄Fault異常中斷處理代碼:
  1. // hard fault handler in C,
  2. // with stack frame location as input parameter
  3. void hard_fault_handler_c (unsigned int * hardfault_args)
  4. {
  5.   unsigned int stacked_r0;
  6.   unsigned int stacked_r1;
  7.   unsigned int stacked_r2;
  8.   unsigned int stacked_r3;
  9.   unsigned int stacked_r12;
  10.   unsigned int stacked_lr;
  11.   unsigned int stacked_pc;
  12.   unsigned int stacked_psr;

  13.   stacked_r0 = ((unsigned long)hardfault_args[0]);
  14.   stacked_r1 = ((unsigned long)hardfault_args[1]);
  15.   stacked_r2 = ((unsigned long)hardfault_args[2]);
  16.   stacked_r3 = ((unsigned long)hardfault_args[3]);

  17.   stacked_r12 = ((unsigned long)hardfault_args[4]);
  18.   stacked_lr = ((unsigned long)hardfault_args[5]);
  19.   stacked_pc = ((unsigned long)hardfault_args[6]);
  20.   stacked_psr = ((unsigned long) hardfault_args[7]);

  21.   printf ("\n\n[Hard faulthandler - all numbers in hex]\n");
  22.   printf ("R0 = %x\n",stacked_r0);
  23.   printf ("R1 = %x\n",stacked_r1);
  24.   printf ("R2 = %x\n",stacked_r2);
  25.   printf ("R3 = %x\n",stacked_r3);
  26.   printf ("R12 = %x\n",stacked_r12);
  27.   printf ("LR [R14] = %x  subroutine call return address\n",stacked_lr);
  28.   printf ("PC [R15] = %x  program counter\n", stacked_pc);
  29.   printf ("PSR = %x\n",stacked_psr);

  30.   /******************* Add yourdebug trace here ***********************/
  31.   _int_kernel_isr();
  32. }

  33. /* hard fault interrupt handler */
  34. void _int_hardfault_isr( )
  35. {
  36.   __asm("TST LR, #4");
  37.   __asm("ITE EQ");
  38.   __asm("MRSEQ R0,MSP");
  39.   __asm("MRSNE R0,PSP");
  40.   __asm("Bhard_fault_handler_c");
  41. }
復制代碼


fault_isr.c.zip (1.42 KB, 下載次數: 12) vectors.c.zip (3.43 KB, 下載次數: 7)

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产激情在线 | 免费电影av| 国产精品高潮呻吟久久 | 91影库| 国产精品精品久久久 | 91麻豆产精品久久久久久夏晴子 | 日韩精品久久久久久 | 欧产日产国产精品国产 | 一区二区不卡视频 | 亚洲一区中文 | av网站推荐 | 亚洲精品中文字幕在线观看 | 成人综合视频在线观看 | 一区二区三区视频免费观看 | 久久久久久免费精品一区二区三区 | 久久久久精| 日本人爽p大片免费看 | 国产三级精品三级在线观看四季网 | 天天操天天天 | 国产精品美女久久久久久久网站 | 亚洲精品免费视频 | 久久av网 | 一区二区精品视频 | 久久99精品久久久久久琪琪 | 国产精品国产a级 | 2019天天操 | 成人一区二区三区在线观看 | 免费成人av网站 | 久久综合一区 | 99精品久久久久 | 国产精品一区免费 | 亚州激情| 黄色中文字幕 | 久精品视频 | 亚洲国产网 | av免费观看在线 | 日本精品久久 | 久久久久亚洲 | 国产精品久久久久久久午夜 | 亚洲三区在线观看 | 欧美精品久久久久久久久老牛影院 |