STM32开发学习——使用 Cortex-M3M4M7 故障异常原因与定位(三)
文章目录
- STM32开发学习——使用 Cortex-M3M4M7 故障异常原因与定位(三)
- 文档说明:
- 官方参考文档线上链接(可在线阅读与下载):
- 使用MDK调试功能查看故障类型与定位
- 故障寄存器的查看
- 确定异常发生的位置
 
- 代码嵌入方式:
 
文档说明:
分享一下在Stm32学习过程收集到的一些值得记录的好资料,以便自己保留印象和尽可能的应用到工作中,达到事半功倍的效果。
这是一篇关于如何使用MDK或者代码嵌入的方式来定位故障发生大概地址。
 之前的参考文档:
 STM32开发学习——使用 Cortex-M3M4M7 故障异常原因与定位
 STM32开发学习——使用 Cortex-M3M4M7 故障异常原因与定位(二)
官方参考文档线上链接(可在线阅读与下载):
MDK:AN209
SEGGER:AN00016_AnalyzingHardFaultsOnCortexM.book
Cortex-M故障 - SEGGER Wiki
使用MDK调试功能查看故障类型与定位
故障寄存器的查看
在进入调试界面后使用Peripherals – Core Peripherals:即可查看到已发生的异常的详细信息。


确定异常发生的位置
右键单击“调用堆栈 + 局部变量”窗口中的“HardFault Handler”,然后选择“显示调用方代码”以突出显示发生点的执行上下文:

