From 731ca297b02087f9a369b548af0e4d5c53d1dad7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 13 Aug 2020 13:04:28 +0200 Subject: [PATCH] Add better config corruption recovery - Add better config corruption recovery (#9046) - Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1 --- RELEASENOTES.md | 4 +++- tasmota/CHANGELOG.md | 5 +++++ tasmota/settings.ino | 35 +++++++++++++++++++++++++++++------ tasmota/tasmota_version.h | 2 +- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 02e5f0044..0aa1daf34 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -53,10 +53,12 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.4.0.1 +### Version 8.4.0.2 +- Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1 - Fix ESP32 PWM range - Add Zigbee better support for IKEA Motion Sensor - Add ESP32 Analog input support for GPIO32 to GPIO39 - Add Zigbee options to ``ZbSend`` ``Config`` and ``ReadCondig`` - Add command ``Restart 2`` to halt system. Needs hardware reset or power cycle to restart (#9046) +- Add better config corruption recovery (#9046) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 13d8b4baf..94cd394ee 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,10 @@ ## Unreleased (development) +### 8.4.0.2 20200813 + +- Add better config corruption recovery (#9046) +- Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1 + ### 8.4.0.1 20200730 - Fix ESP32 PWM range diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 2e8852ae5..09184b093 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -552,10 +552,10 @@ void SettingsSave(uint8_t rotate) RtcSettingsSave(); } -void SettingsLoad(void) -{ +void SettingsLoad(void) { #ifdef ESP8266 // Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate +#ifdef CFG_LEGACY_LOAD struct { uint16_t cfg_holder; // 000 uint16_t cfg_size; // 002 @@ -566,7 +566,7 @@ void SettingsLoad(void) settings_location = 0; uint32_t flash_location = SETTINGS_LOCATION +1; uint16_t cfg_holder = 0; - for (uint32_t i = 0; i < CFG_ROTATES; i++) { + for (uint32_t i = 0; i < CFG_ROTATES; i++) { // Read all config pages in search of valid and latest flash_location--; ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); bool valid = false; @@ -583,10 +583,10 @@ void SettingsLoad(void) valid = (Settings.cfg_holder == _SettingsH.cfg_holder); } if (valid) { - if (Settings.save_flag > save_flag) { + if (Settings.save_flag > save_flag) { // Find latest page based on incrementing save_flag save_flag = Settings.save_flag; settings_location = flash_location; - if (Settings.flag.stop_flash_rotate && (0 == i)) { // Stop only if eeprom area should be used and it is valid + if (Settings.flag.stop_flash_rotate && (0 == i)) { // Stop if only eeprom area should be used and it is valid break; } } @@ -597,13 +597,36 @@ void SettingsLoad(void) ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag); } +#else // CFG_RESILIENT + settings_location = 0; + uint32_t save_flag = 0; + uint32_t flash_location = SETTINGS_LOCATION +1; + for (uint32_t i = 0; i < CFG_ROTATES; i++) { // Read all config pages in search of valid and latest + flash_location--; + ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); + if ((Settings.cfg_crc32 != 0xFFFFFFFF) && (Settings.cfg_crc32 != 0x00000000) && (Settings.cfg_crc32 == GetSettingsCrc32())) { + if (Settings.save_flag > save_flag) { // Find latest page based on incrementing save_flag + save_flag = Settings.save_flag; + settings_location = flash_location; + if (Settings.flag.stop_flash_rotate && (0 == i)) { // Stop if only eeprom area should be used and it is valid + break; + } + } + } + delay(1); + } + if (settings_location > 0) { + ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); + AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag); + } +#endif // CFG_RESILIENT #else // ESP32 SettingsRead(&Settings, sizeof(Settings)); AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded, " D_COUNT " %lu"), Settings.save_flag); #endif // ESP8266 - ESP32 #ifndef FIRMWARE_MINIMAL - if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h + if ((0 == settings_location) || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h SettingsDefault(); } settings_crc32 = GetSettingsCrc32(); diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 308601067..4d0d9e0f2 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08040001; +const uint32_t VERSION = 0x08040002; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006;