From 9a518cd3d7efe418fdb974d0054d139d3898d368 Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 15 Apr 2021 07:31:01 -0400 Subject: [PATCH] LITTLEFS update - partition label and multiple partitions, idea copied from SPIFFS (#5023) Note, maxOpenFiles parameter is unused but kept for compatibility. --- .../examples/LITTLEFS_test/LITTLEFS_test.ino | 26 ++++++-- .../examples/LITTLEFS_test/partitions.csv | 8 +++ libraries/LITTLEFS/src/LITTLEFS.cpp | 59 +++++++++++++++---- libraries/LITTLEFS/src/LITTLEFS.h | 6 +- 4 files changed, 80 insertions(+), 19 deletions(-) create mode 100644 libraries/LITTLEFS/examples/LITTLEFS_test/partitions.csv diff --git a/libraries/LITTLEFS/examples/LITTLEFS_test/LITTLEFS_test.ino b/libraries/LITTLEFS/examples/LITTLEFS_test/LITTLEFS_test.ino index 528bfd18..f905511d 100644 --- a/libraries/LITTLEFS/examples/LITTLEFS_test/LITTLEFS_test.ino +++ b/libraries/LITTLEFS/examples/LITTLEFS_test/LITTLEFS_test.ino @@ -4,8 +4,13 @@ /* You only need to format LITTLEFS the first time you run a test or else use the LITTLEFS plugin to create a partition - https://github.com/lorol/arduino-esp32littlefs-plugin */ + https://github.com/lorol/arduino-esp32littlefs-plugin + If you test two partitions, you need to use a custom + partition.csv file, see in the sketch folder */ + +//#define TWOPART + #define FORMAT_LITTLEFS_IF_FAILED true void listDir(fs::FS &fs, const char * dirname, uint8_t levels){ @@ -123,9 +128,8 @@ void deleteFile(fs::FS &fs, const char * path){ } } -// SPIFFS-like write and delete file +// SPIFFS-like write and delete file, better use #define CONFIG_LITTLEFS_SPIFFS_COMPAT 1 -// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.cpp#L60 void writeFile2(fs::FS &fs, const char * path, const char * message){ if(!fs.exists(path)){ if (strchr(path, '/')) { @@ -158,7 +162,6 @@ void writeFile2(fs::FS &fs, const char * path, const char * message){ file.close(); } -// See: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.h#L149 void deleteFile2(fs::FS &fs, const char * path){ Serial.printf("Deleting file and empty folders on path: %s\r\n", path); @@ -239,6 +242,19 @@ void testFileIO(fs::FS &fs, const char * path){ void setup(){ Serial.begin(115200); + +#ifdef TWOPART + if(!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED, "/lfs2", 5, "part2")){ + Serial.println("part2 Mount Failed"); + return; + } + appendFile(LITTLEFS, "/hello0.txt", "World0!\r\n"); + readFile(LITTLEFS, "/hello0.txt"); + LITTLEFS.end(); + + Serial.println( "Done with part2, work with the first lfs partition..." ); +#endif + if(!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED)){ Serial.println("LITTLEFS Mount Failed"); return; @@ -264,7 +280,7 @@ void setup(){ testFileIO(LITTLEFS, "/test.txt"); deleteFile(LITTLEFS, "/test.txt"); - Serial.println( "Test complete" ); + Serial.println( "Test complete" ); } void loop(){ diff --git a/libraries/LITTLEFS/examples/LITTLEFS_test/partitions.csv b/libraries/LITTLEFS/examples/LITTLEFS_test/partitions.csv new file mode 100644 index 00000000..bf492891 --- /dev/null +++ b/libraries/LITTLEFS/examples/LITTLEFS_test/partitions.csv @@ -0,0 +1,8 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x100000, +app1, app, ota_1, ,0x100000, +spiffs, data, spiffs, ,0x1D0000, +part2, data, spiffs, ,0x20000, +#1048576 \ No newline at end of file diff --git a/libraries/LITTLEFS/src/LITTLEFS.cpp b/libraries/LITTLEFS/src/LITTLEFS.cpp index 4d8e8d67..d14f1ee1 100644 --- a/libraries/LITTLEFS/src/LITTLEFS.cpp +++ b/libraries/LITTLEFS/src/LITTLEFS.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -static constexpr const char LFS_NAME[] = "spiffs"; + #include "vfs_api.h" @@ -20,30 +20,63 @@ extern "C" { #include #include #include -#undef B110 -#undef B1000000 -#include "esp_littlefs.h" +#include "esp_littlefs.h" } #include "LITTLEFS.h" using namespace fs; -LITTLEFSFS::LITTLEFSFS() : FS(FSImplPtr(new VFSImpl())) +class LITTLEFSImpl : public VFSImpl { +public: + LITTLEFSImpl(); + virtual ~LITTLEFSImpl() { } + virtual bool exists(const char* path); +}; +LITTLEFSImpl::LITTLEFSImpl() +{ } -bool LITTLEFSFS::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFilesUnused) +bool LITTLEFSImpl::exists(const char* path) { - if(esp_littlefs_mounted(LFS_NAME)){ + File f = open(path, "r"); + return (f == true); +} + +LITTLEFSFS::LITTLEFSFS() : FS(FSImplPtr(new LITTLEFSImpl())), partitionLabel_(NULL) +{ +} + +LITTLEFSFS::~LITTLEFSFS() +{ + if (partitionLabel_){ + free(partitionLabel_); + partitionLabel_ = NULL; + } +} + +bool LITTLEFSFS::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles, const char * partitionLabel) +{ + + if (partitionLabel_){ + free(partitionLabel_); + partitionLabel_ = NULL; + } + + if (partitionLabel){ + partitionLabel_ = strdup(partitionLabel); + } + + if(esp_littlefs_mounted(partitionLabel_)){ log_w("LITTLEFS Already Mounted!"); return true; } esp_vfs_littlefs_conf_t conf = { .base_path = basePath, - .partition_label = LFS_NAME, + .partition_label = partitionLabel_, .format_if_mount_failed = false }; @@ -63,8 +96,8 @@ bool LITTLEFSFS::begin(bool formatOnFail, const char * basePath, uint8_t maxOpen void LITTLEFSFS::end() { - if(esp_littlefs_mounted(LFS_NAME)){ - esp_err_t err = esp_vfs_littlefs_unregister(LFS_NAME); + if(esp_littlefs_mounted(partitionLabel_)){ + esp_err_t err = esp_vfs_littlefs_unregister(partitionLabel_); if(err){ log_e("Unmounting LITTLEFS failed! Error: %d", err); return; @@ -76,7 +109,7 @@ void LITTLEFSFS::end() bool LITTLEFSFS::format() { disableCore0WDT(); - esp_err_t err = esp_littlefs_format(LFS_NAME); + esp_err_t err = esp_littlefs_format(partitionLabel_); enableCore0WDT(); if(err){ log_e("Formatting LITTLEFS failed! Error: %d", err); @@ -88,7 +121,7 @@ bool LITTLEFSFS::format() size_t LITTLEFSFS::totalBytes() { size_t total,used; - if(esp_littlefs_info(LFS_NAME, &total, &used)){ + if(esp_littlefs_info(partitionLabel_, &total, &used)){ return 0; } return total; @@ -97,7 +130,7 @@ size_t LITTLEFSFS::totalBytes() size_t LITTLEFSFS::usedBytes() { size_t total,used; - if(esp_littlefs_info(LFS_NAME, &total, &used)){ + if(esp_littlefs_info(partitionLabel_, &total, &used)){ return 0; } return used; diff --git a/libraries/LITTLEFS/src/LITTLEFS.h b/libraries/LITTLEFS/src/LITTLEFS.h index fbd6f09e..c76cc887 100644 --- a/libraries/LITTLEFS/src/LITTLEFS.h +++ b/libraries/LITTLEFS/src/LITTLEFS.h @@ -23,11 +23,15 @@ class LITTLEFSFS : public FS { public: LITTLEFSFS(); - bool begin(bool formatOnFail=false, const char * basePath="/littlefs", uint8_t maxOpenFiles=5); + ~LITTLEFSFS(); + bool begin(bool formatOnFail=false, const char * basePath="/littlefs", uint8_t maxOpenFiles=10, const char * partitionLabel="spiffs"); bool format(); size_t totalBytes(); size_t usedBytes(); void end(); + +private: + char * partitionLabel_; }; }