根据异常的类型,调试器将突出显示导致异常的指令或紧随导致错误的指令之后的指令。这取决于导致异常的指令是否实际完成执行。
代码嵌入方式:
将下列SEGGER关于Hardfault的代码嵌入到你的软件工程当中
;
;----------------------------------------------------------------------
;File    : HardFaultHandler.S
;Purpose : HardFault exception handler for IAR, Keil and GNU assembler.
;          Evaluates used stack (MSP, PSP) and passes appropiate stack
;          pointer to the HardFaultHandler "C"-routine.
;------------- END-OF-HEADER ------------------------------------------;
;/*********************************************************************
;*
;*     Forward declarations of segments used
;*
;**********************************************************************
;*/
AREA    OSKERNEL, CODE, READONLY, ALIGN=2
PRESERVE8EXPORT  HardFault_HandlerIMPORT  HardFaultHandlerTHUMB;/*********************************************************************
;*
;*       Global functions
;*
;**********************************************************************
;*/;/*********************************************************************
;*
;*      HardFault_Handler()
;*
;*  Function description
;*    Evaluates the used stack (MSP, PSP) and passes the appropiate
;*    stack pointer to the HardFaultHandler "C"-routine.
;*
;*  Notes
;*    (1) Ensure that HardFault_Handler is part of the exception table
;*/HardFault_Handler;// This version is for Cortex M3, Cortex M4 and Cortex M4F
tst    LR, #4            ;// Check EXC_RETURN in Link register bit 2.
ite    EQ
mrseq  R0, MSP           ;// Stacking was using MSP.
mrsne  R0, PSP           ;// Stacking was using PSP.
b      HardFaultHandler  ;// Stack pointer passed through R0.END;/****** End Of File *************************************************/
/**********************************************************************                     SEGGER Microcontroller GmbH                    **                        The Embedded Experts                        ************************************************************************                                                                    **            (c) 2014 - 2023 SEGGER Microcontroller GmbH             **                                                                    **           www.segger.com     Support: support@segger.com           **                                                                    ************************************************************************                                                                    ** All rights reserved.                                               **                                                                    ** Redistribution and use in source and binary forms, with or         ** without modification, are permitted provided that the following    ** conditions are met:                                                **                                                                    ** - Redistributions of source code must retain the above copyright   **   notice, this list of conditions and the following disclaimer.    **                                                                    ** - Neither the name of SEGGER Microcontroller GmbH                  **   nor the names of its contributors may be used to endorse or      **   promote products derived from this software without specific     **   prior written permission.                                        **                                                                    ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             ** CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           ** DISCLAIMED.                                                        ** IN NO EVENT SHALL SEGGER Microcontroller GmbH BE LIABLE FOR        ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  ** OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   ** DAMAGE.                                                            **                                                                    ***********************************************************************-------------------------- END-OF-HEADER -----------------------------File    : SEGGER_HardFaultHandler.cPurpose : Generic SEGGER HardFault handler for Cortex-MLiterature:[1]  Analyzing HardFaults on Cortex-M CPUs (https://www.segger.com/downloads/appnotes/AN00016_AnalyzingHardFaultsOnCortexM.pdf)Additional information:This HardFault handler enables user-friendly analysis of hard faultsin debug configurations.If a release configuration requires a HardFault handler,a specific HardFault handler should be included instead,which for example issues a reset or turns on an error LED.--------  END-OF-HEADER  ---------------------------------------------*//***********************************************************************       Defines************************************************************************/#define SCB_SHCSR  (*(volatile unsigned int*)  (0xE000ED24u))  // System Handler Control and State Register#define SCB_MMFSR  (*(volatile unsigned char*) (0xE000ED28u))  // MemManage Fault Status Register#define SCB_BFSR   (*(volatile unsigned char*) (0xE000ED29u))  // Bus Fault Status Register#define SCB_UFSR   (*(volatile unsigned short*)(0xE000ED2Au))  // Usage Fault Status Register#define SCB_HFSR   (*(volatile unsigned int*)  (0xE000ED2Cu))  // Hard Fault Status Register#define SCB_DFSR   (*(volatile unsigned int*)  (0xE000ED30u))  // Debug Fault Status Register#define SCB_MMFAR  (*(volatile unsigned int*)  (0xE000ED34u))  // MemManage Fault Manage Address Register#define SCB_BFAR   (*(volatile unsigned int*)  (0xE000ED38u))  // Bus Fault Address Register#define SCB_AFSR   (*(volatile unsigned int*)  (0xE000ED3Cu))  // Auxiliary Fault Status Register#ifndef   DEBUG         // Should be overwritten by project settings#define DEBUG   (0)   // in debug builds#endif/***********************************************************************       Prototypes************************************************************************/#ifdef __cplusplusextern "C" {#endifvoid HardFaultHandler(unsigned int* pStack);#ifdef __cplusplus}#endif/***********************************************************************       Static data************************************************************************/#if DEBUGstatic volatile unsigned int _Continue;  // Set this variable to 1 to run furtherstatic struct {struct {volatile unsigned int r0;            // Register R0volatile unsigned int r1;            // Register R1volatile unsigned int r2;            // Register R2volatile unsigned int r3;            // Register R3volatile unsigned int r12;           // Register R12volatile unsigned int lr;            // Link registervolatile unsigned int pc;            // Program counterunion {volatile unsigned int word;struct {unsigned int IPSR :  8;          // Interrupt Program Status register (IPSR)unsigned int EPSR : 19;          // Execution Program Status register (EPSR)unsigned int APSR :  5;          // Application Program Status register (APSR)} bits;} psr;                               // Program status register.} SavedRegs;union {volatile unsigned int word;struct {unsigned int MEMFAULTACT       :  1;   // [0]  Read as 1 if memory management fault is activeunsigned int BUSFAULTACT       :  1;   // [1]  Read as 1 if bus fault exception is activeunsigned int HARDFAULTACT      :  1;   // [2]  Read as 1 if hard fault exception is active (ARMv8-M)unsigned int USGFAULTACT       :  1;   // [3]  Read as 1 if usage fault exception is activeunsigned int SECUREFAULTACT    :  1;   // [4]  Read as 1 if secure fault exception is active (ARMv8-M)unsigned int NMIACT            :  1;   // [5]  Read as 1 if NMI exception is active (ARMv8-M)unsigned int                   :  1;unsigned int SVCALLACT         :  1;   // [7]  Read as 1 if SVC exception is activeunsigned int MONITORACT        :  1;   // [8]  Read as 1 if debug monitor exception is activeunsigned int                   :  1;unsigned int PENDSVACT         :  1;   // [10] Read as 1 if PendSV exception is activeunsigned int SYSTICKACT        :  1;   // [11] Read as 1 if SYSTICK exception is activeunsigned int USGFAULTPENDED    :  1;   // [12] Usage fault pending; higher priority exception activeunsigned int MEMFAULTPENDED    :  1;   // [13] Memory management fault pending; higher priority exception activeunsigned int BUSFAULTPENDED    :  1;   // [14] Bus fault pending; higher priority exception activeunsigned int SVCALLPENDED      :  1;   // [15] SVC pending; higher priority exception activeunsigned int MEMFAULTENA       :  1;   // [16] Memory management fault exception enableunsigned int BUSFAULTENA       :  1;   // [17] Bus fault exception enableunsigned int USGFAULTENA       :  1;   // [18] Usage fault exception enableunsigned int SECUREFAULTENA    :  1;   // [19] Secure fault exception enable (ARMv8-M)unsigned int SECUREFAULTPENDED :  1;   // [20] Secure fault exception pending; higher priority exception active (ARMv8-M)unsigned int HARDFAULTPENDED   :  1;   // [21] Hard fault exception pending (ARMv8-M)unsigned int                   : 10;} bits;} shcsr;                                   // System Handler Control and State Register (0xE000ED24)union {volatile unsigned char byte;struct {unsigned int IACCVIOL    :  1;     // [0] Instruction access violationunsigned int DACCVIOL    :  1;     // [1] Data access violationunsigned int             :  1;unsigned int MUNSTKERR   :  1;     // [3] Unstacking errorunsigned int MSTKERR     :  1;     // [4] Stacking errorunsigned int MLSPERR     :  1;     // [5] MemManage fault during FP lazy state preservationunsigned int             :  1;unsigned int MMARVALID   :  1;     // [7] Indicates the MMAR is validunsigned int             : 24;} bits;} mmfsr;                               // MemManage Fault Status Register  (0xE000ED28)volatile unsigned int mmfar;           // MemManage Fault Address Register (0xE000ED34)union {volatile unsigned char byte;struct {unsigned int IBUSERR      :  1;      // [0] Instruction access violationunsigned int PRECISERR    :  1;      // [1] Precise data access violationunsigned int IMPRECISERR  :  1;      // [2] Imprecise data access violationunsigned int UNSTKERR     :  1;      // [3] Unstacking errorunsigned int STKERR       :  1;      // [4] Stacking errorunsigned int LSPERR       :  1;      // [5] Bus fault during FP lazy state preservationunsigned int              :  1;unsigned int BFARVALID    :  1;      // [7] Indicates BFAR is validunsigned int              : 24;} bits;} bfsr;                                // Bus Fault Status Register  (0xE000ED29)volatile unsigned int bfar;            // Bus Fault Address Register (0xE000ED38)union {volatile unsigned short halfword;struct {unsigned int UNDEFINSTR :  1;      // [0] Attempts to execute an undefined instructionunsigned int INVSTATE   :  1;      // [1] Attempts to switch to an invalid state (e.g., ARM)unsigned int INVPC      :  1;      // [2] Attempts to do an exception with a bad value in the EXC_RETURN numberunsigned int NOCP       :  1;      // [3] Attempts to execute a coprocessor instructionunsigned int STKOF      :  1;      // [4] Indicates whether a stack overflow error has occurred (ARMv8-M)unsigned int            :  3;unsigned int UNALIGNED  :  1;      // [8] Indicates that an unaligned access fault has taken placeunsigned int DIVBYZERO  :  1;      // [9] Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)unsigned int            : 22;} bits;} ufsr;                                // Usage Fault Status Register (0xE000ED2A)union {volatile unsigned int word;struct {unsigned int             :  1;unsigned int VECTTBL     :  1;     // [1] Indicates hard fault is caused by failed vector fetchunsigned int             : 28;unsigned int FORCED      :  1;     // [30] Indicates hard fault is taken because of bus fault/memory management fault/usage faultunsigned int DEBUGEVT    :  1;     // [31] Indicates hard fault is triggered by debug event} bits;} hfsr;                                // Hard Fault Status Register (0xE000ED2C)union {volatile unsigned int word;struct {unsigned int HALTED   :  1;        // [0] Halt requested in NVICunsigned int BKPT     :  1;        // [1] BKPT instruction executedunsigned int DWTTRAP  :  1;        // [2] DWT match occurredunsigned int VCATCH   :  1;        // [3] Vector fetch occurredunsigned int EXTERNAL :  1;        // [4] EDBGRQ signal assertedunsigned int PMU      :  1;        // [5] PMU counter overflow event has occurredunsigned int          : 26;} bits;} dfsr;                                // Debug Fault Status Register (0xE000ED30)volatile unsigned int afsr;            // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)} HardFaultRegs;#endif/***********************************************************************       Global functions************************************************************************//***********************************************************************       HardFaultHandler()**  Function description*    C part of the hard fault handler which is called by the assembler*    function HardFault_Handler*/void HardFaultHandler(unsigned int* pStack) {//// In case we received a hard fault because of a breakpoint instruction, we return.// This may happen when using semihosting for printf outputs and no debugger is connected,// i.e. when running a "Debug" configuration in release mode.//if (SCB_HFSR & (1u << 31)) {SCB_HFSR |=  (1u << 31);      // Reset Hard Fault status*(pStack + 6u) += 2u;         // PC is located on stack at SP + 24 bytes. Increment PC by 2 to skip break instruction.return;                       // Return to interrupted application}#if DEBUG//// Read NVIC registers//HardFaultRegs.shcsr.word    = SCB_SHCSR;  // System Handler Control and State RegisterHardFaultRegs.mmfsr.byte    = SCB_MMFSR;  // MemManage Fault Status RegisterHardFaultRegs.mmfar         = SCB_MMFAR;  // MemManage Fault Address RegisterHardFaultRegs.bfsr.byte     = SCB_BFSR;   // Bus Fault Status RegisterHardFaultRegs.bfar          = SCB_BFAR;   // Bus Fault Manage Address RegisterHardFaultRegs.ufsr.halfword = SCB_UFSR;   // Usage Fault Status RegisterHardFaultRegs.hfsr.word     = SCB_HFSR;   // Hard Fault Status RegisterHardFaultRegs.dfsr.word     = SCB_DFSR;   // Debug Fault Status RegisterHardFaultRegs.afsr          = SCB_AFSR;   // Auxiliary Fault Status Register//// Halt execution// If NVIC registers indicate readable memory, change the variable value to != 0 to continue execution.//_Continue = 0u;while (_Continue == 0u) {}//// Read saved registers from the stack.//HardFaultRegs.SavedRegs.r0       = pStack[0];  // Register R0HardFaultRegs.SavedRegs.r1       = pStack[1];  // Register R1HardFaultRegs.SavedRegs.r2       = pStack[2];  // Register R2HardFaultRegs.SavedRegs.r3       = pStack[3];  // Register R3HardFaultRegs.SavedRegs.r12      = pStack[4];  // Register R12HardFaultRegs.SavedRegs.lr       = pStack[5];  // Link register LRHardFaultRegs.SavedRegs.pc       = pStack[6];  // Program counter PCHardFaultRegs.SavedRegs.psr.word = pStack[7];  // Program status word PSR//// Halt execution// To step out of the HardFaultHandler, change the variable value to != 0.//_Continue = 0u;while (_Continue == 0u) {}#else//// If this module is included in a release configuration, simply stay in the HardFault handler//(void)pStack;do {} while (1);#endif}/*************************** End of file ****************************/