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 }
Nob,
I'd hope R0 isn't that stack, it should be R0 stacked by the fault. You might want to review the value in R4, as the assembler implicates this register, the value of "hardfault_args" should reflect the stack frame.
You want to make sure the stack is in RAM, and that this hasn't descended into other memory (heap, statics, etc)
Joseph Yiu has several books on the Cortex-M parts, and there should be plenty of web articles, and blogs, on the Hard Fault topic, and potential causes.
Stack size and corruption are pretty high up the list, accessing invalid memory regions will also trigger, as will attempting to run 32-bit code.
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.