单片机的hardfault打印信息定位错误

在实际使用中,单片机会进入hardfault,无法使用仿真器时,只能通过打印信息来定位了

hardfault 处理

c 复制代码
typedef struct {
    uint32_t r0;
    uint32_t r1;
    uint32_t r2;
    uint32_t r3;
    uint32_t r12;
    uint32_t lr;
    uint32_t pc;
    uint32_t psr;
} HardFault_StackFrame_t;

void HardFault_C_Handler(uint32_t *stack_frame);


/**
  * @brief This function handles Hard fault interrupt.
  */
/* Compatible with ARM Compiler 5, ARM Compiler 6, and GCC */
#if defined(__GNUC__)
__attribute__((naked))
void HardFault_Handler(void)
{
    __asm volatile (
        "TST    LR, #4\n\t"
        "ITE    EQ\n\t"
        "MRSEQ  R0, MSP\n\t"
        "MRSNE  R0, PSP\n\t"
        "B      HardFault_C_Handler\n\t"
    );
}
#elif defined(__CC_ARM)
/* ARM Compiler 5 (armcc) */
__asm void HardFault_Handler(void)
{
    IMPORT  HardFault_C_Handler
    TST     LR, #4
    ITE     EQ
    MRSEQ   R0, MSP
    MRSNE   R0, PSP
    B       HardFault_C_Handler
}
#elif defined(__ARMCC_VERSION)
/* ARM Compiler 6 (armclang) */
__attribute__((naked))
void HardFault_Handler(void)
{
    __asm volatile (
        "TST    LR, #4\n\t"
        "ITE    EQ\n\t"
        "MRSEQ  R0, MSP\n\t"
        "MRSNE  R0, PSP\n\t"
        "B      HardFault_C_Handler\n\t"
    );
}
#else
void HardFault_Handler(void)
{
    __BKPT(0);
    while (1)
    {
    }
}
#endif


