Content originally posted in LPCWare by fcarlo on Wed Nov 21 03:59:06 MST 2012
I have replaced the default HardFault handler with this one:
void HardFault_Handler(void) {
__ASM("TST LR, #4");
__ASM("ITE EQ");
__ASM("MRSEQ R0, MSP");
__ASM("MRSNE R0, PSP");
__ASM("B hard_fault_handler_c");
}
// From Joseph Yiu, minor edits by fcarlo
// hard fault handler in C,
// with stack frame location as input parameter
// called from HardFault_Handler in file xxx.s
void hard_fault_handler_c(unsigned int * hardfault_args) {
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
unsigned int stacked_bfar;
unsigned int stacked_cfsr;
unsigned int stacked_hfsr;
unsigned int stacked_dfsr;
unsigned int stacked_afsr;
unsigned int stacked_scb_shcsr;
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]);
stacked_bfar = (*((volatile unsigned long *)(0xE000ED38)));
stacked_cfsr = (*((volatile unsigned long *)(0xE000ED28)));
stacked_hfsr = (*((volatile unsigned long *)(0xE000ED2C)));
stacked_dfsr = (*((volatile unsigned long *)(0xE000ED30)));
stacked_afsr = (*((volatile unsigned long *)(0xE000ED3C)));
stacked_scb_shcsr = SCB->SHCSR;
printf ("\n\n[Hard fault handler - all numbers in hex]\n");
printf ("R0 = %x\n", stacked_r0);
printf ("R1 = %x\n", stacked_r1);
printf ("R2 = %x\n", stacked_r2);
printf ("R3 = %x\n", stacked_r3);
printf ("R12 = %x\n", stacked_r12);
printf ("LR [R14] = %x subroutine call return address\n", stacked_lr);
printf ("PC [R15] = %x program counter\n", stacked_pc);
printf ("PSR = %x\n", stacked_psr);
printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
printf ("SCB_SHCSR = %x\n", SCB->SHCSR);
while (1);
}
And this is the output:
R0 = 0
R1 = 0x100826FB
R2 = 0x10400100
R3 = 0x40050004
R12 = 0x40050044
LR [R14] = 0x1A001E3F
PC [R15] = 0x1040012A
PSR = 0x41000000
BFAR = 0xE000ED38
CFSR = 0x00000400
HFSR = 0x40000000
DFSR = 1
AFSR = 0
SCB_SHCSR = 0
I can't do step-by-step debugging with Segger J-link after the jump to the ROM API address (0x10400100) so I can't understand exactly what could be the problem.
I forgot to mention that I am currently using an external oscillator and PLL1 is enabled to run at 60 MHz.