2025-04-23 3:11 AM
Hi everybody,
I am currently working on an STM32F446RE
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
Solved! Go to Solution.
2025-04-23 6:10 AM - edited 2025-04-23 6:45 AM
@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:
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:
2025-04-23 6:56 AM
> 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.
2025-04-23 7:10 AM
@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 ...
2025-04-23 7:19 AM
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
2025-04-23 8:00 AM
@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:
2025-04-23 8:33 AM
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.
2025-04-23 8:43 AM
@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"...
2025-04-23 8:59 AM
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
}
2025-04-23 9:21 AM
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
2025-04-23 9:35 AM - edited 2025-04-23 9:39 AM
@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://stackoverflow.com/questions/15156201/gnu-linker-section-of-non-contiguous-memory-region