GithubHelp home page GithubHelp logo

littlefs's Introduction

LittleFS_esp32

Ths library is now part of Arduino esp32 core v2

Note, there it is renamed from LITTLEFS to LittleFS, Please post your issues there. This here is kept for Arduino esp32 core 1.x purposes

LittleFS library for arduino-esp32

Installation

  • Use Arduino Library Manager
  • Or download / use git to have latest repository of LITTLEFS added to Arduino IDE /libraries folder
    (File > Preferences > Sketchbook location).
  • See #define CONFIG_LITTLEFS_FOR_IDF_3_2 in esp_littlefs.c.
    Now it is defined / undefined automatically by detecting the IDF version and core version. When defined, the library works with old and new IDFs 3.2 - 4.x but file timestamp feature is removed. See LITTLEFS_time example.
  • See #define CONFIG_LITTLEFS_SPIFFS_COMPAT in esp_littlefs.c.
    When set to 1, folders are recursively created or deleted if empty on creating/deleting a new file like SPIFFS. Default is 0.
  • The other #define CONFIG_LITTLEFS_xxxxx are set to optimal default values.
    Read here and here if you want to modify.
  • For low-level default error reporting modifications, see the defines at beginning of the lfs.c here.

Usage

#define USE_LittleFS

#include <FS.h>
#ifdef USE_LittleFS
  #define SPIFFS LITTLEFS
  #include <LITTLEFS.h> 
#else
  #include <SPIFFS.h>
#endif 
  • Note, this may not work if your sketch uses other libraries that use SPIFFS themselves.
  • See also esp_partition.h . LITTLEFS re-uses same type and subtype as SPIFFS

Differences with SPIFFS

  • LittleFS has folders, you need to iterate files in folders unless you set #define CONFIG_LITTLEFS_SPIFFS_COMPAT 1
  • At root a "/folder" = "folder"
  • Requires a label for mount point, NULL will not work. Recommended is to use default LITTLEFS.begin()
  • maxOpenFiles parameter is unused, kept for compatibility
  • LITTLEFS.mkdir(path) and LITTLEFS.rmdir(path) are available
  • file.seek() behaves like on FFat see more details
  • file.write() and file.print() when partition space is ending may return different than really written bytes (on other FS is also inconsistent).
  • Speed comparison based on LittleFS_test.ino sketch (for a file 1048576 bytes):
Filesystem Read time [ms] Write time [ms]
FAT 276 14493
LITTLEFS 446* 16387
SPIFFS 767 65622

*The read speed improved by changing #define CONFIG_LITTLEFS_CACHE_SIZE from 128 to 512

Arduino ESP32 LittleFS filesystem upload tool

PlatformIO

  • See LITTLEFS_PlatformIO example here
    ( based on notes below from BlueAndi )

  • Add to platformio.ini: extra_scripts = replace_fs.py

  • Add replace_fs.py to project root directory (where platformio.ini is located):

Import("env")
print("Replace MKSPIFFSTOOL with mklittlefs.exe")
env.Replace (MKSPIFFSTOOL = "mklittlefs.exe")
  • Add mklittlefs.exe to project root directory as well.

Credits and license

To Do

  • Submit to be added to Arduino Library Manager
  • Optional drop-in compatibility with SPIFFS' lack of folders, similar to esp8266' way - implemented as a choice by a #define
  • Retire this library when released by esp32 Arduino core
  • Cleanup examples

littlefs's People

Contributors

lorol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

littlefs's Issues

LFS_NAME spiffs override for Arduino library

Hi @lorol,

static constexpr const char LFS_NAME[] = "spiffs";

wondering why the partition name was defaulted/const to spiffs and how to override or add more values in the sketch?
i think this could be any value that user set in the partition table.

Thank you

ESP32 compile time error

Hi,
I tried to used your library while porting code that was using littleFS in esp8266 to ESP32 and it gave me this error
LITTLEFS.cpp:111:21: error: 'disableCore0WDT' was not declared in this scope
disableCore0WDT();

/Documents/Arduino/libraries/LITTLEFS-master/src/LITTLEFS.cpp:111:21: error: 'disableCore0WDT' was not declared in this scope
disableCore0WDT();
^
/Documents/Arduino/libraries/LITTLEFS-master/src/LITTLEFS.cpp:113:20: error: 'enableCore0WDT' was not declared in this scope
enableCore0WDT();

how do I resolve this?

Finally

