8
\$\begingroup\$

I want to store 3 integer values in the flash memory of the microcontroller so that these values are not lost if the device has a power outage.

I am trying to understand which type of memory to use for this purpose and how exactly how can I write to and read from this memory block.

I am doing a hobby project to use a HMI to input data to a PLC which will then drive several motors to control the movement of toy quadcopter.

I am using the Keil uvision IDE.

Some additional notes:

  • The values will be changed once every 2-3 months.
  • There can be power outage during the value update process.
  • Its not critical if process is interrupted and we lose the latest value entered.
\$\endgroup\$
  • \$\begingroup\$ There are several things that need to be answered before proceeding. (1) Do these three integer values stay constant? (2) If they change then how often do they change? (3) For your MCU how long does it take to update the store of the saved data? (4) Can power be lost while storing the values? (5) Is it critical to store the most recent values or would it be OK if after a power cycle you had the previously stored value? \$\endgroup\$ – Michael Karas Jul 13 at 9:27
  • \$\begingroup\$ 1&2) The values will be changed every 2-3 months by the user. \$\endgroup\$ – Aman Kejriwal Jul 13 at 9:30
  • \$\begingroup\$ 4) Power can be lost during the process of storing. 5) No really critical. The idea is to not have the user setup these initial parameters every time the system is started up. \$\endgroup\$ – Aman Kejriwal Jul 13 at 9:31
  • \$\begingroup\$ OK, Based upon your clarifications I will describe how I implement the storage of parametric values like this in an answer here. BTW you should edit your clarifications into the question. Comments can disappear. \$\endgroup\$ – Michael Karas Jul 13 at 9:34
12
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This memory will be written to once in 2-3 months. \$\endgroup\$ – Aman Kejriwal Jul 13 at 9:28
  • \$\begingroup\$ In that case don't care about wear levelling, you can write a memory page like 10K times guaranteed (see par. 3.2, page 16). \$\endgroup\$ – Michel Keijzers Jul 13 at 9:29
  • 1
    \$\begingroup\$ Thank you for sharing the document. I have studied it and now I have to add eeprom.c to my project. \$\endgroup\$ – Aman Kejriwal Jul 13 at 9:45
  • \$\begingroup\$ Yes ... I think I used some GitHub implementation but it was for STM32F1. \$\endgroup\$ – Michel Keijzers Jul 13 at 9:48
  • \$\begingroup\$ I am firing up STM32CUBEIde \$\endgroup\$ – Aman Kejriwal Jul 13 at 9:49
13
\$\begingroup\$

For parameter storage that is not done too often but needs to be reliable I recommend the following approach.

  1. 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.
  2. Use a simple to implement interface to the external memory. I usually choose I2C.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Upvoted for additional subjects to take into account. \$\endgroup\$ – Michel Keijzers Jul 13 at 11:29
  • \$\begingroup\$ Another suggestion: Include a version number parameter within the nonvolatile parameter set. This allows you to update the parameter set contents and maintain backwards compatibility with previous versions. The firmware reads the version number and then can know how to read/interpret the rest of the parameters. \$\endgroup\$ – kkrambo Jul 13 at 13:23
  • \$\begingroup\$ OP writes "I am doing a hobby project" \$\endgroup\$ – Juraj Jul 13 at 15:01
  • \$\begingroup\$ Include byte count with parameters, so it becomes a set of 3 or 4 values. \$\endgroup\$ – VTNCaGNtdDVNalUy Jul 13 at 22:22
  • \$\begingroup\$ @Juraj Doing it right cuts down debugging time and frees up time for other things, even in a hobby project. Even F-RAM is cheaply available in hobbyist friendly packages and as modules. I see nothing wrong with this suggestion even for a hobby project. \$\endgroup\$ – AndreKR Jul 14 at 9:12

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.