From 238c8ce4671e72ae99aacfc023506ba8985b821b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 15 Dec 2020 16:24:01 +0100
Subject: [PATCH] Add ESP32 support for Tasmota FileSystem
- Add ESP32 support for Tasmota FileSystem
- Move ESP32 Zigbee persistence from NVS to SPIFFS (#10121)
---
tasmota/support_esp32.ino | 43 +++++--
tasmota/support_filesystem.ino | 153 +++++++++++++++++++++++
tasmota/xdrv_23_zigbee_4_persistence.ino | 2 +-
3 files changed, 185 insertions(+), 13 deletions(-)
create mode 100644 tasmota/support_filesystem.ino
diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino
index a46809e26..806175505 100644
--- a/tasmota/support_esp32.ino
+++ b/tasmota/support_esp32.ino
@@ -167,10 +167,19 @@ void SettingsErase(uint8_t type) {
}
void SettingsRead(void *data, size_t size) {
+#ifdef USE_TFS
+// if (!TfsLoadFile("/settings", (uint8_t*)data, size)) {
+ NvmLoad("main", "Settings", data, size);
+// }
+#else
NvmLoad("main", "Settings", data, size);
+#endif
}
void SettingsWrite(const void *pSettings, unsigned nSettingsLen) {
+#ifdef USE_TFS
+// TfsSaveFile("/settings", (const uint8_t*)pSettings, nSettingsLen);
+#endif
NvmSave("main", "Settings", pSettings, nSettingsLen);
}
@@ -182,18 +191,6 @@ void QPCWrite(const void *pSettings, unsigned nSettingsLen) {
NvmSave("qpc", "pcreg", pSettings, nSettingsLen);
}
-void ZigbeeErase(void) {
- NvmErase("zb");
-}
-
-void ZigbeeRead(void *pSettings, unsigned nSettingsLen) {
- NvmLoad("zb", "zigbee", pSettings, nSettingsLen);
-}
-
-void ZigbeeWrite(const void *pSettings, unsigned nSettingsLen) {
- NvmSave("zb", "zigbee", pSettings, nSettingsLen);
-}
-
void NvsInfo(void) {
nvs_stats_t nvs_stats;
nvs_get_stats(NULL, &nvs_stats);
@@ -201,6 +198,28 @@ void NvsInfo(void) {
nvs_stats.used_entries, nvs_stats.free_entries, nvs_stats.total_entries, nvs_stats.namespace_count);
}
+void ZigbeeErase(unsigned nSettingsLen) {
+// NvmErase("zb");
+#ifdef USE_TFS
+ TfsEraseFile("/zb", nSettingsLen);
+#endif
+}
+
+void ZigbeeRead(uint8_t *pSettings, unsigned nSettingsLen) {
+// NvmLoad("zb", "zigbee", pSettings, nSettingsLen);
+#ifdef USE_TFS
+ TfsLoadFile("/zb", pSettings, nSettingsLen);
+#endif
+}
+
+void ZigbeeWrite(const uint8_t *pSettings, unsigned nSettingsLen) {
+// NvmSave("zb", "zigbee", pSettings, nSettingsLen);
+#ifdef USE_TFS
+ TfsSaveFile("/zb", pSettings, nSettingsLen);
+#endif
+}
+
+
//
// Flash memory mapping
//
diff --git a/tasmota/support_filesystem.ino b/tasmota/support_filesystem.ino
new file mode 100644
index 000000000..6eef715f4
--- /dev/null
+++ b/tasmota/support_filesystem.ino
@@ -0,0 +1,153 @@
+/*
+ support_filesystem.ino - Filesystem support for Tasmota
+
+ Copyright (C) 2020 Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+/*********************************************************************************************\
+ * ESP32 Filesystem Support
+\*********************************************************************************************/
+
+#ifdef ESP32
+
+#define USE_TFS
+
+#ifdef USE_SCRIPT
+#undef USE_TFS
+#endif // USE_SCRIPT
+
+#ifdef USE_TFS
+
+//#define USE_LITTLEFS // LittleFS not tested yet
+//#define USE_FFAT // FFat minimal 983k partition (4096 sector size) - tested
+#define USE_SPIFFS // SPIFFS - tested
+
+#ifdef USE_LITTLEFS
+ #include
+ #define TASMOTA_FS LittleFS
+#endif
+#ifdef USE_FFAT
+ #include
+ #define TASMOTA_FS FFat
+#endif
+#ifdef USE_SPIFFS
+ #include
+ #define TASMOTA_FS SPIFFS
+#endif
+
+bool TfsInit(void) {
+ static uint8_t FsMounted = 0;
+
+ if (FsMounted) { return FsMounted -1; }
+
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Mounting..."));
+ if (!TASMOTA_FS.begin()) {
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Formatting..."));
+ TASMOTA_FS.format();
+ if (!TASMOTA_FS.begin()) {
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Failed"));
+ FsMounted = 1; // false
+ return false;
+ }
+ }
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Mounted"));
+// TfsInfo();
+ FsMounted = 2; // true
+ return true;
+}
+
+bool TfsFileExists(const char *fname){
+ if (!TfsInit()) { return false; }
+
+ bool yes = false;
+ File file = TASMOTA_FS.open(fname, "r");
+ if (!file.isDirectory()) {
+ yes = true;
+ } else {
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: File not found"));
+ }
+ file.close();
+ return yes;
+}
+
+bool TfsSaveFile(const char *fname, const uint8_t *buf, uint32_t len) {
+ if (!TfsInit()) { return false; }
+
+ File file = TASMOTA_FS.open(fname, "w");
+ if (!file) {
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Save failed"));
+ return false;
+ }
+
+ file.write(buf, len);
+ file.close();
+ return true;
+}
+
+bool TfsEraseFile(const char *fname, uint32_t len) {
+ if (!TfsInit()) { return false; }
+
+ File file = TASMOTA_FS.open(fname, "w");
+ if (!file) {
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Erase failed"));
+ return false;
+ }
+
+ uint8_t init_value = 0xff;
+ for (uint32_t i = 0; i < len; i++) {
+ file.write(&init_value, 1);
+ }
+ file.close();
+ return true;
+}
+
+bool TfsLoadFile(const char *fname, uint8_t *buf, uint32_t len) {
+ if (!TfsInit()) { return false; }
+ if (!TfsFileExists(fname)) { return false; }
+
+ File file = TASMOTA_FS.open(fname, "r");
+ if (!file) {
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: File not found"));
+ return false;
+ }
+
+ file.read(buf, len);
+ file.close();
+ return true;
+}
+
+void TfsInfo(void) {
+#ifdef USE_SPIFFS
+ uint32_t used_bytes = TASMOTA_FS.usedBytes();
+#endif // USE_SPIFFS
+ uint32_t total_bytes = TASMOTA_FS.totalBytes();
+#ifdef USE_FFAT
+ uint32_t used_bytes = total_bytes - TASMOTA_FS.freeBytes();
+#endif // USE_FFAT
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Used %d/%d bytes"), used_bytes, total_bytes);
+
+ File root = TASMOTA_FS.open("/");
+ File file = root.openNextFile();
+ while (file) {
+ String filename = file.name();
+ size_t filesize = file.size();
+ AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: File %s, size %d"), filename.c_str(), filesize);
+ file = root.openNextFile();
+ }
+}
+
+#endif // USE_TFS
+#endif // ESP32
diff --git a/tasmota/xdrv_23_zigbee_4_persistence.ino b/tasmota/xdrv_23_zigbee_4_persistence.ino
index 1d4f31a19..046077771 100644
--- a/tasmota/xdrv_23_zigbee_4_persistence.ino
+++ b/tasmota/xdrv_23_zigbee_4_persistence.ino
@@ -419,7 +419,7 @@ void eraseZigbeeDevices(void) {
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased in %s"), PSTR("Flash"));
#endif // ESP8266
#ifdef ESP32
- ZigbeeErase();
+ ZigbeeErase(z_block_len);
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (%d bytes)"), z_block_len);
#endif // ESP32
}