Aggiornamento firmware e filesystem ESP32 dalla scheda SD – 1

Spread the love

Benvenuti ad un’altra puntata della nostra serie sulla gestione del firmware per il microcontrollore ESP32. In questo articolo, esploreremo un metodo non standard ma altamente efficace per aggiornare sia il firmware che il filesystem sul tuo ESP32. Questa tecnica utilizza una scheda SD per archiviare e trasferire i file di aggiornamento, fornendo una soluzione robusta e facilmente accessibile sia per gli sviluppatori che per gli appassionati.

ESP32 firmware and filesystem update from SD card
ESP32 firmware and filesystem update from SD card

Ci addentriamo in questo argomento, svilupperemo le conoscenze acquisite dai precedenti articoli della serie, che coprivano vari metodi per eseguire il flashing di file firmware compilati (.bin), aggiornamenti OTA con Arduino IDE, aggiornamenti basati su browser Web e auto- Aggiornamenti OTA dai server HTTP. In questo articolo, delineeremo i passaggi necessari per preparare il tuo ESP32 per gli aggiornamenti basati su scheda SD, discuteremo i vantaggi e gli svantaggi di questo approccio e forniremo una procedura dettagliata per configurare l’hardware e il software richiesti.

Alla fine di questo articolo, avrai una comprensione completa di come eseguire gli aggiornamenti del firmware e del filesystem ESP32 utilizzando una scheda SD e sarai in grado di prendere una decisione informata sull’idoneità di questo metodo per i requisiti specifici del tuo progetto.

Qui una selezione di esp32 ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S

Aggiornare il firmware con la classe Update

Un altro sistema interessante per aggiornare il firmware è utilizzare una scheda SD o un filesystem locale, per farlo possiamo usare la classe Update.

Un metodo, in particolare, può gestire gli aggiornamenti tramite stream

Update.begin(firmwareSizeInBytes);
Update.writeStream(streamVar);
Update.end();

Usare la scheda SD per l’aggiornamento

sistema ampiamente utilizzato per aggiornare il firmware consiste nell’aggiungere un file all’interno di una memoria esterna come una SD rimovibile e all’avvio del dispositivo, aggiornare con esso.

In questo caso, seguiremo questi passaggi:

  1. Inserire un firmware denominato firmware.binnella SD;
  2. All’avvio controlla se firmware.binesiste;
  3. Se esiste, avvia lo stream/aggiornamento del file;
  4. Alla fine rinominiamo firmware.bin in firmware.bak, così interrompiamo il ciclo di aggiornamenti;
  5. Ripristina e riavvia il microcontrollore.

Cablaggio adattatore SD

Innanzitutto, dobbiamo collegare la SD e puoi seguire questo tutorial, “Come usare la scheda SD con l’esp32“.

ESP32 SD adapter wiring breadboard
Breadboard cablaggio adattatore SD ESP32

Sketch di aggiornamento del firmware tramite scheda SD

Sketch OTA update File system EEPROM WiFi config

Lo Sketch è abbastanza semplice e lo spiegherò in dettaglio.

/*
 * Update ESP32 firmware with external SD
 * Check firmware.bin, if present start update then rename in firmware.bak
 *
 * Renzo Mischianti <www.mischianti.org>
 *
 * https://mischianti.org/
*/

// include the SD library:
#include <SPI.h>
#include <Update.h>
#include <SD.h>

const int chipSelect = SS;

void progressCallBack(size_t currSize, size_t totalSize) {
	  Serial.printf("CALLBACK:  Update process at %d of %d bytes...\n", currSize, totalSize);
}

