ESP32 and the SPIFFS file system
-
SPIFFS – (Serial Peripheral Interface Flash File System). In simple words: there is an ESP32 microcontroller (figure 1), it has a built-in rewritable non-volatile NOR memory, which stores: settings (Preferences), bootloader (Bootloader), firmware (compiled sketch), file system (SPIFFS) and something else, such as "over-the-air" updates (OTA).
Figure 1. Functional block diagram of the ESP32 microcontroller
NOR-memory is a type of non-volatile rewritable memory, which has a sufficiently high read speed, relatively low write and stream speed, in comparison with the type of memory NAND. It is almost impossible to meet NOR-memory of a large volume, usually it is limited to 128 MBytes. In the case of ESP32– 4 MB.
To date, SPIFFS has some drawbacks
shortcomings, including: lack of folder support; no real-time stack, so the same operation may take different time; lack of ability to find and fix broken blocks. If the listed shortcomings are not critical for You, then we will continue to read the following paragraph.Let's talk about using
Unfortunately, out of the box, the memory of the microcontroller is not marked up under SPIFFS, in order to mark up, you need to use the plugin ESP32FS for the Arduino IDE development environment.
After the plugin is downloaded – it must be installed:
- Make sure you have the latest version of the Arduino IDE and driver for Your device on ESP32. I have M5Stack drivers CP210X I download on this link;
- Copy the downloaded tool folder with the plug-in attached to it to the /Arduino/tools/ESP32FS folder/;
- In macOS the folder is located at ~/Documents/Arduino/;
- Restart the computer and provrete in the development environment in the menu Tools (Tools) appears item ESP32 Sketch Data Upload (figure 2) - so you have done everything correctly;
Figure 2. Menu Tools
- Note the data folder next to the sketch. All files located in this folder will be loaded into the device's memory when formatting;
- Feel free to select the specified item and wait for the end of formatting the memory area. Please note that other memory areas will not be affected, which means that the firmware will remain in the device's memory and will work. Similarly with the sketch, when it is compiled into the firmware and loaded into the device-the file system will not be affected.
If you want comfort
-
If you want to touch files and see information about free space, then download the sketch BRIDGE and stitch your device with it.
-
Also download
and compilecross-platform file Manager A-Explorer (figure 3). On GitHub the binary files are in the realize folder.Figure 3, a. A-Explorer File Manager for macOS
Figure 3, b. A-Explorer File Manager for Windows
This file Manager allows you to find information about free space, upload/download / delete files. There is an indication of the progress of the operation.
As you can see in figure 3, the plugin marked up approximately 1.38 MB of memory under SPIFFS.
Who is this BRIDGE?
BRIDGE is a sketch, and above all a function of the same name that works with the SPIFFS file system and A-Explorer is a graphical shell for it. The latter sends a particular command, and this function processes it on the device itself using the FS and SPIFFSlibraries. Let's see what's interesting about these libraries.
How to use public methods of the SPIFFS class:
-
Bool begin method(bool formatOnFail=false, const char * basePath= "/spiffs", uint8_t maxOpenFiles=10). This method attempts to initialize an instance of the class. The first argument is true or false, in case it is worth formatting the background system if the file system is not formatted. The second argument takes the path where the root of the file system will be located. The third argument will determine the number of files opened at the same time. It is better to leave the last two parameters defaulted and not change them. If there is no file system (the plugin above was not used). that function will return a lie.
-
The bool format() method will check whether the file system is formatted-returns true, in the primitive case-false.
-
Size_t totalBytes() method. This method returns size_t-the number of total Bytes allocated for the file system.
-
Size_t usedBytes() method. This method returns size_t-the number of Bytes used in the file system.
-
Void end() method. This method leads to the deinitialization of this class. After calling this method, it is pointless to call other methods.
In this class, everything, nothing particularly interesting. Let's go to the class FS and see what we can use from there.
-
The first thing that catches your eye is the initializer method of the bool begin() class. This method does not require arguments and there is no need to call it, because we will use the following method immediately.
-
Method File open (const char* path, const char* mode) and its brother File open(const String& path, const char* mode). These methods take two arguments each: the first is a character pointer and a string pointer to the file path, and the second is an open mode, which can be the following constat:
FILE_READ – open read-only;
FILE_WRITE – open for writing only;
FILE_APPEND – open for additional recording.
After we have opened the file, we can now perform any operations on it.
- The size_t write(uint8_t) method allows you to write a single 8-bit unsigned integer to the end of the file.
- The size_t write method (const uint8_t *buf, size_t size) allows you to write a number of unsigned integers of the specified length in the second argument.
- The int available() method counts the number of characters from the end to the pointer.
- The int read() method reads a single character from the file and returns it as an integer, with the cursor shifted one right.
- The size_t readBytes(char *buffer, size_t length) method reads characters to the buffer, the pointer to which is received by the first argument, and the number of characters passed by the second argument. Returns the number of characters used.
- The String readString () method reads a string from a file.
- The int peek() method works similarly to the int read () method, only the cursor remains in place.
- The bool seek(uint32_t pos, SeekMode mode) and bool seek(uint32_t pos, SeekMode mode) methods set the cursor to the specified location. The first argument passes the position, and the second rule (SeekSet - set the cursor). If successful-returns true, otherwise-false.
- The size_t position() method returns the cursor position.
- The size_t size() method returns the file size in Bytes.
- The const char * name() method returns the file name.
- Const char * fullName() method with full path.
- The bool isFile() method returns true if the open object is a file. Otherwise, it's a lie.
- The bool isDirectory() method returns true if the open object is a folder. Otherwise, it's a lie.
- The File openNextFile() method returns a pointer to the next file in the root, otherwise NULL.
- The method bool exists(const char* path) and bool exists(const String& path) takes the full file name as an argument, and if such a file exists, it returns true, otherwise it is false.
- The bool remove(const char* path) and bool remove(const String& path) methods attempt to delete the file whose name is passed as arguments. If successful, returns istrina, otherwise-a lie.
- Method bool rename(const char* pathFrom, const char* pathTo) and bool rename (const String& pathFrom, const String& pathTo); takes the full file name first arguments, and the second full new file name and rename.
Yes, you can take this function and run it in a separate thread in any other sketch 😉
Thank you very much for your time! I will be glad if this article will benefit you.
List of references and (or) sources:
- SPIFFS Filesystem
- Working with the file system in the addon ESP8266 in the Arduino IDE
- Arduino ESP32 filesystem uploader
-
Does anyone have A-Explorer and Bridge saved anywhere? Seems like dsiberia9s account doesnt exist on Github anymore so it seems lost in time otherwise :(