Cortex-M7進入異常中斷分析

使用cmbacktrace庫,其支持M3,4,7。

1、串口輸出異常信息

#define cmb_println(...)    Debug_Printf(__VA_ARGS__)//cmb_println處理可變參數和格式化字符串
int Debug_Printf(const char *fmt, ...) {char buffer[DEBUG_TxBUFLEN];INT16U n;va_list args;va_start(args, fmt);int len = vsnprintf(buffer, sizeof(buffer), fmt, args);va_end(args);for ( n = 0; n < len; n++ )  WriteDebugTxBuffer( buffer[n] );return len;
}//串口查詢方式發送,被cm_backtrace_fault調用
void UartDbg_CheckSend(void)
{
#if 1INT32U status;if ( DebugBuf.PtrTxHead == DebugBuf.PtrTxTail ) return;status = LPUART_GetStatusFlags( DEBUG_SIO_BASE );if ( status & kLPUART_TxDataRegEmptyFlag ){LPUART_WriteByte( DEBUG_SIO_BASE, DebugBuf.TxBuffer[ DebugBuf.PtrTxTail ] );++DebugBuf.PtrTxTail;if ( DebugBuf.PtrTxTail >= DEBUG_TxBUFLEN ) DebugBuf.PtrTxTail = 0;}
#endif
}/*** backtrace for fault* @note only call once** @param fault_handler_lr the LR register value on fault handler* @param fault_handler_sp the stack pointer on fault handler*/
void cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp) {uint32_t stack_pointer = fault_handler_sp, saved_regs_addr = stack_pointer, tcb_stack_pointer = 0;const char *regs_name[] = { "R0 ", "R1 ", "R2 ", "R3 ", "R12", "LR ", "PC ", "PSR" };#ifdef CMB_USING_DUMP_STACK_INFOuint32_t stack_start_addr = main_stack_start_addr;size_t stack_size = main_stack_size;
#endifCMB_ASSERT(init_ok);/* only call once */CMB_ASSERT(!on_fault);on_fault = true;cmb_println(" ");cm_backtrace_firmware_info();#ifdef CMB_USING_OS_PLATFORMon_thread_before_fault = fault_handler_lr & (1UL << 2);/* check which stack was used before (MSP or PSP) */if (on_thread_before_fault) {cmb_println(print_info[PRINT_FAULT_ON_THREAD], get_cur_thread_name() != NULL ? get_cur_thread_name() : "NO_NAME");saved_regs_addr = stack_pointer = cmb_get_psp();#ifdef CMB_USING_DUMP_STACK_INFOget_cur_thread_stack_info(&tcb_stack_pointer, &stack_start_addr, &stack_size);
#endif /* CMB_USING_DUMP_STACK_INFO */} else {cmb_println(print_info[PRINT_FAULT_ON_HANDLER]);}
#else/* bare metal(no OS) environment */cmb_println(print_info[PRINT_FAULT_ON_HANDLER]);
#endif /* CMB_USING_OS_PLATFORM *//* delete saved R0~R3, R12, LR,PC,xPSR registers space */stack_pointer += sizeof(size_t) * 8;#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) || \(CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M33)stack_pointer = statck_del_fpu_regs(fault_handler_lr, stack_pointer);
#endif /* (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) */#ifdef CMB_USING_DUMP_STACK_INFO/* check stack overflow */if (stack_pointer < stack_start_addr || stack_pointer > stack_start_addr + stack_size) {cmb_println("stack_pointer: 0x%08x, stack_start_addr: 0x%08x, stack_end_addr: 0x%08x", stack_pointer, stack_start_addr,stack_start_addr + stack_size);stack_is_overflow = true;
#if (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT)if (on_thread_before_fault) {/* change the stack start adder to TCB->sp when stack is overflow  */stack_pointer = tcb_stack_pointer;}
#endif}/* dump stack information */dump_stack(stack_start_addr, stack_size, (uint32_t *) stack_pointer);
#endif /* CMB_USING_DUMP_STACK_INFO */{/* dump register */cmb_println(print_info[PRINT_REGS_TITLE]);regs.saved.r0        = ((uint32_t *)saved_regs_addr)[0];  // Register R0regs.saved.r1        = ((uint32_t *)saved_regs_addr)[1];  // Register R1regs.saved.r2        = ((uint32_t *)saved_regs_addr)[2];  // Register R2regs.saved.r3        = ((uint32_t *)saved_regs_addr)[3];  // Register R3regs.saved.r12       = ((uint32_t *)saved_regs_addr)[4];  // Register R12regs.saved.lr        = ((uint32_t *)saved_regs_addr)[5];  // Link register LRregs.saved.pc        = ((uint32_t *)saved_regs_addr)[6];  // Program counter PCregs.saved.psr.value = ((uint32_t *)saved_regs_addr)[7];  // Program status word PSRcmb_println("  %s: %08x  %s: %08x  %s: %08x  %s: %08x", regs_name[0], regs.saved.r0,regs_name[1], regs.saved.r1,regs_name[2], regs.saved.r2,regs_name[3], regs.saved.r3);cmb_println("  %s: %08x  %s: %08x  %s: %08x  %s: %08x", regs_name[4], regs.saved.r12,regs_name[5], regs.saved.lr,regs_name[6], regs.saved.pc,regs_name[7], regs.saved.psr.value);cmb_println("==============================================================");}/* the Cortex-M0 is not support fault diagnosis */
#if (CMB_CPU_PLATFORM_TYPE != CMB_CPU_ARM_CORTEX_M0)regs.syshndctrl.value = CMB_SYSHND_CTRL;  // System Handler Control and State Registerregs.mfsr.value       = CMB_NVIC_MFSR;    // Memory Fault Status Registerregs.mmar             = CMB_NVIC_MMAR;    // Memory Management Fault Address Registerregs.bfsr.value       = CMB_NVIC_BFSR;    // Bus Fault Status Registerregs.bfar             = CMB_NVIC_BFAR;    // Bus Fault Manage Address Registerregs.ufsr.value       = CMB_NVIC_UFSR;    // Usage Fault Status Registerregs.hfsr.value       = CMB_NVIC_HFSR;    // Hard Fault Status Registerregs.dfsr.value       = CMB_NVIC_DFSR;    // Debug Fault Status Registerregs.afsr             = CMB_NVIC_AFSR;    // Auxiliary Fault Status Registerfault_diagnosis();
#endifprint_call_stack(stack_pointer);//在末尾處執行串口發送while (1){UartDbg_CheckSend();}
}

?Firmware name: CmBacktrace, hardware version: V1.00, software version: V1.00Fault on interrupt or bare metal(no OS) environment=================== Registers information ==================== ?R0 : 20015ca0 ?R1 : 00000064 ?R2 : 00000000 ?R3 : 00000001 ?R12: 00000001 ?LR : 7008fe8b ?PC : 7008fdee ?PSR: 01000000==============================================================Usage fault is caused by Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)Show more call stack info by run: addr2line -e CmBacktrace.out -afpiC 7008fdee 7008fe8a 7009b45a?

2、ddr2line解析地址,解析出來函數名和行數,準確解析了trigger_hardfault_by_div0函數115行出錯

0x7008fe8b
MainFunction
E:\tfs\12.5\Equipment\firmware\Smartsafe\MC\Source\User_5200N\UserIAR\MiddleControl/Main_Mid.c:171
0x7008fdee
trigger_hardfault_by_div0
E:\tfs\12.5\Equipment\firmware\Smartsafe\MC\Source\User_5200N\UserIAR\MiddleControl/Main_Mid.c:115
PS F:\CmBacktrace\tools\addr2line\win64>?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/75628.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/75628.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/75628.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何管理間接需求?團隊實踐分享

管理間接需求的核心方法包括明確需求識別流程、建立規范的需求管理體系、實施有效的需求溝通機制。 其中&#xff0c;明確需求識別流程最為關鍵。企業在實際業務中&#xff0c;往往會遇到大量的間接需求&#xff0c;如非直接生產性的采購需求、服務類需求等。這些需求往往隱蔽性…