void HardFault_C_Handler(uint32_t *stack_frame)
{
    HardFault_StackFrame_t *frame = (HardFault_StackFrame_t *)stack_frame;

    uint32_t cfsr  = SCB->CFSR;
    uint32_t hfsr  = SCB->HFSR;
    uint32_t dfsr  = SCB->DFSR;
    uint32_t mmfar = SCB->MMFAR;
    uint32_t bfar  = SCB->BFAR;
    uint32_t afsr  = SCB->AFSR;



    printf("\r\n\r\n********** HARD FAULT DETECTED **********\r\n");
    printf("* System halted for debugging             *\r\n");
    printf("*******************************************\r\n\r\n");

    printf("[Core Registers - Auto-saved Stack Frame]\r\n");
    printf("  R0  = 0x%08X\r\n", (unsigned int)frame->r0);
    printf("  R1  = 0x%08X\r\n", (unsigned int)frame->r1);
    printf("  R2  = 0x%08X\r\n", (unsigned int)frame->r2);
    printf("  R3  = 0x%08X\r\n", (unsigned int)frame->r3);
    printf("  R12 = 0x%08X\r\n", (unsigned int)frame->r12);
    printf("  LR  = 0x%08X [Link Register]\r\n", (unsigned int)frame->lr);
    printf("  PC  = 0x%08X [Program Counter - Faulting Instruction]\r\n", (unsigned int)frame->pc);
    printf("  PSR = 0x%08X [Program Status Register]\r\n", (unsigned int)frame->psr);
    printf("\r\n");

    printf("[SCB Fault Status Registers]\r\n");
    printf("  CFSR  = 0x%08X  B", (unsigned int)cfsr); PrintBin32(cfsr);
    printf("  [MMFSR=B7..0 | BFSR=B15..8 | UFSR=B31..16]\r\n");
    printf("  HFSR  = 0x%08X  B", (unsigned int)hfsr); PrintBin32(hfsr);
    printf("  [FORCED=B30 | DEBUGEVT=B31 | VECTTBL=B1]\r\n");
    printf("  DFSR  = 0x%08X  B", (unsigned int)dfsr); PrintBin32(dfsr);
    printf("  [HALTED=B0 | BKPT=B1 | DWTTRAP=B2 | VCATCH=B3 | EXTERNAL=B4]\r\n");
    printf("  MMFAR = 0x%08X\r\n", (unsigned int)mmfar);
    printf("  BFAR  = 0x%08X\r\n", (unsigned int)bfar);
    printf("  AFSR  = 0x%08X\r\n", (unsigned int)afsr);
    printf("\r\n");

    printf("[Fault Cause Analysis]\r\n");

    /* MemManage Faults (CFSR[7:0]) */
    if (cfsr & 0x000000FF) {
        printf("  >> MemManage Fault (MMFSR = 0x%02X B", (unsigned int)(cfsr & 0xFF)); PrintBin32(cfsr & 0xFF);
        printf("       [MMARVALID=B7 | MLSPERR=B5 | MSTKERR=B4 | MUNSTKERR=B3 | DACCVIOL=B1 | IACCVIOL=B0]\r\n");
        if (cfsr & 0x80) printf("     - MMARVALID: MMFAR holds valid address (0x%08X)\r\n", (unsigned int)mmfar);
        if (cfsr & 0x20) printf("     - MLSPERR:   MemManage fault during FP lazy state preservation\r\n");
        if (cfsr & 0x10) printf("     - MSTKERR:   MemManage fault on stacking for exception entry\r\n");
        if (cfsr & 0x08) printf("     - MUNSTKERR: MemManage fault on unstacking for exception return\r\n");
        if (cfsr & 0x02) printf("     - DACCVIOL:  Data access violation\r\n");
        if (cfsr & 0x01) printf("     - IACCVIOL:  Instruction access violation\r\n");
    }

    /* BusFaults (CFSR[15:8]) */
    if (cfsr & 0x0000FF00) {
        printf("  >> BusFault (BFSR = 0x%02X B", (unsigned int)((cfsr >> 8) & 0xFF)); PrintBin32((cfsr >> 8) & 0xFF);
        printf("       [BFARVALID=B7 | LSPERR=B5 | STKERR=B4 | UNSTKERR=B3 | IMPRECISERR=B2 | PRECISERR=B1 | IBUSERR=B0]\r\n");
        if (cfsr & 0x8000) printf("     - BFARVALID: BFAR holds valid address (0x%08X)\r\n", (unsigned int)bfar);
        if (cfsr & 0x2000) printf("     - LSPERR:    BusFault during FP lazy state preservation\r\n");
        if (cfsr & 0x1000) printf("     - STKERR:    BusFault on stacking for exception entry\r\n");
        if (cfsr & 0x0800) printf("     - UNSTKERR:  BusFault on unstacking for exception return\r\n");
        if (cfsr & 0x0400) printf("     - IMPRECISERR: Imprecise data bus error (address unknown)\r\n");
        if (cfsr & 0x0200) printf("     - PRECISERR: Precise data bus error (BFAR = 0x%08X)\r\n", (unsigned int)bfar);
        if (cfsr & 0x0100) printf("     - IBUSERR:   Instruction bus error\r\n");
    }

    /* UsageFaults (CFSR[31:16]) */
    if (cfsr & 0xFFFF0000) {
        printf("  >> UsageFault (UFSR = 0x%04X B", (unsigned int)((cfsr >> 16) & 0xFFFF)); PrintBin32((cfsr >> 16) & 0xFFFF);
        printf("       [DIVBYZERO=B9 | UNALIGNED=B8 | NOCP=B3 | INVPC=B2 | INVSTATE=B1 | UNDEFINSTR=B0]\r\n");
        if (cfsr & 0x02000000) printf("     - DIVBYZERO: Divide by zero\r\n");
        if (cfsr & 0x01000000) printf("     - UNALIGNED: Unaligned memory access\r\n");
        if (cfsr & 0x00080000) printf("     - NOCP:      No coprocessor / coprocessor instruction\r\n");
        if (cfsr & 0x00040000) printf("     - INVPC:     Invalid PC load (bad function pointer, corrupted LR)\r\n");
        if (cfsr & 0x00020000) printf("     - INVSTATE:  Invalid state - instruction in invalid state\r\n");
        if (cfsr & 0x00010000) printf("     - UNDEFINSTR:Undefined instruction\r\n");
    }

    /* HardFault Status */
    if (hfsr) {
        printf("  >> HardFault Status (HFSR = 0x%08X B", (unsigned int)hfsr); PrintBin32(hfsr);
        printf("       [DEBUGEVT=B31 | FORCED=B30 | VECTTBL=B1]\r\n");
        if (hfsr & 0x80000000) printf("     - DEBUGEVT:  Debug event triggered HardFault\r\n");
        if (hfsr & 0x40000000) printf("     - FORCED:    Escalated configurable fault (MemManage/Bus/Usage -> HardFault)\r\n");
        if (hfsr & 0x00000002) printf("     - VECTTBL:   Vector table read fault on exception processing\r\n");
    }

    /* Debug Fault Status */
    if (dfsr) {
        printf("  >> Debug Status (DFSR = 0x%08X B", (unsigned int)dfsr); PrintBin32(dfsr);
        printf("       [EXTERNAL=B4 | VCATCH=B3 | DWTTRAP=B2 | BKPT=B1 | HALTED=B0]\r\n");
        if (dfsr & 0x10) printf("     - EXTERNAL:  External debug request\r\n");
        if (dfsr & 0x08) printf("     - VCATCH:    Vector catch occurred\r\n");
        if (dfsr & 0x04) printf("     - DWTTRAP:   DWT match (watchpoint/breakpoint)\r\n");
        if (dfsr & 0x02) printf("     - BKPT:      BKPT instruction executed\r\n");
        if (dfsr & 0x01) printf("     - HALTED:    Halt request debug event\r\n");
    }

    printf("\r\n[Hints]\r\n");
    printf("  - PC value points to the instruction that triggered the fault.\r\n");
    printf("  - LR value shows EXC_RETURN code (bit2: 0=MSP, 1=PSP used before fault).\r\n");
    printf("  - If FORCED=1, check CFSR for the original fault cause.\r\n");
    printf("  - If BFARVALID/MMARVALID=1, the faulting address is shown above.\r\n");
    printf("\r\nSystem halted in HardFault loop.\r\n");

    __disable_irq();
    while (1) {
        __NOP();
    }
}