I struggled with SPIFFS, finding it to be "A Flash Memory Catastrophe" [https://forum.arduino.cc/index.php?topic=648987](ESP32 mit SPIFFS - eine Speicher Katastrophe), using FFat with some success but issues on power failures, but wanting LittleFS for its claimed Power-loss resilience.

Many, many thanks for making it available in the Arduino libs!

I repeated my earlier tests, and can say that at least in writing performance LittleFS beats the others.

FS_Compare_Auswahl_362

SPIFFS is simply not usable. Why would one uses it when FFat and now LittleFs are avaialble?

There does not seem to any reason to simulate behavior of this very poor FS, so why even bother thinking about it?

delay needed after Serial.begin

Adafruit ESP32 Feather
Arduino IDE v. 1.8.13
ESP core v. 1.0.5 from Arduino Board Manager
LittleFS_esp32 v. 1.0.5 from Arduino Library Manager

If there is no delay after Serial.begin, then some of the prints do not show up on the serial monitor.

For example, with two files in LittleFS and no delay, sometimes I get this:

FILE: /parrot.bmp	SIZE: 61496

dir test complete

and sometimes this:

  FILE: /graph.bmp	SIZE: 307254
  FILE: /parrot.bmp	SIZE: 61496

dir test complete

But with a delay(500), I get this, as expected:

starting LitFS
Listing directory: /
  FILE: /graph.bmp	SIZE: 307254
  FILE: /parrot.bmp	SIZE: 61496

dir test complete

The code:

#include <Arduino.h>
#include "FS.h"
#include <LITTLEFS.h>

void setup()
{
  Serial.begin(115200);

  delay(500);   //<------------------------!!!!!!!!!!!!!!!!!!!!!!!

  Serial.println("starting LitFS");
  if (!LITTLEFS.begin()) {
    Serial.println("LitFS mount failed");
    return;
  }
  listDir(LITTLEFS, "/", 3);
  Serial.println("");
  Serial.println( "dir test complete" );
}

void loop() {
}

void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
  Serial.printf("Listing directory: %s\r\n", dirname);

  File root = fs.open(dirname);
  if (!root) {
    Serial.println("- failed to open directory");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println(" - not a directory");
    return;
  }

  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if (levels) {
        listDir(fs, file.name(), levels - 1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("\tSIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

Custom partition table issue - esp_littlefs: partition "spiffs" could not be found

I am getting 'esp_littlefs: partition "spiffs" could not be found' error on start while using custom partition table. Below is my custom partition table.

# Name,Type,SubType,Offset,Size,Flags
nvs,data,nvs,0x9000,0x5000,
otadata,data,ota,0xe000,0x2000,
ota_0,app,ota_0,0x10000,0x190000,
ota_1,app,ota_1,0x1a0000,0x190000,
data,data,spiffs,0x330000,0xd0000,

Below is platform.ini snippet

[env:nodemcu-32s]
platform = espressif32
board = esp32dev
framework = arduino
board_build.filesystem = littlefs
board_build.partitions = partitions_custom.csv

Arduino framework 3.5.0 vfs_api change

In the newly released Arduino framework the vfs_api.h open functions header changes such that it takes a mandatory additional parameter.
FileImplPtr open(const char* path, const char* mode, const bool create) override;
This caused a problem in LITTLEFS.cpp line 44 where third parameter is not provided.

Suggested fix

By providing third parameter as false the file should not be created when checking with exist function.
Please verify and implement, also make sure its not breaking the older versions.

LittleFS function available for ESP8266 but not for ESP32

Apparently there are a few things available for ESP8266 which are not accessible for the ESP32, according to https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#littlefs-file-system-limitations, like info:

    struct FSInfo {
        size_t totalBytes;
        size_t usedBytes;
        size_t blockSize;
        size_t pageSize;
        size_t maxOpenFiles;
        size_t maxPathLength;
    };

    FSInfo fs_info;
    SPIFFS.info(fs_info);
    or LittleFS.info(fs_info);

At least not under Arduino. Is there a way to read e.g. info and other stuff for the ESP32?

LittleFS has a multithreading problem in esp_littlefs_info

I have a small project which uses the LittleFS in a multithreaded environment (RTOS tasks with a custom ESP32 WROOM board).
One of the threads is using "ESP Async WebServer" and sometimes (every fourth or fifth attempt) it returns "Error 500" because (seen at serial log).

.pio\libdeps\esp32dev\LittleFS_esp32\src\lfs.c:1076:error: Corrupted dir pair at {0x20, 0x1f}
[E][vfs_api.cpp:64] open(): /littlefs/www/favicon.ico does not exist
.pio\libdeps\esp32dev\LittleFS_esp32\src\lfs.c:1076:error: Corrupted dir pair at {0x0, 0x1}
[E][vfs_api.cpp:64] open(): /littlefs/www/config.htm does not exist
.pio\libdeps\esp32dev\LittleFS_esp32\src\lfs.c:1076:error: Corrupted dir pair at {0x20, 0x1f}
...

and yes the above files exists and after the next attempt (just reload in Chrome) it works also again (it's sporadic failing).

A second thread publishes some data to the MQTT server in regular intervals (also the currently used size of the filesystem - so FS.usedBytes() gets called). After I disable this call it works perfectly and no FS errors are there.

...after I added a sem_take/sem_give at esp_littlefs.c esp_littlefs_info it works so please include the fix in your repository :-)

Error compiling library

Hi,
when I compile the library I'm getting an error (I'm just trying one of the examples):
I'm using the latest version from Github.

`esp_littlefs.c: In function esp_vfs_littlefs_register

esp_littlefs.c: 203:9: error: unknown field 'utime_p' specified in initializer
utime_p = &vfs_littlefs_utime`

can't open a file while in the loop()

Description:

Hi all,
I am using ESP32 Dev Module and I am trying to open a file using LittleFS library in the loop() method, but my ESP32 board always restarts and throws Guru Meditation Error.
If I am opening the same file the same way in setup() method it opens the file without any problem and I can read it and write to it.
Would someone kindly tell to me what is going on or what I am doing wrong? How can I achieve this in the loop() method?
The module actually crashes when executing this line of code:

File file = LITTLEFS.open(filename);

Sketch:

#include <Arduino.h>
#include <ArduinoJson.h>
#include <LITTLEFS.h>

// Create Task handle objects
TaskHandle_t Core0_Task0;
TaskHandle_t Core1_Task0;

void listAllFiles() {
  // List all available files (if any) in the SPI Flash File System
  File root = LITTLEFS.open("/");
  File file = root.openNextFile();
  while (file) {
    Serial.print("FILE: ");
    Serial.println(file.name());
    file = root.openNextFile();
  }
  root.close();
  file.close();  
}

void readDataFromFile(const char* filename) {
  // Read JSON data from a file
  File file = LITTLEFS.open(filename);
  if (file) {
    // Deserialize the JSON data
    DynamicJsonDocument doc(5120);
    DeserializationError error = deserializeJson(doc, file);
    if (!error) {
      int data_str = doc["ports"][1];
      Serial.println(data_str);
    } else {
      log_v("deserializing JSON", error);
    }
  } else {
    Serial.print("Could not open file: ");
    Serial.println(filename);
  }
  file.close();  
}

void writeDataToFile(const char* filename) {
  File outfile = LITTLEFS.open(filename, FILE_WRITE);
  
  DynamicJsonDocument doc(5120);
  doc["ports"][0] = "80";
  doc["ports"][1] = 443;

  serializeJson(doc, Serial);
  if (!serializeJson(doc, outfile)) {
    Serial.println("Failed to write to LITTLEFS file.");
  } else {
    Serial.println("Success!");
  }
  outfile.close();  
}

void createTasks() {
  xTaskCreatePinnedToCore(
    primaryTask,      // Function to implement the task
    "PrimaryTask",    // Name of the task
    2000,             // Stack size in words
    NULL,             // Task input parameter
    0,                // Priority of the task
    &Core1_Task0,     // Task handle.
    1                 // Core where the task should run
  );

  xTaskCreatePinnedToCore(
    secondaryTask,    // Function to implement the task
    "SecondaryTask",  // Name of the task
    2000,             // Stack size in words
    NULL,             // Task input parameter
    0,                // Priority of the task
    &Core0_Task0,     // Task handle.
    0                 // Core where the task should run
  );
}

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  
  /* if (!LITTLEFS.begin(true)) {
    Serial.println("LITTLEFS Mount Failed.");
  } else {
    Serial.println("LITTLEFS Mount SUCCESSFUL.");
  }

  const char* filename = "/data.json";
  writeDataToFile(filename);
  listAllFiles();  
  readDataFromFile(filename);

  LITTLEFS.end(); */
  createTasks();
}

void loop() {
  vTaskDelete(NULL);
}

void primaryTask(void * parameter) {

  bool flag = true;
  for (;;) {
   if (flag) {
      flag = false;
      if (!LITTLEFS.begin(true)) {
        Serial.println("LITTLEFS Mount Failed.");
      } else {
        Serial.println("LITTLEFS Mount SUCCESSFUL.");
        const char* filename = "/data.json";
        writeDataToFile(filename);
        listAllFiles();  
        readDataFromFile(filename);
      }
      
      LITTLEFS.end();
    }
  }
}

void secondaryTask(void * parameter) {  
  for (;;) {
    // do nothing
  }
}

Debug Messages:

This is out of my Serial monitor:

Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (PrimaryTask) 
Core 1 register dump:
PC      : 0x40083780  PS      : 0x00060236  A0      : 0x3ffb8510  A1      : 0x3ffb8450  
A2      : 0x3ff000e0  A3      : 0x00000001  A4      : 0x3ffbde5c  A5      : 0x00000001  
A6      : 0x00060223  A7      : 0x00000000  A8      : 0x80082b8e  A9      : 0x3ffb84f0  
A10     : 0x00000000  A11     : 0x3ffb8c2c  A12     : 0x00000001  A13     : 0x00000001  
A14     : 0x00060220  A15     : 0x00000000  SAR     : 0x00000018  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000  

ELF file SHA256: 0000000000000000

Backtrace: 0x40083780:0x3ffb8450 0x3ffb850d:0x3ffb8530 0x40086109:0x3ffb8550 0x400ea4ca:0x3ffb8590 0x400ea592:0x3ffb85b0 0x40083b49:0x3ffb85d0 0x4008403d:0x3ffb85f0 0x400ee046:0x3ffb8660 0x400d6eec:0x3ffb8690 0x400d3be5:0x3ffb86c0 0x400d4037:0x3ffb86f0 0x400d45d5:0x3ffb8790 0x400d6a35:0x3ffb87f0 0x400d2d51:0x3ffb8840 0x400e94ad:0x3ffb8970 0x4000bcc5:0x3ffb8990 0x400dee19:0x3ffb89b0 0x400d7727:0x3ffb89d0 0x400d7c13:0x3ffb8a00 0x400d7ed9:0x3ffb8a40 0x400d73c7:0x3ffb8ac0 0x400d2509:0x3ffb8af0 0x400d2626:0x3ffb8b70 0x400862c1:0x3ffb8b90

This is the output of the Exception decoder:

PC: 0x40083780
EXCVADDR: 0x00000000

Decoding stack results
0x40086109: xQueueGenericReceive at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c line 1592
0x400ea4ca: esp_ipc_call_and_wait at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/ipc.c line 116
0x400ea592: esp_ipc_call at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/ipc.c line 123
0x40083b49: spi_flash_disable_interrupts_caches_and_other_cpu at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/spi_flash/cache_utils.c line 122
0x4008403d: spi_flash_read at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/spi_flash/flash_ops.c line 165
0x400ee046: esp_partition_read at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/spi_flash/partition.c line 242
0x400d6eec: littlefs_api_read at D:\Projects\Arduino\libraries\LittleFS_esp32\src\littlefs_api.c line 22
0x400d3be5: lfs_bd_read at D:\Projects\Arduino\libraries\LittleFS_esp32\src\lfs.c line 104
0x400d4037: lfs_dir_fetchmatch at D:\Projects\Arduino\libraries\LittleFS_esp32\src\lfs.c line 861
0x400d45d5: lfs_dir_find at D:\Projects\Arduino\libraries\LittleFS_esp32\src\lfs.c line 1245
0x400d6a35: lfs_stat at D:\Projects\Arduino\libraries\LittleFS_esp32\src\lfs.c line 3189
0x400d2d51: vfs_littlefs_stat at D:\Projects\Arduino\libraries\LittleFS_esp32\src\esp_littlefs.c line 1196
0x400e94ad: esp_vfs_stat at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/vfs/vfs.c line 492
0x400dee19: stat at ../../../.././newlib/libc/syscalls/sysstat.c line 12
0x400d7727: VFSFileImpl::VFSFileImpl(VFSImpl*, char const*, char const*) at C:\Users\franc\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\FS\src\vfs_api.cpp line 237
0x400d7c13: std::__shared_ptr ::__shared_ptr  , VFSImpl*&, char const*, char const*&>(std::_Sp_make_shared_tag, std::allocator  const&, VFSImpl*&, char const*&&, char const*&) at c:\users\franc\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-97-gc752ad5-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\ext/new_allocator.h line 120
0x400d7ed9: VFSImpl::open(char const*, char const*) at c:\users\franc\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-97-gc752ad5-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\bits/shared_ptr.h line 319
0x400d73c7: fs::FS::open(char const*, char const*) at C:\Users\franc\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\FS\src\FS.cpp line 191
0x400d2509: writeDataToFile(char const*) at D:\Projects\Arduino\sketch_jul15b/sketch_jul15b.ino line 43
0x400d2626: primaryTask(void*) at D:\Projects\Arduino\sketch_jul15b/sketch_jul15b.ino line 114
0x400862c1: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Major Writing Problem with LittleFS

I reported before excellent performance with LittleFS. This was when I grew the file size by APPENDING new records. Now I attempted to OVERWRITE early records of a large file - like one would do in a circular buffer - and ran into major problems. I used the same writing method (file.print(text); with text being an exactly 100 bytes record of only ASCII chars ending with LF ) but now using the file open command with "rb+" instead of "a" and positioning the pointer with file.seek(position). But now the writing time exploded up to 11 SECONDS for a 100 bytes record! This makes LittleFS useless for such an application. FFat does work.

I compared FFat, SPIFFS, and LittleFS. First graph repeats the previously reported APPENDING situation:

image

SPIFFS has 2 problems:

  • you cannot fill the FS by more than 67%, no matter how long you try writing
  • after a fill level of about 50% is reached, writing times jump to 2.5 sec per 100 bytes record

LittleFS and FFat

  • both allow to fill the FS 100%
  • writing times per records remain the same throughout fill level. LittleFS has a little bit of advantage, ans its max times are only 0.22 sec, while FFat has 0.34 sec.

Next test was to fill the file system with approx 45% with a file created in the append mode. The I began overwriting beginning at record 0. Graph shows results:

image

SPIFFS shows basically same behavior as before: filling limited to 2/3rd, write times jump to 2.5sec at approx. 50% fill level, but overwriting initial 45% is ok.

FFat also behaves basically the same as before: 100% fill possible, writing times as before, except that during overwrite the average writing times are even a little bit shorter.

But LittleFS presents a huge problem! The writing times for the first record reach 11 SECONDS for 100 bytes! They slowly decrease down to the values seen with appending, but only when the 45% are overwritten, and every new record is basically being appended.

LittleFS cannot be used in any overwriting application, but FFat can. Unfortunately, during the course of testing I experienced several corrupted file systems when using FFat, but not with LittleFS. SPIFFS is no serious competition. :-((

When the file write data is full, the data is lost

Thank you so much for porting Littlefs to Arduino. SPIFFS don't work very well for me, and as the free space gets smaller, the writing gets slower and slower.

Space allocation was 1.9MB APP 190KB SPIFFS.
My platform is ESP32, and I'm testing Littlefs in a very simple way, writing the file until it's full and then reading it out.

void appendFile(fs::FS &fs)
{
	uint32_t i = 0;
	uint32_t size;

	File file = fs.open(path, FILE_APPEND);
	if (!file)
	{
		Serial.println("- failed to open file for appending");
		return;
	}

	i = 0;
	while(1)
	{
		size = file.print("0123456789");
		if(size > 0)
		{
			i += 10;
			printf("used size = %d\n", LITTLEFS.usedBytes());
		}
		else
		{
			break;
		}
	}
	Serial.printf("i = %d\n", i);
	Serial.printf("\nfile size = %d\n", file.size());

	file.close();
}

This is a serial output:

............
............
used size = 376832
used size = 376832
used size = 376832
used size = 376832
D:\git\LITTLEFS\src\lfs.c:495:error: No more free space 53

i= 184060

file size = 0

I expect the variable "size" return less than 1 when the file is full and the data is written to the file system.
But the fact is not written, and file.size() returns 0. Because my application needs to keep writing data, it cannot write again when the file is full. Don't know how to solve this situation?

In addition, SPIFFS also appear in a similar situation, but worse is the endless cycle of writing without any return.I've also posted references herehttps://github.com/espressif/arduino-esp32/issues/4256.

Crash on file read.

assert failed: lfs_file_read lfs.c:5161 (lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file))


Backtrace:0x40083e1d:0x3ffee6800x4008edc5:0x3ffee6a0 0x40094521:0x3ffee6c0 0x40148667:0x3ffee7f0 0x40144588:0x3ffee810 0x401194fe:0x3ffee830 0x4008ba79:0x3ffee850 0x4008b9bd:0x3ffee870 0x4019a586:0x3ffee890 0x4019a619:0x3ffee8d0 0x40195267:0x3ffee8f0 0x400f7515:0x3ffee910 0x40108054:0x3ffee940 0x401080ad:0x3ffee960 0x400e0201:0x3ffee980 0x400ed6f1:0x3ffeea20 0x400ee1c5:0x3ffeeaf0 0x401ab55b:0x3ffeeb10 0x401abb55:0x3ffeeb30 0x400f8d72:0x3ffeeb80 0x400f8d99:0x3ffeebc0 04 
0196386:0x3ffeebe0 0x401963c9:0x3ffeec10 0x40196a5a:0x3ffeec30
  #0  0x40083e1d:0x3ffee6800 in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:402

DECODED:

Decoding stack results
0x40083e1d: panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c line 402
0x4008edc5: esp_system_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/esp_system.c line 128
0x40094521: __assert_func at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/assert.c line 85
0x40148667: lfs_file_read at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/components/esp_littlefs/src/littlefs/lfs.c line 5161
0x40144588: vfs_littlefs_read at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/components/esp_littlefs/src/esp_littlefs.c line 1037
0x401194fe: esp_vfs_read at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/vfs/vfs.c line 457
0x4008ba79: __sread at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/stdio.c line 47
0x4008b9bd: __srefill_r at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/refill.c line 117
0x4019a586: _fread_r at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/fread.c line 226
0x4019a619: fread at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/fread.c line 266
0x40195267: VFSFileImpl::read(unsigned char*, unsigned int) at C:/Users/Pc/.platformio/packages/framework-arduinoespressif32/libraries/FS/src/vfs_api.cpp line 387
0x400f7515: fs::File::read() at c:\users\pc\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/shared_ptr_base.h line 1018
0x40108054: Stream::timedRead() at C:/Users/Pc/.platformio/packages/framework-arduinoespressif32/cores/esp32/Stream.cpp line 36
0x401080ad: Stream::readString() at C:/Users/Pc/.platformio/packages/framework-arduinoespressif32/cores/esp32/Stream.cpp line 319
0x400e0201: fSystem::getFile(char const*) at lib/ArduinoJson-6.x/src/ArduinoJson/Object/MemberProxy.hpp line 31
0x400ed6f1: sSystem::handleSocketMessages(int) at lib/ArduinoJson-6.x/src/ArduinoJson/Variant/VariantRef.hpp line 241
0x400ee1c5: hsh_mainSocketEvent(AsyncWebSocket*, AsyncWebSocketClient*, AwsEventType, void*, unsigned char*, unsigned int) at lib/ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup/src/AsyncWebSocket.h line 138
0x401ab55b: std::_Function_handler ::_M_invoke(std::_Any_data const&, AsyncWebSocket*&&, AsyncWebSocketClient*&&, AwsEventType&&, void*&&, unsigned char*&&, unsigned int&&) at c:\users\pc\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h line 88
0x401abb55: AsyncWebSocket::_handleEvent(AsyncWebSocketClient*, AwsEventType, void*, unsigned char*, unsigned int) at c:\users\pc\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h line 682
0x400f8d72: AsyncWebSocketClient::_onData(void*, unsigned int) at lib/ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup/src/AsyncWebSocket.cpp line 563
0x400f8d99: std::_Function_handler   >::_M_invoke(const std::_Any_data &, void *&&, AsyncClient *&&, void *&&, unsigned int &&) at lib/ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup/src/AsyncWebSocket.cpp line 272

[Solved] Append to file after removing last character from previous write or append

I am using your excellent library and everything works as expected except when I try to append I wanted to remove last character from previous append and it is not happening.

My code is below:

#include <Arduino.h>
#include "LITTLEFS.h"

void setup() {
  Serial.begin(112500);
  delay(1000);

  LITTLEFS.begin(true);
  File f = LITTLEFS.open("/test.json", "w");
  f.println("[1623287518,24785,1535,15,6,-22,292,49,89,250,76]");
  f.close();
  Serial.println("Wrote first line to file");

  f = LITTLEFS.open("/test.json", "a");
  Serial.print("File size: "); Serial.println(f.size());
  f.seek((f.size() - 1), SeekSet);
  Serial.print("Position: "); Serial.println(f.position());
  f.println(",1623287518,24785,1535,15,6,-22,292,49,89,250,76]");
  Serial.println();
  Serial.println("Appended to file");
  Serial.print("File size: "); Serial.println(f.size());
  f.close();
   
  f = LITTLEFS.open("/test.json", "r");
  Serial.println("Reading from file...");
  while(f.available()){
  Serial.write(f.read());
  }
 f.close();
}

void loop() {}

And result I get is below:

Wrote first line to file
File size: 51
Position: 50

Appended to file
File size: 51
Reading from file...
[1623287518,24785,1535,15,6,-22,292,49,89,250,76]
,1623287518,24785,1535,15,6,-22,292,49,89,250,76]

But result I wanted to see was below:

[1623287518,24785,1535,15,6,-22,292,49,89,250,76
,1623287518,24785,1535,15,6,-22,292,49,89,250,76]

May be I am doing it all wrong.

Can you show me the right way to do it?

Thanks.

Feature request: support multiple SPIFFs partitions

I'm working on a project where I need to store webpages and settings/logs in a permanent storage. And over time I need to update the webpages, but not the settings and logs (which are device-dependent).

If I use the current implementation of LittleFS, when I perform a web pages OTA update of the SPIFFS, I will lose the settings. I can work around it by temporarily storing all settings in memory, unmounting the SPIFFS, performing OTA update, remounting the SPIFFS and finally restoring the settings. But would be problematic to do the same for the logs.

Would be great if LittleFS provided a way to support multiple SPIFFS partitions, so that I could independently update them

Seek mode "SeekEnd" attempts to read outside of file

First off all, thank you so much @lorol for making the best embedded FS easily usable on ESP32! It's highly appreciated :)

I've ran into a problem with the seek() function, specifically in SeekEnd mode. It doesn't set the position correctly and attempting to read just causes 255 to be read. On closer inspection it seems like SeekEnd takes the file end and adds the offset to it (instead of subtracting), thus setting the position outsite the file. I would have tried setting a negative offset, but the seek() function only takes an unsigned integer.

Should it matter, this is with CONFIG_LITTLEFS_FOR_IDF_3_2 defined to enable support for the current ESP32 core release 1.0.4.

MCVE

#include <Arduino.h>
#include "LITTLEFS.h"

void printChar(char r) {
  Serial.print(r);
  Serial.print(" (");
  Serial.print((byte)r);
  Serial.println(")");
}

void setup() {
  Serial.begin(112500);
  delay(2000);

  LITTLEFS.begin(true);
  File f = LITTLEFS.open("/test.txt", "w");
  f.print("test1234");
  f.close();
  Serial.println("Wrote file.");

  f = LITTLEFS.open("/test.txt", "r");
  uint32_t fsize = f.size();

  //this is very inefficient, for demo purposes only
  Serial.println("Reading with SeekSet");
  Serial.print("File size ");
  Serial.println(f.size());
  for (int i = 0; i < fsize; i++) {
    f.seek(i,SeekSet);
    Serial.print("pos ");
    Serial.print(f.position());
    Serial.print(" --> ");
    
    printChar(f.read());
  }

  Serial.println("Reading with SeekEnd");
  for (int i = 1; i < fsize + 1; i++) {
    f.seek(i,SeekEnd);
    Serial.print("pos ");
    Serial.print(f.position());
    Serial.print(" --> ");

    printChar(f.read());
  }

}

void loop() {

}

Output

Wrote file.
Reading with SeekSet
File size 8
pos 0 --> t (116)
pos 1 --> e (101)
pos 2 --> s (115)
pos 3 --> t (116)
pos 4 --> 1 (49)
pos 5 --> 2 (50)
pos 6 --> 3 (51)
pos 7 --> 4 (52)
Reading with SeekEnd
pos 9 --> � (255)
pos 10 --> � (255)
pos 11 --> � (255)
pos 12 --> � (255)
pos 13 --> � (255)
pos 14 --> � (255)
pos 15 --> � (255)
pos 16 --> � (255)

For reference, the correct output from the ESP8266 version of LittleFS

Wrote file.
Reading with SeekSet
File size 8
pos 0 --> t (116)
pos 1 --> e (101)   
pos 2 --> s (115)   
pos 3 --> t (116)   
pos 4 --> 1 (49)    
pos 5 --> 2 (50)
pos 6 --> 3 (51)
pos 7 --> 4 (52)
Reading with SeekEnd
pos 7 --> 4 (52)
pos 6 --> 3 (51)
pos 5 --> 2 (50)
pos 4 --> 1 (49)
pos 3 --> t (116)
pos 2 --> s (115)
pos 1 --> e (101)
pos 0 --> t (116)

LITTLEFSimpl::exists() bug with Platformio (ESP32 arduino framework) in Visual Studio Code

Compiling .pio/build/esp32dev/lib63a/LittleFS_esp32/LITTLEFS.cpp.o
.pio/libdeps/esp32dev/LittleFS_esp32/src/LITTLEFS.cpp: In member function 'virtual bool LITTLEFSImpl::exists(const char*)':
.pio/libdeps/esp32dev/LittleFS_esp32/src/LITTLEFS.cpp:44:28: error: no matching function for call to 'LITTLEFSImpl::open(const char*&, const char [2])'
     File f = open(path, "r");
In file included from .pio/libdeps/esp32dev/LittleFS_esp32/src/LITTLEFS.cpp:17:
/home/hari/.platformio/packages/framework-arduinoespressif32/libraries/FS/src/vfs_api.h:38:17: note: candidate: 'virtual fs::FileImplPtr VFSImpl::open(const char*, const char*, bool)'
     FileImplPtr open(const char* path, const char* mode, const bool create) override;
                 ^~~~
/home/hari/.platformio/packages/framework-arduinoespressif32/libraries/FS/src/vfs_api.h:38:17: note:   candidate expects 3 arguments, 2 provided
*** [.pio/build/esp32dev/lib63a/LittleFS_esp32/LITTLEFS.cpp.o] Error 1

Fixed by adding third argument
File f = open(path, "r", false);

ESP32 restarts if route exist but file dont with async webserver.

If i request a webpage with defined route like this:

server.on("/devicesTable", HTTP_GET, [](AsyncWebServerRequest *request) {
    AsyncWebServerResponse* response = request->beginResponse(LITTLEFS, "/hwConfig.html", "text/html");
    response->addHeader("Content-Encoding", "gzip");
    request->send(response);
});

but the files does not exists in the filesystem, the esp restarts with the following serial message:

E (3608859) esp_littlefs: Failed to opendir "/hwConfig.html". Error  (-2)
E (3608873) esp_littlefs: Failed to opendir "/hwConfig.html.gz". Error  (-2)
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.        
Core 1 register dump:
PC      : 0x400d52df  PS      : 0x00060930  A0      : 0x800ee1bf  A1      : 0x3ffd7150  
A2      : 0x00000000  A3      : 0x3ffc7b78  A4      : 0x3ffe3220  A5      : 0x195f9cbd    
A6      : 0x0000000d  A7      : 0x00000000  A8      : 0x800d52d9  A9      : 0x3ffd7130  
A10     : 0x3ffd716c  A11     : 0x3f4006f2  A12     : 0x195f9cbd  A13     : 0x3ffc7b78    
A14     : 0x00000000  A15     : 0x3ffd716c  SAR     : 0x00000004  EXCCAUSE: 0x0000001c    
EXCVADDR: 0x00000000  LBEG    : 0x4008cc35  LEND    : 0x4008cc45  LCOUNT  : 0xfffffffb    

ELF file SHA256: 0000000000000000

Backtrace: 0x400d52df:0x3ffd7150 0x400ee1bc:0x3ffd71a0 0x400ebb29:0x3ffd71f0 0x400ebbfa:0x3ffd7230 0x400ebe71:0x3ffd7280 0x400e59e2:0x3ffd72a0 0x400e5a79:0x3ffd72e0 0x400e61ea:0x3ffd7300 0x4008e89a:0x3ffd7330
  #0  0x400d52df:0x3ffd7150 in std::_Function_handler<void (AsyncWebServerRequest*), HTTP_Requests()::{lambda(AsyncWebServerRequest*)#4}>::_M_invoke(std::_Any_data const&, AsyncWebServerRequest*&&) at src/Own_Headers/ModBus.h:365 (discriminator 2)
  #1  0x400ee1bc:0x3ffd71a0 in AsyncWebServer::_rewriteRequest(AsyncWebServerRequest*) at 
lib\ESPAsyncWebServer-dev\src/StringArray.h:73
  #2  0x400ebb29:0x3ffd71f0 in std::function<void (AsyncWebHeader* const&)>::function(std::function<void (AsyncWebHeader* const&)> const&) at lib\ESPAsyncWebServer-dev\src/WebRequest.cpp:806
      (inlined by) LinkedList<AsyncWebHeader*, LinkedListNode>::LinkedList(std::function<void (AsyncWebHeader* const&)>) at lib\ESPAsyncWebServer-dev\src/StringArray.h:64
      (inlined by) AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer*, AsyncClient*) at lib\ESPAsyncWebServer-dev\src/WebRequest.cpp:70
  #3  0x400ebbfa:0x3ffd7230 in AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer*, AsyncClient*) at lib\ESPAsyncWebServer-dev\src/WebRequest.cpp:806
  #4  0x400ebe71:0x3ffd7280 in LinkedList<AsyncWebParameter*, LinkedListNode>::free() at lib\ESPAsyncWebServer-dev\src/WebRequest.cpp:806
      (inlined by) AsyncWebServerRequest::~AsyncWebServerRequest() at lib\ESPAsyncWebServer-dev\src/WebRequest.cpp:83
  #5  0x400e59e2:0x3ffd72a0 in std::function<void (void*, AsyncClient*)>::~function() at 
lib\AsyncTCP-Fix_-111\src/AsyncTCP.cpp:1080
      (inlined by) AsyncClient::~AsyncClient() at lib\AsyncTCP-Fix_-111\src/AsyncTCP.cpp:596
  #6  0x400e5a79:0x3ffd72e0 in AsyncClient::_s_fin(void*, tcp_pcb*, signed char) at lib\AsyncTCP-Fix_-111\src/AsyncTCP.cpp:1080
  #7  0x400e61ea:0x3ffd7300 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) at C:\Users\Pc\.platformio\packages\framework-arduinoespressif32\libraries\FS\src/FS.cpp:258
      (inlined by) std::__shared_ptr<fs::FileImpl, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<fs::FileImpl, (__gnu_cxx::_Lock_policy)2> const&) at c:\users\pc\.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0\bits/shared_ptr_base.h:923
      (inlined by) std::shared_ptr<fs::FileImpl>::shared_ptr(std::shared_ptr<fs::FileImpl> const&) at c:\users\pc\.platformio\packages\toolchain-xtensa32\xtensa-esp32-elf\include\c++\5.2.0\bits/shared_ptr.h:107
      (inlined by) fs::File::File(std::shared_ptr<fs::FileImpl>) at C:\Users\Pc\.platformio\packages\framework-arduinoespressif32\libraries\FS\src/FS.h:50
  #8  0x4008e89a:0x3ffd7330 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1) 