與Aspose.pdf類似的jar庫分享

如果你在尋找類似于 Aspose.PDF 的 JAR 庫&#xff0c;這些庫通常用于處理 PDF 文檔的創建、編輯、轉換、合并等功能。以下是一些類似的 Java 庫&#xff0c;它們提供 PDF 處理的功能&#xff0c;其中一些是收費的&#xff0c;但也有開源選項&#xff1a; 1. iText (iText PDF…

2-2 MATLAB鮣魚優化算法ROA優化CNN超參數回歸預測

本博客來源于CSDN機器魚&#xff0c;未同意任何人轉載。 更多內容&#xff0c;歡迎點擊本專欄目錄&#xff0c;查看更多內容。 目錄 0.引言 1.ROA優化CNN 2.主程序調用 3.結語 0.引言 在博客【ROA優化LSTM超參數回歸】中&#xff0c;我們采用ROA對LSTM的學習率、迭代次數…

企業入駐成都國際數字影像產業園,可享150多項專業服務

企業入駐成都國際數字影像產業園&#xff0c;可享150多項專業服務 全方位賦能&#xff0c;助力影像企業騰飛 入駐成都國際數字影像產業園&#xff0c;企業將獲得一個涵蓋超過150項專業服務的全周期、一站式支持體系&#xff0c;旨在精準解決企業發展各階段的核心需求&#xf…

線路板元器件介紹及選型指南:提高電路設計效率

電路板&#xff08;PCB&#xff09;是現代電子設備的核心&#xff0c;其上安裝了各類電子元器件&#xff0c;這些元器件通過PCB的導電線路彼此連接&#xff0c;實現信號傳輸與功能執行。 元器件的選擇與安裝直接決定了電子產品的性能與穩定性。本文將為大家詳細介紹電路板上的…

探究 Arm Compiler for Embedded 6 的 Clang 版本

原創標題&#xff1a;Arm Compiler for Embedded 6 的 Clang 版本 原創作者&#xff1a;莊曉立&#xff08;LIIGO&#xff09; 原創日期&#xff1a;20250218&#xff08;首發日期20250326&#xff09; 原創連接&#xff1a;https://blog.csdn.net/liigo/article/details/14653…

RedHat7.6_x86_x64服務器(最小化安裝)搭建使用記錄(二)

PostgreSQL數據庫部署管理 1.rpm方式安裝 掛載系統安裝鏡像&#xff1a; [rootlocalhost ~]# mount /dev/cdrom /mnt 進入安裝包路徑&#xff1a; [rootlocalhost ~]# cd /mnt/Packages 依次安裝如下程序包&#xff1a; [rootlocalhost Packages]# rpm -ihv postgresql-libs-9…

瀏覽器存儲 IndexedDB

IndexedDB 1. 什么是 IndexedDB&#xff1f; IndexedDB 是一種 基于瀏覽器的 NoSQL 數據庫&#xff0c;用于存儲大量的結構化數據&#xff0c;包括文件和二進制數據。它比 localStorage 和 sessionStorage 更強大&#xff0c;支持索引查詢、事務等特性。 IndexedDB 主要特點…

panda3d 渲染

目錄 安裝 設置渲染寬高&#xff1a; 渲染3d 安裝 pip install Panda3D 設置渲染寬高&#xff1a; import panda3d.core as pdmargin 100 screen Tk().winfo_screenwidth() - margin, Tk().winfo_screenheight() - margin width, height (screen[0], int(screen[0] / 1…

Node.js 包管理工具 - NPM 與 PNPM 清理緩存

NPM 清理緩存 1、基本介紹 npm 緩存是 npm 用來存儲已下載包的地方&#xff0c;以加快后續安裝速度 但是&#xff0c;有時緩存可能會損壞或占用過多磁盤空間&#xff0c;這時可以清理 npm 緩存 2、清理操作 執行如下指令&#xff0c;清理 npm 緩存 npm cache clean --for…

STM32F103_LL庫+寄存器學習筆記05 - GPIO輸入模式,捕獲上升沿進入中斷回調

