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

Order of variable declaration causes a hard fault

Hello all,

I am developing a project using the LPC1752 and uVision 4.10 on my own hardware using the FatFS library. I am having a problem whereby the order in which I declare my variables seems to determine whether or not the code causes a hard fault or not.

I my main.c file, I have declared two global variables:

FATFS fso;
char ReadData[512];

My test code simply creates a file on the SD card, writes some data to it and then reads the data back into the ReadData array. With the variables declared in the format shown above, my code works fine. However, if I swap the declaration to this:

char ReadData[512];
FATFS fso;

The code generates a hard fault. I have examined the Fault Reports dialog in uVision and it has shown me that the INVSTATE bit is set. According to the call stack, the fault has occurred at the end of my SDReadBlock function, just as I am returning a value. Here is a snippet of the function where the fault occurs:

        // Read the 2 CRC bytes
        SPIWrite(0xFF);
        SPIWrite(0xFF);

        CSHigh();

        SPIWrite(0xFF);

        return SDOK; //<== Here is where the call stack is pointing to
}

The corresponding assembly code is:

   370:         // Read the 2 CRC bytes
0x00002E6E 20FF      MOVS     r0,#0xFF
0x00002E70 F000F924  BL.W     SPIWrite (0x000030BC)
0x00002E74 F8050B01  STRB     r0,[r5],#0x01
0x00002E78 9800      LDR      r0,[sp,#0x00]
0x00002E7A 1E40      SUBS     r0,r0,#1
0x00002E7C 9000      STR      r0,[sp,#0x00]
0x00002E7E 9800      LDR      r0,[sp,#0x00]
0x00002E80 2800      CMP      r0,#0x00
0x00002E82 D1F4      BNE      0x00002E6E
   371:         SPIWrite(0xFF);
0x00002E84 20FF      MOVS     r0,#0xFF
0x00002E86 F000F919  BL.W     SPIWrite (0x000030BC)
   372:         SPIWrite(0xFF);
   373:
0x00002E8A 20FF      MOVS     r0,#0xFF
0x00002E8C F000F916  BL.W     SPIWrite (0x000030BC)
   374:         CSHigh();
   375:
0x00002E90 F000F8E6  BL.W     CSHigh (0x00003060)
   376:         SPIWrite(0xFF);
   377:
0x00002E94 20FF      MOVS     r0,#0xFF
0x00002E96 F000F911  BL.W     SPIWrite (0x000030BC)
   378:         return SDOK;
0x00002E9A 2000      MOVS     r0,#0x00
   379: }

What could be causing the problem?

--Amr

  • Hi,

    my best guess is that something is writing in ReadData[] beyond the 512 bytes it holds.

    In first case, the writes beyond its limit do not cause a crash because ... may because RAM after ReadData[] is never used.

    In second case, the writes beyond its limit corrupt the FATFS data structure. It may be that some sw module uses it and makes your system crash.

    Advice: have a look at the RAM where is the FATFS data structure to see if it is corrupted.

    Reagrds, Marco.

  • You could check if that is the case by increasing the size of ReadData[] and then setting a memory-write breakpoint on ReadData[512] ...

  • Hi all,

    Thanks for your replies. I have completely removed ReadData and all the code that used it, so that my only global variable is fso and I am still getting a hard fault in the same place.

    --Amr

  • I've just been doing some more reading on this. According to uVision's debug windows, I am getting a forced hard fault which is actually an INVSTATE error. On ARM's website (infocenter.arm.com/.../index.jsp), INVSTATE errors are due to the processor attempting to execute in an invalid EPSR state. Drilling down some more into the documentation reveals this page (href="infocenter.arm.com/.../ch02s03s02.html), which shows the EPSR register bitmap. According to this, an INVSTATE exception occurs if the processor attempts to execute an instruction with the T bit clear.

    Now all the code I have written in my project is in C and the only assembly code is the startup code which is bundled with Keil, so I would have thought that the compiler would ensure that the code doesn't branch to a PC location with bit 0 cleared.

    Any thoughts on how I can track this down?

    --Amr

  • If the stack is damaged, POP {...,PC} may make the LSB=0.


    The Definitive Guide to the ARM Cortex-M3
    Joseph Yiu

  • Hi John,

    Thanks for the pointer - it looks like that was the culprit. I've increased the stack size and now the program is working. Thanks for your help!

    --Amr