Rebooting...
ets Jul 29 2019 12:21:46

I have an onNotFound handler too and the "NotFound.html" does exists on the filesystem.

server.onNotFound([](AsyncWebServerRequest *request){
    AsyncWebServerResponse* response = request->beginResponse(LITTLEFS, "/NotFound.html", "text/html");
    response->addHeader("Content-Encoding", "gzip");
    request->send(response);
 });

Should i check every file on the route before adding it to the response like this?

server.on("/devicesTable", HTTP_GET, [](AsyncWebServerRequest *request) {
    String path = "/hwConfig.html";
    if( !LITTLEFS.exists(path) ) { path = "/NotFound.html" }
    AsyncWebServerResponse* response = request->beginResponse(LITTLEFS, "/hwConfig.html", "text/html");
    response->addHeader("Content-Encoding", "gzip");
    request->send(response);
});

I could do that but i think its a workaround:

static const inline String checkPath(String path){
  if( LITTLEFS.exists(path) ){ return path; }
  return "/NotFound.html";
}

server.on("/devicesTable", HTTP_GET, [](AsyncWebServerRequest *request) {
    AsyncWebServerResponse* response = request->beginResponse(LITTLEFS, checkPath("/hwConfig.html"), "text/html");
    response->addHeader("Content-Encoding", "gzip");
    request->send(response);
});

