Skip to main content
Graduate
April 23, 2025
Solved

explanation about flash memory on sector method

  • April 23, 2025
  • 9 replies
  • 2680 views

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

 

 

 

    This topic has been closed for replies.
    Best answer by Andrew Neil

    If that's resolved it for, please mark that as the solution:

    https://community.st.com/t5/community-guidelines/help-others-to-solve-their-issues/ta-p/575256

    9 replies

    Super User
    April 23, 2025

    @JJoao.1 wrote:

    The memory is divided into sectors.


    Correct.

     


    @JJoao.1 wrote:

    I think I have to write my data to the end of the memory.


    You don't have to.

    By default, CubeIDE uses memory from the beginning - but you could reconfigure that.

     


    @JJoao.1 wrote:

    Can't we just delete a 2KB page?


    Sure you can - you just need to make sure that the sector isn't used for anything else

    Correction: The smallest sector is 16K - not 2K - see the post by @Hl_st, below.

    Have you seen

    STSW-STM32066, EEPROM emulation in STM32F40x/STM32F41x microcontrollers (AN3969) :

    https://www.st.com/en/embedded-software/stsw-stm32066.html

    ST Employee
    April 23, 2025

    Hello,

    I attached easy example of reading and writing to flash memory for STM32C031 but it can be easily reconfigured to your MCU. Example writes to the last page of flash (user program is saved to the beginning of flash by default). Address of the last flash page is defined by these constants (you should find it in reference manual for your device):

    Screenshot (18).png

    #define FLASH_USER_START_ADDR 0x08007800 /* Start @ of user Flash area */
    #define FLASH_USER_END_ADDR 0x08007FFF /* End @ of user Flash area */

    Write function in the example erase memory by pages (2 kB) and then saves data by doubleworlds (8 B). 

    Explorer
    April 23, 2025

    > 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?

    If you want to use the same locations, yes. 

    The term "sector" in regard to Flash denominates individually erasable segments.

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

    If the MCU variant contains no explicit 2kB Flash sector, no.

    And you will invariably come across another term (and problem) related to Flash - the "bank".
    All sectors in one Flash bank can only be set to programming mode at once(especially, applying programming voltage internally). And you cannot execute code from a Flash bank while under programming voltage.

    Most MCUs are single-bank designs. This means, you either accept to stall during the actual flash programming, or run the flashing code from RAM.

    An alternative solution is a cheap external EEPROM (I2C or SPI).

    Super User
    April 23, 2025

    @Ozone wrote:

    And you cannot execute code from a Flash bank while under programming voltage.


    @JJoao.1 see the RM:

    AndrewNeil_4-1745413334521.png

    JJoao.1Author
    Graduate
    April 23, 2025

    Thank you fot you quick reply !

    @Andrew NeilI took a look at your EEPROM simulation link. It's too complicated for me at the moment.

    Can you confirm that for me :

    I want to write my data on the last sector.

    Sector 7      0x0806 0000 - 0x0807 FFFF       128 Kbytes .

    In this 128Kb in would like use only the 2 last Kb .  Can I erase only 2Kb on the sector 7 ?

    So at this adress   0x807 FFFF - 2048 =  0x807F7FF

    0x807F7FF is my start adress

     

    Or maybe it's more simple to change the start adress of my program like 0x0800 0000 to 0x800 0000 + 16Kb to reserved for me the sector 0 ?

     

    ST Employee
    April 23, 2025

    Yes, you can erase only 2 kB on sector 7 at the address 0x807F7FF. Try to follow the example I have send in my last reply there is also erased only 2 kB. Full sector have to be erased, 128 kB for the last one.

    Super User
    April 23, 2025

    @Hl_st wrote:

    Yes, you can erase only 2 kB on sector 7 at the address 0x807F7FF. 


    Really?

    Surely the whole point of the "Sector" is that it defines the size which can be erased? You can only ever erase a whole sector - not a part thereof.

    Surely, that's what the RM means by, "Sector erase":

    AndrewNeil_0-1745412653613.png

     

    And, explicitly:

    AndrewNeil_1-1745412748921.png

    AndrewNeil_3-1745413178974.png

     

     

     


    @Hl_st wrote:

     Try to follow the example I have send in my last reply there is also erased only 2 kB.


    But that is for an entirely different processor

    JJoao.1Author
    Graduate
    April 23, 2025

    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

    Super User
    April 23, 2025

    @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

     

    JJoao.1Author
    Graduate
    April 23, 2025

    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.

    Super User
    April 23, 2025

    @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"...

    JJoao.1Author
    Graduate
    April 23, 2025

    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
    }

     

    Super User
    April 23, 2025

    @JJoao.1 does it have to be STM32F446RE ?

    Maybe look at other parts which have more "friendly" flash layouts?

    I think the only STM32s with true EEPROM are some L0s (Cortex-M0+) and L1s (M3).

    JJoao.1Author
    Graduate
    April 23, 2025
    does it have to be STM32F446RE ?

    Yes, I have already ordered it, and place on my PCB .

    I need the fast 40Mhz SPI module to communicate with a screen so 80Mhz clock.

    I think it's to dangerous for me to try t owrite at the begin of Flash.

    I will stay at the end , It doesn't matter for the 128kB. I will erase it every time. Or If i need to modify my PCB maybe  Iwill implemente an extern memory.

     

    I thought it was going to be easier, it's my fault

     

    Thank you so much for your help/

    See you later

     

    Super User
    April 23, 2025