Initialise EEPROM and save periodically

This should be less of a disaster for the emulated
EEPROM on the pico, but could use some finesse
This commit is contained in:
Richard Bowman 2023-02-22 17:09:51 +00:00
parent 28f7b538f0
commit f0ec05cc20
2 changed files with 52 additions and 2 deletions

View file

@ -20,6 +20,11 @@
#include <Arduino.h> #include <Arduino.h>
#include <stdint.h> #include <stdint.h>
#include <ComPort.h> #include <ComPort.h>
#ifdef SUPPORT_EEPROM
#include <EEPROM.h>
#else
#include "dummyEEPROM.h"
#endif
#ifdef HELP #ifdef HELP
#include "modules/help/help.h" #include "modules/help/help.h"
@ -54,6 +59,7 @@ uint8_t registered_loop_fn_count = 0;
const Command core_commands[] = { const Command core_commands[] = {
{"version", get_version}, {"version", get_version},
{"list_modules", get_modules}, {"list_modules", get_modules},
{"eeprom_last_commit", get_eeprom_last_commit},
END_COMMAND}; END_COMMAND};
void register_module(const Command commands[], void (*loop_fn)(void)) void register_module(const Command commands[], void (*loop_fn)(void))
@ -135,8 +141,42 @@ void get_modules(String)
comPort->println("--END--"); comPort->println("--END--");
} }
#if defined(SUPPORT_EEPROM) && defined(MCU_PICO)
unsigned long eeprom_last_commit;
void eeprom_commit_at_interval(unsigned long interval)
{
unsigned long next_commit = eeprom_last_commit + interval;
unsigned long now = millis();
// millis() can overflow - this if statement will trigger
// every `interval` accounting for overflows.
if ( (now > next_commit && next_commit > eeprom_last_commit) // no overflow
|| (now > next_commit && now < eeprom_last_commit)) // overflow
{
EEPROM.commit();
eeprom_last_commit = millis();
}
}
#endif
void get_eeprom_last_commit(String)
{
#if defined(SUPPORT_EEPROM) && defined(MCU_PICO)
comPort->println(eeprom_last_commit);
#else
comPort->println("Not using pico");
#endif
return;
}
void setup() void setup()
{ {
#if defined(SUPPORT_EEPROM) && defined(MCU_PICO)
// On the Pico, EEPROM is emulated.
// This means we need to explicitly enable it, and also
// call EEPROM.commit() periodically to persist it to flash.
EEPROM.begin(256);
eeprom_last_commit = millis();
#endif
// initialise serial port // initialise serial port
#ifdef WIRING_SERIAL_TX #ifdef WIRING_SERIAL_TX
Serial2.setTX(WIRING_SERIAL_TX); Serial2.setTX(WIRING_SERIAL_TX);
@ -186,17 +226,26 @@ void setup()
void loop() void loop()
{ {
bool bytesAvailable = false;
if (PRIMARY_SERIAL_PORT.available()) if (PRIMARY_SERIAL_PORT.available())
{ {
comPort = (HardwareSerial*) &PRIMARY_SERIAL_PORT; comPort = (HardwareSerial*) &PRIMARY_SERIAL_PORT;
handle_command(comPort->readStringUntil('\n')); bytesAvailable = true;
} }
#if defined(SECONDARY_SERIAL_PORT) #if defined(SECONDARY_SERIAL_PORT)
if (SECONDARY_SERIAL_PORT.available()) else if (SECONDARY_SERIAL_PORT.available())
{ {
comPort = (HardwareSerial*) &SECONDARY_SERIAL_PORT; comPort = (HardwareSerial*) &SECONDARY_SERIAL_PORT;
bytesAvailable = true;
}
if (bytesAvailable)
{
handle_command(comPort->readStringUntil('\n')); handle_command(comPort->readStringUntil('\n'));
} }
#if defined(SUPPORT_EEPROM) && defined(MCU_PICO)
// On the Pico, emulated EEPROM is only saved to flash when we call commit()
eeprom_commit_at_interval(10000); // NB this only writes to flash if something has changed.
#endif
for (int i = 0; i < registered_loop_fn_count; i++) for (int i = 0; i < registered_loop_fn_count; i++)
registered_loop_functions[i](); registered_loop_functions[i]();

View file

@ -29,5 +29,6 @@ extern void register_module(const Command commands[], void (*loop_fn)(void));
void get_version(String); void get_version(String);
void get_modules(String); void get_modules(String);
void get_eeprom_last_commit(String);
#define MAIN_H #define MAIN_H
#endif #endif