crash on file upload

esp8266 hosts a webserver.
LittleFS serves file "upload.html"
client submits file to "/upload"
LittleFS handles the file and writes it chunk by chunk but throws and exception at random progress.
I use nothing more than example code (see screenshots below), yet it is not reliable and crashes 8 times out of 10. Why? Stack trace below + relevant sketch.
Thanks

https://i.imgur.com/ccrifNo.png
https://i.imgur.com/xXBFVf3.png

edit: same potatoe behavior occured with SPIFFS lib. Upgraded to LittleFS for this very reason but it's not any better.

arduino-esp32fs-plugin upload fails...

arduino-esp32fs-plugin doesn't allow posting issues, so it's here. esptool.py can fail uploading some images when compression is used. Might want to add --no-compress when calling it. Unfortunately, they don't offer a configurable timeout. More info here.

Porting issues

Some months ago I started a new development on ESP8266, and following various guide lines I started with LittleFS, the new only now supported file system. Perfect.
I discover now that LittleFS is beeing integrated now in ESP32 core. Perfect. And so I tried to port my project on ESP32, using https://github.com/lorol/LITTLEFS and fall into some frustrating incompatibility / porting issues:
- no dir / openDir support
- change in   .info / totalBytes / usedBytes support
- file name must start with "/"
- no file.fileName() support

I discovered that most of these issues are wellknown.
Of course I found here some links and helps dealing with these issues and we can play with some #ifdef ESP32  but the code become soon obfuscated and cryptic.
I admit that ESP8266 and ESP32 are different platforms, but maybe not that much for a simple user playing with basic filesystem application, at "high level"  far from bit and bytes. 
LittleFS being pusched as the new "standard" I would espect a bit more high level compatibility for basic users.
Or just name this new filesystem for ESP32 with a different name.

On the other hand: congratulation for your work and implication

LittleFS unresponsive under many simultaneous .open() / read() for the same file

Hi,

I have a project using AsyncWebServer in a captive portal mode and sending all requests to /index.html.
When I connect my PC to the ESP32 wifi, it generates many random requests that all ends up in requests for /index.html (captive portal).
On SPIFFS I had no issues to get these requests served (the file itself is very small).
After moving to LittleFS, AsyncWebServer sends the header but cannot send the file content and the page hangs.
If I replace the automatic redirect to /index.html by a 404, /index.html get served without any issue when I request it.

I did not dig in LittleFS_esp32 code too much, but I see it is using semaphores. Could there be a race condition when multiple open() / read() requests come at the same time?

Can't compile on Arduino 1.8.13

Message is:
~/Documents/Arduino/libraries/LittleFS_esp32-1.0.5/src/LITTLEFS.h:17:10: fatal error: FS.h: No such file or directory
#include "FS.h"
Which version do I need to compile?

Cant delete files inside dir

Hi,
I want to use this library but I have problem delete files from specific directory.
Can someone help?
What I am doing wrong?
here is code example:


#include "FS.h"                                                              
#include "LITTLEFS.h"

void setup() {
  Serial.flush();                                                             
  Serial.begin( 115200 );                                                    
  delay(1000);

  LITTLEFS.format();
  if (!LITTLEFS.begin(true)) {                                                
    Serial.println(F("An Error has occurred while mounting LITTLEFS"));       
    return;
  }
  Serial.println( F("LITTLEFS test started... ")) ;                          
 
  if ( !LITTLEFS.exists("/DIR1" ) ) {
    Serial.println( " dir /DIR1 does not exist! ");
    if ( LITTLEFS.mkdir( "/DIR1" ) ) Serial.println( " dir /DIR1 is created ");
    else Serial.println( " dir /DIR create failed");
  } else {
    Serial.println( " dir /DIR1 allready exist...");
  }
  test( "hello", 5 );
  
  Serial.println( F("LITTLEFS test end")) ;                         

}

void loop() {

}

void test( String message, int cnt ) {
  for ( int i = 0; i < cnt; i++ ) {
    File f = LITTLEFS.open("/DIR1/file" + String(i) + ".txt", "w+");        
    if ( f ) {                                                                               
      f.print( message );
      f.close();
    }
  }
  listDir( "/", 1 );
  
  LITTLEFS.rmdir("/DIR1");
  File root = LITTLEFS.open("/DIR1");
  File file;
  while ( file = root.openNextFile() ) {
    file.close();
    if ( !LITTLEFS.remove(file.name()) ) {
      Serial.println( "remove failed" );
    }
  }

  listDir( "/", 1 );
}

void listDir(const char * dirname, int levels ) {
  Serial.printf("Listing directory: %s\r\n", dirname);
  File root = LITTLEFS.open(dirname);
  if (!root) {
    Serial.println("- failed to open directory");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println(" - not a directory");
    return;
  }
  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if (levels) {
        listDir( file.name(), levels - 1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("\tSIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

and here is output, files stay inside directory

LITTLEFS test started... 
 dir /DIR1 does not exist! 
 dir /DIR1 is created 
Listing directory: /
  DIR : /DIR1
Listing directory: /DIR1
  FILE: /DIR1/file0.txt	SIZE: 5
  FILE: /DIR1/file1.txt	SIZE: 5
  FILE: /DIR1/file2.txt	SIZE: 5
  FILE: /DIR1/file3.txt	SIZE: 5
  FILE: /DIR1/file4.txt	SIZE: 5
remove failed
remove failed
remove failed
remove failed
remove failed
Listing directory: /
  DIR : /DIR1
Listing directory: /DIR1
  FILE: /DIR1/file0.txt	SIZE: 5
  FILE: /DIR1/file1.txt	SIZE: 5
  FILE: /DIR1/file2.txt	SIZE: 5
  FILE: /DIR1/file3.txt	SIZE: 5
  FILE: /DIR1/file4.txt	SIZE: 5
LITTLEFS test end

Thank you

Linking fails with ESP32-C3 latest Arduino git (IDF4.4 riscv32 toolchain)

Like LITTLEFS a lot. Works great with ESP32 :-)

Trying to build with the ESP32-C3 fails with linking error (using included LITTLEFS lib in Arduino):

c:/users/hans/.platformio/packages/toolchain-riscv32/bin/../lib/gcc/riscv32-esp-elf/8.4.0/../../../../riscv32-esp-elf/bin/ld.exe: C:\Users\Hans\.platformio\packages\framework-arduinoespressif32@src-334b65656024015419a5766890f3216e\tools\sdk\esp32c3\lib\libesp_littlefs.a(esp_littlefs.c.obj): in function `esp_littlefs_init':
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/build/../components/esp_littlefs/src/esp_littlefs.c:492: undefined reference to `g_rom_flashchip'
c:/users/hans/.platformio/packages/toolchain-riscv32/bin/../lib/gcc/riscv32-esp-elf/8.4.0/../../../../riscv32-esp-elf/bin/ld.exe: /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/build/../components/esp_littlefs/src/esp_littlefs.c:492: undefined reference to `g_rom_flashchip'

THX!

Recursive delete of directory does not work as expected on LittleFS

Deltree.ino.txt

The attached Arduino sketch compiled for ESP32 fails to recursively delete a directory. When executed on an SD_MMC FAT filesystem the directory is succesfully removed.
When built with debug the following messages are shown :

/testdir/sub1 is a directory
E (1507) esp_littlefs: Failed to unlink path "/testdir/sub1/vier.txt". Has open FD.
result of removing file /testdir/sub1/vier.txt: 0
E (1539) esp_littlefs: Failed to unlink path "/testdir/sub1/vijf.txt". Has open FD.
result of removing file /testdir/sub1/vijf.txt: 0
E (1570) esp_littlefs: Failed to unlink path "/testdir/sub1/zes.txt". Has open FD.
result of removing file /testdir/sub1/zes.txt: 0
result of removing directory /testdir/sub1: 0

Is this a bug? Should I use another method to remove a directory tree?

Need to call close while listing files in SPIFFS with openNextFile

Hi,

I've been taking a look at the LITTLEFS example LittleFS_test.ino, in particular to the listDir function.

I've noticed that the procedure doesn't make any call to the close method. It just keeps calling the openNextFile method until there are no more files available.

Isn't a call to the close method needed to make sure no resources are left hanging?

Regards

LITTLEFSFS::begin() unexpected behavior

Relatively minor issue. The code behaves as expected, but doesn't return the right value

I used the following code in the setup() part of my project

  // Format SPIFFS if not yet
  if (!FileFS.begin(true))
  {
    Serial.println(F("Init failed! AutoFormatting."));
  }

I expected to see the "Init failed! AutoFormatting." message on my terminal window, instead I get

lib\LittleFS_esp32\lfs.c:998:error: Corrupted dir pair at {0x0, 0x1}
E (230) esp_littlefs: mount failed,  (-84)
E (234) esp_littlefs: Failed to initialize LittleFS

It actually auto-formats the SPIFFS partition, just doesn't return false, so the code doesn't know it's been auto formatted. In some cases, the code needs to know if the SPIFFS area has been auto formatted, so would be nice to fix

Creating lfs_config to use lfs_file_write() to write to file (help wanted)

Hello, After doing a bit of reading over the source code, I'd like to use the lfs_file_write() function from lfs.c to write to file because it handles caching a buffer for me to reduce writes to flash. I am trying to create a lfs_config struct but cannot figure out some fields.

const struct lfs_config cfg = {
    // block device operations
    .read  = user_provided_block_device_read,
    .prog  = user_provided_block_device_prog,
    .erase = user_provided_block_device_erase,
    .sync  = user_provided_block_device_sync,

I am not sure how to ago about filling .read .prog .erase .sync . I see that in in esp_littlefs.c

        // block device operations
        efs->cfg.read  = littlefs_api_read;
        efs->cfg.prog  = littlefs_api_prog;
        efs->cfg.erase = littlefs_api_erase;
        efs->cfg.sync  = littlefs_api_sync;

littlefs_api is used but I get a ton of errors like:
src\main.cpp:61:1: sorry, unimplemented: non-trivial designated initializers not supported
when trying to implement something similar. Any help would be much appreciated!

'Dir' was not declared in this scope

#include <Arduino.h>
#include <FS.h>
#include <LITTLEFS.h>
#include <esp_int_wdt.h>
#include <esp_task_wdt.h>
#include <esp32-hal-cpu.h>
#include <stdlib.h>
void setup() {
  Dir dir = fs.open("/");
}

The Arduino compiler throws 'Dir' was not declared in this scope. Is there any other way I can list all the files in a directory?

problem for first startup after flashing only firmware

hello and thank you so much for your rich contribution
i am having a problem when i first flash a firmware ( not the partition image )
the thing is: each time i flash a new firmware to the flash, i cant get the littlefs working in the first boot without a hardware reset , not for read/write/ nor format
to produce the problem :

  • erase the flash
  • flash firmware and partition table
  • ( flash partition image or not : same result)
    the only solution is to boot the firmware once: ( the little fs tries to format and fails), (tried to make software reboot via esp_restart and didnt work out) then do a hardware reset via the button . although i had something similar to this in SPIFFS (couldnt resolve it) before changing to LittleFS.
    here is the log where the firmware tries to format and access littlefs partition and force reboot when fails, until i do a hardware reset and then it works like a charm ! :
    any idea ?

rst:0xc (SW_CPU_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7192
load:0x40078000,len:13100
load:0x40080400,len:3896
entry 0x40080688
␛[0;32mI (29) boot: ESP-IDF 3.40100.200827 2nd stage bootloader␛[0m
␛[0;32mI (29) boot: compile time 09:19:17␛[0m
␛[0;32mI (29) boot: chip revision: 3␛[0m
␛[0;32mI (33) boot_comm: chip revision: 3, min. bootloader chip revision: 0␛[0m
␛[0;32mI (40) boot.esp32: SPI Speed : 40MHz␛[0m
␛[0;32mI (44) boot.esp32: SPI Mode : DIO␛[0m
␛[0;32mI (49) boot.esp32: SPI Flash Size : 16MB␛[0m
␛[0;32mI (54) boot: Enabling RNG early entropy source...␛[0m
␛[0;32mI (59) boot: Partition Table:␛[0m
␛[0;32mI (63) boot: ## Label Usage Type ST Offset Length␛[0m
␛[0;32mI (70) boot: 0 nvs WiFi data 01 02 00009000 00006000␛[0m
␛[0;32mI (77) boot: 1 phy_init RF data 01 01 0000f000 00001000␛[0m
␛[0;32mI (85) boot: 2 factory factory app 00 00 00010000 00100000␛[0m
␛[0;32mI (92) boot: 3 ota_0 OTA app 00 10 00110000 00100000␛[0m
␛[0;32mI (100) boot: 4 ota_1 OTA app 00 11 00210000 00100000␛[0m
␛[0;32mI (107) boot: 5 wifi1 Unknown data 01 82 00310000 00100000␛[0m
␛[0;32mI (115) boot: End of partition table␛[0m
␛[0;32mI (119) boot_comm: chip revision: 3, min. application chip revision: 0␛[0m
␛[0;32mI (126) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x083b0 ( 33712) map␛[0m
␛[0;32mI (148) esp_image: segment 1: paddr=0x000183d8 vaddr=0x3ffb0000 size=0x021dc ( 8668) load␛[0m
␛[0;32mI (152) esp_image: segment 2: paddr=0x0001a5bc vaddr=0x40080000 size=0x00404 ( 1028) load␛[0m
␛[0;32mI (156) esp_image: segment 3: paddr=0x0001a9c8 vaddr=0x40080404 size=0x05650 ( 22096) load␛[0m
␛[0;32mI (174) esp_image: segment 4: paddr=0x00020020 vaddr=0x400d0020 size=0x22530 (140592) map␛[0m
␛[0;32mI (228) esp_image: segment 5: paddr=0x00042558 vaddr=0x40085a54 size=0x04790 ( 18320) load␛[0m
␛[0;32mI (242) boot: Loaded app from partition at offset 0x10000␛[0m
␛[0;32mI (242) boot: Disabling RNG early entropy source...␛[0m
␛[0;32mI (242) cpu_start: Pro cpu up.␛[0m
␛[0;32mI (246) cpu_start: Application information:␛[0m
␛[0;32mI (251) cpu_start: Project name: draft␛[0m
␛[0;32mI (255) cpu_start: App version: 6d88366-dirty␛[0m
␛[0;32mI (261) cpu_start: Compile time: Sep 22 2020 09:18:26␛[0m
␛[0;32mI (267) cpu_start: ELF file SHA256: 5a1f2dd8a49c75c6...␛[0m
␛[0;32mI (273) cpu_start: ESP-IDF: 3.40100.200827␛[0m
␛[0;32mI (278) cpu_start: Starting app cpu, entry point is 0x40081040␛[0m
␛[0;32mI (271) cpu_start: App cpu up.␛[0m
␛[0;32mI (289) heap_init: Initializing. RAM available for dynamic allocation:␛[0m
␛[0;32mI (296) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM␛[0m
␛[0;32mI (302) heap_init: At 3FFB2A70 len 0002D590 (181 KiB): DRAM␛[0m
␛[0;32mI (308) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM␛[0m
␛[0;32mI (315) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM␛[0m
␛[0;32mI (321) heap_init: At 4008A1E4 len 00015E1C (87 KiB): IRAM␛[0m
␛[0;32mI (327) cpu_start: Pro cpu start user code␛[0m
␛[0;32mI (345) spi_flash: detected chip: gd␛[0m
␛[0;32mI (346) spi_flash: flash io: dio␛[0m
␛[0;32mI (346) cpu_start: Starting scheduler on PRO CPU.␛[0m
␛[0;32mI (0) cpu_start: Starting scheduler on APP CPU.␛[0m
␛[0;32mI (6559) SPIFFS wifi1: mounting SPIFFS partition wifi1....␛[0m
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:998:error: Corrupted dir pair at {0x0, 0x1}
␛[0;33mW (6567) esp_littlefs: mount failed, (-84). formatting...␛[0m
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1685:debug: Bad block at 0x0
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1691:warn: Superblock 0x0 has become unwritable
␛[0;31mE (6598) esp_littlefs: Failed to format filesystem␛[0m
␛[0;31mE (6603) esp_littlefs: format failed␛[0m
␛[0;31mE (6607) esp_littlefs: Failed to initialize LittleFS␛[0m
␛[0;33mW (6613) SPIFFS wifi1: Failed to mount ..formatting ␛[0m
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1685:debug: Bad block at 0x0
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1691:warn: Superblock 0x0 has become unwritable
␛[0;31mE (6643) esp_littlefs: Failed to format filesystem␛[0m
␛[0;31mE (6649) SPIFFS wifi1: Mount and format Failed ,check partition table...rebooting : this might be the first firmware boot after erase...␛[0m
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7192
load:0x40078000,len:13100
load:0x40080400,len:3896
entry 0x40080688
␛[0;32mI (29) boot: ESP-IDF 3.40100.200827 2nd stage bootloader␛[0m
␛[0;32mI (29) boot: compile time 09:19:17␛[0m
␛[0;32mI (29) boot: chip revision: 3␛[0m
␛[0;32mI (33) boot_comm: chip revision: 3, min. bootloader chip revision: 0␛[0m
␛[0;32mI (40) boot.esp32: SPI Speed : 40MHz␛[0m
␛[0;32mI (44) boot.esp32: SPI Mode : DIO␛[0m
␛[0;32mI (49) boot.esp32: SPI Flash Size : 16MB␛[0m
␛[0;32mI (54) boot: Enabling RNG early entropy source...␛[0m
␛[0;32mI (59) boot: Partition Table:␛[0m
␛[0;32mI (63) boot: ## Label Usage Type ST Offset Length␛[0m
␛[0;32mI (70) boot: 0 nvs WiFi data 01 02 00009000 00006000␛[0m
␛[0;32mI (77) boot: 1 phy_init RF data 01 01 0000f000 00001000␛[0m
␛[0;32mI (85) boot: 2 factory factory app 00 00 00010000 00100000␛[0m
␛[0;32mI (92) boot: 3 ota_0 OTA app 00 10 00110000 00100000␛[0m
␛[0;32mI (100) boot: 4 ota_1 OTA app 00 11 00210000 00100000␛[0m
␛[0;32mI (107) boot: 5 wifi1 Unknown data 01 82 00310000 00100000␛[0m
␛[0;32mI (115) boot: End of partition table␛[0m
␛[0;32mI (119) boot_comm: chip revision: 3, min. application chip revision: 0␛[0m
␛[0;32mI (126) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x083b0 ( 33712) map␛[0m
␛[0;32mI (148) esp_image: segment 1: paddr=0x000183d8 vaddr=0x3ffb0000 size=0x021dc ( 8668) load␛[0m
␛[0;32mI (152) esp_image: segment 2: paddr=0x0001a5bc vaddr=0x40080000 size=0x00404 ( 1028) load␛[0m
␛[0;32mI (156) esp_image: segment 3: paddr=0x0001a9c8 vaddr=0x40080404 size=0x05650 ( 22096) load␛[0m
␛[0;32mI (174) esp_image: segment 4: paddr=0x00020020 vaddr=0x400d0020 size=0x22530 (140592) map␛[0m
␛[0;32mI (228) esp_image: segment 5: paddr=0x00042558 vaddr=0x40085a54 size=0x04790 ( 18320) load␛[0m
␛[0;32mI (242) boot: Loaded app from partition at offset 0x10000␛[0m
␛[0;32mI (242) boot: Disabling RNG early entropy source...␛[0m
␛[0;32mI (242) cpu_start: Pro cpu up.␛[0m
␛[0;32mI (246) cpu_start: Application information:␛[0m
␛[0;32mI (251) cpu_start: Project name: draft␛[0m
␛[0;32mI (255) cpu_start: App version: 6d88366-dirty␛[0m
␛[0;32mI (261) cpu_start: Compile time: Sep 22 2020 09:18:26␛[0m
␛[0;32mI (267) cpu_start: ELF file SHA256: 5a1f2dd8a49c75c6...␛[0m
␛[0;32mI (273) cpu_start: ESP-IDF: 3.40100.200827␛[0m
␛[0;32mI (278) cpu_start: Starting app cpu, entry point is 0x40081040␛[0m
␛[0;32mI (271) cpu_start: App cpu up.␛[0m
␛[0;32mI (289) heap_init: Initializing. RAM available for dynamic allocation:␛[0m
␛[0;32mI (296) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM␛[0m
␛[0;32mI (302) heap_init: At 3FFB2A70 len 0002D590 (181 KiB): DRAM␛[0m
␛[0;32mI (308) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM␛[0m
␛[0;32mI (315) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM␛[0m
␛[0;32mI (321) heap_init: At 4008A1E4 len 00015E1C (87 KiB): IRAM␛[0m
␛[0;32mI (327) cpu_start: Pro cpu start user code␛[0m
␛[0;32mI (345) spi_flash: detected chip: gd␛[0m
␛[0;32mI (346) spi_flash: flash io: dio␛[0m
␛[0;32mI (346) cpu_start: Starting scheduler on PRO CPU.␛[0m
␛[0;32mI (0) cpu_start: Starting scheduler on APP CPU.␛[0m
␛[0;32mI (6559) SPIFFS wifi1: mounting SPIFFS partition wifi1....␛[0m
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:998:error: Corrupted dir pair at {0x0, 0x1}
␛[0;33mW (6567) esp_littlefs: mount failed, (-84). formatting...␛[0m
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1685:debug: Bad block at 0x0
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1691:warn: Superblock 0x0 has become unwritable
␛[0;31mE (6598) esp_littlefs: Failed to format filesystem␛[0m
␛[0;31mE (6603) esp_littlefs: format failed␛[0m
␛[0;31mE (6607) esp_littlefs: Failed to initialize LittleFS␛[0m
␛[0;33mW (6613) SPIFFS wifi1: Failed to mount ..formatting ␛[0m
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1685:debug: Bad block at 0x0
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:1691:warn: Superblock 0x0 has become unwritable
␛[0;31mE (6643) esp_littlefs: Failed to format filesystem␛[0m
␛[0;31mE (6649) SPIFFS wifi1: Mount and format Failed ,check partition table...rebooting : this might be the first firmware boot after erase...␛[0m
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7192
load:0x40078000,len:13100
load:0x40080400,len:3896
entry 0x40080688
␛[0;32mI (29) boot: ESP-IDF 3.40100.200827 2nd stage bootloader␛[0m
␛[0;32mI (29) boot: compile time 09:19:17␛[0m
␛[0;32mI (29) boot: chip revision: 3␛[0m
␛[0;32mI (33) boot_comm: chip revision: 3, min. bootloader chip revision: 0␛[0m
␛[0;32mI (40) boot.esp32: SPI Speed : 40MHz␛[0m
␛[0;32mI (44) boot.esp32: SPI Mode : DIO␛[0m
␛[0;32mI (49) boot.esp32: SPI Flash Size : 16MB␛[0m
␛[0;32mI (54) boot: Enabling RNG early entropy source...␛[0m
␛[0;32mI (59) boot: Partition Table:␛[0m
␛[0;32mI (63) boot: ## Label Usage Type ST Offset Length␛[0m
␛[0;32mI (70) boot: 0 nvs WiFi data 01 02 00009000 00006000␛[0m
␛[0;32mI (77) boot: 1 phy_init RF data 01 01 0000f000 00001000␛[0m
␛[0;32mI (85) boot: 2 factory factory app 00 00 00010000 00100000␛[0m
␛[0;32mI (92) boot: 3 ota_0 OTA app 00 10 00110000 00100000␛[0m
␛[0;32mI (100) boot: 4 ota_1 OTA app 00 11 00210000 00100000␛[0m
␛[0;32mI (107) boot: 5 wifi1 Unknown data 01 82 00310000 00100000␛[0m
␛[0;32mI (115) boot: End of partition table␛[0m
␛[0;32mI (119) boot_comm: chip revision: 3, min. application chip revision: 0␛[0m
␛[0;32mI (126) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x083b0 ( 33712) map␛[0m
␛[0;32mI (148) esp_image: segment 1: paddr=0x000183d8 vaddr=0x3ffb0000 size=0x021dc ( 8668) load␛[0m
␛[0;32mI (152) esp_image: segment 2: paddr=0x0001a5bc vaddr=0x40080000 size=0x00404 ( 1028) load␛[0m
␛[0;32mI (156) esp_image: segment 3: paddr=0x0001a9c8 vaddr=0x40080404 size=0x05650 ( 22096) load␛[0m
␛[0;32mI (174) esp_image: segment 4: paddr=0x00020020 vaddr=0x400d0020 size=0x22530 (140592) map␛[0m
␛[0;32mI (228) esp_image: segment 5: paddr=0x00042558 vaddr=0x40085a54 size=0x04790 ( 18320) load␛[0m
␛[0;32mI (242) boot: Loaded app from partition at offset 0x10000␛[0m
␛[0;32mI (242) boot: Disabling RNG early entropy source...␛[0m
␛[0;32mI (242) cpu_start: Pro cpu up.␛[0m
␛[0;32mI (246) cpu_start: Application information:␛[0m
␛[0;32mI (251) cpu_start: Project name: draft␛[0m
␛[0;32mI (255) cpu_start: App version: 6d88366-dirty␛[0m
␛[0;32mI (261) cpu_start: Compile time: Sep 22 2020 09:18:26␛[0m
␛[0;32mI (267) cpu_start: ELF file SHA256: 5a1f2dd8a49c75c6...␛[0m
␛[0;32mI (273) cpu_start: ESP-IDF: 3.40100.200827␛[0m
␛[0;32mI (278) cpu_start: Starting app cpu, entry point is 0x40081040␛[0m
␛[0;32mI (271) cpu_start: App cpu up.␛[0m
␛[0;32mI (289) heap_init: Initializing. RAM available for dynamic allocation:␛[0m
␛[0;32mI (296) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM␛[0m
␛[0;32mI (302) heap_init: At 3FFB2A70 len 0002D590 (181 KiB): DRAM␛[0m
␛[0;32mI (308) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM␛[0m
␛[0;32mI (315) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM␛[0m
␛[0;32mI (321) heap_init: At 4008A1E4 len 00015E1C (87 KiB): IRAM␛[0m
␛[0;32mI (327) cpu_start: Pro cpu start user code␛[0m
␛[0;32mI (345) spi_flash: detected chip: gd␛[0m
␛[0;32mI (346) spi_flash: flash io: dio␛[0m
␛[0;32mI (346) cpu_start: Starting scheduler on PRO CPU.␛[0m
␛[0;32mI (0) cpu_start: Starting scheduler on APP CPU.␛[0m
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7192
load:0x40078000,len:13100
load:0x40080400,len:3896
entry 0x40080688
␛[0;32mI (29) boot: ESP-IDF 3.40100.200827 2nd stage bootloader␛[0m
␛[0;32mI (29) boot: compile time 09:19:17␛[0m
␛[0;32mI (29) boot: chip revision: 3␛[0m
␛[0;32mI (33) boot_comm: chip revision: 3, min. bootloader chip revision: 0␛[0m
␛[0;32mI (40) boot.esp32: SPI Speed : 40MHz␛[0m
␛[0;32mI (45) boot.esp32: SPI Mode : DIO␛[0m
␛[0;32mI (49) boot.esp32: SPI Flash Size : 16MB␛[0m
␛[0;32mI (54) boot: Enabling RNG early entropy source...␛[0m
␛[0;32mI (59) boot: Partition Table:␛[0m
␛[0;32mI (63) boot: ## Label Usage Type ST Offset Length␛[0m
␛[0;32mI (70) boot: 0 nvs WiFi data 01 02 00009000 00006000␛[0m
␛[0;32mI (77) boot: 1 phy_init RF data 01 01 0000f000 00001000␛[0m
␛[0;32mI (85) boot: 2 factory factory app 00 00 00010000 00100000␛[0m
␛[0;32mI (92) boot: 3 ota_0 OTA app 00 10 00110000 00100000␛[0m
␛[0;32mI (100) boot: 4 ota_1 OTA app 00 11 00210000 00100000␛[0m
␛[0;32mI (107) boot: 5 wifi1 Unknown data 01 82 00310000 00100000␛[0m
␛[0;32mI (115) boot: End of partition table␛[0m
␛[0;32mI (119) boot_comm: chip revision: 3, min. application chip revision: 0␛[0m
␛[0;32mI (126) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x083b0 ( 33712) map␛[0m
␛[0;32mI (148) esp_image: segment 1: paddr=0x000183d8 vaddr=0x3ffb0000 size=0x021dc ( 8668) load␛[0m
␛[0;32mI (152) esp_image: segment 2: paddr=0x0001a5bc vaddr=0x40080000 size=0x00404 ( 1028) load␛[0m
␛[0;32mI (156) esp_image: segment 3: paddr=0x0001a9c8 vaddr=0x40080404 size=0x05650 ( 22096) load␛[0m
␛[0;32mI (174) esp_image: segment 4: paddr=0x00020020 vaddr=0x400d0020 size=0x22530 (140592) map␛[0m
␛[0;32mI (228) esp_image: segment 5: paddr=0x00042558 vaddr=0x40085a54 size=0x04790 ( 18320) load␛[0m
␛[0;32mI (242) boot: Loaded app from partition at offset 0x10000␛[0m
␛[0;32mI (242) boot: Disabling RNG early entropy source...␛[0m
␛[0;32mI (242) cpu_start: Pro cpu up.␛[0m
␛[0;32mI (246) cpu_start: Application information:␛[0m
␛[0;32mI (251) cpu_start: Project name: draft␛[0m
␛[0;32mI (255) cpu_start: App version: 6d88366-dirty␛[0m
␛[0;32mI (261) cpu_start: Compile time: Sep 22 2020 09:18:26␛[0m
␛[0;32mI (267) cpu_start: ELF file SHA256: 5a1f2dd8a49c75c6...␛[0m
␛[0;32mI (273) cpu_start: ESP-IDF: 3.40100.200827␛[0m
␛[0;32mI (279) cpu_start: Starting app cpu, entry point is 0x40081040␛[0m
␛[0;32mI (0) cpu_start: App cpu up.␛[0m
␛[0;32mI (289) heap_init: Initializing. RAM available for dynamic allocation:␛[0m
␛[0;32mI (296) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM␛[0m
␛[0;32mI (302) heap_init: At 3FFB2A70 len 0002D590 (181 KiB): DRAM␛[0m
␛[0;32mI (308) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM␛[0m
␛[0;32mI (314) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM␛[0m
␛[0;32mI (321) heap_init: At 4008A1E4 len 00015E1C (87 KiB): IRAM␛[0m
␛[0;32mI (327) cpu_start: Pro cpu start user code␛[0m
␛[0;32mI (345) spi_flash: detected chip: gd␛[0m
␛[0;32mI (346) spi_flash: flash io: dio␛[0m
␛[0;32mI (346) cpu_start: Starting scheduler on PRO CPU.␛[0m
␛[0;32mI (0) cpu_start: Starting scheduler on APP CPU.␛[0m
␛[0;32mI (6559) SPIFFS wifi1: mounting SPIFFS partition wifi1....␛[0m
C:\Users\Rami_Domalys.platformio\packages\framework-espidf\components\esp_littlefs\src\littlefs\lfs.c:998:error: Corrupted dir pair at {0x0, 0x1}
␛[0;33mW (6567) esp_littlefs: mount failed, (-84). formatting...␛[0m
␛[0;32mI (6917) SPIFFS wifi1: Partition size: total: 1024.0 KB, used: 8.0 KB , free: 1016.0 KB␛[0m
␛[0;32mI (6919) SPIFFS wifi1: Active partition is set to :(wifi1)␛[0m
␛[0;32mI (6922) SPIFFS wifi1: Mount OK␛[0m
␛[0;32mI (6926) SPIFFS wifi1: Opening file /w/config1.txt for mode r ....␛[0m
␛[0;31mE (6934) SPIFFS wifi1: Failed to open file for r ␛[0m
␛[0;31mE (6938) WIFI Directory: No file found..␛[0m
␛[0;33mW (6943) WIFI Directory: Creating new file w/config1.txt .. ␛[0m
␛[0;32mI (6949) SPIFFS wifi1: Opening file /w/config1.txt for mode w+ ....␛[0m
␛[0;32mI (6963) SPIFFS wifi1: file /w/config1.txt is OPEN.␛[0m
␛[0;32mI (6963) WIFI Directory: file created succefully ...no entries over here, adding default entry ␛[0m
␛[0;32mI (6977) SPIFFS wifi1: File closed␛[0m
␛[0;32mI (6978) WIFI Directory: Entry with ssid : DOM_18DD7F is added␛[0m

THANKS IN ADVANCE

flash_utils.h not found error in ESP32

Hi, Thanks for the excellent library.

During compilation, I'm getting the error "LITTLEFS.h:34:25: fatal error: flash_utils.h: No such file or directory"

Can you help please.

Thanks in advance.

ESP32 - littlefs path prefix is added - works as designed ?

I'm using ESP Async [email protected] with lorol/LittleFS_esp32 @ ^1.0.5.
I moved my project from SPIFFS to LITTLEFS.
When I'm running ESP8266 code, paths are resolved correctly.
When I'm using ESP32 with LittleFS_esp32 library, it first tries to resolve paths starting with littlefs, for example:

get /folder/example.html
logs say:

/littlefs/folder/example/html does not exist
/littlefs/folder/example/html.gz does not exist
/littlefs/folder/example/html/index.html does not exist
/littlefs/folder/example/html/index.html.gz does not exist
...
OK fetch from /folder/example.html

Is there a configuration flag to specify prefix ?
Is this behavior as designed by Littlefs or i'm missing something ?

Question: frequently writing life span.

Hi, I have a question. I have a TinyPICO with 4MB of Flash acting as a client sending structured data at 24fps to a server PC through TCP, where the data is parsed and stored to a .CSV. I would like to create and store the data locally on the microcontrollers flash then FTP to the server. My question is with a write speed of 24 packets a second and one packet being ~32bytes, will that just kill the lifespan of the on board flash? Is there any work arounds like writing pages rather than lines?

Thanks.

Trouble fetching file from AsyncWebServer.

I have a file called data.json created by LittleFS on my AsyncWebServer. Now I am trying to fetch that file from index.html file in root of same domain using following:

fetch("data.json").then(r => r.json()).then(packed => {wait.textContent = "Rendering...";
				let data = prepData(packed);
				setTimeout(() => makeChart(data), 0);
			});

But it gives me following error message:

(index):640 GET http://192.168.0.9/data.json 500 (Internal Server Error)
(index):640 Fetch failed loading: GET "http://192.168.0.9/data.json".

Am I fetching the file from right directory ? Should I try different directory ?

In a sketch I defined file as "/data.json"

Thanks.

Tutorial missing - Use the built-in LITTLEFS library - how to use the library itself

Im wondering people creating good things for arduino/esp32 but if somebody try as beginner use these fail, because there is no tutorial, description/use case.

Without any description as beginner i have downloaded the library and added to my librarys, i got this errors:

C:\Users\X\Documents\Arduino\libraries\LittleFS_esp32\src\esp_littlefs.c:19:2: warning: #warning ("Use the built-in LITTLEFS library") [-Wcpp]

C:\Users\X\Documents\Arduino\libraries\LittleFS_esp32\src\LITTLEFS.cpp: In member function 'virtual bool LITTLEFSImpl::exists(const char*)':
C:\Users\X\Documents\Arduino\libraries\LittleFS_esp32\src\LITTLEFS.cpp:44:28: error: no matching function for call to 'LITTLEFSImpl::open(const char*&, const char [2])'
File f = open(path, "r");
^
In file included from C:\Users\X\Documents\Arduino\libraries\LittleFS_esp32\src\LITTLEFS.cpp:17:
C:\Users\X\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.2\libraries\FS\src/vfs_api.h:38:17: note: candidate: 'virtual fs::FileImplPtr VFSImpl::open(const char*, const char*, bool)'
FileImplPtr open(const char* path, const char* mode, const bool create) override;
^~~~
C:\Users\X\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.2\libraries\FS\src/vfs_api.h:38:17: note: candidate expects 3 arguments, 2 provided
exit status 1

Use the built-in LITTLEFS library - And?

Im sure need something todo before use, but im not sure without any tutorial.

Im using arduino ide version 1.8.12

Example code from the arduino ide forum:

#define dbg(myFixedText, variableName)
Serial.print( F(#myFixedText " " #variableName"=") );
Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval)
do {
static unsigned long intervalStartTime;
if ( millis() - intervalStartTime >= timeInterval ){
intervalStartTime = millis();
Serial.print( F(#myFixedText " " #variableName"=") );
Serial.println(variableName);
}
} while (false);

#include <FS.h>
#include <LITTLEFS.h>
#define FORMAT_LITTLEFS_IF_FAILED true

String MyEmail = "[email protected]";
String MyPassWord = "thereisnopassword";
String MySecret = "NUX007";

void prepareLittleFS() {
//Start LittleFS
if(!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
Serial.println("LITTLEFS Mount failed");
return;
}
writeDefaultData();
}

void readData() {
File file = LITTLEFS.open("/SavedFile.txt", "r");

if(!file){
Serial.println("No Saved Data!");
writeDefaultData();
Serial.println("writeDefaultData(); done");
}
while(file.available()){
MyEmail = file.readString();
dbg("FileRead:",MyEmail);

MyPassWord = file.readString();
dbg("FileRead:",MyPassWord);

MySecret   = file.readString(); 
dbg("FileRead:",MySecret);

}
file.close();
}

void writeDefaultData() {
File file = LITTLEFS.open("/SavedFile.txt", "w");

MyEmail = "[email protected]";
file.println(MyEmail);

dbg("file.println:",MyEmail);

MyPassWord = "enter_your_password";
file.println(MyPassWord);
dbg("file.println:",MyPassWord);

MySecret = "enter_your_secret";
file.println(MySecret);
dbg("file.println:",MySecret);
delay(1);

file.close();

Serial.println("Write successful");
}

void writeData() {
File file = LITTLEFS.open("/SavedFile.txt", "w");

file.println(MyEmail);
dbg("file.println:",MyEmail);

file.println(MyPassWord);
dbg("file.println:",MyPassWord);

file.println(MySecret);
dbg("file.println:",MySecret);
delay(1);

file.close();

Serial.println("Write successful");
}

void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(FILE) );;
Serial.print( F(" compiled ") );
Serial.print( F(DATE) );
Serial.print( F(" ") );
Serial.println( F(TIME) );
}

void setup() {
Serial.begin(115200);
Serial.println();
Serial.println( F("Setup-Start") );
PrintFileNameDateTime();
dbg("right before prepareLittleFS()",0);
prepareLittleFS();
dbg("right after prepareLittleFS()",0);
readData();

}

void loop() {

}

unable to remove a file when it's open?

With SPIFFS this was valid:

  File root = fs->open("/configdir");
  File file;
  while (file = root.openNextFile()) {
    fs->remove(file.name());
  }

but with LITTLEFS it will throw an error esp_littlefs: Failed to unlink path "/configdir/file.json". Has open FD.

it's easy to circumvent by cloning the path and issuing a file.close() before the remove() but was I just curious whether this is by design?

Directories support

Thank you for implementing LIttleFS for Arduino esp32.
I am migrating from esp8266 to esp32
My working esp8266 code looks next:

uint8_t get_chunks_number(const char *dir_path)
{
    uint8_t result = 0;
    Dir root = LITTLEFS.openDir(dir_path);
    while (root.next())
    {
        result++;
    }
    return result;
}

Is there a way to go through folder?

LITTLEFS(fs_info); causes error.

#include <Arduino.h>
#include <FS.h>
#include <LITTLEFS.h>
#define  fs LITTLEFS
#include <stdlib.h>
struct FSInfo {
    size_t totalBytes;
    size_t usedBytes;
    size_t blockSize;
    size_t pageSize;
    size_t maxOpenFiles;
    size_t maxPathLength;
};
void setup() {
  FSInfo fs_info;
  LITTLEFS(fs_info);
}

This causes no match for call to '(fs::LITTLEFSFS) (FSInfo&)'
and when doing it the way it is supposed to be:

#include <Arduino.h>
#include <FS.h>
#include <LITTLEFS.h>
#define  fs LITTLEFS
#include <stdlib.h>
struct FSInfo {
    size_t totalBytes;
    size_t usedBytes;
    size_t blockSize;
    size_t pageSize;
    size_t maxOpenFiles;
    size_t maxPathLength;
};
void setup() {
  FSInfo fs_info;
  LittleFS.info(fs_info);
}

This causes 'LittleFS' was not declared in this scope
I have even tried using FS.info and I get expected unqualified-id before '.' token
There is absolutely no reason any of these should give any errors at all. This should just simply work. I am very close to just giving up on making this stupid os.

Errors of open files

I have esp32 board. I using ESPAsyncWebServer and your little fs library. When i refresh web page ill get opening files errors. But page opening fully and working normally. Only errors in serial haunt me...

E (18932) esp_littlefs: Failed to opendir "/index.htm". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/index.htm does not exist

E (20877) esp_littlefs: Failed to opendir "/js/build.chart.js". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/js/build.chart.js does not exist

E (20925) esp_littlefs: Failed to opendir "/css/build.css". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/css/build.css does not exist

E (21264) esp_littlefs: Failed to opendir "/index.json.gz". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/index.json.gz does not exist

E (21302) esp_littlefs: Failed to opendir "/favicon.ico". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico does not exist

E (21308) esp_littlefs: Failed to opendir "/favicon.ico.gz". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico.gz does not exist

E (21322) esp_littlefs: Failed to opendir "/favicon.ico/index.htm". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico/index.htm does not exist

E (21333) esp_littlefs: Failed to opendir "/favicon.ico/index.htm.gz". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico/index.htm.gz does not exist

E (21347) esp_littlefs: Failed to opendir "/favicon.ico". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico does not exist

E (21359) esp_littlefs: Failed to opendir "/favicon.ico.gz". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico.gz does not exist

E (21371) esp_littlefs: Failed to opendir "/favicon.ico/index.htm". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico/index.htm does not exist

E (21385) esp_littlefs: Failed to opendir "/favicon.ico/index.htm.gz". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/favicon.ico/index.htm.gz does not exist

NOT_FOUND: GET http://192.168.1.116/favicon.ico
_HEADER[Host]: 192.168.1.116
_HEADER[Connection]: keep-alive
_HEADER[Pragma]: no-cache
_HEADER[Cache-Control]: no-cache
_HEADER[Authorization]: Digest username="admin", realm="asyncesp", nonce="795d0e2e77f0bd1ac56d88a223e30cc8", uri="/favicon.ico", response="38eb1459f010bfbd37082bd9cf4a697d", opaque="0bc073c1bf61fa0ae678fa5892cfd2a6", qop=auth, nc=00000007, cnonce="4cc4260a509fc0f7"
_HEADER[User-Agent]: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
_HEADER[Accept]: image/webp,image/apng,image/,/*;q=0.8
_HEADER[Referer]: http://192.168.1.116/
_HEADER[Accept-Encoding]: gzip, deflate
_HEADER[Accept-Language]: en-US,en;q=0.9,ru;q=0.8,mt;q=0.7
E (21476) esp_littlefs: Failed to opendir "/config.live.json". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/config.live.json does not exist

E (21483) esp_littlefs: Failed to opendir "/config.live.json.gz". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/config.live.json.gz does not exist

E (21497) esp_littlefs: Failed to opendir "/config.live.json/index.htm". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/config.live.json/index.htm does not exist

E (21511) esp_littlefs: Failed to opendir "/config.live.json/index.htm.gz". Error (-2)
[E][vfs_api.cpp:64] open(): /littlefs/config.live.json/index.htm.gz does not exist

This files exist in flash:

Скриншот 17-08-2020 194422

I not aware what reason of this problem. I cannot understand how the file paths are formed. For example, this path: /config.live.json/index.htm.gz. It consists of two names of two files concatenated together.

For declaration i using two lines:

#include "LITTLEFS.h"
#define LittleFS LITTLEFS

For initialization i using this line:

LittleFS.begin(false,"/littlefs", 10);

In asinc web server i using object of little fs library to give acsess to web page files:

server.serveStatic("/css/", LittleFS, "/css/").setCacheControl("max-age=31536000");
server.serveStatic("/js/", LittleFS, "/js/").setCacheControl("max-age=31536000");
server.serveStatic("/favicon.ico", LittleFS, "/favicon.ico").setCacheControl("max-age=31536000");
server.serveStatic("/icon.jpeg", LittleFS, "/icon.jpeg").setCacheControl("max-age=31536000");

    server.serveStatic("/", LittleFS, "/")
        .setDefaultFile("index.htm")
        .setAuthentication(jsonReadStr(configSetupJson, "WebUser").c_str(), jsonReadStr(configSetupJson, "WebPass").c_str());

If i change File System back to SPIFFS , i have no any errors.

Please help me with this problem. Thank you for this great job!

Platformio and littlefs

At the moment it is rather nasty to install the correct version of Arduino and littlefs when using platformio.

The core issue is #14: littlefs by default is compatible with a newer version of IDF than platformio installs for Arduino, therefore littlefs 1.0.5 does not compile.

The work-around of manually editing the littlefs source does not work in case of using platformio to build with a CI/CD (there's no-one there to do the manual editing).

At the moment my workaround is to use

lib_deps = lorol/LittleFS_esp32@!=1.0.5

but in effect this uses 1.0, because intermediate versions (like 1.0.4) are not available in the platformio library manager.

Life would be a lot simpler if littlefs set this CONFIG_LITTLEFS_FOR_IDF_3_2 define dynamically (at compile time), by triggering on some IDF define for the IDF version currently being built for. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/system.html#idf-version-h suggests this is possible (but I've never tried it myself).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.