This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Failed to solve a imprecise hardfault error

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.