From a7eb474a97d9ceab0da18a9108217d9bccb3e0fc Mon Sep 17 00:00:00 2001 From: "feeling001@gmail.com" Date: Mon, 8 Jun 2026 14:33:53 +0200 Subject: [PATCH] initial commit --- .gitignore | 16 +++ Makefile | 132 +++++++++++++++++++ README.md | 129 +++++++++++++++++++ data/.gitkeep | 4 + default.csv | 10 ++ default_16MB.csv | 10 ++ platformio.ini | 57 ++++++++ src/main.cpp | 328 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 686 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 data/.gitkeep create mode 100644 default.csv create mode 100644 default_16MB.csv create mode 100644 platformio.ini create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..27314b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# PlatformIO build artefacts +.pio/ +.pioenvs/ +.piolibdeps/ + +# IDE +.vscode/ +.idea/ +*.suo +*.user + +# macOS +.DS_Store + +# Linux +*~ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cef1096 --- /dev/null +++ b/Makefile @@ -0,0 +1,132 @@ +# ============================================================ +# Makefile – LittleFS test ESP32-S3 +# Usage : +# make BOARD=esp32s3_zero # build +# make flash BOARD=esp32s3_zero # build + flash firmware +# make flashfs BOARD=esp32s3_zero # upload la partition LittleFS +# make monitor BOARD=esp32s3_zero # ouvre le moniteur série +# make all BOARD=esp32s3_n16r8v # build + flash firmware + flashfs +# make clean # nettoyage +# +# Boards disponibles : +# esp32s3_zero – Waveshare ESP32-S3-Zero (4 MB flash) +# esp32s3_n16r8v – Generic ESP32-S3 N16R8V (16 MB flash / 8 MB PSRAM OPI) +# ============================================================ + +# ── Valeur par défaut de la carte ────────────────────────────── +BOARD ?= esp32s3_zero + +# ── Outil PlatformIO ─────────────────────────────────────────── +PIO := pio + +# ── Port série (optionnel, PIO le détecte automatiquement) ───── +# PORT ?= /dev/ttyUSB0 + +# ── Cibles valides ───────────────────────────────────────────── +VALID_BOARDS := esp32s3_zero esp32s3_n16r8v + +.PHONY: all build flash flashfs monitor clean check-board help + +# ───────────────────────────────────────────────────────────── +# help (cible par défaut si aucun argument) +# ───────────────────────────────────────────────────────────── +help: + @echo "" + @echo " ┌─────────────────────────────────────────────────────────┐" + @echo " │ Makefile – LittleFS test ESP32-S3 │" + @echo " └─────────────────────────────────────────────────────────┘" + @echo "" + @echo " Utilisation : make BOARD=" + @echo "" + @echo " Cartes disponibles :" + @echo " esp32s3_zero – Waveshare ESP32-S3-Zero (4 MB flash)" + @echo " esp32s3_n16r8v – ESP32-S3 N16R8V (16 MB flash / 8 MB PSRAM OPI)" + @echo "" + @echo " Cibles :" + @echo " build – Compile le firmware (défaut)" + @echo " flash – Compile et flashe le firmware" + @echo " flashfs – Upload la partition LittleFS (répertoire data/)" + @echo " monitor – Ouvre le moniteur série (Ctrl+C pour quitter)" + @echo " all – build + flash + flashfs" + @echo " clean – Supprime les artefacts de build" + @echo " help – Affiche ce message" + @echo "" + @echo " Exemples :" + @echo " make BOARD=esp32s3_zero" + @echo " make flash BOARD=esp32s3_n16r8v" + @echo " make all BOARD=esp32s3_zero" + @echo "" + +# ───────────────────────────────────────────────────────────── +# Vérification de la valeur de BOARD +# ───────────────────────────────────────────────────────────── +check-board: + @if ! echo "$(VALID_BOARDS)" | grep -qw "$(BOARD)"; then \ + echo ""; \ + echo " ERREUR : carte inconnue '$(BOARD)'"; \ + echo " Cartes valides : $(VALID_BOARDS)"; \ + echo ""; \ + exit 1; \ + fi + @echo " → Carte sélectionnée : $(BOARD)" + +# ───────────────────────────────────────────────────────────── +# build – compilation uniquement +# ───────────────────────────────────────────────────────────── +build: check-board + @echo "" + @echo " ── Compilation pour $(BOARD) ──────────────────────────────" + $(PIO) run -e $(BOARD) + +# ───────────────────────────────────────────────────────────── +# flash – compilation + upload du firmware +# ───────────────────────────────────────────────────────────── +flash: check-board + @echo "" + @echo " ── Flash firmware → $(BOARD) ──────────────────────────────" +ifdef PORT + $(PIO) run -e $(BOARD) -t upload --upload-port $(PORT) +else + $(PIO) run -e $(BOARD) -t upload +endif + +# ───────────────────────────────────────────────────────────── +# flashfs – upload la partition LittleFS (contenu de data/) +# ───────────────────────────────────────────────────────────── +flashfs: check-board + @echo "" + @echo " ── Upload LittleFS partition → $(BOARD) ───────────────────" +ifdef PORT + $(PIO) run -e $(BOARD) -t uploadfs --upload-port $(PORT) +else + $(PIO) run -e $(BOARD) -t uploadfs +endif + +# ───────────────────────────────────────────────────────────── +# monitor – moniteur série +# ───────────────────────────────────────────────────────────── +monitor: check-board + @echo "" + @echo " ── Moniteur série ($(BOARD)) – Ctrl+C pour quitter ────────" +ifdef PORT + $(PIO) device monitor -e $(BOARD) --port $(PORT) +else + $(PIO) device monitor -e $(BOARD) +endif + +# ───────────────────────────────────────────────────────────── +# all – build + flash + flashfs +# ───────────────────────────────────────────────────────────── +all: build flash flashfs + @echo "" + @echo " ✔ all : build + flash + flashfs terminé pour $(BOARD)" + +# ───────────────────────────────────────────────────────────── +# clean – suppression des artefacts +# ───────────────────────────────────────────────────────────── +clean: + @echo "" + @echo " ── Nettoyage ───────────────────────────────────────────────" + $(PIO) run -t clean || true + rm -rf .pio + @echo " ✔ Nettoyage terminé" diff --git a/README.md b/README.md new file mode 100644 index 0000000..29e4011 --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ +# esp32_littlefs_test + +Test verbeux de LittleFS sur ESP32-S3 avec PlatformIO (framework Arduino, espressif32@6). + +## Cartes supportées + +| Environnement PIO | Carte physique | Flash | PSRAM | +|---|---|---|---| +| `esp32s3_zero` | Waveshare ESP32-S3-Zero | 4 MB QIO | — | +| `esp32s3_n16r8v` | Generic ESP32-S3 N16R8V | 16 MB QIO | 8 MB OPI | + +## Prérequis + +- [PlatformIO Core](https://docs.platformio.org/en/latest/core/installation/) installé (`pip install platformio`) +- Driver USB-JTAG / USB-CDC selon la carte (pas de driver externe sur la plupart des ES32-S3) + +## Utilisation avec le Makefile + +```bash +# Afficher l'aide +make + +# Compiler uniquement +make BOARD=esp32s3_zero + +# Compiler + flasher le firmware +make flash BOARD=esp32s3_zero + +# Uploader la partition LittleFS (contenu de data/) +make flashfs BOARD=esp32s3_zero + +# Tout en une commande +make all BOARD=esp32s3_n16r8v + +# Ouvrir le moniteur série +make monitor BOARD=esp32s3_zero + +# Nettoyer les artefacts +make clean +``` + +### Spécifier un port série manuellement + +```bash +make flash BOARD=esp32s3_zero PORT=/dev/ttyACM0 +``` + +## Utilisation directe avec PlatformIO + +```bash +# Build +pio run -e esp32s3_zero + +# Flash firmware +pio run -e esp32s3_zero -t upload + +# Upload partition LittleFS +pio run -e esp32s3_zero -t uploadfs + +# Moniteur série +pio device monitor -e esp32s3_zero +``` + +## Séquence de tests effectués + +| Étape | Description | +|---|---| +| 1 | Montage de LittleFS (avec formatage automatique si nécessaire) | +| 2 | Affichage des infos de la partition (total / utilisé / libre) | +| 3 | Écriture d'un fichier texte UTF-8 | +| 4 | Relecture et vérification du contenu (round-trip) | +| 5 | Écriture binaire (256 octets, valeurs 0x00…0xFF) | +| 6 | Relecture binaire et vérification byte-à-byte | +| 7 | Listage du répertoire racine | +| 8 | Test d'append (ajout à un fichier existant) | +| 9 | Renommage de fichier | +| 10 | Suppression de tous les fichiers de test | +| 11 | Vérification de l'absence des fichiers supprimés | +| 12 | Démontage propre | +| 13 | Résumé PASS / FAIL | + +## Sortie attendue + +``` +╔════════════════════════════════════════╗ +║ TEST LittleFS – ESP32-S3 ║ +╚════════════════════════════════════════╝ + Compilé le : Jun 8 2025 12:00:00 + CPU Freq : 240 MHz + Flash size : 4 MB + Free heap : 346120 octets + +── Étape 1 : Montage de LittleFS + [ OK ] LittleFS.begin() + +── Étape 2 : Informations de la partition + [INFO] Taille totale : 1376256 octets (1344 KB) + ... + +── Étape 13 : ... +╔════════════════════════════════════════╗ +║ RÉSUMÉ DES TESTS ║ +╠════════════════════════════════════════╣ +║ PASS : 20 FAIL : 0 ║ +╠════════════════════════════════════════╣ +║ ✔ Tous les tests sont PASSÉS ! ║ +╚════════════════════════════════════════╝ +``` + +## LED de statut + +Après les tests, la LED intégrée (`LED_BUILTIN`) clignote : +- **Lentement (500 ms)** : tous les tests sont passés ✔ +- **Rapidement (100 ms)** : un ou plusieurs tests ont échoué ✘ + +## Structure du projet + +``` +esp32_littlefs_test/ +├── platformio.ini # Configuration PlatformIO (2 environnements) +├── Makefile # Makefile avec paramètre BOARD= +├── default.csv # Table de partitions 4 MB (esp32s3_zero) +├── default_16MB.csv # Table de partitions 16 MB (esp32s3_n16r8v) +├── src/ +│ └── main.cpp # Code de test LittleFS +├── data/ # Contenu uploadé sur LittleFS (vide = OK) +│ └── .gitkeep +└── README.md +``` diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..6fd5015 --- /dev/null +++ b/data/.gitkeep @@ -0,0 +1,4 @@ +Ce répertoire est uploadé tel-quel sur la partition LittleFS via : + pio run -t uploadfs -e + +Il peut rester vide pour le test de validation. diff --git a/default.csv b/default.csv new file mode 100644 index 0000000..30f6180 --- /dev/null +++ b/default.csv @@ -0,0 +1,10 @@ +# Partition table for ESP32-S3 – 4 MB flash +# Adapted for LittleFS (no OTA to keep a large FS partition) +# +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x140000, +app1, app, ota_1, 0x150000, 0x140000, +littlefs, data, spiffs, 0x290000, 0x160000, +coredump, data, coredump,0x3F0000, 0x10000, diff --git a/default_16MB.csv b/default_16MB.csv new file mode 100644 index 0000000..05c845d --- /dev/null +++ b/default_16MB.csv @@ -0,0 +1,10 @@ +# Partition table for ESP32-S3 N16R8V – 16 MB flash +# Generous app partitions + large LittleFS +# +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x300000, +app1, app, ota_1, 0x310000, 0x300000, +littlefs, data, spiffs, 0x610000, 0x9E0000, +coredump, data, coredump,0xFF0000, 0x10000, diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..03d8335 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,57 @@ +; ============================================================ +; PlatformIO configuration – LittleFS test +; Boards: esp32s3_zero | esp32s3_n16r8v +; ============================================================ + +[platformio] +default_envs = esp32s3_zero + +; ───────────────────────────────────────── +; Common settings shared by all envs +; ───────────────────────────────────────── +[env] +platform = espressif32@6 +framework = arduino + +; LittleFS filesystem upload tool +board_build.filesystem = littlefs + +; Serial monitor speed +monitor_speed = 115200 + +monitor_rts = 0 +monitor_dtr = 0 + +; Build flags common to all targets +build_flags = + -DCORE_DEBUG_LEVEL=5 + -DARDUINO_USB_CDC_ON_BOOT=1 + +; Pas de lib_deps : LittleFS est inclus dans espressif32@6 (framework-arduinoespressif32) +; #include suffit + +; ───────────────────────────────────────── +; Waveshare ESP32-S3-Zero +; Flash : 4 MB QIO / PSRAM : none +; ───────────────────────────────────────── +[env:esp32s3_zero] +board = waveshare_esp32_s3_zero +; Partition scheme with LittleFS (default_8MB has ota+littlefs) +board_build.partitions = default.csv +upload_speed = 921600 +monitor_speed = 115200 + +; ───────────────────────────────────────── +; Generic ESP32-S3 N16R8V +; Flash : 16 MB QIO / PSRAM : 8 MB OPI +; ───────────────────────────────────────── +[env:esp32s3_n16r8v] +board = esp32-s3-devkitc-1 +board_build.partitions = default_16MB.csv +board_upload.flash_size = 16MB +board_build.arduino.memory_type = qio_opi ; OPI PSRAM +upload_speed = 921600 +monitor_speed = 115200 +build_flags = + ${env.build_flags} + -DBOARD_HAS_PSRAM diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d6f3259 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,328 @@ +/** + * @file main.cpp + * @brief Test verbeux LittleFS sur ESP32-S3 + * + * Séquence de tests : + * 1. Montage du système de fichiers LittleFS + * 2. Affichage des infos de la partition (total / utilisé / libre) + * 3. Écriture d'un fichier texte + * 4. Relecture et vérification du contenu + * 5. Écriture binaire (tableau d'octets) + * 6. Relecture binaire et vérification byte-à-byte + * 7. Listage du répertoire racine + * 8. Test d'append (ajout à un fichier existant) + * 9. Renommage de fichier + * 10. Suppression de tous les fichiers de test + * 11. Vérification de la suppression + * 12. Démontage propre + * 13. Résumé PASS / FAIL + */ + +#include +#include + +// ────────────────────────────────────────────────────────────── +// Macros de log colorées (ANSI – visible dans un terminal VT100) +// ────────────────────────────────────────────────────────────── +#define CLR_RESET "\033[0m" +#define CLR_GREEN "\033[32m" +#define CLR_RED "\033[31m" +#define CLR_CYAN "\033[36m" +#define CLR_YELLOW "\033[33m" +#define CLR_BOLD "\033[1m" + +#define LOG_INFO(fmt, ...) Serial.printf(" [INFO] " fmt "\r\n", ##__VA_ARGS__) +#define LOG_OK(fmt, ...) Serial.printf(CLR_GREEN " [ OK ] " fmt CLR_RESET "\r\n", ##__VA_ARGS__) +#define LOG_FAIL(fmt, ...) Serial.printf(CLR_RED " [FAIL] " fmt CLR_RESET "\r\n", ##__VA_ARGS__) +#define LOG_STEP(n, fmt, ...) \ + Serial.printf(CLR_CYAN CLR_BOLD "\n── Étape %d : " fmt CLR_RESET "\r\n", n, ##__VA_ARGS__) +#define LOG_WARN(fmt, ...) Serial.printf(CLR_YELLOW " [WARN] " fmt CLR_RESET "\r\n", ##__VA_ARGS__) + +// ────────────────────────────────────────────────────────────── +// Noms des fichiers de test +// IMPORTANT : ne pas utiliser FILE_WRITE / FILE_READ / FILE_APPEND +// comme noms de variables — ce sont des macros définies dans FS.h +// ("w", "r", "a"). On préfixe avec TEST_ pour éviter le conflit. +// ────────────────────────────────────────────────────────────── +static const char* TEST_FILE_TEXT = "/test_text.txt"; +static const char* TEST_FILE_BIN = "/test_binary.bin"; +static const char* TEST_FILE_APPEND = "/test_append.txt"; +static const char* TEST_FILE_RENAMED = "/test_renamed.txt"; + +// ────────────────────────────────────────────────────────────── +// Compteurs globaux de tests +// ────────────────────────────────────────────────────────────── +static uint32_t g_pass = 0; +static uint32_t g_fail = 0; + +// ────────────────────────────────────────────────────────────── +// Helpers +// ────────────────────────────────────────────────────────────── +static void check(bool condition, const char* label) +{ + if (condition) { + LOG_OK("%s", label); + g_pass++; + } else { + LOG_FAIL("%s", label); + g_fail++; + } +} + +/** Liste récursive d'un répertoire */ +static void listDir(const char* path, uint8_t depth = 0) +{ + File root = LittleFS.open(path); + if (!root || !root.isDirectory()) { + LOG_WARN("Impossible d'ouvrir le répertoire : %s", path); + return; + } + + File entry = root.openNextFile(); + while (entry) { + for (uint8_t i = 0; i < depth; i++) Serial.print(" "); + if (entry.isDirectory()) { + Serial.printf(" [DIR] %s\r\n", entry.name()); + listDir(entry.path(), depth + 1); + } else { + Serial.printf(" [FIL] %-30s %6lu octets\r\n", + entry.name(), (unsigned long)entry.size()); + } + entry = root.openNextFile(); + } +} + +/** Supprime un fichier et log le résultat */ +static void removeFile(const char* path) +{ + if (LittleFS.exists(path)) { + bool ok = LittleFS.remove(path); + LOG_INFO("Suppression de %s -> %s", path, ok ? "succes" : "ERREUR"); + check(ok, String(String("remove(") + path + ")").c_str()); + } else { + LOG_WARN("Fichier absent (skip remove) : %s", path); + } +} + +// ────────────────────────────────────────────────────────────── +// setup() +// ────────────────────────────────────────────────────────────── +void setup() +{ + Serial.begin(115200); + delay(2000); // Laisse le temps à l'hôte de s'connecter + + Serial.println(); + Serial.println(CLR_BOLD "╔════════════════════════════════════════╗" CLR_RESET); + Serial.println(CLR_BOLD "║ TEST LittleFS – ESP32-S3 ║" CLR_RESET); + Serial.println(CLR_BOLD "╚════════════════════════════════════════╝" CLR_RESET); + Serial.printf(" Compilé le : %s %s\r\n", __DATE__, __TIME__); + Serial.printf(" CPU Freq : %u MHz\r\n", (unsigned)(ESP.getCpuFreqMHz())); + Serial.printf(" Flash size : %u MB\r\n", (unsigned)(ESP.getFlashChipSize() / (1024*1024))); + Serial.printf(" Free heap : %u octets\r\n", (unsigned)ESP.getFreeHeap()); + + // ── Étape 1 : Montage ─────────────────────────────────────── + LOG_STEP(1, "Montage de LittleFS"); + bool mounted = LittleFS.begin(true); // true = formater si nécessaire + check(mounted, "LittleFS.begin()"); + if (!mounted) { + LOG_FAIL("Abandon : impossible de monter LittleFS"); + return; + } + + // ── Étape 2 : Informations de la partition ─────────────────── + LOG_STEP(2, "Informations de la partition"); + size_t total = LittleFS.totalBytes(); + size_t used = LittleFS.usedBytes(); + size_t free_ = total - used; + LOG_INFO("Taille totale : %7u octets (%u KB)", (unsigned)total, (unsigned)(total/1024)); + LOG_INFO("Utilisé : %7u octets (%u KB)", (unsigned)used, (unsigned)(used /1024)); + LOG_INFO("Libre : %7u octets (%u KB)", (unsigned)free_, (unsigned)(free_/1024)); + check(total > 0, "Partition non nulle"); + + // ── Étape 3 : Écriture texte ───────────────────────────────── + LOG_STEP(3, "Ecriture d'un fichier texte"); + const char* textContent = + "Ligne 1 : Hello from LittleFS!\n" + "Ligne 2 : ESP32-S3 test ecriture / lecture.\n" + "Ligne 3 : Caracteres speciaux : eaü\n" + "Ligne 4 : Fin du fichier texte.\n"; + + { + File f = LittleFS.open(TEST_FILE_TEXT, "w"); // "w" = FILE_WRITE + check(f, "open(\"w\") - fichier texte"); + if (f) { + size_t written = f.print(textContent); + LOG_INFO("Octets ecrits : %u / %u", (unsigned)written, (unsigned)strlen(textContent)); + check(written == strlen(textContent), "Nombre d'octets ecrits correct"); + f.close(); + LOG_INFO("Fichier ferme : %s", TEST_FILE_TEXT); + } + } + + // ── Étape 4 : Relecture et vérification texte ──────────────── + LOG_STEP(4, "Relecture et verification du fichier texte"); + { + File f = LittleFS.open(TEST_FILE_TEXT, "r"); // "r" = FILE_READ + check(f, "open(\"r\") - fichier texte"); + if (f) { + String readBack = f.readString(); + f.close(); + LOG_INFO("Octets relus : %u", (unsigned)readBack.length()); + bool match = (readBack == String(textContent)); + check(match, "Contenu texte identique (round-trip)"); + if (!match) { + LOG_FAIL("--- Attendu ---"); + Serial.println(textContent); + LOG_FAIL("--- Obtenu ---"); + Serial.println(readBack); + } else { + LOG_INFO("Apercu contenu :"); + int lineCount = 0; + for (char c : readBack) { + Serial.print(c); + if (c == '\n' && ++lineCount >= 2) break; + } + Serial.println(); + } + } + } + + // ── Étape 5 : Écriture binaire ─────────────────────────────── + LOG_STEP(5, "Ecriture d'un fichier binaire (256 octets)"); + uint8_t binData[256]; + for (int i = 0; i < 256; i++) binData[i] = (uint8_t)i; // 0x00 … 0xFF + + { + File f = LittleFS.open(TEST_FILE_BIN, "w"); // "w" = FILE_WRITE + check(f, "open(\"w\") - fichier binaire"); + if (f) { + size_t written = f.write(binData, sizeof(binData)); + LOG_INFO("Octets ecrits : %u / %u", (unsigned)written, (unsigned)sizeof(binData)); + check(written == sizeof(binData), "Nombre d'octets ecrits correct (binaire)"); + f.close(); + } + } + + // ── Étape 6 : Relecture binaire byte-à-byte ────────────────── + LOG_STEP(6, "Relecture binaire et verification byte-a-byte"); + { + File f = LittleFS.open(TEST_FILE_BIN, "r"); // "r" = FILE_READ + check(f, "open(\"r\") - fichier binaire"); + if (f) { + check((size_t)f.size() == sizeof(binData), "Taille fichier binaire correcte"); + uint8_t buf[256] = {0}; + size_t bytesRead = f.read(buf, sizeof(buf)); + f.close(); + LOG_INFO("Octets relus : %u", (unsigned)bytesRead); + + bool allMatch = (bytesRead == sizeof(binData)); + uint32_t errors = 0; + for (size_t i = 0; i < bytesRead && i < sizeof(binData); i++) { + if (buf[i] != binData[i]) { + allMatch = false; + errors++; + if (errors <= 5) + LOG_FAIL("Byte[%u] attendu=0x%02X obtenu=0x%02X", + (unsigned)i, binData[i], buf[i]); + } + } + if (errors > 5) + LOG_FAIL("... et %u autre(s) erreur(s).", (unsigned)(errors - 5)); + check(allMatch, "Contenu binaire identique (round-trip)"); + } + } + + // ── Étape 7 : Listage du répertoire ────────────────────────── + LOG_STEP(7, "Listage du répertoire racine"); + LOG_INFO("Contenu de '/' :"); + listDir("/"); + + // ── Étape 8 : Test d'append ─────────────────────────────────── + LOG_STEP(8, "Test d'append (ajout a un fichier existant)"); + { + // Première écriture + File f1 = LittleFS.open(TEST_FILE_APPEND, "w"); // "w" = FILE_WRITE + check(f1, "open(\"w\") - fichier append (creation)"); + if (f1) { f1.println("Premiere ligne."); f1.close(); } + + // Ajout + File f2 = LittleFS.open(TEST_FILE_APPEND, "a"); // "a" = FILE_APPEND + check(f2, "open(\"a\") - ajout"); + if (f2) { f2.println("Deuxieme ligne ajoutee."); f2.close(); } + + // Relecture + File f3 = LittleFS.open(TEST_FILE_APPEND, "r"); // "r" = FILE_READ + check(f3, "open(\"r\") - verification append"); + if (f3) { + String content = f3.readString(); + f3.close(); + bool hasBoth = content.indexOf("Premiere") >= 0 && + content.indexOf("Deuxieme") >= 0; + check(hasBoth, "Les deux lignes presentes apres append"); + LOG_INFO("Contenu apres append :\n%s", content.c_str()); + } + } + + // ── Étape 9 : Renommage ─────────────────────────────────────── + LOG_STEP(9, "Renommage de fichier"); + { + bool renamed = LittleFS.rename(TEST_FILE_APPEND, TEST_FILE_RENAMED); + check(renamed, "rename() - succes"); + check(!LittleFS.exists(TEST_FILE_APPEND), "Ancien nom absent apres rename"); + check(LittleFS.exists(TEST_FILE_RENAMED), "Nouveau nom present apres rename"); + } + + // ── Étape 10 : Suppression ──────────────────────────────────── + LOG_STEP(10, "Suppression de tous les fichiers de test"); + removeFile(TEST_FILE_TEXT); + removeFile(TEST_FILE_BIN); + removeFile(TEST_FILE_RENAMED); + + // ── Étape 11 : Vérification de la suppression ───────────────── + LOG_STEP(11, "Verification de l'absence des fichiers supprimes"); + check(!LittleFS.exists(TEST_FILE_TEXT), "TEST_FILE_TEXT absent"); + check(!LittleFS.exists(TEST_FILE_BIN), "TEST_FILE_BIN absent"); + check(!LittleFS.exists(TEST_FILE_RENAMED), "TEST_FILE_RENAMED absent"); + + LOG_INFO("Contenu final du FS (doit être vide) :"); + listDir("/"); + + // ── Étape 12 : Démontage ────────────────────────────────────── + LOG_STEP(12, "Démontage propre de LittleFS"); + LittleFS.end(); + LOG_OK("LittleFS.end() appelé"); + + // ── Étape 13 : Résumé ───────────────────────────────────────── + Serial.println(); + Serial.println(CLR_BOLD "╔════════════════════════════════════════╗" CLR_RESET); + Serial.println(CLR_BOLD "║ RÉSUMÉ DES TESTS ║" CLR_RESET); + Serial.println(CLR_BOLD "╠════════════════════════════════════════╣" CLR_RESET); + Serial.printf( CLR_BOLD "║ " CLR_GREEN "PASS : %-3u" CLR_BOLD " " CLR_RED "FAIL : %-3u" CLR_BOLD " ║\r\n" CLR_RESET, + (unsigned)g_pass, (unsigned)g_fail); + Serial.println(CLR_BOLD "╠════════════════════════════════════════╣" CLR_RESET); + if (g_fail == 0) { + Serial.println(CLR_BOLD CLR_GREEN "║ ✔ Tous les tests sont PASSÉS ! ║" CLR_RESET); + } else { + Serial.printf( CLR_BOLD CLR_RED "║ ✘ %2u test(s) en ÉCHEC ! ║\r\n" CLR_RESET, + (unsigned)g_fail); + } + Serial.println(CLR_BOLD "╚════════════════════════════════════════╝" CLR_RESET); +} + +// ────────────────────────────────────────────────────────────── +// loop() – rien à faire, on clignote juste la LED interne +// ────────────────────────────────────────────────────────────── +void loop() +{ + // LED built-in sur la plupart des boards ESP32-S3 : GPIO 48 ou 21 + // On clignote pour indiquer que le firmware tourne toujours. +#ifdef LED_BUILTIN + static bool ledState = false; + digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW); + ledState = !ledState; + delay(g_fail == 0 ? 500 : 100); // lent = OK, rapide = erreur +#else + delay(1000); +#endif +}