概述
在使用ARM Cortex-M系列MCU時(shí)(如AT32 MCU),有時(shí)會(huì)出現(xiàn)程序運(yùn)行異常。當(dāng)通過(guò)編譯器在debug模式查原因時(shí),會(huì)發(fā)現(xiàn)程序跑到HardFault_Handler函數(shù)中,產(chǎn)生HardFault,即硬件錯(cuò)誤。
圖1. HardFault_Handler函數(shù)
本文檔主要介紹一種基于CmBacktrace庫(kù),快速追蹤和定位產(chǎn)生HardFault原因的方法。
HardFault產(chǎn)生原因
常見(jiàn)產(chǎn)生HardFault產(chǎn)生的原因大概有如下幾類(lèi):
數(shù)組越界操作;
內(nèi)存溢出,訪問(wèn)越界;
堆棧溢出,程序跑飛;
中斷處理錯(cuò)誤。
數(shù)組越界
程序中使用了靜態(tài)數(shù)組,而在動(dòng)態(tài)傳參時(shí)數(shù)組賦值溢出?;蛘邉?dòng)態(tài)分配內(nèi)存太小,導(dǎo)致程序異常。
內(nèi)存溢出
重點(diǎn)檢查RAM區(qū)域,程序編譯后執(zhí)行的RAM數(shù)據(jù)量大小為多少是否可能越界。一般不要設(shè)置到極致的情況,程序中的一些動(dòng)態(tài)數(shù)組傳參時(shí)會(huì)導(dǎo)致異常。
堆棧溢出
這在使用操作系統(tǒng)的代碼中尤其容易發(fā)生,在操作系統(tǒng)中,任務(wù)的變量均分配放置在任務(wù)所申請(qǐng)的堆??臻g中。
例如FreeRTOS中調(diào)用xTaskCreate來(lái)創(chuàng)建任務(wù),該函數(shù)以參數(shù)usStackDepth指定任務(wù)堆棧的大小,如果指定的堆棧太小,則會(huì)堆棧申請(qǐng)不足,進(jìn)入HardFault。
中斷處理異常
程序中開(kāi)啟了某些中斷,例如USART,TIMER,RTC等。
但在程序執(zhí)行中,滿足中斷條件,但并未能查找到該部分對(duì)應(yīng)的中斷服務(wù)函數(shù),則可能會(huì)出現(xiàn)該異常。
HardFault分析方法
常見(jiàn)的分析方法是:發(fā)生異常之后可首先查看LR寄存器中的值,確定當(dāng)前使用堆棧為MSP或PSP,然后找到相應(yīng)堆棧的指針,并在內(nèi)存中查看相應(yīng)堆棧里的內(nèi)容。由于異常發(fā)生時(shí),內(nèi)核將R0~R3、R12 Returnaddress、PSR、LR寄存器依次入棧,其中Return address即為發(fā)生異常前PC將要執(zhí)行的下一條指令地址。
但以上方法要求對(duì)ARM內(nèi)核比較熟悉,且操作較為繁瑣。
以下重點(diǎn)介紹采用開(kāi)源庫(kù)CmBacktrace作為快速分析的方法。
基于CmBacktrace庫(kù)分析方法
CmBacktrace(Cortex Microcontroller Backtrace)是一款針對(duì)ARM Cortex-M系列MCU的錯(cuò)誤代碼自動(dòng)追蹤、定位,錯(cuò)誤原因自動(dòng)分析的開(kāi)源庫(kù)。主要特性如下:
支持的錯(cuò)誤包括:
1) 斷言(Assert)
2) 故障(Hard Fault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault)
故障原因自動(dòng)診斷:可在故障發(fā)生時(shí),自動(dòng)分析出故障的原因,定位發(fā)生故障的代碼位置,而無(wú)需再手動(dòng)分析繁雜的故障寄存器;
適配Cortex-M0/M3/M4/M7 MCU;
支持IAR、KEIL、GCC編譯器;
支持FreeRTOS、UCOSII、UCOSIII、RT-Thread等OS;
基于MDK的CmBacktrace庫(kù)使用流程
基于MDK的移植方法按如下步驟進(jìn)行:
步驟一 添加cm_backtrace庫(kù)文件到MDK中
圖2. cm_backtrace庫(kù)文件夾
把cm_backtrace文件夾復(fù)制到我們的工程目錄下,并添加至keil工程中。
圖3. 添加cm_backtrace后keil工程目錄
步驟二 添加頭文件、勾選C99模式
圖4. Keil中配置C99和頭文件
步驟三 編譯和調(diào)試
首先,cmb_cfg.h文件按以下提示配置修改。
圖5. cmb_cfg.h文件配置
這時(shí)候編譯有一個(gè)錯(cuò)誤,這是因?yàn)閏mb_fault.c與at32f4xx_int.c中的HardFault_Handler函數(shù)重復(fù)定義:
圖6. at32f4xx_it.c編譯報(bào)錯(cuò)
需要把a(bǔ)t32f4xx_int.c中的HardFault_Handler函數(shù)屏蔽掉。
圖7. HardFault_Handler函數(shù)屏蔽
步驟四 測(cè)試與查看
這時(shí)候就可以編譯通過(guò)了。下面測(cè)試這個(gè)庫(kù)的功能。
測(cè)試函數(shù)如下:
圖8. 編寫(xiě)除零錯(cuò)誤函數(shù)
然后在主函數(shù)中調(diào)用cm_backtrace_init();來(lái)初始化cm_backtrace,并調(diào)用該測(cè)試函數(shù):
圖9. main函數(shù)調(diào)用除零錯(cuò)誤函數(shù)
圖10. 串口助手輸出錯(cuò)誤信息
可以看到,列出了出錯(cuò)原因(除0)和一條命令。運(yùn)行這個(gè)命令需要用到addr2line.exe工具,該工具在tools文件夾中:
圖11. 定位addr2line.exe位置
有32bit和64bit兩個(gè)版本,根據(jù)環(huán)境選擇,并拷貝到keil工程目錄下的.axf文件所在的文件夾中,如demo中所附工程,則拷貝到如下目錄:
AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\non_os\mdk_v5\objects
圖12. 拷貝addr2line.exe工具
進(jìn)入到cmd窗口,轉(zhuǎn)到上述文件夾位置,運(yùn)行串口助手中的那條命令:
addr2line -e CmBacktrace(此處要依據(jù)用戶的工程名修改).axf -a -f 080019c6 08001ae9
如demo中工程名為printf,命令則應(yīng)修改為addr2line -e printf.axf -a -f 080019c6 08001ae9
圖13. 調(diào)用CMD運(yùn)行addr2line.exe工具
可以看到addr2line.exe工具定位出了錯(cuò)誤相關(guān)的代碼行號(hào),查看對(duì)應(yīng)行的代碼:
圖14. 確認(rèn)錯(cuò)誤代碼區(qū)域
可以看到addr2line.exe工具定位出了錯(cuò)誤相關(guān)的代碼行號(hào),main.c的第60行,fault_test.c的第38行,查看對(duì)應(yīng)行的代碼:
可見(jiàn),對(duì)應(yīng)的行號(hào)正是出錯(cuò)的地方,使用這個(gè)CmBacktrace庫(kù)能幫助用戶有效、快速地定位到HardFault之類(lèi)的錯(cuò)誤。
案例展示
案例一 無(wú)OS除零錯(cuò)誤
工程位置:AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\non_os
測(cè)試內(nèi)容:在裸機(jī)上除零錯(cuò)誤
案例二 FreeRTOS上除零錯(cuò)誤
工程位置:AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\os\freertos
測(cè)試內(nèi)容:在FreeROTOS上除零錯(cuò)誤,需注意tasks.c中有注釋/**/的三處為針對(duì)CmBacktrace做出的修改
案例三 USOCⅢ上非對(duì)齊訪問(wèn)錯(cuò)誤
工程位置:AN0028_SourceCode_V2.0.0\utilities\AN0028_demo\os\ucosiii
測(cè)試內(nèi)容:在UCOSⅢ上非對(duì)齊訪問(wèn)錯(cuò)誤,需注意os_cfg.h中#define OS_CFG_DBG_EN為1u
關(guān)于雅特力雅特力科技于2016年成立,是一家致力于推動(dòng)全球市場(chǎng)32位微控制器(MCU)創(chuàng)新趨勢(shì)的芯片設(shè)計(jì)公司,專(zhuān)注于ARM Cortex-M4/M0+的32位微控制器研發(fā)與創(chuàng)新,全系列采用55nm先進(jìn)工藝及ARM Cortex-M4高效能或M0+低功耗內(nèi)核,締造M4業(yè)界最高主頻288MHz運(yùn)算效能,并支持工業(yè)級(jí)別芯片工作溫度范圍(-40°~105°)。雅特力目前已累積相當(dāng)多元的終端產(chǎn)品成功案例:如微型打印機(jī)、掃地機(jī)、光流無(wú)人機(jī)、熱成像儀、激光雷達(dá)、工業(yè)縫紉機(jī)、伺服驅(qū)控、電競(jìng)周邊市場(chǎng)、斷路器、ADAS、T-BOX、數(shù)字電源、電動(dòng)工具等終端設(shè)備應(yīng)用,廣泛地覆蓋5G、物聯(lián)網(wǎng)、消費(fèi)、商務(wù)及工控等領(lǐng)域。
-
mcu
+關(guān)注
關(guān)注
146文章
16922瀏覽量
349995
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論