#define FIRMWARE_VERSION 0.2

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!SD.begin(SS)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  Serial.print("Card size:  ");
  Serial.println((float)SD.cardSize()/1000);

  Serial.print("Total bytes: ");
  Serial.println(SD.totalBytes());

  Serial.print("Used bytes: ");
  Serial.println(SD.usedBytes());

  Serial.print(F("\nCurrent firmware version: "));
  Serial.println(FIRMWARE_VERSION);

  Serial.print(F("\nSearch for firmware.."));
  File firmware =  SD.open("/firmware.bin");
  if (firmware) {
	  Serial.println(F("found!"));
	  Serial.println(F("Try to update!"));

	  Update.onProgress(progressCallBack);

	  Update.begin(firmware.size(), U_FLASH);
	  Update.writeStream(firmware);
	  if (Update.end()){
		  Serial.println(F("Update finished!"));
	  }else{
		  Serial.println(F("Update error!"));
		  Serial.println(Update.getError());
	  }

	  firmware.close();

	  if (SD.rename("/firmware.bin", "/firmware.bak")){
		  Serial.println(F("Firmware rename succesfully!"));
	  }else{
		  Serial.println(F("Firmware rename error!"));
	  }
	  delay(2000);

	  ESP.restart();
  }else{
	  Serial.println(F("not found!"));
  }

  Serial.print(F("Firmware version "));
  Serial.println(FIRMWARE_VERSION);
}

void loop(void) {
}

esp32 sd card adapter connection
esp32 sd card adapter connection

