diff --git a/tools/WLED_ESP32_8MB_SafeBoot.csv b/tools/WLED_ESP32_8MB_SafeBoot.csv new file mode 100644 index 0000000000..8dc47b8c1c --- /dev/null +++ b/tools/WLED_ESP32_8MB_SafeBoot.csv @@ -0,0 +1,10 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x240000, +app1, app, ota_1, 0x250000, 0x240000, +spiffs, data, spiffs, 0x490000, 0x100000, +spiffs_backup, data, 0x40, 0x590000, 0x100000, +crc0, data, 0x41, 0x690000, 0x1000, +crc1, data, 0x42, 0x691000, 0x1000, +coredump, data, coredump,,64K diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 97b48c4ab6..1d446c2818 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -1,5 +1,6 @@ #include "wled.h" #include "wled_ethernet.h" +#include "safe_boot_functions.h" /* * Serializes and parses the cfg.json and wsec.json settings files, stored in internal FS. @@ -832,6 +833,9 @@ void serializeConfigToFS() { if (f) serializeJson(root, f); f.close(); releaseJSONBufferLock(); + #ifdef WLED_ENABLE_SAFE_BOOT + update_spiffs_crc(); + #endif configNeedsWrite = false; } diff --git a/wled00/file.cpp b/wled00/file.cpp index dcc2d57c41..568d661a9b 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -1,4 +1,5 @@ #include "wled.h" +#include "safe_boot_functions.h" /* * Utility for SPIFFS filesystem @@ -40,6 +41,9 @@ void closeFile() { #endif f.close(); // "if (f)" check is aleady done inside f.close(), and f cannot be nullptr -> no need for double checking before closing the file handle. DEBUGFS_PRINTF("took %lu ms\n", millis() - s); + #ifdef WLED_ENABLE_SAFE_BOOT + update_spiffs_crc(); + #endif doCloseFile = false; } @@ -478,6 +482,9 @@ bool copyFile(const char* src_path, const char* dst_path) { DEBUG_PRINTLN(F("copy failed")); WLED_FS.remove(dst_path); // delete incomplete file } + #ifdef WLED_ENABLE_SAFE_BOOT + else {update_spiffs_crc();} + #endif return success; } diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 9023baf344..8bb2587e5d 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -1,4 +1,5 @@ #include "wled.h" +#include "safe_boot_functions.h" /* * Methods to handle saving and loading presets to/from the filesystem @@ -114,6 +115,9 @@ void initPresetsFile() } serializeJson(doc, f); f.close(); + #ifdef WLED_ENABLE_SAFE_BOOT + update_spiffs_crc(); + #endif } bool applyPresetFromPlaylist(byte index) diff --git a/wled00/safe_boot_functions.cpp b/wled00/safe_boot_functions.cpp new file mode 100644 index 0000000000..242b87397d --- /dev/null +++ b/wled00/safe_boot_functions.cpp @@ -0,0 +1,86 @@ +/* + This functions are used to use WLED together with "Safe Bootbootloader" + https://github.com/wled-install/SafeBootloader +*/ +#ifdef WLED_ENABLE_SAFE_BOOT +#include "safe_boot_functions.h" +#include "wled.h" +#include + +#define SPIFFS_CRC_MAGIC 0x53504653 + +typedef struct { + uint32_t magic; + uint32_t crc_spiffs; // CRC SPIFFS / Backup + uint32_t size_spiffs; // Größe SPIFFS / Backup +} crc_group_t; + +uint32_t calc_crc(const esp_partition_t* part) +{ + const size_t bufsize = 4096; + uint8_t buf[bufsize]; + + uint32_t crc = 0; + size_t offset = 0; + + while (offset < part->size) { + size_t toread = bufsize; + if (offset + toread > part->size) + toread = part->size - offset; + + esp_partition_read(part, offset, buf, toread); + + crc = crc32_le(crc, buf, toread); + offset += toread; + } + + return crc; +} + +bool update_spiffs_crc() +{ + const esp_partition_t* spiffs = + esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_DATA_SPIFFS, + "spiffs"); + + const esp_partition_t* crcpart = + esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, + static_cast(0x41), // crc subtype + "crc0"); + + if (!spiffs || !crcpart) { + DEBUG_PRINTLN(F("SPIFFS or CRC partition not found!")); + return false; + } + + + uint32_t crc = calc_crc(spiffs); + + crc_group_t stored = {}; + esp_partition_read(crcpart, 0, &stored, sizeof(stored)); + + // prüfen ob identisch + if (stored.magic == SPIFFS_CRC_MAGIC && + stored.crc_spiffs == crc && + stored.size_spiffs == spiffs->size) + { + // nichts zu tun + DEBUG_PRINTLN(F("SPIFFS CRC matches stored value, no update needed.")); + return true; + } + + stored.magic = SPIFFS_CRC_MAGIC; + stored.crc_spiffs = crc; + stored.size_spiffs = spiffs->size; + DEBUG_PRINTLN(F("Updating SPIFFS CRC partition with new values.")); + esp_partition_erase_range(crcpart, 0, 4096); + esp_partition_write(crcpart, 0, &stored, sizeof(stored)); + DEBUG_PRINTLN(F("SPIFFS CRC partition updated.")); + + return true; +} + +#endif \ No newline at end of file diff --git a/wled00/safe_boot_functions.h b/wled00/safe_boot_functions.h new file mode 100644 index 0000000000..4166ed6e17 --- /dev/null +++ b/wled00/safe_boot_functions.h @@ -0,0 +1,16 @@ +/* + This functions are used to use WLED together with "Safe Bootbootloader" + https://github.com/wled-install/SafeBootloader +*/ + +#pragma once + +#ifdef WLED_ENABLE_SAFE_BOOT +#include +#include +#include +#include + +bool update_spiffs_crc(); + +#endif \ No newline at end of file