Skip to content

Instantly share code, notes, and snippets.

@haeshh
Last active February 15, 2023 13:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haeshh/3884ce1849157bd2bfe103917a981318 to your computer and use it in GitHub Desktop.
Save haeshh/3884ce1849157bd2bfe103917a981318 to your computer and use it in GitHub Desktop.
LittleFS-Dateisystem für den ESP32: Belegung des Dateisystems // Basisfunktionen (siehe https://unsinnsbasis.de/littlefs-esp32/)
/* ------------------------------------------------------------
* Testprogramm für Dateisystem LittleFS
* (verwendet Code aus der Beispieldatei
* LittleFS_esp32\examples\LITTLEFS_test\LittleFS_test.ino)
*
* - Liste der vorhandenen Dateien anzeigen
* - Dateiinhalt anzeigen
* - Anlegen eines Verzeichnisses
* - Schreiben von Daten in eine neue Datei, weitere Daten anhängen
* - Datei und Verzeichnis löschen
*
* 2021-05-21 Heiko / unsinnsbasis.de
* ------------------------------------------------------------ */
/* ------------------------------------------------------------
* Einbinden der benötigten Bibliotheken,
* Defintion von Konstanten,
* Anlegen der Datenobjekte
* ------------------------------------------------------------ */
// Übertragungsrate für Ausgabe zum seriellen Monitor
#define SERIAL_BAUDRATE 115200
#include <Arduino.h>
#include "FS.h"
#include <LITTLEFS.h>
// Dateisystem automatisch formatieren (true/false)
// (ist nicht nötig, wenn es mit ESP32FS (ESP32 Sketch
// Data Upload) erstellt wurde)
#define FORMAT_LITTLEFS_IF_FAILED true
/* ------------------------------------------------------------
* Liste aller Dateien und Unterverzeichnisse in einem
* Verzeichnis anzeigen
*
* Parameter:
* - Dateisystem (sollte LITTLEFS sein)
* - Verzeichnisname ("/" für das Root-Dir)
* - maximale Verzeichnistiefe
* ------------------------------------------------------------ */
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
Serial.printf("Directory-Listing: %s\r\n", dirname);
File root = fs.open(dirname);
if (!root) { // Verzeichnis nicht vorhanden
Serial.println("- Fehler beim Öffnen des Verzeichnisses");
return;
}
if (!root.isDirectory()) { // kein Verzeichnis, sondern Datei
Serial.println(" - kein Verzeichnis");
return;
}
File file = root.openNextFile();
// in einer Schleife durch die Liste aller vorhandenen
// Einträge gehen
while (file) {
if (file.isDirectory()) {
Serial.print(" DIR : ");
Serial.println(file.name());
// ist der Eintrag ein Verz., dann dessen Inhalt rekursiv
// anzeigen, wenn maximale Tiefe noch nicht erreicht ist
if (levels) {
listDir(fs, file.name(), levels-1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print("\tGröße: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
/* ------------------------------------------------------------
* Daten in eine Datei schreiben
* - existiert die Datei, wird sie überschrieben (Modus FILE_WRITE)
* oder die Daten werden angehängt (Modus FILE_APPEND)
*
* Parameter:
* - Dateisystem (sollte LITTLEFS sein)
* - Dateiname (vollständige Pfadangabe)
* - zu schreibende Daten (als Zeichenkette)
* - Modus zum Öffnen (FILE_WRITE oder FILE_APPEND)
* ------------------------------------------------------------ */
void writeFile(fs::FS &fs,
const char * path,
const char * message,
const char * mode) {
Serial.printf("Schreibe Datei: %s\r\n", path);
if (mode != FILE_WRITE && mode != FILE_APPEND) {
Serial.println("- ungültiger Zugriffsmodus (WRITE/APPEND)");
}
File file = fs.open(path, mode);
if (!file) {
Serial.println("- kann Datei nicht zum Schreiben öffnen");
return;
}
if (file.print(message)) {
if (mode == FILE_WRITE) {
Serial.println("- Datei neu geschrieben");
} else {
Serial.println("- Daten an Datei angehängt");
}
} else {
Serial.println("- Schreiben fehlgeschlagen");
}
file.close();
}
/* ------------------------------------------------------------
* Inhalt einer (Text-)Datei ausgeben
*
* Parameter:
* - Dateisystem (sollte LITTLEFS sein)
* - Dateiname (vollständige Pfadangabe)
* ------------------------------------------------------------ */
void readFile(fs::FS &fs, const char * path) {
Serial.printf("Lese Datei: %s\r\n", path);
File file = fs.open(path);
if (!file || file.isDirectory()) {
Serial.println("- kann Datei nicht zum Lesen öffnen");
return;
}
Serial.println("- lese Datei:");
while(file.available()) {
// Dateiinhalt Zeichen für Zeichen lesen und ausgeben
Serial.write(file.read());
}
file.close();
}
/* ------------------------------------------------------------
* Datei löschen
*
* Parameter:
* - Dateisystem (sollte LITTLEFS sein)
* - Dateiname (vollständige Pfadangabe)
* ------------------------------------------------------------ */
void deleteFile(fs::FS &fs, const char * path) {
Serial.printf("Lösche Datei: %s\r\n", path);
if (fs.remove(path)) {
Serial.println("- Datei gelöscht");
} else {
Serial.println("- Datei konnte nicht gelöscht werden");
}
}
/* ------------------------------------------------------------
* Verzeichnis anlegen
*
* Parameter:
* - Dateisystem (sollte LITTLEFS sein)
* - Verzeichnisname (vollständige Pfadangabe)
* ------------------------------------------------------------ */
void createDir(fs::FS &fs, const char * path) {
Serial.printf("Erstelle Verzeichnis: %s\n", path);
if (fs.mkdir(path)) {
Serial.println("Verzeichnis erstellt");
} else {
Serial.println("Erstellen des Verzeichnisses fehlgeschlagen");
}
}
/* ------------------------------------------------------------
* Verzeichnis löschen
*
* Parameter:
* - Dateisystem (sollte LITTLEFS sein)
* - Verzeichnisname (vollständige Pfadangabe)
* ------------------------------------------------------------ */
void removeDir(fs::FS &fs, const char * path) {
Serial.printf("Lösche Verzeichnis: %s\n", path);
if (fs.rmdir(path)) {
Serial.println("Verzeichnis gelöscht");
} else {
Serial.println("Fehler beim Löschen");
}
}
/* ------------------------------------------------------------ */
void setup() {
Serial.begin(SERIAL_BAUDRATE);
delay(500);
Serial.println("\n-------- LITTLEFS Test --------");
// Dateisystem einbinden
// (ggf. beim ersten Mal formatieren)
if(!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
Serial.println("LITTLEFS Mount fehlgeschlagen");
return;
}
Serial.println("Informationen zum Dateisystem:");
Serial.printf("- Bytes total: %ld\n", LITTLEFS.totalBytes());
Serial.printf("- Bytes genutzt: %ld\n\n", LITTLEFS.usedBytes());
// Liste aller vorhandenen Dateien anzeigen
// (rekursiv bis zu 3 Verzeichnisebenen tief)
listDir(LITTLEFS, "/", 3);
Serial.println();
// Liste eines nicht vorhandenen Verz. anzeigen
// -> Fehlermeldung
listDir(LITTLEFS, "/unsinnsbasis", 3);
Serial.println();
// versuchen, einen Dateinamen als Verzeichnis anzuzeigen
// -> Fehlermeldung
listDir(LITTLEFS, "/testdatei.txt", 3);
Serial.println();
// Inhalt der Testdatei anzeigen
readFile(LITTLEFS, "/testdatei.txt");
Serial.println();
// bereits vorhandenes Verzeichnis nochmal erstellen
createDir(LITTLEFS, "/test-dir");
Serial.println();
// neues Verzeichnis anlegen
createDir(LITTLEFS, "/mein-directory");
Serial.println();
// dort eine Datei anlegen bzw. bei Vorhandensein überschreiben
writeFile(LITTLEFS, "/mein-directory/demo.dat",
"Das ist eine Demodatei\n", FILE_WRITE);
Serial.println();
// Liste der Dateien zeigt, ob Datei angelegt wurde
listDir(LITTLEFS, "/mein-directory", 1);
Serial.println();
writeFile(LITTLEFS, "/mein-directory/demo.dat",
"Mehr Daten", FILE_APPEND); // ohne Zeilenvorschub
Serial.println();
writeFile(LITTLEFS, "/mein-directory/demo.dat",
"Noch mehr Daten\n", FILE_APPEND);
Serial.println();
listDir(LITTLEFS, "/mein-directory", 1);
Serial.println();
readFile(LITTLEFS, "/mein-directory/demo.dat");
Serial.println();
// neu angelegtes Verzeichnis löschen
// -> Fehler, weil Verzeichnis nicht leer
removeDir(LITTLEFS, "/mein-directory");
// also Datei löschen und dann das Verzeichnis
deleteFile(LITTLEFS, "/mein-directory/demo.dat");
removeDir(LITTLEFS, "/mein-directory");
Serial.println();
// nach dem Aufräumen sollte es aussehen wie zu Beginn
listDir(LITTLEFS, "/", 1);
}
void loop() {
// nichts tun
}
/* ------------------------------------------------------------
* Testprogramm für Dateisystem LittleFS
* (verwendet Code aus der Beispieldatei
* LittleFS_esp32\examples\LITTLEFS_test\LittleFS_test.ino)
*
* Programm stellt nur fest, ob das Dateisystem genutzt werden
* kann. Falls nein, wird es formatiert.
*
* Falls ein Zugriff möglich ist, wird die Belegung angezeigt.
*
* 2021-05-22 Heiko / unsinnsbasis.de
* ------------------------------------------------------------ */
/* ------------------------------------------------------------
* Einbinden der benötigten Bibliotheken,
* Defintion von Konstanten,
* Anlegen der Datenobjekte
* ------------------------------------------------------------ */
// Übertragungsrate für Ausgabe zum seriellen Monitor
#define SERIAL_BAUDRATE 115200
#include <Arduino.h>
#include "FS.h"
#include <LITTLEFS.h>
/* ------------------------------------------------------------
* Liste aller Dateien und Unterverzeichnisse in einem
* Verzeichnis anzeigen
*
* Parameter:
* - Dateisystem (sollte LITTLEFS sein)
* - Verzeichnisname ("/" für das Root-Dir)
* - maximale Verzeichnistiefe
* ------------------------------------------------------------ */
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
Serial.printf("Directory-Listing: %s\r\n", dirname);
File root = fs.open(dirname);
if (!root) { // Verzeichnis nicht vorhanden
Serial.println("- Fehler beim Öffnen des Verzeichnisses");
return;
}
if (!root.isDirectory()) { // kein Verzeichnis, sondern Datei
Serial.println(" - kein Verzeichnis");
return;
}
File file = root.openNextFile();
// in einer Schleife durch die Liste aller vorhandenen
// Einträge gehen
while (file) {
if (file.isDirectory()) {
Serial.print(" DIR : ");
Serial.println(file.name());
// ist der Eintrag ein Verz., dann dessen Inhalt rekursiv
// anzeigen, wenn maximale Tiefe noch nicht erreicht ist
if (levels) {
listDir(fs, file.name(), levels-1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print("\tGröße: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
/* ------------------------------------------------------------ */
void setup() {
Serial.begin(SERIAL_BAUDRATE);
delay(500);
Serial.println("\n-------- LITTLEFS Test --------");
// versuchen, ein vorhandenes Dateisystem einzubinden
if (!LITTLEFS.begin(false)) {
Serial.println("LITTLEFS Mount fehlgeschlagen");
Serial.println("Kein Dateisystemsystem gefunden; wird formatiert");
// falls es nicht klappt, erneut mit Neu-Formatierung versuchen
if (!LITTLEFS.begin(true)) {
Serial.println("LITTLEFS Mount fehlgeschlagen");
Serial.println("Formatierung nicht möglich");
return;
} else {
Serial.println("Formatierung des Dateisystems erfolgt");
}
}
Serial.println("Informationen zum Dateisystem:");
Serial.printf("- Bytes total: %ld\n", LITTLEFS.totalBytes());
Serial.printf("- Bytes genutzt: %ld\n\n", LITTLEFS.usedBytes());
// Liste aller vorhandenen Dateien anzeigen
// (rekursiv bis zu 3 Verzeichnisebenen tief)
listDir(LITTLEFS, "/", 3);
}
void loop() {
// nichts tun
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment