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

How to trace the root cause of HardFault Cortex M3 with .lst file?

Dear All,

Now I'm trying to trace the root cause of HardFault Cortex M3 with .lst and tarmac0.log files.

Currently problem is that I'm not sure how to trace the root cause when I come across HardFault.

In especially, I'm wonder that does disassembly code help us to trace the root cause?

 UartPutc((char) DBG_ESCAPE); //send ESCAPE code
     2da:       201b            movs    r0, #27
     2dc:       f000 f8aa       bl      434 <UartPutc>
  UartPutc((char) DBG_CONNECT_ENABLE); //send debug test enable command
     2e0:       2011            movs    r0, #17
     2e2:       f000 f8a7       bl      434 <UartPutc>
  puts("\nEnabling debug tester...\n");
     2e6:       4810            ldr     r0, [pc, #64]   ; (328 <EnableDebugTester+0x60>)
     2e8:       f000 fa8e       bl      808 <puts>
  // If debug tester is not present,
  if((CMSDK_GPIO0->DATA & DEBUG_ERROR) != 0)
     2ec:       6823            ldr     r3, [r4, #0]
     2ee:       045b            lsls    r3, r3, #17
     2f0:       d405            bmi.n   2fe <EnableDebugTester+0x36>
  // (Zero the 4 words above Stack Top)
  //

  for(i=0; i<4 ; i++)
    {
  puts("\nInitialise the Communication Region...\n");
     2f2:       480e            ldr     r0, [pc, #56]   ; (32c <EnableDebugTester+0x64>)
     2f4:       f000 fa88       bl      808 <puts>
      DEBUGTESTERDATA[i] = 0;        //<================================HERE
     2f8:       2300            movs    r3, #0
     2fa:       681b            ldr     r3, [r3, #0]
     2fc:       deff            udf     #255    ; 0xff
  UartPutc((char) DBG_CONNECT_ENABLE); //send debug test enable command
  puts("\nEnabling debug tester...\n");
  // If debug tester is not present,
  if((CMSDK_GPIO0->DATA & DEBUG_ERROR) != 0)
    {
      puts("DBGERROR bit (debug error) asserted.\n");
     2fe:       480c            ldr     r0, [pc, #48]   ; (330 <EnableDebugTester+0x68>)
     300:       f000 fa82       bl      808 <puts>
      puts("Debug tester not available:\n");
     304:       480b            ldr     r0, [pc, #44]   ; (334 <EnableDebugTester+0x6c>)
     306:       f000 fa7f       bl      808 <puts>
      puts("1: The ARM_CMSDK_INCLUDE_DEBUG_TESTER macro is not defined, or\n");
     30a:       480b            ldr     r0, [pc, #44]   ; (338 <EnableDebugTester+0x70>)
     30c:       f000 fa7c       bl      808 <puts>
      puts("2: Cortex-M0 DesignStart is used\n");
     310:       480a            ldr     r0, [pc, #40]   ; (33c <EnableDebugTester+0x74>)
     312:       f000 fa79       bl      808 <puts>


As you can see the above code, I come across "Unexpected Hard Fault", when DEBUGTESTERDATA[i] = 0; run after.

Would you help me what am I supposed to do to resolve this problem?

  • You'd need to look at the registers when it faults.
    Should it be reading a value from address zero?
    You'd be better stepping in a debugger.

  • Only by looking into .lst file won't help you at all.

    Follow this app note to debug hardfault:
    http://www.keil.com/appnotes/docs/apnt_209.asp

  • I would be better to use print the some address about hardfault.

    Would you help me what does kind of way exist to print out to see the fault R0~R12 and MSP LR PC registers?

  • community.st.com/.../31521

    //*****************************************************************************
    
    /* Add ASM code to startup.s and remove C Handler from stm32fxyz_it.c
    
    HardFault_Handler\ 
                    PROC
                    EXPORT  HardFault_Handler
    
                    TST     lr, #4          ; Determine correct stack
                    ITE     EQ
                    MRSEQ   R0, MSP         ; Read MSP (Main)
                    MRSNE   R0, PSP         ; Read PSP (Process)
    
                    MOV     R1, R4          ; Registers R4-R6
                    MOV     R2, R5
                    MOV     R3, R6          ;  sourcer32@gmail.com
    
                    EXTERN  hard_fault_handler_c
                    B       hard_fault_handler_c
                    ENDP
    */
    
    void hard_fault_handler_c(unsigned int * hardfault_args, unsigned int r4, unsigned int r5, unsigned int r6)
    {
      printf ("[Hard Fault]\n"); // After Joseph Yiu
    
      printf ("r0 = %08X, r1 = %08X, r2 = %08X, r3 = %08X\n",
        hardfault_args[0], hardfault_args[1], hardfault_args[2], hardfault_args[3]);
      printf ("r4 = %08X, r5 = %08X, r6 = %08X, sp = %08X\n",
        r4, r5, r6, (unsigned int)&hardfault_args[8]);
      printf ("r12= %08X, lr = %08X, pc = %08X, psr= %08X\n",
        hardfault_args[4], hardfault_args[5], hardfault_args[6], hardfault_args[7]);
    
      printf ("bfar=%08X, cfsr=%08X, hfsr=%08X, dfsr=%08X, afsr=%08X\n",
        *((volatile unsigned int *)(0xE000ED38)),
        *((volatile unsigned int *)(0xE000ED28)),
        *((volatile unsigned int *)(0xE000ED2C)),
        *((volatile unsigned int *)(0xE000ED30)),
        *((volatile unsigned int *)(0xE000ED3C)) );
    
      while(1);
    }
    
    //****************************************************************************
    

  •       DEBUGTESTERDATA[i] = 0;        //<================================HERE
         2f8:       2300            movs    r3, #0
         2fa:       681b            ldr     r3, [r3, #0]
         2fc:       deff            udf     #255    ; 0xff
    

    The "udf #255" will generate an "undefined instruction exception" (part of the Usage Fault)
    If the Usage Fault is not enabled, it will generate a Hard Fault.

    This is clearly being done on purpose so you either need to enable the Usage Fault Handler and handle this undefined instruction or Handle it in the Hard Fault Handler.

    You are likely using other code (linking in) that is counting on a certain behavior when the udf #255 instruction is being executed and it is not happening so you get a hard fault rather than proper behavior.

  • Thanks for replying that.

    I'm wondering that I came across that HardFault error when I compiled with gcc as the below.

    arm-none-eabi-gcc --version
    arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977]
    Copyright (C) 2014 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    

    Today, I just found that in DS-5 environment, that point have some warning as
    warning: indirection of non-volatile null pointer will be deleted, not trap
    You can see here. https://imgur.com/a/roZjK and DEBUGTESTERDATA is defined like

     #define DEBUGTESTERDATA ((volatile uint32_t *) *((uint32_t *) 0x0))
    

    ans that defined like this https://imgur.com/a/3ZGo1

    Might be gcc environment can't handle like this warning but I'm not sure.

    Today, I found that in DS-5 environment the compile and simulation are more likely to have success without HardFault error.

  • Would you help me how to resolve this problem in gcc compile environment?

  • This is the Keil forum - for discussions about Keil products.
    http://www.keil.com/forum/

    GCC is not a Keil product!

  • >>Would you help me

    I'm open to offers for my time.