大家在用STM32的時候有沒有遇到過HardFault的問題呢:
下面針對這個問題做個小總結。
現象還原:在debug模式下進行仿真調試,全速運行再停止運行,程序會跑到 HardFault_Handler函數中,產生 HardFault,即硬錯。其產生的原因大概有如下幾類:
(1)數組越界操作;
(2)內存溢出,訪問越界;
(3)堆棧溢出,程序跑飛;
(4)中斷處理錯誤;
針對HardFault問題的定位,網上有幾種方法,大概都是圍繞著:在debug模式下,查看一些地址,分析寄存器、函數調用棧等,這是很讓人頭疼的事情。這裡分享一種簡單的、直觀的HardFault錯誤定位的方法,使用開源庫:CmBacktrace 。這個庫之前已經有介紹過了,這篇筆記我們來實踐一下。
CmBacktrace簡介
CmBacktrace (Cortex Microcontroller Backtrace)是一款針對 ARM Cortex-M 系列 MCU 的錯誤代碼自動追蹤、定位,錯誤原因自動分析的開源庫。主要特性如下:
支持的錯誤包括:斷言(assert)故障(Hard Fault, Memory Management Fault, Bus Fault, Usage Fault, Debug Fault)故障原因移植及使用(keil)
CmBacktrace 源碼地址:
https://github.com/armink/CmBacktrace
把cm_backtrace文件夾複製到我們的工程目錄下,並添加至keil工程中,並添加頭文件、勾選C99模式:
此時,編譯會產生幾個錯誤:
那是因為有些預處理宏沒有找到,打開、修改cmb_cfg.h文件的內容。cmb_cfg.h文件默認內容為:
我們修改後的cmb_cfg.h內容變為:
這時候編譯還會有一個錯誤,cmb_fault.c與stm32f10x_it.c中的HardFault_Handler函數重定義:
需要把stm32f10x_it.c中的HardFault_Handler函數屏蔽掉:
這時候就可以編譯通過了。下面我們來看看這個庫的效果。
測試函數:
然後在主函數中調用測試函數:
下載運行程序:
可以看到,列出的信息很詳細,包括出錯原因。按照它的提示,我們運行命令:
addr2line -e stm32f10x_demo.axf -a -f 0800162a 080016b7 08001719
運行這個命令需要用到addr2line.exe工具,這個工具在CmBacktrace源碼目錄下的tools文件夾中:
有32bit和64bit兩個版本,根據我們的環境選擇,並拷貝到我們的keil工程目錄下可執行文件.axf所在的文件夾中:
在這個文件中進入到cmd窗口,方法:按下Shift鍵的同時點擊鼠標右鍵:
運行上面那條命令:
可以看到addr2line.exe工具給我們定位出了錯誤相關的代碼行號,我們看看對應行的代碼是什麼:
可見,對應的行號正是出錯的地方。
可以看到,使用這個CmBacktrace 庫能幫助我們有效、快速地定位到HardFault之類的錯誤。addr2line命令後面跟著幾個地址就是錯誤相關的地址,這幾個地址可以牽扯的內容很深,如果我們不使用CmBacktrace 庫,我們可能就得自己去分析這些偏底層的內容了,相關知識可閱讀:《Cortex-M3/M4權威指南》。
以上就是本次的筆記分享,如有錯誤歡迎指出!謝謝