Retained memory

Storing data in Backup RAM (SRAM)

With regular RAM, data is stored in RAM by declaring variables.

// regular variables stored in RAM
float lastTemperature;
int numberOfPresses;
int numberOfTriesRemaining = 10;

This tells the system to store these values in RAM so they can be changed. The system takes care of giving them initial values. Before they are set, they will have the initial value 0 if an initial value isn't specified.

Variables stored in backup RAM follow a similar scheme but use an additional keyword retained:

// retained variables stored in backup RAM
retained float lastTemperature;
retained int numberOfPresses;
retained int numberOfTriesRemaining = 10;

A retained variable is similar to a regular variable, with some key differences:

  • it is stored in backup RAM - no space is used in regular RAM
  • instead of being initialized on each program start, retained variables are initialized when the device is first powered on (with VIN, from being powered off with VIN and VBAT completely removed). When the device is powered on, the system takes care of setting these variables to their initial values. lastTemperature and numberOfPresses would be initialized to 0, while numberOfTriesRemaining would be initialized to 10.
  • the last value set on the variable is retained as long as the device is powered from VIN or VBAT and is not hard reset.

retained variables can be updated freely just as with regular RAM variables and operate just as fast as regular RAM variables.

Here's some typical use cases for retained variables:

  • storing data for use after waking up from deep sleep
  • storing data for use after power is removed on VIN, while power is still applied to VBAT (with coin cell battery or super capacitor)
  • storing data for use after a hardware or software reset

Finally, if you don't need the persistence of retained variables, you can consider them simply as extra RAM to use.

// EXAMPLE USAGE
SerialLogHandler logHandler;

retained int value = 10;

void setup() {
    System.enableFeature(FEATURE_RETAINED_MEMORY);
}

void loop() {
    Log.info("value before=%s", value);
    value = 20;
    Log.info("value after=%s", value);
    delay(100); // Give the serial TX buffer a chance to empty
    System.sleep(SLEEP_MODE_DEEP, 10);
    // Or try a software reset
    // System.reset();
}

/* OUTPUT
 *
 * 10
 * 20
 * DEEP SLEEP for 10 seconds
 * 20 (value is retained as 20)
 * 20
 *
 */