cancel
Showing results for 
Search instead for 
Did you mean: 

explanation about flash memory on sector method

JJoao.1
Associate III

Hi everybody,

I am currently working on an STM32F446RE

Datasheet 

I need to save some bytes like 10 for example. I need to save some bytes like 10 for example, in flash memory to save my HMI configuration.

I have read articles and done research but I don't understand everything.

The memory is divided into sectors. I think I have to write my data to the end of the memory. However, the last sector is 128kB. Do I have to erase 128kB each time?

 

Isn't there a simpler and less resource-intensive method? Can't we just delete a 2KB page?

I really need to save only a few variables

 

Thank you to reading me

 

 

 

24 REPLIES 24

@JJoao.1 wrote:

It's too complicated for me at the moment.


Another issue you need to consider is that of Flash wear.

Erasing flash does cause wear; ie, it degrades the memory's ability to store data

This is specified in the datasheet as endurance:

AndrewNeil_5-1745413624548.png

https://www.st.com/resource/en/datasheet/stm32f446re.pdf#page=112

 

What that means is that, once you've erased a sector 10k times, ST no longer guarantee that it will continue to store data.

So one of the things that the EEPROM emulation does is wear-levelling - to minimise the number of erase cycles.

This is something you will have to consider, whatever you do ...

 

PS:

https://community.st.com/t5/stm32-mcus-products/understanding-on-flash-memory-endurance-cycles-for-stm32/m-p/711676/highlight/true#M258609

https://community.st.com/t5/stm32-mcus-products/erasing-flash-what-does-really-affect-the-wear/td-p/623282 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

> I took a look at your EEPROM simulation link. It's too complicated for me at the moment.

And it does not circumvent the sector erase issue.
This EEPROM simulation uses a Flash sector, you gain nothing in regard to size to allocate.

You would need real EEPROM, which is byte/word erasable & programmable.


@Ozone wrote:

> I took a look at your EEPROM simulation link. It's too complicated for me at the moment.

And it does not circumvent the sector erase issue.


That's true - the issue is unavoidable.

But it does illustrate making use of the whole sector for wear levelling ...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
JJoao.1
Associate III

Ok, I'm a little confused.

To resume what I understood /

Only an entire sector can be erased. So If I want put my data at the end, I should use and erase the 128kB.

It's not a very big problems, but It's just a lot for only a few bytes. Why not....

 

Otherwise there would be a possibility by putting my data in a sector at the beginning of 16kB ( like sector 0 or 1 or 2 or 3 ).

I don't understand what you mean's @Andrew Neil  in this setence :

But remember that the reset vectors (at least) will have to remain at the start of Flash...

Can you explain that ! I not an expert I don't know what's reset verctor

 

Or the last solution is to use extern memory


@JJoao.1 wrote:

Only an entire sector can be erased.


Correct.

 


@JJoao.1 wrote:

So If I want put my data at the end, I should use and erase the 128kB.


Yes: the last sector is 128K - so, if you want to use that one, then that's the one you have to erase.

But you don't have to use that one.

 


@JJoao.1 wrote:

Otherwise there would be a possibility by putting my data in a sector at the beginning of 16kB ( like sector 0 or 1 or 2 or 3 ).


Again, not sector 0 - but any of the others.

 


@JJoao.1 wrote:

I don't know what's reset verctor


That's fundamental to the operation of the Cortex-M architectures (and, in fact, most microcontroller architectures)!

The Reset Vector is what tells the processor, immediately after a reset, where to find the start of your code.

https://en.wikipedia.org/wiki/Reset_vector

This is defined by the hardware - it has to be, since it happens before the processor has even started your code.

In Cortex-M, there is also the starting address for the Stack:

https://developer.arm.com/documentation/107565/0101/Use-case-examples/Generic-Information/What-is-inside-a-program-image-/Vector-table

https://developer.arm.com/documentation/dui0552/a/the-cortex-m3-processor/exception-model/vector-table

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
JJoao.1
Associate III

Okay, I roughly see what you mean, but I don't quite understand.
So, writing to sector 0 is prohibited for vector resets.

So in this case, can I write to sector 1 and indicate (I don't know how yet) that the program starts in sector 2?
So, I leave the original sector 0, use sector 1, which is 16Kb, for my data, and indicate that my program starts in sector 2 to skip sector 1.


@JJoao.1 wrote:

So, writing to sector 0 is prohibited for vector resets.


Not exactly prohibited,  but you'd have to be very careful to ensure that the reset vectors remained intact - otherwise your system would be unable to boot!

 


@JJoao.1 wrote:

So in this case, can I write to sector 1 and indicate (I don't know how yet) that the program starts in sector 2?


Yes.

You'd specify it in the .ld Linker script file, then the Linker takes care of allocating your code around the "gap"...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
JJoao.1
Associate III

Ok I found this file named : STM32F446RETX_FLASH.ld

I read this line :

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 512K
}

So if I want want write on the sector 1 I need to change this like this :

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 496k  // 512K - 16k 
  My_FLASH (rx)    : ORIGIN = 0x8004000,   LENGTH = 16k
}

 

Yes, you can fashion a hole, with the smaller sectors.

The first sector can be a boot-loader, or something to transfer control deeper into the memory.

You can also journal a structure over the entire sector before you need to erase and start over, this means you write newer copies of the data, and then fish out the most recent.

The EEPROM Emulation does this, and uses two sectors, so the data you want to recover is never completely erased

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Tesla DeLorean wrote:

The first sector can be a boot-loader


Does it need to be a bootloader?

Can the Linker not cope with working around a gap?

 

PS:

https://community.st.com/t5/stm32-mcus-products/how-to-store-code-into-two-discontinuous-flash-area/td-p/159561

https://stackoverflow.com/questions/15156201/gnu-linker-section-of-non-contiguous-memory-region

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.