cancel
Showing results for 
Search instead for 
Did you mean: 

''int'' requires more than 4 bytes - but why ?

jogerh
Associate II
Posted on June 16, 2015 at 13:48

Dear community,

I use a STM32F051 plattform 

and I want to pre-define the flash address of a few integer values during compile-time to e.g. later on change those values using flash- write operations. Since I use a keil compiler I tried:

int a __atribute__((at(0x080008000                         ))) = 1234;

int b __atribute__((at(0x080008000 + 2* sizeof(int)))) = 1234; 

int c __atribute__((at(0x080008000 + 3* sizeof(int)))) = 1234; 

int d __atribute__((at(0x080008000 + 4* sizeof(int)))) = 1234; 

int e __atribute__((at(0x080008000 + 5* sizeof(int)))) = 1234; 

However this produces an internal fault [0x5352b9:5050106].

Then I tried:

int a __atribute__((at(0x080008000                         ))) = 123456;

int b __atribute__((at(0x080008000 + 2* 4* sizeof(int)))) = 123456; 

int c __atribute__((at(0x080008000 + 3* 4* sizeof(int)))) = 123456; 

int d __atribute__((at(0x080008000 + 4* 4* sizeof(int)))) = 123456; 

int e __atribute__((at(0x080008000 + 5* 4* sizeof(int)))) = 123456; 

and it works for some reason. I would be very happy, if someone could explain, why “int�? requires more FLASH size than it actually uses.

5 REPLIES 5
Posted on June 16, 2015 at 15:06

Missed the *1 element.

Wouldn't this be far easier if you just used a structure, and nailed that to the base address?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
jogerh
Associate II
Posted on June 16, 2015 at 16:47

Hi,

thank you for responding  - I would be very happy, 

if you would explain the meaning of “

Missed the *1 element

�?. 

Q: Wouldn't this be far easier if you just used a structure, and nailed that to the base address?

A: Currently I try to understand how to flash something into the flash. Therefore I stick to ugly int’s. Latter on I will try your hint to use a ''struct'' instead.

However currently I see another problem associated with my question:

The compiler assigns “const�? to my int values which is the cause of a hard fault, if I try to overwrite those values during runtime. One solution would be to FLASH_OB_Erase(). However I would be happier if I could just tell the compiler to keep the RW status of the int’s. Is there a way to achieve this ? 

Posted on June 16, 2015 at 17:11

0, 2, 3, 4, 5, you've missed index 1

Flash memory doesn't write like normal RAM, the erase/write process is slow, involved, and device specific. It's therefore not the compiler's responsibility to deal with it, but rather the developer has to come up with a method to manage it.

OB_Erase would be for the options, this data is being placed in the primary flash array, where the sector, and thus minimum erase size, is 16KB

One of the more usual ways of dealing with this is to have a structure, and have the FLASH copy moved into a RAM copy, which you modify, and when you're done changing that, you erase the FLASH copy, and write back the new values.

As to your initial question, you'd have to review the .MAP file, or analyze the object format (ELF) to understand what's happening. It would take some time, and I'm not that interested in the answer, as the AT mechanism is one of the least portable methods of addressing this.

I've posted FLASH example to the forum before, and there are examples in the Standard Peripheral Library.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
jogerh
Associate II
Posted on June 17, 2015 at 08:50

Dear community,

my original question regarding “internal fault [0x5352b9:5050106]�? is no longer relevant since no more reproducible. As expected, integers just require 4 bytes of flash space. However my other particular question seems to be more important. If I assign integers to a certain flash space (far away from the  program code), then this works so far (it is possible to write values into this flash space and use them in the code of investigation. 

#define ADR_BASE  

0x08006000

#define ADR_1   ADR_BASE    

#define ADR_2     ADR_BASE  + 1*sizeof(int)

#define ADR_3     ADR_BASE  + 2*sizeof(int)

#define ADR_4   ADR_BASE  + 3*sizeof(int)

#define ADR_5     ADR_BASE  + 4*sizeof(int)

#define ADR_6     ADR_BASE  + 5*sizeof(int)

int MEM_1 __attribute__((at(ADR_1)));

int MEM_2   __attribute__((at(ADR_2))); 

int MEM_3   __attribute__((at(ADR_3))); 

int MEM_4       __attribute__((at(ADR_4)));  

int MEM_5       __attribute__((at(ADR_5))); 

int MEM_6       __attribute__((at(ADR_6))); 

0x08005FF0 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

0x08006000 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

However if I assign values during compile time to the integers....

int MEM_1 __attribute__((at(ADR_1))) = 1;

int MEM_2   __attribute__((at(ADR_2))) = 1; 

int MEM_3   __attribute__((at(ADR_3))) = 1; 

int MEM_4       __attribute__((at(ADR_4))) = 1;  

int MEM_5       __attribute__((at(ADR_5))) = 1; 

int MEM_6       __attribute__((at(ADR_6))) = 1; 

... then I get the following flash readout:

0x08005FF0 00000000 00000000 00000000 00000000

0x08006000 00000001 00000001 00000001 00000001

0x08006010 00000001 00000001 00000000 00000000

                     00000000 00000000 00000000 00000000

                     0000000 00000000 00000000 00000000

                     00000000 00000000 00000000 00000000

                     00000000 00000000 00000000 00000000

                     00000000 00000000 00000000 00000000

                     00000000 00000000 00000000 00000000

0x080060B0 00000000 08001AA9 080019E1 00000000

0x08006090

 

080022E9 0800232D 08002445 08002171

0x080060A0 00000000 08000FB9 08000881 08000E39

0x080060B0 00000000 04030201 04030201 09080706

                      FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

                      FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

Deleting those int-values to assign new values during runtime is also possible - however after reset (or power off) the cpu triggers the hardware-fault handler. Currently I guess it might be a Flash Time Out issue. However if I look to the flash readout, then I recognize some strange stuff from 0x080060B0 upwards (maybe a checksum ?).  Perhaps someone knows more…

jogerh
Associate II
Posted on June 17, 2015 at 13:20

Dear Community,

I found two work a round’s so far. The strange region added behind the integers is the END- OF PROGRAM code.

0x080060B0:00000000 08001AA9 080019E1 00000000

0x08006090:080022E9 0800232D 08002445 08002171

0x080060A0:00000000 08000FB9 08000881 08000E39

0x080060B0:00000000 04030201 04030201 09080706

Either you save this region prior erasing and wrote it back together with the values you need to change or you define another value just one page above the used page to force the compiler for adding the end of program there. I tried both ways successfully (so far).

int END_ofProg        __attribute__((at(ADR_BASE + 0x400)))     = 1;