The storage module allows an application to store samples all of identical size in non-volatile memories EEPROM and FLASH.
It will:
- abstract away where and how the samples are stored
- provide an easy interface via which samples can be written to and read from
- utilize all bits, placing all samples back to back, maximizing storage capacity
- minimize FLASH program operations, thereby avoiding the time penalty, voltage drop and current consumption that comes with every FLASH program operation
- move data from EEPROM to FLASH automatically whenever necessary to make sure the newest data is always in EEPROM
- allow application-specific compression of the data just before moving data from EEPROM to FLASH
- allow application-specific decompression of the data before they are read out again
- recover its full state based on the contents of the non-volatile memory alone
The storage module will use general purpose registers, EEPROM and FLASH to store bits of data. The usage of the three types of memories is prioritized. When a new sample is to be stored:
- first an attempt is made to store it in the general purpose registers ("cached").
- when this is not possible, the storage module tries to store it (together with all the cached samples) in EEPROM
After moving data to EEPROM, the general purpose registers are re-used.
- only when a sufficient amount of samples are stored in EEPROM, all the data is moved to FLASH.
After moving data to FLASH, the EEPROM is re-used.
Writing samples always means appending them to the already written samples; it is not possible to edit the already written stream of bits. When reading out, the user can control the starting read position using a sequence number. It is automatically deduced where the corresponding sample is written, whether it is compressed, and what needs to be done to be able to return the requested sample(s).
- Hardening
- The storage module provides a ready-made solution to maximize storage of samples in persistent memory. It can:
- store more than 10.000 samples without hitting the write endurance limit of both EEPROM and FLASH
- recover state from unexpected resets
- recover all or most of the samples in case of data corruption (this may occur when the battery is degraded and can no longer supply the minimum voltage when the load increases during a write operation in EEPROM or FLASH)
It is not possible to fully recover data under all circumstances. The storage module guarantees that only the last few samples may get lost. The number is dependent on the number of the reserved general purpose registers and the size of a sample, both of which (and more) can be tweaked using diversity settings.
- Diversity
- This module supports diversity settings. Some settings define the type and size of the sample. Others define the EEPROM and FLASH regions placed under control of this module. The rest of the settings control the behavior of the module. Check Diversity Settings for all diversity settings.
It is expected that each application that requires this module includes it and configures the diversity settings of the module according to its specific needs.
- Memory Requirements
- The storage module requires a large chunk of SRAM, called its workarea - see STORAGE_WORKAREA and STORAGE_WORKAREA_SIZE. This is used for two purposes:
- When storing samples, and a move from EEPROM to FLASH is required, the assigned compress callback - see STORAGE_COMPRESS_CB - is given a pointer inside this SRAM memory. The output is then stored in FLASH.
- When reading samples from FLASH, the assigned decompress callback - see STORAGE_DECOMPRESS_CB - is called as little as possible: its output is cached in the work area to speed up subsequent reads.
If two operations in your code require such a big chunk of memory, you can overlap them if they don't have to operate concurrently. Diversity setting STORAGE_WORKAREA can be used for this.
- How to use the module
- Define the best diversity settings for your application or accept the default ones.
- Initialize the EEPROM driver and the storage module, in that order.
- Read and write samples as necessary, in any order or quantity that is required for your use case.
- De-initialize the storage module and the EEPROM driver, in that order.
- Example
int n;
uint8_t one = 1;
uint8_t ten[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Chip_EEPROM_Init(NSS_EEPROM);
ASSERT(n == 1);
ASSERT(n == 7);
ASSERT(n == 4);
- Warning
- These functions are not re-entrant. Calling these functions from multiple threads or in an interrupt is highly discouraged.
-
The storage module requires the exclusive use of at least one register in the always-on domain (see STORAGE_FIRST_ALON_REGISTER). Under no circumstance may the reserved registers be touched from outside the storage module.
-
Although the storage module is able to recover after a power loss or going to Power-off, it is slow in doing so. The slow recovery time only occurs once as long as no changes to the NVM are made (e.g. by calling Storage_Write).