How to store persistent values in STM32F407VGT6 embedded microcontroller?
For parameter storage that is not done too often but needs to be reliable I recommend the following approach.
- Use external memory component separate from the MCU. This scheme is more portable if you decide to change MCUs in the future. You can also reuse the scheme from project to project.
- Use a simple to implement interface to the external memory. I usually choose I2C.
- I use external memory called F-RAM. This ferroelectric technology has many benefits such as no incurred block erases, high endurance into the 100 trillion read/writes, ability to rewrite individual locations and finally super long data retention. Data update is as fast as the I2C interface operates. Last project I used the Cypress FM24W256.
- Always store the parameters as a set and attach a CRC-16 or CRC-32 to the parameter set when you write it. Check it when you read the data to ensure its integrity.
- Every time you write the data set write two copies of it. Make sure to fully complete one copy before you start to write the second copy. If power is lost during one of these writes the other copy is still there.
- At startup when you read the parameters check the CRCs and take the data set copy that has a correct CRC verification. Under normal circumstances both copies will be the same with good CRCs. If there was a power failure at last parameter update one or the other copy may be bad.
- It can be a choice at startup to inform the user if one CRC was bad or to simply restore both copies to be the same. This is really not necessary and could wait till the next time the user updates the parameters.
- If both CRCs are bad at startup when reading the parameters then setup the parameter values to defaults and in some cases take the system through whatever process is needed to initialize the parameters. If done correctly this also covers the case where storage has not yet been initialized such as a fresh build off the production line.
Final note. You can apply the reliability algorithm scheme that I describe above to any non-volatile memory technology, serial EEPROM, Flash, EEPROM emulation. It just does not carry the very nice advantages of the F-RAM type memory devices. In some of my applications I have to store data sets that can become quite large and this is where the ferroelectric technology can really shine. In some applications I divide up my parametric data into two parts, that which only changes when the user changes some setting and then the other part (which is usually way smaller) that updates often. Often changing data could be an accumulation counter or a product usage time meter.
You can use so called EEPROM emulation
, which uses a part of the Flash memory to be used as EEPROM.
You can read all about it for the STM40x/STM41x in the following document:
https://www.st.com/resource/en/application_note/dm00036065-eeprom-emulation-in-stm32f40x-stm32f41x-microcontrollers-stmicroelectronics.pdf
Of course this EEPROM memory will reduce from the regular Flash memory. It will be needed to assign a full page (not sure how many bytes), but one page is more than enough for your 3 bytes.
Note to think about wear levelling in case you need to store those 3 values often (use different pages if so).
For others: There are different application notes for other STM32 models.