在实际使用中,单片机会进入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里面