1
\$\begingroup\$

So I have STM32F4 board and long story short - I am stuck at putting a user defined number (0 - 60) in FLASH memory, so after restarting, I could use last-used-settings. How do I allocate correct space in flash memory, so it doesn't interfere with my code? How to I store it?

\$\endgroup\$
  • 1
    \$\begingroup\$ You have a linker script defining precisely which space is occupied by your program.You can export some symbols from it and use them in your program. \$\endgroup\$ – Eugene Sh. May 2 '16 at 20:32
  • 2
    \$\begingroup\$ Can't you use EEPROM for that? It's much easier to organise persistent storage in this area if you run from Flash. \$\endgroup\$ – user72833 May 2 '16 at 21:00
  • 1
    \$\begingroup\$ STM32F4 has a few bytes of battery-backed RAM. Can you add a small battery and use that instead? \$\endgroup\$ – gbulmer May 2 '16 at 21:43
  • 1
    \$\begingroup\$ you can erase a block, then write as needed, on boot examine the block, take the last non 0xFF...FF value, once you see it full then do another erase. you wont have to erase every power down (or boot). saves on wear and tear. \$\endgroup\$ – old_timer May 3 '16 at 20:22
  • 1
    \$\begingroup\$ Peek at this doc on EEPROM emulation in RAM for STM32F4 www2.st.com/content/ccc/resource/technical/document/… \$\endgroup\$ – Scott Seidman May 3 '16 at 21:39
2
\$\begingroup\$

Write data to Flash memory via EEPROM Emulation, as described in Application Note AN3969: EEPROM emulation in STM32F40x/STM32F41x microcontrollers, here.

\$\endgroup\$
1
\$\begingroup\$

To save a value to restart after an unexpected shutdown, it would be much better to use a byte of battery backed RAM than try to write to Flash.

An update of one byte in flash has to erase then update the entire 'sector'. According to ST's datasheet, the typical time for a 16kB sector erase is 250ms for a STM32F405/7 (5.3.12 "Memory characteristics", Table 40 "Flash memory programming"). If power is lost while flash is being updated, the entire sector may be corrupted. Also, the whole sectr is erased, so it can't be used for code. It depends on the exact STM32 part, but the smallest sector might be 16kB, which might be quite a lot to lose for the sake of one byte.

A smaller further problem with Flash is that it is only guaranteed for 10k erase/write cycles. This might be plenty for your application, but a bug in the program could burn through those in an hour or two.

Other things to consider, while Flash is being written, the CPU will be stalled from accessing that sector, so it won't be able to update the magic value, so you might need to protect access to the value with some code to check Flash is not being changed. So it might be more complex than you expect to use.

The obvious alternative, without adding an external EEPROM, is use battery backed RAM. This is slightly more complex to program than using an in-memory variable because it is part of the RTC which needs to be initialised. However once it set up, it can be read and written with only a few extra instructions. So it's access time is sub-microsecond, fast enough to use in an interrupt service routine, and it won't wear out.

This does mean you need to be able to get at the VBat pin, and connect it to a small battery, e.g. a hearing aid battery.

\$\endgroup\$
  • 1
    \$\begingroup\$ Or one uses eeprom emulation on top of flash. Basically the scheme writes continuously blocks of <addr><data> into flash page until reaching the end. Loading just reads all pairs and fetches the data into a ram buffer. When page is full, an erase is done. This way flash is very rarely erased. \$\endgroup\$ – Martin Nov 22 '17 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.