We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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 }
infocenter.arm.com/.../index.jsp reading this article, i checked the value in LR register, it is 0xFFFFFFF1. The last bit being 1, its not an error invoked by switching from Thumb to ARM instruction set.
What else do i check . how can this be solve. i am in search of more relevant articles.
the following are the values of the registers as retrieved from the stack
r0 = 0x0000 1F64 //remains unchanged even after multiple times execution r1 = 0x0000 0100 //remains unchanged r2 = 0x0000 000C r3 = 0x0000 0011 r12 = 0x0000 0025 LR = 0x0001 B499 PC = 0x0001 AEB4 PSR = 0x2100 0000
in the disassembly window, i found out the following code written at the address 0x0001 AEB4
rt_evt_psh: // <- a generate event asm code, is it ? 0x0001AEA8 B510 PUSH {r4,lr} 0x0001AEAA 4604 MOV r4,r0 0x0001AEAC 8B00 LDRH r0,[r0,#0x18] 0x0001AEAE 4308 ORRS r0,r0,r1 0x0001AEB0 8320 STRH r0,[r4,#0x18] 0x0001AEB2 7862 LDRB r2,[r4,#0x01] 0x0001AEB4 8B61 LDRH r1,[r4,#0x1A] // <- Here 0x0001AEB6 2A06 CMP r2,#0x06 0x0001AEB8 D016 BEQ 0x0001AEE8 0x0001AEBA 2A05 CMP r2,#0x05 0x0001AEBC D117 BNE 0x0001AEEE 0x0001AEBE 4208 TST r0,r1 0x0001AEC0 D015 BEQ 0x0001AEEE 0x0001AEC2 EA010200 AND r2,r1,r0 0x0001AEC6 8362 STRH r2,[r4,#0x1A] 0x0001AEC8 4388 BICS r0,r0,r1 0x0001AECA 8320 STRH r0,[r4,#0x18] 0x0001AECC 4620 MOV r0,r4 0x0001AECE F000FB8F BL.W rt_rmv_dly (0x0001B5F0) 0x0001AED2 2001 MOVS r0,#0x01 0x0001AED4 7060 STRB r0,[r4,#0x01] 0x0001AED6 2002 MOVS r0,#0x02 0x0001AED8 F8840025 STRB r0,[r4,#0x25] 0x0001AEDC 4621 MOV r1,r4 0x0001AEDE E8BD4010 POP {r4,lr} 0x0001AEE2 4803 LDR r0,[pc,#12] ; @0x0001AEF0 0x0001AEE4 F000BB44 B.W rt_put_prio (0x0001B570) 0x0001AEE8 EA310200 BICS r2,r1,r0 0x0001AEEC D0EC BEQ 0x0001AEC8 0x0001AEEE BD10 POP {r4,pc} 0x0001AEF0 D98C DCW 0xD98C 0x0001AEF2 1000 DCW 0x1000
How to further analyse this piece of information and where do i look in my code? Because this code it seems is an RTOS code from the keil RTOS library.
The value in the r0 is MSP.
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.