单片机的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里面

相关推荐
FreakStudio11 天前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
✎ ﹏梦醒͜ღ҉繁华落℘16 天前
单片机基础知识---stm32单片机的优先级
stm32·单片机·mongodb
zd84510150016 天前
RS485 总线详解
单片机·嵌入式硬件
✎ ﹏梦醒͜ღ҉繁华落℘16 天前
编程基础 --高内聚,低耦合
c语言·单片机
科芯创展16 天前
1A,1MHz,30VIN,XZ4115,降压恒流LED驱动芯片
单片机·嵌入式硬件
集芯微电科技有限公司16 天前
四通道2A输出集成功率电感降压模块专为紧凑型方案设计
人工智能·单片机·嵌入式硬件·生成对抗网络·计算机外设
踏着七彩祥云的小丑16 天前
嵌入式测试学习第 37 天:异常场景测试:断电、拔插、干扰、非法指令
单片机·嵌入式硬件·学习
意法半导体STM3216 天前
【官方原创】如何为STM32CubeMX2配置Visual Studio Code配置方案
vscode·stm32·单片机·嵌入式硬件·策略模式·stm32cubemx·嵌入式开发
雾削木16 天前
B语言经典教程现代化重构
java·前端·stm32·单片机·嵌入式硬件
Hello-FPGA16 天前
Camera Link 与 CoaXPress 技术对比 如何选择你的相机接口
单片机·嵌入式硬件