WeMos D1 mini (esp8266), integrated LittleFS Filesystem – Part 5

Spread the love

LittleFS File System

esp8266 LittleFS integrated filesystem ArduinoIDE
esp8266 LittleFS integrated filesystem ArduinoIDE

SPIFFS is the original filesystem and is ideal for space and RAM constrained applications that utilize many small files and care about static and dynamic wear levelling and don’t need true directory support. Filesystem overhead on the flash is minimal as well.

But with the introduction of new LittleFS, SPIFFS become deprecated.

LittleFS is recently added and focuses on higher performance and directory support, but has higher filesystem and per-file overhead (4K minimum vs. SPIFFS’ 256 byte minimum file allocation unit).

The LittleFS implementation for the ESP8266 supports filenames of up to 31 characters + terminating zero (i.e. char filename[32]), and as many subdirectories as space permits.

Unlike SPIFFS, the actual file descriptors are allocated as requested by the application, so in low memory conditions you may not be able to open new files. Conversely, this also means that only file descriptors used will actually take space on the heap.

Because there are directories, the openDir method behaves differently than SPIFFS. Whereas SPIFFS will return files in “subdirectories” when you traverse a Dir::next() (because they really aren’t subdirs but simply files with “/”s in their names), LittleFS will only return files in the specific subdirectory. This mimics the POSIX behavior for directory traversal most C programmers are used to.

WeMos D1 mini have 4Mb of flash and you can use since 3Mb of that for your file.
In this flash memory ESP stores the program. Along with program you can store your files on it. Limitation of this memory is it has only 10000 (ten thousand) write cycles.

Sketch OTA update File system EEPROM WiFi config

Add files from IDE to LittleFS

This operation without an extension for the Arduino IDE is not so simple, but here we are going to explain the simpliest way.

First you must download the plugin for Arduino IDE here.

Than you must find your Shetckbook folder, so you must go to File --> Preferences, in that screen you can find at the top of window the Sketchbook location.

Sketchbook Location, additional file Arduino IDE
Preferences window

Now you must create (if not exist) the folder tools/ESP8266LittleFS/tool and add the jar file esp8266littlefs.jar there.

esp8266 LittleFS plugin folder ArduinoIDE
esp8266 LittleFS plugin folder ArduinoIDE

Now restart the IDE and on Tools menu you can find new menu line ESP8266 LittleFS Data Upload.

esp8266 LittleFS plugin menu on ArduinoIDE
esp8266 LittleFS plugin menu on ArduinoIDE

On Arduino IDE do Ctrl+K to open a filebrowser on directory of the sketch.
Create a directory data where you are going to put the data you want to upload.

 Serial Peripheral Interface Flash File System, or SPIFFS for short. It's a light-weight file system for microcontrollers with an SPI flash chip. The on-board flash chip of the ESP8266 has plenty of space for your files.
Sketch to upload data on LittleFS on esp8266: directory structure

Set the size of LittleFS on Tools --> Flash size and set the size of your Microcontroller LittleFS.

Upload your sketch, and than click on ESP8266 LittleFS Data Upload.

Now go to the example sketch to check if all is OK.

Commands

There are some standard command that you can use with this filesystem

LittleFS.begin()
This method mounts LittleFS file system and It must be called before any other FS APIs are used. Returns true if file system was mounted successfully, false otherwise.

LittleFS.format()
Formats the file system. Returns true if formatting was successful.

LittleFS.open(path, mode)
Opens a file. path should be an absolute path starting with a slash (e.g. /dir/filename.txt). mode is a string specifying access mode. It can be one of “r”, “w”, “a”, “r+”, “w+”, “a+”. Meaning of these modes is the same as for fopen C function.
Returns File object. To check whether the file was opened successfully, use the boolean operator.

LittleFS.exists(path)
Returns true if a file with given path exists, false otherwise.

LittleFS.openDir(path)
Opens a directory given its absolute path. Returns a Dir object.