Per prima cosa, proviamo ad aprire firmware.bin

  File firmware =  SD.open("/firmware.bin");
  if (firmware) {

Se il file esiste, avvia lo stream del file nella partizione OTA

	  Update.begin(firmware.size(), U_FLASH);
	  Update.writeStream(firmware);
	  if (Update.end()){

E seguire l’avanzamento con la relativa richiamata

	  Update.onProgress(progressCallBack);

Alla fine, rinomino firmware.bin per impedire un altro aggiornamento al riavvio.

	  if (SD.rename("/firmware.bin", "/firmware.bak")){
		  Serial.println(F("Firmware rename succesfully!"));
	  }else{
		  Serial.println(F("Firmware rename error!"));
	  }

Infine ho riavviato l’esp per consentire la copia del firmware dalla partizione OTA nella flash.

Eseguire il test

Per il test, rimuoveremo la SD e caricheremo lo sketch con questa versione del firmware.

#define FIRMWARE_VERSION 0.1

Quindi modificare la versione in 0.2

#define FIRMWARE_VERSION 0.2

E generare binario compilato fa riferimento all’articolo “ESP32: flash del firmware binario compilato (.bin)

esp8266 esp32 Arduino Export compiled binary IDE menu
esp8266 esp32 Arduino Export compiled binary IDE menu

Ora puoi ottenere il file bin dalla cartella dello schizzo (Sketch -> Show Sketch Folder), copiarlo sulla SD e rinominarlo come firmware.bin.

Ora, quando reinserisci la SD e fai clic sul ripristino, puoi ottenere questo output seriale.

Initializing SD card...Wiring is correct and a card is present.
Card size:  3972006.00
Total bytes: 3967680512
Used bytes: 458752

Current firmware version: 0.10

Search for firmware..found!
Try to update!
CALLBACK:  Update process at 0 of 308272 bytes...
CALLBACK:  Update process at 4096 of 308272 bytes...
CALLBACK:  Update process at 8192 of 308272 bytes...
CALLBACK:  Update process at 12288 of 308272 bytes...
CALLBACK:  Update process at 16384 of 308272 bytes...
CALLBACK:  Update process at 20480 of 308272 bytes...

[...]

CALLBACK:  Update process at 294912 of 308272 bytes...
CALLBACK:  Update process at 299008 of 308272 bytes...
CALLBACK:  Update process at 303104 of 308272 bytes...
CALLBACK:  Update process at 307200 of 308272 bytes...
CALLBACK:  Update process at 308272 of 308272 bytes...
Update finished!
Firmware rename succesfully! 
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_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:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4

Initializing SD card...Wiring is correct and a card is present.
Card size:  3972006.00
Total bytes: 3967680512
Used bytes: 458752 

Current firmware version: 0.20

Search for firmware..not found!
Firmware version 0.20

Generare il file system (SPIFFS, LittleFS e FFat)

Una caratteristica interessante è la gestione dei File System come il firmware compilato.

Aggiungere un output dettagliato all’IDE di Arduino

Per comprendere meglio tutti i processi, abiliteremo l’output dettagliato sul nostro IDE di Arduino. Puoi trovare queste opzioni su File -> Preferences e controllare i controlli Show verbose output.

Arduino IDE enable show verbose ouput
Arduino IDE enables showing verbose output

Ora possiamo prendere e riutilizzare il comando della console.

Generare il file system binario

Per gestire il filesystem, possiamo utilizzare la stessa modalità, ma prima devi leggere una delle seguenti guide:

Dopo tale operazione, puoi utilizzare il plug-in come al solito.

Arduino IDE esp32 SPIFFS Sketch Data Upload
Arduino IDE esp32 SPIFFS Sketch Data Upload
esp32 SPIFFS LittleFS FatFS file uploader from Arduino IDE
esp32 SPIFFS LittleFS FatFS file uploader from Arduino IDE

Puoi controllare l’output della console IDE per verificare cosa è successo.

Chip : esp32
Using partition scheme from Arduino IDE.
Start: 0x290000
Size : 0x170000
mkspiffs : C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\tools\mkspiffs\0.2.3\mkspiffs.exe

espota : C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\espota.exe

[SPIFFS] data   : D:\Projects\Arduino\sloeber-workspace-OTA\ArduinoOTAesp32_basic_arduino\data
[SPIFFS] offset : 0
[SPIFFS] start  : 2686976
[SPIFFS] size   : 1472
[SPIFFS] page   : 256
[SPIFFS] block  : 4096
->/version.txt
[SPIFFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin
[SPIFFS] IP     : 192.168.1.186
Running: C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\espota.exe -i 192.168.1.186 -p 3232 -s -f C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin

_>Sending invitation to 192.168.1.186 
_>Uploading................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
_>09:21:38 [ERROR]: Error response from device
SPIFFS Upload failed!

La console dell’IDE restituisce un errore, ma il caricamento funziona. Penso che ora ci sia un piccolo bug quando scrivo questo articolo.

L’IDE dà un errore ma è un bug, il caricamento funziona correttamente

È possibile recuperare il file bin del file system da questa riga

[SPIFFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin

Sketch per aggiornare il filesystem con un file nella scheda SD

Riutilizzo lo sketch precedente, e aggiungo una sezione per gestire l’aggiornamento del firmware.

/*
 * Update ESP32 firmware with external SD
 * Check firmware.bin, if present start update then rename in firmware.bak
 *
 * Update filesystem with external SD
 * Check filesystem.bin, if present start update then rename in filesystem.bak
 *
 * Renzo Mischianti <www.mischianti.org>
 *
 * https://mischianti.org/
*/

// include the SD library:
#include <SPI.h>
#include <Update.h>
#include <SD.h>
#include <SPIFFS.h>

const int chipSelect = SS;

void progressCallBack(size_t currSize, size_t totalSize) {
	  Serial.printf("CALLBACK:  Update process at %d of %d bytes...\n", currSize, totalSize);
}

#define FIRMWARE_VERSION 0.1
String FILESYSTEM_VERSION = "0.0";

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!SD.begin(SS)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  Serial.print("Card size:  ");
  Serial.println((float)SD.cardSize()/1000);

  Serial.print("Total bytes: ");
  Serial.println(SD.totalBytes());

  Serial.print("Used bytes: ");
  Serial.println(SD.usedBytes());

  Serial.print(F("\nCurrent firmware version: "));
  Serial.println(FIRMWARE_VERSION);

  Serial.print(F("\nSearch for firmware.."));
  File firmware =  SD.open("/firmware.bin");
  if (firmware) {
	  Serial.println(F("found!"));
	  Serial.println(F("Try to update!"));

	  Update.onProgress(progressCallBack);

	  Update.begin(firmware.size(), U_FLASH);
	  Update.writeStream(firmware);
	  if (Update.end()){
		  Serial.println(F("Update finished!"));
	  }else{
		  Serial.println(F("Update error!"));
		  Serial.println(Update.getError());
	  }

	  firmware.close();

	  if (SD.rename("/firmware.bin", "/firmware.bak")){
		  Serial.println(F("Firmware rename succesfully!"));
	  }else{
		  Serial.println(F("Firmware rename error!"));
	  }
	  delay(2000);

	  ESP.restart();
  }else{
	  Serial.println(F("not found!"));
  }

  Serial.print(F("Firmware version "));
  Serial.println(FIRMWARE_VERSION);

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

  Serial.print(F("FileSystem version "));
  File versionFile = SPIFFS.open(F("/version.txt"), "r");
  if (versionFile) {
	  FILESYSTEM_VERSION = versionFile.readString();
	  versionFile.close();
  }
  Serial.println(FILESYSTEM_VERSION);

  Serial.print(F("\nSearch for filesystem update.."));
  File filesystem =  SD.open("/filesystem.bin");
  if (filesystem) {
	  Serial.println(F("found!"));
	  Serial.println(F("Try to update!"));

	  Update.onProgress(progressCallBack);

	  Update.begin(filesystem.size(), U_SPIFFS);
	  Update.writeStream(filesystem);
	  if (Update.end()){
		  Serial.println(F("Update finished!"));
	  }else{
		  Serial.println(F("Update error!"));
		  Serial.println(Update.getError());
	  }

	  filesystem.close();

	  if (SD.rename("/filesystem.bin", "/filesystem.bak")){
		  Serial.println(F("Filesystem rename succesfully!"));
	  }else{
		  Serial.println(F("Filesystem rename error!"));
	  }
	  delay(2000);

	  ESP.restart();
  }else{
	  Serial.println(F("not found!"));
  }


}

void loop(void) {
}

Ci sono delle informazioni relevanti:

	  Update.begin(filesystem.size(), U_SPIFFS);

Cambio U_FLASH in U_SPIFFS, questo imposta internamente l’indirizzo corretto della sezione flash e inizia l’aggiornamento da lì.

Provare lo sketch

Creiamo un file version.txt nella cartella dei dati dello sketch, e scrivo 0.1 all’interno, e lo uso come versione del FileSystem, quindi carico la cartella dei dati nel filesystem.

Initializing SD card...Wiring is correct and a card is present.
Card size:  3972006.00
Total bytes: 3967680512
Used bytes: 458752

Current firmware version: 0.10

Search for firmware..not found!
Firmware version 0.10
Inizializing FS...done.
FileSystem version 0.1

Search for filesystem update..not found!

Ora modificheremo il file version.txt con la versione 0.2, quindi lo caricheremo sul dispositivo, quindi

Cambia versione in 0.2 in version.txt, rigenera senza caricare e copia il file ArduinoOTAesp8266_sd_fs_update.mklittlefs.binsulla SD e rinominalo in filesystem.bin.

Ora inserisci la SD e controlla l’uscita seriale.

Initializing SD card...Wiring is correct and a card is present.
Card size:  3972006.00
Total bytes: 3967680512
Used bytes: 1966080

Current firmware version: 0.10

Search for firmware..not found!
Firmware version 0.10
Inizializing FS...done.
FileSystem version 0.2

Search for filesystem update..found!
Try to update!
CALLBACK:  Update process at 0 of 1507328 bytes...
CALLBACK:  Update process at 4096 of 1507328 bytes...
CALLBACK:  Update process at 8192 of 1507328 bytes...
CALLBACK:  Update process at 12288 of 1507328 bytes...
CALLBACK:  Update process at 16384 of 1507328 bytes...

[...]

CALLBACK:  Update process at 1486848 of 1507328 bytes...
CALLBACK:  Update process at 1490944 of 1507328 bytes...
CALLBACK:  Update process at 1495040 of 1507328 bytes...
CALLBACK:  Update process at 1499136 of 1507328 bytes...
CALLBACK:  Update process at 1503232 of 1507328 bytes...
CALLBACK:  Update process at 1507328 of 1507328 bytes...
Update finished!
Filesystem rename succesfully!
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_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:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4

Initializing SD card...Wiring is correct and a card is present.
Card size:  3972006.00
Total bytes: 3967680512
Used bytes: 1966080

Current firmware version: 0.10

Search for firmware..not found!
Firmware version 0.10
Inizializing FS...done.
FileSystem version 0.3

Search for filesystem update..not found!

La prima volta trova il filesystem.bin poi cambia il nome e la volta successiva non fa nulla.

Grazie

  1. ESP32: piedinatura, specifiche e configurazione dell’Arduino IDE
  2. ESP32: fileSystem integrato SPIFFS
  3. ESP32: gestire più seriali e logging per il debug
  4. ESP32 risparmio energetico pratico
    1. ESP32 risparmio energetico pratico: gestire WiFi e CPU
    2. ESP32 risparmio energetico pratico: modem e light sleep
    3. ESP32 risparmio energetico pratico: deep sleep e ibernazione
    4. ESP32 risparmio energetico pratico: preservare dati al riavvio, sveglia a tempo e tramite tocco
    5. ESP32 risparmio energetico pratico: sveglia esterna e da ULP
    6. ESP32 risparmio energetico pratico: sveglia da UART e GPIO
  5. ESP32: filesystem integrato LittleFS
  6. ESP32: filesystem integrato FFat (Fat/exFAT)
  7. ESP32-wroom-32
    1. ESP32-wroom-32: flash, piedinatura, specifiche e configurazione dell’Arduino IDE
  8. ESP32-CAM
    1. ESP32-CAM: piedinatura, specifiche e configurazione dell’Arduino IDE
    2. ESP32-CAM: upgrade CamerWebServer con gestione della luce flash
  9. ESP32: ethernet w5500 con chiamate standard (HTTP) e SSL (HTTPS)
  10. ESP32: ethernet enc28j60 con chiamate standard (HTTP) e SSL (HTTPS)
  11. Come usare la scheda SD con l’esp32
  12. esp32 e esp8266: file system FAT su memoria SPI flash esterna
  13. Gestione aggiornamenti firmware e OTA
    1. Gestione del firmware
      1. ESP32: flash del firmware binario compilato (.bin)
      2. ESP32: flash del firmware e filesystem (.bin) con strumenti grafici
    2. Aggiornamento OTA con Arduino IDE
      1. Aggiornamenti OTA su ESP32 con Arduino IDE: filesystem, firmware e password
    3. Aggiornamento OTA con browser web
      1. Aggiornamenti OTA su ESP32 tramite browser web: firmware, filesystem e autenticazione
      2. Aggiornamenti OTA su ESP32 tramite browser web: caricamento in HTTPS (SSL/TLS) con certificato autofirmato
      3. Aggiornamenti OTA su ESP32 tramite browser web: interfaccia web personalizzata
    4. Aggiornamenti automatici OTA da un server HTTP
      1. Aggiornamento automatico Firmware OTA dell’ESP32 dal server
      2. Aggiornamento automatico Firmware OTA dell’ESP32 dal server con controllo della versione
      3. Aggiornamento automatico Firmware OTA dell’ESP32 in HTTPS (SSL/TLS) con certificato autofirmato affidabile
    5. Aggiornamento del firmware non standard
      1. Aggiornamento firmware e filesystem ESP32 dalla scheda SD
      2. Aggiornamento firmware e filesystem ESP32 con client FTP
  14. Integrare LAN8720 con ESP32 per la connettività Ethernet con plain (HTTP) e SSL (HTTPS)
  15. Collegare l’EByte E70 (CC1310) ai dispositivi ESP32 c3/s3 ed un semplice sketch di esempio
  16. ESP32-C3: piedinatura, specifiche e configurazione dell’IDE Arduino
  17. Integrazione del modulo W5500 su ESP32 con Core 3: supporto nativo ai protocolli Ethernet con SSL e altre funzionalità
  18. Integrazione del modulo LAN8720 su ESP32 con Core 3: supporto nativo del protocollo Ethernet con SSL e altre funzionalità.

Spread the love

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *