parent
e617b4f283
commit
509b19a9bc
@ -0,0 +1,192 @@ |
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2017/07/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "persist.h" |
||||||
|
#include <esp8266.h> |
||||||
|
#include "wifimgr.h" |
||||||
|
#include "screen.h" |
||||||
|
|
||||||
|
FullPersistBlock persist; |
||||||
|
|
||||||
|
#define PERSIST_SECTOR_ID 0x3D |
||||||
|
|
||||||
|
//region Persist and restore individual modules
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load persistent settings to live config structs |
||||||
|
*/ |
||||||
|
static void ICACHE_FLASH_ATTR |
||||||
|
load_settings_to_live(void) |
||||||
|
{ |
||||||
|
dbg("[Persist] Loading current settings to modules..."); |
||||||
|
memcpy(&wificonf, &persist.current.wificonf, sizeof(WiFiConfigBlock)); |
||||||
|
memcpy(&termconf, &persist.current.termconf, sizeof(TerminalConfigBlock)); |
||||||
|
// ...
|
||||||
|
} |
||||||
|
|
||||||
|
static void ICACHE_FLASH_ATTR |
||||||
|
store_settings_from_live(void) |
||||||
|
{ |
||||||
|
dbg("[Persist] Collecting live settings to persist block..."); |
||||||
|
memcpy(&persist.current.wificonf, &wificonf, sizeof(wificonf)); |
||||||
|
memcpy(&persist.current.termconf, &termconf, sizeof(termconf)); |
||||||
|
// ...
|
||||||
|
} |
||||||
|
|
||||||
|
static void ICACHE_FLASH_ATTR |
||||||
|
apply_live_settings(void) |
||||||
|
{ |
||||||
|
dbg("[Persist] Applying live settings..."); |
||||||
|
terminal_apply_settings(); |
||||||
|
wifimgr_apply_settings(); |
||||||
|
// ...
|
||||||
|
} |
||||||
|
|
||||||
|
static void ICACHE_FLASH_ATTR |
||||||
|
restore_live_settings_to_hard_defaults(void) |
||||||
|
{ |
||||||
|
wifimgr_restore_defaults(); |
||||||
|
terminal_restore_defaults(); |
||||||
|
// ...
|
||||||
|
} |
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute CRC32. Adapted from https://github.com/esp8266/Arduino
|
||||||
|
* @param data |
||||||
|
* @param length |
||||||
|
* @return crc32 |
||||||
|
*/ |
||||||
|
static uint32_t ICACHE_FLASH_ATTR |
||||||
|
calculateCRC32(const uint8_t *data, size_t length) |
||||||
|
{ |
||||||
|
uint32_t crc = 0xffffffff; |
||||||
|
while (length--) { |
||||||
|
uint8_t c = *data++; |
||||||
|
for (uint32_t i = 0x80; i > 0; i >>= 1) { |
||||||
|
bool bit = (bool) (crc & 0x80000000UL); |
||||||
|
if (c & i) { |
||||||
|
bit = !bit; |
||||||
|
} |
||||||
|
crc <<= 1; |
||||||
|
if (bit) { |
||||||
|
crc ^= 0x04c11db7UL; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return crc; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a persist bundle checksum |
||||||
|
* |
||||||
|
* @param bundle |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
static uint32_t ICACHE_FLASH_ATTR |
||||||
|
compute_checksum(PersistBundle *bundle) |
||||||
|
{ |
||||||
|
return calculateCRC32((uint8_t *) bundle, sizeof(PersistBundle) - 4); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Load, verify and apply persistent config |
||||||
|
*/ |
||||||
|
void ICACHE_FLASH_ATTR |
||||||
|
persist_load(void) |
||||||
|
{ |
||||||
|
info("[Persist] Loading stored settings from FLASH..."); |
||||||
|
|
||||||
|
bool hard_reset = false; |
||||||
|
|
||||||
|
// Try to load
|
||||||
|
hard_reset |= !system_param_load(PERSIST_SECTOR_ID, 0, &persist, sizeof(persist)); |
||||||
|
|
||||||
|
// Verify checksums
|
||||||
|
if (hard_reset || |
||||||
|
(compute_checksum(&persist.defaults) != persist.defaults.checksum) || |
||||||
|
(compute_checksum(&persist.current) != persist.current.checksum)) { |
||||||
|
error("[Persist] Config block failed to load, restoring to hard defaults."); |
||||||
|
hard_reset = true; |
||||||
|
} |
||||||
|
|
||||||
|
if (hard_reset) { |
||||||
|
persist_restore_hard_default(); |
||||||
|
// this also stores them to flash and applies to modues
|
||||||
|
} else { |
||||||
|
load_settings_to_live(); |
||||||
|
apply_live_settings(); |
||||||
|
} |
||||||
|
|
||||||
|
info("[Persist] All settings loaded and applied."); |
||||||
|
} |
||||||
|
|
||||||
|
void ICACHE_FLASH_ATTR |
||||||
|
persist_store(void) |
||||||
|
{ |
||||||
|
info("[Persist] Storing all settings to FLASH..."); |
||||||
|
store_settings_from_live(); |
||||||
|
|
||||||
|
// Update checksums before write
|
||||||
|
persist.current.checksum = compute_checksum(&persist.current); |
||||||
|
persist.defaults.checksum = compute_checksum(&persist.defaults); |
||||||
|
|
||||||
|
if (!system_param_save_with_protect(PERSIST_SECTOR_ID, &persist, sizeof(persist))) { |
||||||
|
error("[Persist] Store to flash failed!"); |
||||||
|
} |
||||||
|
info("[Persist] All settings persisted."); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore to built-in defaults |
||||||
|
*/ |
||||||
|
void ICACHE_FLASH_ATTR |
||||||
|
persist_restore_hard_default(void) |
||||||
|
{ |
||||||
|
info("[Persist] Restoring all settings to hard defaults..."); |
||||||
|
|
||||||
|
// Set live config to default values
|
||||||
|
restore_live_settings_to_hard_defaults(); |
||||||
|
|
||||||
|
// Store live -> current
|
||||||
|
store_settings_from_live(); |
||||||
|
|
||||||
|
// Store current -> default
|
||||||
|
memcpy(&persist.defaults, &persist.current, sizeof(persist.current)); |
||||||
|
persist_store(); |
||||||
|
|
||||||
|
info("[Persist] All settings restored to hard defaults."); |
||||||
|
|
||||||
|
apply_live_settings(); // apply
|
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore default settings & apply |
||||||
|
*/ |
||||||
|
void ICACHE_FLASH_ATTR |
||||||
|
persist_restore_default(void) |
||||||
|
{ |
||||||
|
info("[Persist] Restoring live settings to stored defaults..."); |
||||||
|
memcpy(&persist.current, &persist.defaults, sizeof(persist.defaults)); |
||||||
|
load_settings_to_live(); |
||||||
|
apply_live_settings(); |
||||||
|
info("[Persist] Settings restored to stored defaults."); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Store current settings as defaults & write to flash |
||||||
|
*/ |
||||||
|
void ICACHE_FLASH_ATTR |
||||||
|
persist_set_as_default(void) |
||||||
|
{ |
||||||
|
info("[Persist] Storing live settings as defaults.."); |
||||||
|
|
||||||
|
store_settings_from_live(); |
||||||
|
memcpy(&persist.defaults, &persist.current, sizeof(persist.current)); |
||||||
|
|
||||||
|
persist_store(); |
||||||
|
|
||||||
|
info("[Persist] Default settings updated."); |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2017/07/09.
|
||||||
|
//
|
||||||
|
// There are 4 sets of settings.
|
||||||
|
// - hard defaults - hardcoded in firmware, used for init defaults after flash or if stored data are corrupt
|
||||||
|
// - defaults - persisted by privileged user
|
||||||
|
// - current - persistent current config state, can be restored to defaults any time
|
||||||
|
// - live - non-persistent settings valid only for the current runtime
|
||||||
|
|
||||||
|
#ifndef ESP_VT100_FIRMWARE_PERSIST_H |
||||||
|
#define ESP_VT100_FIRMWARE_PERSIST_H |
||||||
|
|
||||||
|
#include "wifimgr.h" |
||||||
|
#include "screen.h" |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
WiFiConfigBlock wificonf; |
||||||
|
TerminalConfigBlock termconf; |
||||||
|
// ...
|
||||||
|
// other settings here
|
||||||
|
// ...
|
||||||
|
uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults.
|
||||||
|
} PersistBundle; |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
PersistBundle defaults; // defaults are stored here
|
||||||
|
PersistBundle current; // settings persisted by user
|
||||||
|
} FullPersistBlock; |
||||||
|
|
||||||
|
// Persist holds the data currently loaded from the flash
|
||||||
|
extern FullPersistBlock persist; |
||||||
|
|
||||||
|
void persist_load(void); |
||||||
|
void persist_restore_hard_default(void); |
||||||
|
void persist_restore_default(void); |
||||||
|
void persist_set_as_default(void); |
||||||
|
void persist_store(void); |
||||||
|
|
||||||
|
#endif //ESP_VT100_FIRMWARE_PERSIST_H
|
Loading…
Reference in new issue