From 7c85225764d98edce8596283d7fc72af35287811 Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Tue, 9 Oct 2018 03:36:19 +0300 Subject: [PATCH 1/4] Trigger commit in eeprom module --- code/espurna/eeprom.ino | 37 +++++++++++++++++++++++++++++++++++++ code/espurna/mqtt.ino | 2 +- code/espurna/relay.ino | 4 ++-- code/espurna/settings.ino | 14 +++----------- code/espurna/system.ino | 2 +- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/code/espurna/eeprom.ino b/code/espurna/eeprom.ino index ceee1868..29e07427 100644 --- a/code/espurna/eeprom.ino +++ b/code/espurna/eeprom.ino @@ -8,6 +8,11 @@ EEPROM MODULE // ----------------------------------------------------------------------------- +bool _eeprom_commit = false; + +uint32_t _eeprom_commit_count = 0; +bool _eeprom_last_commit_result = false; + void eepromRotate(bool value) { // Enable/disable EEPROM rotation only if we are using more sectors than the // reserved by the memory layout @@ -34,15 +39,38 @@ String eepromSectors() { return response; } +bool _eepromCommit() { + _eeprom_commit_count++; + _eeprom_last_commit_result = EEPROMr.commit(); + return _eeprom_last_commit_result; +} + +void eepromCommit() { + _eeprom_commit = true; +} + #if TERMINAL_SUPPORT void _eepromInitCommands() { settingsRegisterCommand(F("EEPROM"), [](Embedis* e) { infoMemory("EEPROM", SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE - settingsSize()); + if (_eeprom_commit_count > 0) { + DEBUG_MSG_P(PSTR("[MAIN] Commits done: %lu\n"), _eeprom_commit_count); + DEBUG_MSG_P(PSTR("[MAIN] Last result: %s\n"), _eeprom_last_commit_result ? "OK" : "ERROR"); + } DEBUG_MSG_P(PSTR("+OK\n")); }); + settingsRegisterCommand(F("EEPROM.COMMIT"), [](Embedis* e) { + const bool res = _eepromCommit(); + if (res) { + DEBUG_MSG_P(PSTR("+OK\n")); + } else { + DEBUG_MSG_P(PSTR("-ERROR\n")); + } + }); + settingsRegisterCommand(F("EEPROM.DUMP"), [](Embedis* e) { EEPROMr.dump(settingsSerial()); DEBUG_MSG_P(PSTR("\n+OK\n")); @@ -69,6 +97,13 @@ void _eepromInitCommands() { // ----------------------------------------------------------------------------- +void eepromLoop() { + if (_eeprom_commit) { + _eepromCommit(); + _eeprom_commit = false; + } +} + void eepromSetup() { #ifdef EEPROM_ROTATE_SECTORS @@ -92,4 +127,6 @@ void eepromSetup() { _eepromInitCommands(); #endif + espurnaRegisterLoop(eepromLoop); + } diff --git a/code/espurna/mqtt.ino b/code/espurna/mqtt.ino index bbd0e3d9..eef83bac 100644 --- a/code/espurna/mqtt.ino +++ b/code/espurna/mqtt.ino @@ -291,7 +291,7 @@ unsigned long _mqttNextMessageId() { EEPROMr.write(EEPROM_MESSAGE_ID + 1, (id >> 16) & 0xFF); EEPROMr.write(EEPROM_MESSAGE_ID + 2, (id >> 8) & 0xFF); EEPROMr.write(EEPROM_MESSAGE_ID + 3, (id >> 0) & 0xFF); - saveSettings(); + eepromCommit(); } id++; diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index df01fbc4..acd3f36c 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -418,7 +418,7 @@ void relaySave(bool do_commit) { // We are actually enqueuing the commit so it will be // executed on the main loop, in case this is called from a callback - saveSettings(); + eepromCommit(); } @@ -548,7 +548,7 @@ void _relayBoot() { // Save if there is any relay in the RELAY_BOOT_TOGGLE mode if (trigger_save) { EEPROMr.write(EEPROM_RELAY_STATUS, mask); - saveSettings(); + eepromCommit(); } _relayRecursive = false; diff --git a/code/espurna/settings.ino b/code/espurna/settings.ino index 53657cab..db65a52c 100644 --- a/code/espurna/settings.ino +++ b/code/espurna/settings.ino @@ -22,8 +22,6 @@ EmbedisWrap embedis(_serial, TERMINAL_BUFFER_SIZE); #endif // SERIAL_RX_ENABLED #endif // TERMINAL_SUPPORT -bool _settings_save = false; - // ----------------------------------------------------------------------------- // Reverse engineering EEPROM storage format // ----------------------------------------------------------------------------- @@ -310,7 +308,7 @@ void _settingsInitCommands() { #if not SETTINGS_AUTOSAVE settingsRegisterCommand(F("SAVE"), [](Embedis* e) { - _settings_save = true; + eepromCommit(); DEBUG_MSG_P(PSTR("\n+OK\n")); }); #endif @@ -367,7 +365,7 @@ bool hasSetting(const String& key, unsigned int index) { void saveSettings() { #if not SETTINGS_AUTOSAVE - _settings_save = true; + eepromCommit(); #endif } @@ -464,7 +462,7 @@ void settingsSetup() { [](size_t pos) -> char { return EEPROMr.read(pos); }, [](size_t pos, char value) { EEPROMr.write(pos, value); }, #if SETTINGS_AUTOSAVE - []() { _settings_save = true; } + []() { eepromCommit(); } #else []() {} #endif @@ -485,12 +483,6 @@ void settingsSetup() { void settingsLoop() { - if (_settings_save) { - EEPROMr.commit(); - _settings_save = false; - } - - #if TERMINAL_SUPPORT #if DEBUG_SERIAL_SUPPORT diff --git a/code/espurna/system.ino b/code/espurna/system.ino index c988c6cd..560cb84c 100644 --- a/code/espurna/system.ino +++ b/code/espurna/system.ino @@ -42,7 +42,7 @@ void systemCheck(bool stable) { } } EEPROMr.write(EEPROM_CRASH_COUNTER, value); - EEPROMr.commit(); + eepromCommit(); } bool systemCheck() { From f8cb3d12f32509cb4cf2f974b769723edf731e9c Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Tue, 9 Oct 2018 03:56:44 +0300 Subject: [PATCH 2/4] Show sector info in EEPROM command --- code/espurna/config/prototypes.h | 2 ++ code/espurna/eeprom.ino | 6 ++++++ code/espurna/utils.ino | 3 +-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/code/espurna/config/prototypes.h b/code/espurna/config/prototypes.h index d8cf3430..3e3d3579 100644 --- a/code/espurna/config/prototypes.h +++ b/code/espurna/config/prototypes.h @@ -69,6 +69,8 @@ extern "C" { #include EEPROM_Rotate EEPROMr; +void eepromSectorsDebug(); + // ----------------------------------------------------------------------------- // GPIO // ----------------------------------------------------------------------------- diff --git a/code/espurna/eeprom.ino b/code/espurna/eeprom.ino index 29e07427..ed1ad2b6 100644 --- a/code/espurna/eeprom.ino +++ b/code/espurna/eeprom.ino @@ -39,6 +39,11 @@ String eepromSectors() { return response; } +void eepromSectorsDebug() { + DEBUG_MSG_P(PSTR("[MAIN] EEPROM sectors: %s\n"), (char *) eepromSectors().c_str()); + DEBUG_MSG_P(PSTR("[MAIN] EEPROM current: %lu\n"), eepromCurrent()); +} + bool _eepromCommit() { _eeprom_commit_count++; _eeprom_last_commit_result = EEPROMr.commit(); @@ -55,6 +60,7 @@ void _eepromInitCommands() { settingsRegisterCommand(F("EEPROM"), [](Embedis* e) { infoMemory("EEPROM", SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE - settingsSize()); + eepromSectorsDebug(); if (_eeprom_commit_count > 0) { DEBUG_MSG_P(PSTR("[MAIN] Commits done: %lu\n"), _eeprom_commit_count); DEBUG_MSG_P(PSTR("[MAIN] Last result: %s\n"), _eeprom_last_commit_result ? "OK" : "ERROR"); diff --git a/code/espurna/utils.ino b/code/espurna/utils.ino index b5e838f4..1afe2013 100644 --- a/code/espurna/utils.ino +++ b/code/espurna/utils.ino @@ -347,8 +347,7 @@ void info() { // ------------------------------------------------------------------------- - DEBUG_MSG_P(PSTR("[MAIN] EEPROM sectors: %s\n"), (char *) eepromSectors().c_str()); - DEBUG_MSG_P(PSTR("[MAIN] EEPROM current: %lu\n"), eepromCurrent()); + eepromSectorsDebug(); DEBUG_MSG_P(PSTR("\n")); // ------------------------------------------------------------------------- From 004a485e6f5f5148a578cd15c2e6489225bbb8bb Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Tue, 9 Oct 2018 03:45:05 +0300 Subject: [PATCH 3/4] Defer restart until next loop --- code/espurna/debug.ino | 5 +++++ code/espurna/settings.ino | 1 + code/espurna/system.ino | 8 ++++++++ code/espurna/utils.ino | 12 +++++++++--- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/code/espurna/debug.ino b/code/espurna/debug.ino index 7eea7ccb..e7c18e7d 100644 --- a/code/espurna/debug.ino +++ b/code/espurna/debug.ino @@ -209,6 +209,11 @@ void debugSetup() { */ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack_start, uint32_t stack_end ) { + // Do not record crash data when resetting the board + if (checkNeedsReset()) { + return; + } + // This method assumes EEPROM has already been initialized // which is the first thing ESPurna does diff --git a/code/espurna/settings.ino b/code/espurna/settings.ino index db65a52c..6c545e85 100644 --- a/code/espurna/settings.ino +++ b/code/espurna/settings.ino @@ -187,6 +187,7 @@ void _settingsInitCommands() { settingsRegisterCommand(F("ERASE.CONFIG"), [](Embedis* e) { DEBUG_MSG_P(PSTR("+OK\n")); resetReason(CUSTOM_RESET_TERMINAL); + _eepromCommit(); ESP.eraseConfig(); *((int*) 0) = 0; // see https://github.com/esp8266/Arduino/issues/1494 }); diff --git a/code/espurna/system.ino b/code/espurna/system.ino index 560cb84c..6afd96b2 100644 --- a/code/espurna/system.ino +++ b/code/espurna/system.ino @@ -77,6 +77,14 @@ unsigned long systemLoadAverage() { void systemLoop() { + // ------------------------------------------------------------------------- + // User requested reset + // ------------------------------------------------------------------------- + + if (checkNeedsReset()) { + reset(); + } + // ------------------------------------------------------------------------- // Check system stability // ------------------------------------------------------------------------- diff --git a/code/espurna/utils.ino b/code/espurna/utils.ino index 1afe2013..baa9e9a8 100644 --- a/code/espurna/utils.ino +++ b/code/espurna/utils.ino @@ -9,6 +9,8 @@ Copyright (C) 2017-2018 by Xose PĂ©rez #include Ticker _defer_reset; +uint8_t _reset_reason = 0; + String getIdentifier() { char buffer[20]; snprintf_P(buffer, sizeof(buffer), PSTR("%s-%06X"), APP_NAME, ESP.getChipId()); @@ -463,8 +465,9 @@ unsigned char resetReason() { } void resetReason(unsigned char reason) { + _reset_reason = reason; EEPROMr.write(EEPROM_CUSTOM_RESET, reason); - EEPROMr.commit(); + eepromCommit(); } void reset() { @@ -472,8 +475,11 @@ void reset() { } void deferredReset(unsigned long delay, unsigned char reason) { - resetReason(reason); - _defer_reset.once_ms(delay, reset); + _defer_reset.once_ms(delay, resetReason, reason); +} + +bool checkNeedsReset() { + return _reset_reason > 0; } // ----------------------------------------------------------------------------- From 89ed0cacebb359eccfbd70d17b07d52f96d060c1 Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Tue, 9 Oct 2018 03:58:00 +0300 Subject: [PATCH 4/4] Avoid overwriting settings in custom_crash_callback --- code/espurna/debug.ino | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/code/espurna/debug.ino b/code/espurna/debug.ino index e7c18e7d..ba70ffee 100644 --- a/code/espurna/debug.ino +++ b/code/espurna/debug.ino @@ -236,9 +236,13 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack EEPROMr.put(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_STACK_START, stack_start); EEPROMr.put(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_STACK_END, stack_end); - // write stack trace to EEPROM + // starting address of Embedis data plus reserve + const uint16_t settings_start = SPI_FLASH_SEC_SIZE - settingsSize() - 0x10; + + // write stack trace to EEPROM and avoid overwriting settings int16_t current_address = SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_STACK_TRACE; for (uint32_t i = stack_start; i < stack_end; i++) { + if (current_address >= settings_start) break; byte* byteValue = (byte*) i; EEPROMr.write(current_address++, *byteValue); } @@ -278,16 +282,23 @@ void debugDumpCrashInfo() { EEPROMr.get(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_EPC3, epc3); EEPROMr.get(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_EXCVADDR, excvaddr); EEPROMr.get(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_DEPC, depc); + DEBUG_MSG_P(PSTR("[DEBUG] epc1=0x%08x epc2=0x%08x epc3=0x%08x\n"), epc1, epc2, epc3); DEBUG_MSG_P(PSTR("[DEBUG] excvaddr=0x%08x depc=0x%08x\n"), excvaddr, depc); uint32_t stack_start, stack_end; EEPROMr.get(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_STACK_START, stack_start); EEPROMr.get(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_STACK_END, stack_end); - DEBUG_MSG_P(PSTR("[DEBUG] >>>stack>>>\n[DEBUG] ")); + + DEBUG_MSG_P(PSTR("[DEBUG] sp=0x%08x end=0x%08x\n"), stack_start, stack_end); + int16_t current_address = SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_STACK_TRACE; int16_t stack_len = stack_end - stack_start; + uint32_t stack_trace; + + DEBUG_MSG_P(PSTR("[DEBUG] >>>stack>>>\n[DEBUG] ")); + for (int16_t i = 0; i < stack_len; i += 0x10) { DEBUG_MSG_P(PSTR("%08x: "), stack_start + i); for (byte j = 0; j < 4; j++) {