LittleFS.remove(path):
Deletes the file given its absolute path. Returns true if file was deleted successfully.

LittleFS.mkdir(path):
Create a new folder. Returns true if the directory creation succeeded, false otherwise.

LittleFS.rmdir(path):
Remove directory. Returns true if the directory was successfully removed, false otherwise.

LittleFS.rename(pathFrom, pathTo)
Renames file from pathFrom to pathTo. Paths must be absolute. Returns true if file was renamed successfully.

LittleFS.info(fs_info)
Fills FSInfo structure with information about the file system. Returns true is successful, false otherwise.

file.seek(offset, mode)
This function behaves like fseek C function. Depending on the value of mode, it moves current position in a file as follows:

  • if mode is SeekSet, position is set to offset bytes from the beginning.
  • if mode is SeekCur, current position is moved by offset bytes.
  • if mode is SeekEnd, position is set to offset bytes from the end of the file.
  • Returns true if position was set successfully.

file.position()
Returns the current position inside the file, in bytes.

file.size()
Returns file size, in bytes.

file.name()
Returns file name, as const char*.

file.close()
Close the file.

dir.next()
Returns true while there are files in the directory to iterate over. It must be called before calling fileName()fileSize(), and openFile() functions.

dir.fileName()
Returns the name of the current file pointed to by the internal iterator.

dir.fileSize()
Returns the size of the current file pointed to by the internal iterator.

dir.fileTime()
Returns the time_t write time of the current file pointed to by the internal iterator.

dir.fileCreationTime()
Returns the time_t creation time of the current file pointed to by the internal iterator.

dir.isFile()
Returns true if the current file pointed to by the internal iterator is a File.

dir.isDirectory()
Returns true if the current file pointed to by the internal iterator is a Directory.

dir.openFile()
This method takes mode argument which has the same meaning as for LittleFS.open() function.

dir.rewind()
Resets the internal pointer to the start of the directory.

Pratical examples

Here a sketch to get info and check all file in your LittleFS.

/*
 *  WeMos D1 mini (esp8266)
 *  LittleFS get info, read dir and show all file uploaded
 *  add a data folder to use with esp8266 data uploader
 *  by Mischianti Renzo <https://mischianti.org>
 *
 *  https://mischianti.org/
 *
 */

#include "Arduino.h"
#include "LittleFS.h"

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

	delay(500);

	Serial.println(F("Inizializing FS..."));
	if (LittleFS.begin()){
		Serial.println(F("done."));
	}else{
		Serial.println(F("fail."));
	}

	// To format all space in LittleFS
	// LittleFS.format()

	// Get all information of your LittleFS
	FSInfo fs_info;
	LittleFS.info(fs_info);

	Serial.println("File sistem info.");

	Serial.print("Total space:      ");
	Serial.print(fs_info.totalBytes);
	Serial.println("byte");

	Serial.print("Total space used: ");
	Serial.print(fs_info.usedBytes);
	Serial.println("byte");

	Serial.print("Block size:       ");
	Serial.print(fs_info.blockSize);
	Serial.println("byte");

	Serial.print("Page size:        ");
	Serial.print(fs_info.totalBytes);
	Serial.println("byte");

	Serial.print("Max open files:   ");
	Serial.println(fs_info.maxOpenFiles);

	Serial.print("Max path length:  ");
	Serial.println(fs_info.maxPathLength);

	Serial.println();

	// Open dir folder
	Dir dir = LittleFS.openDir("/");
	// Cycle all the content
	while (dir.next()) {
		// get filename
	    Serial.print(dir.fileName());
        Serial.print(" - ");
        // If element have a size display It else write 0
	    if(dir.fileSize()) {
	        File f = dir.openFile("r");
	        Serial.println(f.size());
	        f.close();
	    }else{
	    	Serial.println("0");
	    }
	}
}

void loop()
{

}

The result of the inquity

