Skip to main content
anonymous1234
Associate
December 14, 2009
Question

STM3210C GCC - hard fault when is active

  • December 14, 2009
  • 7 replies
  • 1681 views
Posted on December 14, 2009 at 20:13

STM3210C GCC - hard fault when is active

    This topic has been closed for replies.

    7 replies

    anonymous1234
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 13:33

    Hi all,

    Eval board STM3210C, using Template Project and 3.1.2 CMSIS Library.

    All is fine when GCC Compiler option 'pack structure members' is NO.

    When set to YES, this create hard fault.

    In detail, this is when accessing to FLASH register, into SetSysClockTo72() function :

    -----------------------------------

    if (HSEStatus == (uint32_t)0x01)

    {

    /* Enable Prefetch Buffer */

    FLASH->ACR |= FLASH_ACR_PRFTBE; <<<<

    -----------------------------------

    I have the same issue if I make a single read access to this address :

    -----------------------------------

    void FLASH_SetLatency(uint32_t FLASH_Latency)

    {

    uint32_t tmpreg = 0;

    /* Check the parameters */

    assert_param(IS_FLASH_LATENCY(FLASH_Latency));

    /* Read the ACR register */

    tmpreg = FLASH->ACR; <<<<

    -----------------------------------

    Any idea ???

    Many thanks

    anonymous1234
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 13:33

    Thanks edison.

    you're right. I think addresses shifted. But disassembly seems OK.

    I solved it by setting individual option 'no pack' to each c source file (CMSIS and StdPeriphDriver libraries). And 'pack' for general options.

    Many thanks.

    tomas23
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 13:33

    GCC is sometimes weird. STM32 (resp. Cortex-M3) issues MemoryFault if trying to access non-defined location in memory map.

    If you pack the structures, doesn't the ACR address shift somehow? Look into disassembly and check.

    st3
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 13:33

    Quote:

    I solved it by setting individual option 'no pack' to each c source file (CMSIS and StdPeriphDriver libraries). And 'pack' for general options.

    I think this must be a general GCC ''feature'' - I've had similar problems with getting GCC to obey the 'packed' option on another ARM target (not cortex)... :|

    tomas23
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 13:33

    Glad you solved it.

    Btw. what the hell the GCC created? In your faulty example, it reads the register in BYTES, with offset +1 from its base address. This is horribly wrong!

    st3
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 13:33

    Also be very careful when accessing (elemnts of) a packed struct via pointers - the fact that it's packed could get ''lost'' in the pointers and, end up with an unexpected unaligned access...

    andreas2
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:33

    When you declare a struct as packed, you're removing all alignment requirements associated with it. So any function operating on (a pointer to) a packed struct must either select between different access paths at runtime or, as gcc does, simply access it byte wise. Of course, since Cortex-M3 supports unaligned accesses (for most load/store operations anyway) it's possible to disregard the fact that the struct may be unaligned and just read it as if it was. But gcc seems to be unaware of this feature or need to be told to use it.

    The code gcc generated is perfectly valid, it's the use of -fpack-struct that is wrong in this (as well as most other) contexts. That option should only be used if you have to link with other code built with that option. It causes the generated code to be horribly inefficient, as can be seen from the screenshots. If you really need some structs to be packed, it's better to mark them selectively with ''__attribute__ ((packed))'', instead of applying the global option.