This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Many years ago someone at TI sent me routines that allowed me to query the registers that enabled me to determine the source of a hard fault, its code was:
// HardFaultHandler_C:
//
// This is called from the HardFault_HandlerAsm with a pointer the Fault stack
// as the parameter. We can then read the values from the stack and place them
// into local variables for ease of reading.
// We then read the various Fault Status and Address Registers to help decode
// cause of the fault.
// The function ends with a BKPT instruction to force control back into the debugger
void HardFault_HandlerC(unsigned long *hardfault_args) {
volatile unsigned long stacked_r0 ;
volatile unsigned long stacked_r1 ;
volatile unsigned long stacked_r2 ;
volatile unsigned long stacked_r3 ;
volatile unsigned long stacked_r12 ;
volatile unsigned long stacked_lr ;
volatile unsigned long stacked_pc ;
volatile unsigned long stacked_psr ;
volatile unsigned long _CFSR ;
volatile unsigned long _HFSR ;
// volatile unsigned long _DFSR ; // Not on our CPU
// volatile unsigned long _AFSR ; // Not on our CPU
volatile unsigned long _BFAR ;
volatile unsigned long _MMAR ;
stacked_r0 = ((unsigned long)hardfault_args[0]) ;
stacked_r1 = ((unsigned long)hardfault_args[1]) ;
stacked_r2 = ((unsigned long)hardfault_args[2]) ;
stacked_r3 = ((unsigned long)hardfault_args[3]) ;
stacked_r12 = ((unsigned long)hardfault_args[4]) ;
stacked_lr = ((unsigned long)hardfault_args[5]) ;
stacked_pc = ((unsigned long)hardfault_args[6]) ;
stacked_psr = ((unsigned long)hardfault_args[7]) ;
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
_CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
// Hard Fault Status Register
_HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
// Debug Fault Status Register
// _DFSR = (*((volatile unsigned long *)(0xE000ED30))) ; Doesn't exist on our CPU.
// Auxiliary Fault Status Register
// _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ; Doesn't exist on our CPU.
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
_MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
// Bus Fault Address Register
_BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
__asm("BKPT #0\n") ; // Break into the debugger
}
Is there something like this for my current MPU?
Thanks, Doug
Many years ago someone at TI sent me routines that allowed me to query the registers that enabled me to determine the source of a hard fault, its code was:
Hi Doug,
I'm not sure who you get this from. I don't see a problem to reuse this function if this function was created for a Arm M4 processor. Your function has the registers that are matching the M4. Please refer to the datasheet for detail. If you get a fault, you can see the same registers in the NVIC module in the register window.