i m working on lpc1788. I use Keil rtos and mailbox to pass the data from the uart handler (as read from a thread on this forum). All was working well till date, untill i added a few bytes of code on saturday. The seventh string that is received to the uart creates an imprecise error. it always has to be the 7th (irrespective of the size of the previous strings)
to check the cause, i came across this piece of code, but doesnt work in keil
__attribute__((naked)) void HardFault_handlerAsm(void) { __ASM ( ".syntax unified\n" "MOVS R0, #4 \n" "MOV R1, LR \n" "TST R0, R1 \n" "BEQ _MSP \n" "MRS R0, PSP \n" "B HardFault_HandlerC \n" "_MSP: \n" "MRS R0, MSP \n" "B HardFault_HandlerC \n" ".syntax divided\n" ) ; } 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 ; volatile unsigned long _AFSR ; 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))) ; // Auxiliary Fault Status Register _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ; // 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 }
Dear Pier, I wrote a generic hardfault handler (with help of Feabhas' document that i got online - the document takes Joseph Yiu's books as reference). This new hardfault handler POPs all the register values stored in stack, which are the actual values before the core enters Hardfault. The values that i mentioned in the previous post are actually the values read from the stack.