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