導言 GPIO設置輸入模式后&#xff0c;一般會用輪詢的方式去查看GPIO的電平狀態。比如&#xff0c;最常用的案例是用于檢測按鈕的當前狀態&#xff08;是按下還是沒按下&#xff09;。中斷的使用一般用于計算脈沖的頻率與計算脈沖的數量。 項目地址&#xff1a;https://github.…

【C++進階二】string的模擬實現

【C進階二】string的模擬實現 1.構造函數和C_strC_str: 2.operator[]3.拷貝構造3.1淺拷貝3.2深拷貝 4.賦值5.迭代器6.比較ascll碼值的大小7.reverse擴容8.push_back尾插和append尾插9.10.insert10.1在pos位置前插入字符ch10.2在pos位置前插入字符串str 11.resize12.erase12.1從…

wokwi arduino mega 2560 - 點亮LED案例

截圖&#xff1a; 點亮LED案例仿真截圖 代碼&#xff1a; unsigned long t[20]; // 定義一個數組t&#xff0c;用于存儲20個LED的上次狀態切換時間&#xff08;單位&#xff1a;毫秒&#xff09;void setup() {pinMode(13, OUTPUT); // 將引腳13設置為輸出模式&#xff08;此…

vue3項目使用 python +flask 打包成桌面應用

server.py import os import sys from flask import Flask, send_from_directory# 獲取靜態文件路徑 if getattr(sys, "frozen", False):# 如果是打包后的可執行文件base_dir sys._MEIPASS else:# 如果是開發環境base_dir os.path.dirname(os.path.abspath(__file…

后端學習day1-Spring(八股)--還剩9個沒看

一、Spring 1.請你說說Spring的核心是什么 參考答案 Spring框架包含眾多模塊&#xff0c;如Core、Testing、Data Access、Web Servlet等&#xff0c;其中Core是整個Spring框架的核心模塊。Core模塊提供了IoC容器、AOP功能、數據綁定、類型轉換等一系列的基礎功能&#xff0c;…

LeetCode 第34、35題

LeetCode 第34題&#xff1a;在排序數組中查找元素的第一個和最后一個位置 題目描述 給你一個按照非遞減順序排列的整數數組nums&#xff0c;和一個目標值target。請你找出給定目標值在數組中的開始位置和結束位置。如果數組中不存在目標值target&#xff0c;返回[-1,1]。你必須…

告別分庫分表,時序數據庫 TDengine 解鎖燃氣監控新可能

達成效果&#xff1a; 從 MySQL 遷移至 TDengine 后&#xff0c;設備數據自動分片&#xff0c;運維更簡單。 列式存儲可減少 50% 的存儲占用&#xff0c;單服務器即可支撐全量業務。 毫秒級漏氣報警響應時間控制在 500ms 以內&#xff0c;提升應急管理效率。 新架構支持未來…

第十四屆藍橋杯真題

一.LED 先配置LED的八個引腳為GPIO_OutPut,鎖存器PD2也是,然后都設置為起始高電平,生成代碼時還要去解決引腳沖突問題 二.按鍵 按鍵配置,由原理圖按鍵所對引腳要GPIO_Input 生成代碼,在文件夾中添加code文件夾,code中添加fun.c、fun.h、headfile.h文件,去資源包中把lc…

《基于機器學習發電數據電量預測》開題報告

個人主頁&#xff1a;大數據蟒行探索者 目錄 一、選題背景、研究意義及文獻綜述 &#xff08;一&#xff09;選題背景 &#xff08;二&#xff09;選題意義 &#xff08;三&#xff09;文獻綜述 1. 國內外研究現狀 2. 未來方向展望 二、研究的基本內容&#xff0c;擬解…

UWP程序用多頁面實現應用實例多開

Windows 10 IoT ARM64平臺下&#xff0c;UWP應用和MFC程序不一樣&#xff0c;同時只能打開一個應用實例。以串口程序為例&#xff0c;如果用戶希望同時打開多個應用實例&#xff0c;一個應用實例打開串口1&#xff0c;一個應用實例打開串口2&#xff0c;那么我們可以加載多個頁…