概述
在使用ARM Cortex-M系列MCU時(如AT32 MCU),有時會出現程序運行異常。當通過編譯器在debug模式查原因時,會發現程序跑到HardFault_Handler函數中,產生HardFault,即硬件錯誤。
圖1. HardFault_Handler函數
本文檔主要介紹一種基于CmBacktrace庫,快速追蹤和定位產生HardFault原因的方法。
HardFault產生原因
常見產生HardFault產生的原因大概有如下幾類:
數組越界操作;
內存溢出,訪問越界;
堆棧溢出,程序跑飛;
中斷處理錯誤。
數組越界
程序中使用了靜態數組,而在動態傳參時數組賦值溢出。或者動態分配內存太小,導致程序異常。
內存溢出
重點檢查RAM區域,程序編譯后執行的RAM數據量大小為多少是否可能越界。一般不要設置到極致的情況,程序中的一些動態數組傳參時會導致異常。
堆棧溢出
這在使用操作系統的代碼中尤其容易發生,在操作系統中,任務的變量均分配放置在任務所申請的堆棧空間中。
例如FreeRTOS中調用xTaskCreate來創建任務,該函數以參數usStackDepth指定任務堆棧的大小,如果指定的堆棧太小,則會堆棧申請不足,進入HardFault。
中斷處理異常
程序中開啟了某些中斷,例如USART,TIMER,RTC等。
但在程序執行中,滿足中斷條件,但并未能查找到該部分對應的中斷服務函數,則可能會出現該異常。
HardFault分析方法
常見的分析方法是:發生異常之后可首先查看LR寄存器中的值,確定當前使用堆棧為MSP或PSP,然后找到相應堆棧的指針,并在內存中查看相應堆棧里的內容。由于異常發生時,內核將R0~R3、R12 Returnaddress、PSR、LR寄存器依次入棧,其中Return address即為發生異常前PC將要執行的下一條指令地址。
但以上方法要求對ARM內核比較熟悉,且操作較為繁瑣。
以下重點介紹采用開源庫CmBacktrace作為快速分析的方法。
基于CmBacktrace庫分析方法
CmBacktrace(Cortex Microcontroller Backtrace)是一款針對ARM Cortex-M系列MCU的錯誤代碼自動追蹤、定位,錯誤原因自動分析的開源庫。主要特性如下:
支持的錯誤包括:
1) 斷言(Assert)
2) 故障(Hard Fault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault)
故障原因自動診斷:可在故障發生時,自動分析出故障的原因,定位發生故障的代碼位置,而無需再手動分析繁雜的故障寄存器;
適配Cortex-M0/M3/M4/M7 MCU;
支持IAR、KEIL、GCC編譯器;
支持FreeRTOS、UCOSII、UCOSIII、RT-Thread等OS;
基于MDK的CmBacktrace庫使用流程
基于MDK的移植方法按如下步驟進行:
步驟一 添加cm_backtrace庫文件到MDK中
圖2. cm_backtrace庫文件夾
把cm_backtrace文件夾復制到我們的工程目錄下,并添加至keil工程中。
圖3. 添加cm_backtrace后keil工程目錄
步驟二 添加頭文件、勾選C99模式
圖4. Keil中配置C99和頭文件
步驟三 編譯和調試
首先,cmb_cfg.h文件按以下提示配置修改。
圖5. cmb_cfg.h文件配置
這時候編譯有一個錯誤,這是因為cmb_fault.c與at32f4xx_int.c中的HardFault_Handler函數重復定義:
圖6. at32f4xx_it.c編譯報錯
需要把at32f4xx_int.c中的HardFault_Handler函數屏蔽掉。
圖7. HardFault_Handler函數屏蔽
步驟四 測試與查看
這時候就可以編譯通過了。下面測試這個庫的功能。
測試函數如下:
圖8. 編寫除零錯誤函數
然后在主函數中調用cm_backtrace_init();來初始化cm_backtrace,并調用該測試函數:
圖9. main函數調用除零錯誤函數
下載運行程序,PC端接收串口信息:
圖10. 串口助手輸出錯誤信息
可以看到,列出了出錯原因(除0)和一條命令。運行這個命令需要用到addr2line.exe工具,該工具在tools文件夾中:
圖11. 定位addr2line.exe位置
有32bit和64bit兩個版本,根據環境選擇,并拷貝到keil工程目錄下的.axf文件所在的文件夾中,如demo中所附工程,則拷貝到如下目錄:
AN0028_SourceCode_V2.0.0utilitiesAN0028_demonon_osmdk_v5objects
圖12. 拷貝addr2line.exe工具
進入到cmd窗口,轉到上述文件夾位置,運行串口助手中的那條命令:
addr2line -e CmBacktrace(此處要依據用戶的工程名修改).axf -a -f 080019c6 08001ae9
如demo中工程名為printf,命令則應修改為addr2line -e printf.axf -a -f 080019c6 08001ae9
圖13. 調用CMD運行addr2line.exe工具
可以看到addr2line.exe工具定位出了錯誤相關的代碼行號,查看對應行的代碼:
可以看到addr2line.exe工具定位出了錯誤相關的代碼行號,main.c的第60行,fault_test.c的第38行,查看對應行的代碼:
圖14. 確認錯誤代碼區域
可見,對應的行號正是出錯的地方,使用這個CmBacktrace庫能幫助用戶有效、快速地定位到HardFault之類的錯誤。
案例展示
案例一 無OS除零錯誤
工程位置:AN0028_SourceCode_V2.0.0utilitiesAN0028_demonon_os
測試內容:在裸機上除零錯誤
案例二 FreeRTOS上除零錯誤
工程位置:AN0028_SourceCode_V2.0.0utilitiesAN0028_demoosfreertos
測試內容:在FreeROTOS上除零錯誤,需注意tasks.c中有注釋/**/的三處為針對CmBacktrace做出的修改
案例三 USOCⅢ上非對齊訪問錯誤
工程位置:AN0028_SourceCode_V2.0.0utilitiesAN0028_demoosucosiii
測試內容:在UCOSⅢ上非對齊訪問錯誤,需注意os_cfg.h中#define OS_CFG_DBG_EN為1u
來源:AT32 MCU 雅特力科技
免責聲明:本文為轉載文章,轉載此文目的在于傳遞更多信息,版權歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權問題,請聯系小編進行處理
審核編輯 黃宇
-
mcu
+關注
關注
146文章
17642瀏覽量
357132 -
Cortex
+關注
關注
2文章
203瀏覽量
46951 -
MDK
+關注
關注
4文章
209瀏覽量
32388
發布評論請先 登錄
相關推薦
【轉載】快速追蹤和定位產生HardFault原因的方法
Cortex-M系列MCU錯誤追蹤庫有何作用
CmBacktrace是什么?主要特性是什么
如何快速定位HardFault
基于ARM Cortex-M的MCU錯誤追蹤庫有何功能呢
CmBacktrace打印hardfault信息時提示棧溢出是何原因?如何解決
cmbacktrace里面的HARDFAULT函數如何移植?
專治MCU各種HardFault問題的開源庫
一點理解之 CmBacktrace: ARM Cortex-M 系列 MCU 錯誤追蹤庫

庫 keil 編譯很慢_CmBacktrace: ARM CortexM 系列 MCU 錯誤追蹤庫

ARM Cortex-M 系列 MCU錯誤代碼自動追蹤庫(CmBacktrace)的使用經驗分享

ARM Cortex-M 系列 MCU 錯誤追蹤庫 --- CmBacktrace

專治MCU各種 HardFault 的庫:CmBacktrace(錯誤追蹤庫)

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

評論