Skip to content

EEPROM wrapper to help with keeping Arduino configuration persistent over updates

License

Notifications You must be signed in to change notification settings

aardsoft/PersistentConfiguration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

PersistentConfiguration

Introduction

This is a very thin wrapper around EEPROM, mainly to provide shared variables and defines, allowing libraries to expect persistent configuration fields for saving data to be available. One example is the MACTool library, expecting the mac entry. It is up to the user to define the configuration entries described in each libraries documentation.

Configuration

This library can be configured using defines in the sketch. It is possible to use it without any configuration for the first software version, later ones need to change at least CONFIG_MAGIC.

Depending on the way this is compiled it might be required to explicitely add the EEPROM library to the main sketch.

CONFIG_STRUCT

A struct defining the data written to the EEPROM, with the default defined as follows:

struct PersistentConfig{
    unsigned int magic;
    // MAC address used by this device
    char mac[18];
};

magic is the only mandatory field here, used for checking if a configuration is valid, and which software version the configuration data belongs to. The MAC address field is often sensible on non-Ethernet-devices as well as an easy to use unique identifier. The MAC address can be generated and verified using the MACTools library.

To use a custom struct for additional configuration fields define a struct with a different name, and do

#define CONFIG_STRUCT MyConfigStruct

Depending on how you compile the code this may also need to be set as a compiler flag. CONFIG_STRUCT is not defined per default to throw a compiler error on incorrect definitions.

STATE_STRUCT

A struct containing state data, with the default definition as follows:

struct PersistentState{
    // track if there are unsaved config changes
    bool config_changed = false;
};

To use a custom struct for also tracking application state define a struct with a different name, and do

#define STATE_STRUCT MyStateStruct

CONFIG_MAGIC

Magic to check if the configuration was initialized and is the latest version. Defaults to 0xA001.

Methods and variables

config

A shared variable of type CONFIG_STRUCT defining the configuration saved to the EEPROM. Any application wanting to save more than a persistent MAC address will want to use a custom struct for this.

state

A shared variable of type STATE_STRUCT to track the state of the configuration data. It often makes sense to use a custom struct here to also track application state in the same variable.

load()

Load the configuration from EEPROM into a CONFIG_STRUCT variable named config.

save()

Save the configuration from a CONFIG_STRUCT variable named config, if the config_changed field of the state variable of type STATE_STRUCT is true. This additional check avoids unnecessary write cycles wearing out the EEPROM.

Usage example

PersistentConfiguration c;

void setup(){
  // this will load the EEPROM configuration into the config variable
  // the data loaded might be invalid, so in a next step that needs to
  // be verified.
  c.load();

  // when using the MACTool library this is a useful additional step to
  // check sanity of the configuration - this will check if the EEPROM
  // contains a valid MAC address, and if not, generate one.
  init_MAC();

  // check if the configuration has a known magic value. This is the bare
  // minimum for verifying stored configuration. Values which are supposed
  // to persist (like MAC addresses) should be separately checked for validity.
  // To upgrade configuration between versions two ways are possible:
  // - if magic is wrong, check each entry that shouldn't be set to defaults
  //   for sanity, and keep it if it makes sense
  // - add defines like CONFIG_MAGIC_V1 for magic of older versions upgrade
  //   should be possible from, check the magic field against those, and on
  //   match selectively upgrade the fields added/changed since then
  if (config.app_magic != CONFIG_MAGIC){
    // [..]
    // initialize all the config members to defaults here, as described above
    // [..]
    // this needs to be set to true on configuration changes. To avoid EEPROM
    // wear the save function will only save data if it is marked as changed.
    state.config_changed=true;
  }

  // save data to EEPROM if state.config_changed is true
  c.save();
}

About

EEPROM wrapper to help with keeping Arduino configuration persistent over updates

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages