0
\$\begingroup\$

I want to reserve a space in the internal flash memory of my microcontroller (STM32L4) to store the latest 100 measured values by a sensor (in a circular FIFO Fashion) and be able to load them again when I restart the device.

My logic looks like this:

typedef struct
{
   uint16_t   measuredValue;
   DateTime_t timestamp;
}MeasuredValue_t;
// ..
// ..    
MeasuredValue_t measuredValue;
// ..
// ..
while(1)
{
   GetValue(&measuredValue); // Read values (Sensor value + timestamp from the RTC)
   Flash_Fifo_Push(measuredValue);         // Push to buffer
   Sleep();                               // Sleep until the next cycle
}

My questions are:

  1. How to reserve this space in the linker file of my microcontroller (ARM Cortex-M4 2MB flash)?
  2. How to implement the circular FIFO fashion?
\$\endgroup\$
  • \$\begingroup\$ How often do you measure? \$\endgroup\$ – Jeroen3 May 23 '19 at 11:50
  • \$\begingroup\$ Every 15 minutes the whole day \$\endgroup\$ – Pryda May 23 '19 at 11:51
  • 3
    \$\begingroup\$ You can start by reading this application note: EEPROM emulation techniques and software for STM32L4 and STM32L4+ Series microcontrollers \$\endgroup\$ – Bora May 23 '19 at 11:51
  • 1
    \$\begingroup\$ @Jeroen3 The write block size is 8 bytes. Assuming 16 bytes/record, a 2 kByte block would be filled in 32 hours. Using two erase blocks, each one would be erased once in 64 hours. That's actually a lifetime of 73 years. \$\endgroup\$ – berendi - protesting May 24 '19 at 3:58
  • 1
    \$\begingroup\$ @Jeroen3 That's what the reference manual says. "The Flash memory is programmed 72 bits at a time (64 bits + 8 bits ECC). [...] When the flash interface has received a good sequence (a double word), programming is automatically launched" (ECC is calculated by HW) \$\endgroup\$ – berendi - protesting May 24 '19 at 5:51
5
\$\begingroup\$

How to reserve this space in the linker file of my microcontroller (ARM Cortex-M4 2MB flash)?

As each linker brand uses it's own linker file format, it's impossible to answer without knowing which toolchain are you using. Generally, look into the linker file, find the flash size (usually at the top), and subtract the size of a few erase blocks.

How to implement the circular FIFO fashion?

The internal flash can be programmed in 8 byte blocks, and erased in 2 kByte blocks. When erased, the contents are set to 0xFF.

Arrange your data in 8 or 16 byte structs, and just start filling the reserved space, and erase the next block. Simply wrap around at the end of the flash. Ensure that a struct with all 0xFF bytes doesn't represent valid data (should be no problem if your timestamp structure can cover at least a few centuries). At powerup, just look for the first invalid record following a valid one to find the head.

Keep in mind that the internal flash is rated only for 10000 erase operations, although it shouldn't be a problem at one sample every 15 minutes.

\$\endgroup\$
  • 1
    \$\begingroup\$ Note that 10000 erase operations and 15 mins, means just over 100 days. \$\endgroup\$ – Michel Keijzers May 23 '19 at 12:52
  • 1
    \$\begingroup\$ @MichelKeijzers At 16 bytes/sample, a single flash erase block can hold 128 records, that's more than a day's worth of data. \$\endgroup\$ – berendi - protesting May 23 '19 at 13:03
  • \$\begingroup\$ He wants to be able to read the last 100 also after a reset, so you have to store it every time new values are read (every 15 minutes). If that requirement is left out, than indeed you can wait until there is a full buffer to be written. \$\endgroup\$ – Michel Keijzers May 23 '19 at 13:56
  • 2
    \$\begingroup\$ @MichelKeijzers The full buffer for the purpose of writing is 8 bytes. \$\endgroup\$ – berendi - protesting May 24 '19 at 3:31
  • \$\begingroup\$ It seems viable. You would only be doing an erase every ~1.2 days and swapping between blocks. So ~2.4 days between each erase on a block? That would give you something like ~65 years of endurance at 10,000 erase ops. Which is higher than the operating life of the flash memory... \$\endgroup\$ – hekete May 24 '19 at 4:29

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.