cancel
Showing results for 
Search instead for 
Did you mean: 

Weird behaviour with data in flash ( STM32F412RE)

Bertrand1
Senior

Hello,

I have some application parameters stored in flash area, declared like this :

__attribute__((__section__(".storageFlash"))) const parametersTable_t flashParameters;

The linker script has been modified as follow:

/* Specify the memory areas */

MEMORY

{

RAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 256K

FLASH (rx)     : ORIGIN = 0x8000000, LENGTH = 384K

PARAMETERS_STORAGE (rx)   : ORIGIN = 0x08060000, LENGTH = 64K

CALIBRATION_STORAGE (rx) : ORIGIN = 0x08068000, LENGTH = 64K

}

....

 .storageFlash (NOLOAD) :

 {

   . = ALIGN(4);

   *(storageFlash)

   . = ALIGN(4);

 } >PARAMETERS_STORAGE

In my program I do a simple copy on a local data or make a comparaison with Ram data like this : temp = flashParameters.version;

With Atollic , I can read that flashParameters.version = 12 but temp = 0!!

If I read the raw memory I can also find 12.

I don't understand why the programm read always 0 instead of 12.

Thanks for your help

Bertrand

11 REPLIES 11

Observe how do the Rx registers change. It's not that hard to guess.

From your snippet:

> ldr r4, [pc, #148] ; (8019a20 <isConfigInFlashValid+0xac>)

This load content of 0x08019a20 into register r4.

> movs r2, #0

This moves constant 2 into register 2.

> ldr r1, [pc, #148] ; (8019a24 <isConfigInFlashValid+0xb0>)

This loads content of 0x8019a24 into r1

> mov r0, r4

This moves content of r4 into r0.

> bl 801dcac <siprintf>

This calls sprintf (okay, siprintf, which is an optimization on sprintf performed by the library).

First 4 parameters to functions are usually passed in r0, r1, r2, r3; return value is passed back in r0 (this is given by ARM ABI).

The first parameter, address of sbuf, was loaded in the first step into r4 then moved to r0.

The second parameter, address of the format string, was loaded in the third step.

The third parameter, in r2, is 0, and that's what's printed out.

So, the optimizer judged that flashParameters.version == 0. It did so because you probably don't initialize flashParameters.version (you probably load some direct value into it through a different mechanism which the C compiler does not see), so for C, it's an global variable which is not explicitly initialized - as such it's implicitly initialized to 0 so the optimizer may assume it is 0.

Qualify flashParameters as volatile.

JW

Ok, thanks.

I will check that.

Bertrand