From 274c9cac89da721f1e533b95fa152ed2a31f52c2 Mon Sep 17 00:00:00 2001 From: Will Miles Date: Tue, 19 Aug 2025 19:01:33 -0400 Subject: [PATCH 1/4] Fix bootloop if config missing/reset Can't reset the config if there's nothing to reset! --- wled00/cfg.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 916aac576a..09742221da 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -787,13 +787,16 @@ bool verifyConfig() { } // rename config file and reboot +// if the file doesn't exist, such as after a reset, do nothing void resetConfig() { - DEBUG_PRINTLN(F("Reset config")); - char backupname[32]; - strcpy(backupname, s_cfg_json); - strcat(backupname, ".rst.json"); - WLED_FS.rename(s_cfg_json, backupname); - doReboot = true; + if (WLED_FS.exists(s_cfg_json)) { + DEBUG_PRINTLN(F("Reset config")); + char backupname[32]; + strcpy(backupname, s_cfg_json); + strcat(backupname, ".rst.json"); + WLED_FS.rename(s_cfg_json, backupname); + doReboot = true; + } } bool deserializeConfigFromFS() { From c636aae0b2baa3cef8f941d795a9b6bfb597e22b Mon Sep 17 00:00:00 2001 From: Will Miles Date: Tue, 19 Aug 2025 19:05:05 -0400 Subject: [PATCH 2/4] ESP8266: Commit ACTIONT_TRACKER --- wled00/util.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wled00/util.cpp b/wled00/util.cpp index 0e662bd790..14cc143897 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -836,6 +836,9 @@ void handleBootLoop() { #endif else dumpFilesToSerial(); +#ifdef ESP8266 + ESP.rtcUserMemoryWrite(ACTIONT_TRACKER_IDX, &bl_actiontracker, sizeof(uint32_t)); +#endif ESP.restart(); // restart cleanly and don't wait for another crash } From 9a940a0a851c512ce0027ddb1b6c4eccc8b5793c Mon Sep 17 00:00:00 2001 From: Will Miles Date: Tue, 19 Aug 2025 19:55:39 -0400 Subject: [PATCH 3/4] Use consistent naming for backups and reset cfgs Use 'rst.cfg.json' instead of 'cfg.json.rst.json' for configs that were reset. --- wled00/cfg.cpp | 5 ++--- wled00/util.cpp | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 09742221da..eac6ea25a2 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -787,13 +787,12 @@ bool verifyConfig() { } // rename config file and reboot -// if the file doesn't exist, such as after a reset, do nothing +// if the cfg file doesn't exist, such as after a reset, do nothing void resetConfig() { if (WLED_FS.exists(s_cfg_json)) { DEBUG_PRINTLN(F("Reset config")); char backupname[32]; - strcpy(backupname, s_cfg_json); - strcat(backupname, ".rst.json"); + snprintf_P(backupname, sizeof(backupname), PSTR("/rst.%s"), &s_cfg_json[1]); WLED_FS.rename(s_cfg_json, backupname); doReboot = true; } diff --git a/wled00/util.cpp b/wled00/util.cpp index 14cc143897..84473ce711 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -721,8 +721,8 @@ void *realloc_malloc(void *ptr, size_t size) { // if a bootloop is detected: restore settings from backup, then reset settings, then switch boot image (and repeat) #define BOOTLOOP_THRESHOLD 5 // number of consecutive crashes to trigger bootloop detection -#define BOOTLOOP_ACTION_RESTORE 0 // default action: restore config from /cfg.bak -#define BOOTLOOP_ACTION_RESET 1 // if restore does not work, reset config (rename /cfg.json to /cfg.fault) +#define BOOTLOOP_ACTION_RESTORE 0 // default action: restore config from /bak.cfg.json +#define BOOTLOOP_ACTION_RESET 1 // if restore does not work, reset config (rename /cfg.json to /rst.cfg.json) #define BOOTLOOP_ACTION_OTA 2 // swap the boot partition #define BOOTLOOP_ACTION_DUMP 3 // nothing seems to help, dump files to serial and reboot (until hardware reset) #ifdef ESP8266 From 2a4f816b83ac48c375de1f350aa85310cc82f2e5 Mon Sep 17 00:00:00 2001 From: Will Miles Date: Tue, 19 Aug 2025 19:56:26 -0400 Subject: [PATCH 4/4] Add a little more PSTR to bootloop handling --- wled00/file.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wled00/file.cpp b/wled00/file.cpp index 7ec9bd6152..108c41bd44 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -515,7 +515,7 @@ bool compareFiles(const char* path1, const char* path2) { return identical; } -static const char s_backup_json[] PROGMEM = "/bkp."; +static const char s_backup_fmt[] PROGMEM = "/bkp.%s"; bool backupFile(const char* filename) { DEBUG_PRINTF("backup %s \n", filename); @@ -524,7 +524,7 @@ bool backupFile(const char* filename) { return false; } char backupname[32]; - snprintf(backupname, sizeof(backupname), "%s%s", s_backup_json, filename + 1); // skip leading '/' in filename + snprintf_P(backupname, sizeof(backupname), s_backup_fmt, filename + 1); // skip leading '/' in filename if (copyFile(filename, backupname)) { DEBUG_PRINTLN(F("backup ok")); @@ -537,7 +537,7 @@ bool backupFile(const char* filename) { bool restoreFile(const char* filename) { DEBUG_PRINTF("restore %s \n", filename); char backupname[32]; - snprintf(backupname, sizeof(backupname), "%s%s", s_backup_json, filename + 1); // skip leading '/' in filename + snprintf_P(backupname, sizeof(backupname), s_backup_fmt, filename + 1); // skip leading '/' in filename if (!WLED_FS.exists(backupname)) { DEBUG_PRINTLN(F("no backup found")); @@ -565,9 +565,9 @@ bool validateJsonFile(const char* filename) { bool result = deserializeJson(doc, file, DeserializationOption::Filter(filter)) == DeserializationError::Ok; file.close(); if (!result) { - DEBUG_PRINTF("Invalid JSON file %s\n", filename); + DEBUG_PRINTF_P(PSTR("Invalid JSON file %s\n"), filename); } else { - DEBUG_PRINTF("Valid JSON file %s\n", filename); + DEBUG_PRINTF_P(PSTR("Valid JSON file %s\n"), filename); } return result; }