Inizializing FS...
done.
File sistem info.
Total space:      2072576byte
Total space used: 73728byte
Block size:       8192byte
Page size:        2072576byte
Max open files:   5
Max path length:  32

logo.jpg - 46136
provaTXT.txt - 4416

Here a sketch with more pratical commands, write a string in a file, read all file content, positioning on the 9 byte of the file and read from there the data.

/*
 *  WeMos D1 mini (esp8266)
 *  LittleFS write, read and seek file
 *  by Mischianti Renzo <https://mischianti.org>
 *
 *  https://mischianti.org/
 *
 */
#include "Arduino.h"
#include "LittleFS.h"

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

	delay(500);

	Serial.println(F("Inizializing FS..."));
	if (LittleFS.begin()){
		Serial.println(F("done."));
	}else{
		Serial.println(F("fail."));
	}

	// To remove previous test
	// LittleFS.remove(F("/testCreate.txt"));

	File testFile = LittleFS.open(F("/testCreate.txt"), "w");

	if (testFile){
		Serial.println("Write file content!");
		testFile.print("Here the test text!!");

		testFile.close();
	}else{
		Serial.println("Problem on create file!");
	}

	testFile = LittleFS.open(F("/testCreate.txt"), "r");
	if (testFile){
		Serial.println("Read file content!");
		/**
		 * File derivate from Stream so you can use all Stream method
		 * readBytes, findUntil, parseInt, println etc
		 */
		Serial.println(testFile.readString());
		testFile.close();
	}else{
		Serial.println("Problem on read file!");
	}

	testFile = LittleFS.open(F("/testCreate.txt"), "r");
	if (testFile){
		/**
		 * mode is SeekSet, position is set to offset bytes from the beginning.
		 * mode is SeekCur, current position is moved by offset bytes.
		 * mode is SeekEnd, position is set to offset bytes from the end of the file.
		 * Returns true if position was set successfully.
		 */
		Serial.println("Position inside the file at 9 byte!");
		testFile.seek(9, SeekSet);

		Serial.println("Read file content!");
		Serial.println(testFile.readString());
		testFile.close();
	}else{
		Serial.println("Problem on read file!");
	}


}

void loop()
{

}

Here the result of the sketch

Inizializing FS...
done.
Write file content!
Read file content!
Here the test text!!
Position inside the file at 9 byte!
Read file content!
test text!!

Thanks

  1. WeMos D1 mini (esp8266), specs and IDE configuration
  2. WeMos D1 mini (esp8266), integrated SPIFFS Filesystem
  3. WeMos D1 mini (esp8266), debug on secondary UART
  4. WeMos D1 mini (esp8266), the three type of sleep mode to manage energy savings
  5. WeMos D1 mini (esp8266), integrated LittleFS Filesystem
  6. esp12 esp07 (esp8266): flash, pinout, specs and IDE configuration
  7. Firmware and OTA update management
    1. Firmware management
      1. esp8266: flash firmware binary (.bin) compiled and signed
      2. esp8266: flash firmware and filesystem binary (.bin) compiled with GUI tools
    2. OTA update with Arduino IDE
      1. esp8266 OTA update with Arduino IDE: filesystem, signed and password
    3. OTA update with Web Browser
      1. esp8266 OTA update with Web Browser: firmware, filesystem and authentication
      2. esp8266 OTA update with Web Browser: sign the firmware and HTTPS (SSL/TLS)
      3. esp8266 OTA update with Web Browser: custom web interface
    4. Self OTA uptate from HTTP server
      1. esp8266 self OTA update firmware from server
      2. esp8266 self OTA update firmware from server with version check
      3. esp8266 self OTA update in HTTPS (SSL/TLS) with trusted self signed certificate
    5. Non standard Firmware update
      1. esp8266 firmware and filesystem update from SD card
      2. esp8266 firmware and filesystem update with FTP client
  8. esp32 and esp8266: FAT filesystem on external SPI flash memory
  9. i2c esp8266: how to, network 5v, 3.3v, speed, and custom pins
  10. […]

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *