Hi,
I have a project in a STM32F410CBT (128KB) compiled with STM32duino version 2.10.1. This is for existing hardware that has been using eeprom emulation for quite some time. This project has been growing and now crossing the 64KB flash line that would not be an issue if I could move the EEPROM for the default last sector of 64KB. The F410 has 5 sectors 0 to 3 of 16KB and last of 64KB! No idea why this, but I think I found the bad way in this device, that from the EEPROM library that any EEprom writing will wipe the whole last 64KB sector (as flashes do). So this means that currently my 128KB device is limited to 64KB if I use EEprom.
If so far I am understanding the problem right, one possibility, would be to move the EEPROM emulation to sector 3 (16KB) and then to have the rest of the space to program flash. No idea if this is possible without getting too crazy, but so far I failed with the information I found on line, particularly to constrain the EEPROM library to sector 3 starting in 0x08000C000 (16KB). The initial (failed plan) was: first constrain the flash memory to sector 3, and then modify the linking memory space in ldscript.ld to reflect this and avoid that code gets compiled in this area. But apparently I cannot get the EEProm reading or writing in that sector 3, I am using the memory window from the cube programmer to verify that. I tried some defines other people has mentioned and then I found that you can define FLASH_EEPROM_BASE, but it appears this is more related with the HAL?
Did anybody achieve this successfully? Or is any documentation I am not aware that can direct me on it? Any help would be appreciated. Alternatively a procedure using HAL I could try.
Thank you,
Rick.
Procedure to change EEPROM default sector/base address using STM32Duino?
Re: Procedure to change EEPROM default sector/base address using STM32Duino?
Emulated eeprom always uses 2 sectors of flash memory. It won't work for long with just one.
In case of your MCU it should use sectors 2 and 3: https://www.st.com/resource/en/applicat ... ronics.pdf
In case of your MCU it should use sectors 2 and 3: https://www.st.com/resource/en/applicat ... ronics.pdf
Re: Procedure to change EEPROM default sector/base address using STM32Duino?
Thank you Gonzo for the answer. I noticed this ST App note before that describes a very robust way to implement a EEPROM emulation. However I realized as I commented earlier that STM32Duino eeprom library uses a simpler approach with a single sector defaulting to be the last one, that in my device happens to be half the whole flash.
In my application I should be fine without wear leveling, backup mechanism, etc offered in AN3969 that uses a different library. This takes 32KB of the flash, for just a max of 200 bytes that I store, but at the end I may have to explore this anyway if there is no another alternative. The extra 32KB will buy me some time with my current hardware.
Next design I learned the lesson, so I will populate an external real eeprom device.
In my application I should be fine without wear leveling, backup mechanism, etc offered in AN3969 that uses a different library. This takes 32KB of the flash, for just a max of 200 bytes that I store, but at the end I may have to explore this anyway if there is no another alternative. The extra 32KB will buy me some time with my current hardware.
Next design I learned the lesson, so I will populate an external real eeprom device.
-
- Posts: 1
- Joined: Mon Apr 21, 2025 7:10 am
- Location: https://stickmanhookgame.org
Re: Procedure to change EEPROM default sector/base address using STM32Duino?
Would a minimal version of the AN3969 approach, without wear leveling but with a simpler backup system, be a middle ground worth considering?rhormigo wrote: Fri Apr 18, 2025 5:25 pm Thank you Gonzo for the answer. I noticed this ST App note before that describes a very robust way to implement a EEPROM emulation. However I realized as I commented earlier that STM32Duino eeprom library uses a simpler approach with a single sector defaulting to be the last one, that in my device happens to be half the whole flash.
In my application I should be fine without wear leveling, backup mechanism, etc offered in AN3969 that uses a different library. This takes 32KB of the flash, for just a max of 200 bytes that I store, but at the end I may have to explore this anyway if there is no another alternative. The extra 32KB will buy me some time with my current hardware.
Next design I learned the lesson, so I will populate an external real eeprom device.
Re: Procedure to change EEPROM default sector/base address using STM32Duino?
it is possible to write directly to flash instead of using EEPROM emulation, these are mostly covered in the FLASH sections of the ref manuals.
The way flash works is that if a page is erased it is reset to 0xff for all bytes, writing data to them toggle the bits to 0.
Hence, it may be possible to use some other schemes, e.g. spiffs
https://github.com/pellepl/spiffs
to manage the pages, or perhaps invent one e.g. modify the EEPROM emulation codes to implement your preferred scheme.
A thing about on chip flash is that the sectors are larger at the 'back' e.g. 0-3 is 16 kB, 4 is 64k, and 5 and higher is 128k etc.
This is perhaps ok if say you only need one sector say the 64k sector to keep your data.
Using the 'lower' sectors risk overlapping into program codes.
I've been using external SPI flash e.g. those W25Q64xx style SPI flash
https://www.winbond.com/hq/product/code ... o=W25Q64FV
there are various open sourced libraries that support them, and in the same way the flash works by having erased sectors all filled with 0xff.
SPI flash works well if your storage requirements is in the low MB, I've got a temperature and light sensor logging data every 10 secs and I managed to fit that in every 16 bits (12 bits are ADC data, the remaining 4 bits I used to indicate the channel) and that at rather low data rates e.g. 10 secs intervals, I managed to fit like 6-9 months or so of records in a 8 MB (64 Mbits) SPI flash. That probably works well for GPS loggers as well which could log like say at 10 secs intervals or more.
Then that if you want to store a huge amount of data, these days even the smallest uSD cards runs in capacities like 4 GB - 128 GB, and 8-16 GB are practically quite common, and they can mostly work over SPI ! A thing about uSD cards is that the book keeping for keeping FAT data etc cost SRAM memory on the chip, so if you want to conform to using FAT (or FAT32 or even ex-FAT) memory could be a challenge for high capacity cards, but that 4-8 GB I'd think is still managable.
btw these days one of the more 'esoteric' storage is SPI PSRAM, they can run on low pin count like sop8 over SPI and offer easily like 8 MB (64 Mbit) DRAM storage, and that these days PSRAM can run in capacities like up to 1 GB, some use QSPI interfaces for faster throughput.
A thing about PSRAM is they are DRAM and a power fail would lose the data. And the good thing about PSRAM is they are DRAM, write speeds is much faster and doesn't need an erase cycle.
in terms of 'custom' internal flash schemes, you may end up needing to 'split' your program 'bin' file into 2 pieces, the 'main' program and the 'library' part, and perhaps install that in the different sectors. e.g.
sector 0 and 1 - the 1st part of flash memory, you need to keep your program here so perhaps that takes the 1st 32 kB.
then that say if you use 2 and 3 for your EEPROM emulation.
you end up with having to put the 'library' part of the bin file in sector 4, the 64 KB flash sector.
The challenge then is that you need to play with the 'ld scripts' and your project to re-organise your sectors to place your program codes.
That in itself could be pretty challenging. a 'trick' is perhaps to put the 'bootloader' at sector 0 0x8000000, then that to build your actual sketch
to sit in that sector 4 64 KB flash, that works if your program bin file fits in that 64 KB. It is a bit of ld script hacking and bootloader hacking to fit the program that way. And of course, you need your custom EEPROM emulation that uses the different sectors. or you could make your program/sketch bin code sit at sector 3 (16k) + sector 4 (64k), bootloader sits at sector0 (16k), then sector 1+2 (16k x2) for EEPROM emulation. pretty convoluted but if you insist on using every available flash footprint, maybe that is the 'best' possible.
The 'normal' way is your 'bin' file sits at the beginning from sector 0-3, then perhaps at the 'back' say sector 4, you can use it say for data.
And of course you still have the option of purchasing a bigger device, e.g. the CE, VE, VG, IG suffix etc devices often have much more on chip flash.
e.g. STM32F411CEU6 100Mhz 512KB flash, 128KB sram
https://github.com/WeActStudio/WeActStu ... iSTM32F4x1
that is plenty compared to the 'stm32f103c8' blue pill, standards.
even Adafruit has a stm32f405 'feather' that sports 1 MB flash and 192 KB ram, and they threw in extra 2MB SPI flash, LiPo connector, charger + uSD card slot etc.
https://www.adafruit.com/product/4382
ok but how to build that 'bootloader'?
your 'bootloader' sketch needs to start at 0x8000000 sector 0 16k, this is your 1st 'bin' file.
your 'normal' sketch: then you hack your ld script 2nd sketch to sit at say sector 2 (16k), 3 (16k), 4 (64k) ~ now you have a 'whopping' 96k
lets say it is at sector 2, that is 32k offset away from 0x8000000
32k ~ 0x8000 hex, so that is 0x8008000, that need to be hacked into the 2nd sketch ld script as start of address to compile for.
how do you call your 'normal' sketch from your 'bootloader'?
I'm not really sure if this'd work 
and you still need to bundle your custom EEPROM lib to use sector 1 at that 16k boundary and you have max 16k of it
btw it is still a 'waste' of the bootloader space, presumably you can fit that 'bootloader' sketch in that 16k, then 'jump' to the 32k boundary where your 'main' sketch starts, so if the bootloader use less than 16k, that 'spare' space is 'wasted'. You could try to fill that for other purposes if u'd like.
The extreme of that 'bootloader' if you'd like may be only that 'jump' statement, if you bother to do in assembly possibly a handful of bytes, just that at 0x8000000 you need to 'jump' to your 'main' sketch.
The way flash works is that if a page is erased it is reset to 0xff for all bytes, writing data to them toggle the bits to 0.
Hence, it may be possible to use some other schemes, e.g. spiffs
https://github.com/pellepl/spiffs
to manage the pages, or perhaps invent one e.g. modify the EEPROM emulation codes to implement your preferred scheme.
A thing about on chip flash is that the sectors are larger at the 'back' e.g. 0-3 is 16 kB, 4 is 64k, and 5 and higher is 128k etc.
This is perhaps ok if say you only need one sector say the 64k sector to keep your data.
Using the 'lower' sectors risk overlapping into program codes.
I've been using external SPI flash e.g. those W25Q64xx style SPI flash
https://www.winbond.com/hq/product/code ... o=W25Q64FV
there are various open sourced libraries that support them, and in the same way the flash works by having erased sectors all filled with 0xff.
SPI flash works well if your storage requirements is in the low MB, I've got a temperature and light sensor logging data every 10 secs and I managed to fit that in every 16 bits (12 bits are ADC data, the remaining 4 bits I used to indicate the channel) and that at rather low data rates e.g. 10 secs intervals, I managed to fit like 6-9 months or so of records in a 8 MB (64 Mbits) SPI flash. That probably works well for GPS loggers as well which could log like say at 10 secs intervals or more.
Then that if you want to store a huge amount of data, these days even the smallest uSD cards runs in capacities like 4 GB - 128 GB, and 8-16 GB are practically quite common, and they can mostly work over SPI ! A thing about uSD cards is that the book keeping for keeping FAT data etc cost SRAM memory on the chip, so if you want to conform to using FAT (or FAT32 or even ex-FAT) memory could be a challenge for high capacity cards, but that 4-8 GB I'd think is still managable.
btw these days one of the more 'esoteric' storage is SPI PSRAM, they can run on low pin count like sop8 over SPI and offer easily like 8 MB (64 Mbit) DRAM storage, and that these days PSRAM can run in capacities like up to 1 GB, some use QSPI interfaces for faster throughput.
A thing about PSRAM is they are DRAM and a power fail would lose the data. And the good thing about PSRAM is they are DRAM, write speeds is much faster and doesn't need an erase cycle.
in terms of 'custom' internal flash schemes, you may end up needing to 'split' your program 'bin' file into 2 pieces, the 'main' program and the 'library' part, and perhaps install that in the different sectors. e.g.
sector 0 and 1 - the 1st part of flash memory, you need to keep your program here so perhaps that takes the 1st 32 kB.
then that say if you use 2 and 3 for your EEPROM emulation.
you end up with having to put the 'library' part of the bin file in sector 4, the 64 KB flash sector.
The challenge then is that you need to play with the 'ld scripts' and your project to re-organise your sectors to place your program codes.
That in itself could be pretty challenging. a 'trick' is perhaps to put the 'bootloader' at sector 0 0x8000000, then that to build your actual sketch
to sit in that sector 4 64 KB flash, that works if your program bin file fits in that 64 KB. It is a bit of ld script hacking and bootloader hacking to fit the program that way. And of course, you need your custom EEPROM emulation that uses the different sectors. or you could make your program/sketch bin code sit at sector 3 (16k) + sector 4 (64k), bootloader sits at sector0 (16k), then sector 1+2 (16k x2) for EEPROM emulation. pretty convoluted but if you insist on using every available flash footprint, maybe that is the 'best' possible.
The 'normal' way is your 'bin' file sits at the beginning from sector 0-3, then perhaps at the 'back' say sector 4, you can use it say for data.
And of course you still have the option of purchasing a bigger device, e.g. the CE, VE, VG, IG suffix etc devices often have much more on chip flash.
e.g. STM32F411CEU6 100Mhz 512KB flash, 128KB sram
https://github.com/WeActStudio/WeActStu ... iSTM32F4x1
that is plenty compared to the 'stm32f103c8' blue pill, standards.
even Adafruit has a stm32f405 'feather' that sports 1 MB flash and 192 KB ram, and they threw in extra 2MB SPI flash, LiPo connector, charger + uSD card slot etc.
https://www.adafruit.com/product/4382
ok but how to build that 'bootloader'?
your 'bootloader' sketch needs to start at 0x8000000 sector 0 16k, this is your 1st 'bin' file.
your 'normal' sketch: then you hack your ld script 2nd sketch to sit at say sector 2 (16k), 3 (16k), 4 (64k) ~ now you have a 'whopping' 96k
lets say it is at sector 2, that is 32k offset away from 0x8000000
32k ~ 0x8000 hex, so that is 0x8008000, that need to be hacked into the 2nd sketch ld script as start of address to compile for.
how do you call your 'normal' sketch from your 'bootloader'?
Code: Select all
void *addr = 0x8008000;
(addr)();

and you still need to bundle your custom EEPROM lib to use sector 1 at that 16k boundary and you have max 16k of it
btw it is still a 'waste' of the bootloader space, presumably you can fit that 'bootloader' sketch in that 16k, then 'jump' to the 32k boundary where your 'main' sketch starts, so if the bootloader use less than 16k, that 'spare' space is 'wasted'. You could try to fill that for other purposes if u'd like.
The extreme of that 'bootloader' if you'd like may be only that 'jump' statement, if you bother to do in assembly possibly a handful of bytes, just that at 0x8000000 you need to 'jump' to your 'main' sketch.
Re: Procedure to change EEPROM default sector/base address using STM32Duino?
Thank you all for the answers,
Yes I was willing to do a simpler AN3969 no leveling single sector as I advanced. I am stuck with a STM32F410CBT hardware that only offers to move from the top 64KB sector to 16KB 4th sector, but it looks a significant effort, specially to use the top 64KB to extend linked code that is already going over 64KB. That would be the purpose.
So I found acceptable to put one of these small piggy 256 Byte I2C boards on my PCB: https://a.co/d/5dDYNgV. Easily reemplazable for bigger size as 16KB if needed. In my application I need just 100 Bytes of user configuration. There are also a few libs around that implement the same functions than the EEPROM emulation, so I am working now on it and looks like minimal changes.
Now I get the whole 128KB with free headaches.

Yes I was willing to do a simpler AN3969 no leveling single sector as I advanced. I am stuck with a STM32F410CBT hardware that only offers to move from the top 64KB sector to 16KB 4th sector, but it looks a significant effort, specially to use the top 64KB to extend linked code that is already going over 64KB. That would be the purpose.
So I found acceptable to put one of these small piggy 256 Byte I2C boards on my PCB: https://a.co/d/5dDYNgV. Easily reemplazable for bigger size as 16KB if needed. In my application I need just 100 Bytes of user configuration. There are also a few libs around that implement the same functions than the EEPROM emulation, so I am working now on it and looks like minimal changes.
Now I get the whole 128KB with free headaches.
