cancel
Showing results for 
Search instead for 
Did you mean: 

STM3210C GCC - hard fault when <pack struct members> is active

anonymous1234
Associate II
Posted on December 14, 2009 at 20:13

STM3210C GCC - hard fault when is active

7 REPLIES 7
anonymous1234
Associate II
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

tomas23
Associate II
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.

anonymous1234
Associate II
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
Associate II
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 II
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)... :|

andreas2
Associate II
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.

st3
Associate II
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...