加入测试异常

c 复制代码
/**
  * @brief  HardFault test trigger function.
  *         Uncomment one of the methods below to test HardFault handler.
  */
void Trigger_HardFault_Test(void)
{
    typedef void (*func_t)(void);
    volatile func_t bad_func = (func_t)0xFFFFFFFF;
    bad_func();
}

测试


通过map文件分析,定位在了Trigger_HardFault_Test里面

相关推荐
振浩微433射频芯片5 小时前
告别“遥控失灵”:如何评估国产433芯片在智能家居领域的可靠性?
网络·单片机·嵌入式硬件·物联网·智能家居
互联科技报5 小时前
极海APM32F427高性能MCU赋能中高端PLC,筑牢工业自动化控制核心
单片机·嵌入式硬件·自动化
0南城逆流06 小时前
【网站分享】常用网站分享三:STM32常用模块链接
stm32·单片机·嵌入式硬件
星夜夏空996 小时前
STM32单片机学习(17) —— 串口外设中断
stm32·单片机·学习
hhcgchpspk6 小时前
easyx按键游戏
c++·stm32·单片机·游戏·easyx
行走的大喇叭7 小时前
Linux kernel目录、配置文件介绍
linux·单片机·嵌入式硬件
0南城逆流07 小时前
【网站分享】常用网站分享四:STM32常用外设链接
stm32·单片机·嵌入式硬件
yu85939587 小时前
STM32 控制 W5500 以太网传输程序
stm32·单片机·嵌入式硬件
LCG元7 小时前
STM32实战:基于STM32F103的车内防窒息系统(红外检测+GSM报警)
stm32·单片机·嵌入式硬件