esp8266 aggiornamenti del firmware e del filesystem da scheda SD – 1

Spread the love

In questa serie di articoli sul firmware e su come aggiornarlo, vorrei aggiungere una serie di metodi alternativi di aggiornamento per me molto utili.

esp8266 firmware and filesystem update from SD card
esp8266 firmware and filesystem update from SD card

In questo articolo impareremo come utilizzare la memoria esterna come la scheda SD per aggiornare il firmware e il filesystem.

Aggiornare il firmware da una memoria con la classe Update

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

Un metodo, in particolare, può gestire l’aggiornamento via stream

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

Usare la scheda SD per l’aggiornamento

Un 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 aggiornarlo con esso.

In questo caso, seguiremo questi passaggi:

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

Collegare l’adattatore SD

Innanzitutto, dobbiamo cablare la SD e puoi seguire questo tutorial “Come utilizzare la scheda SD con esp8266 e Arduino“.

WeMos D1 mini esp8266 SD adapter wiring
WeMos D1 mini esp8266 SD adapter wiring

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 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 <SD.h>

// WeMos D1 esp8266: D8 as standard
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

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.");
  }

  FSInfo fs_info;
  SDFS.info(fs_info);

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

  Serial.print("Used bytes: ");
  Serial.println(fs_info.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.reset();
  }else{
	  Serial.println(F("not found!"));
  }


}

void loop(void) {
}

WeMos D1 mini esp8266 SD adapter wiring photo
WeMos D1 mini esp8266 SD adapter wiring photo

Per prima cosa, proviamo ad aprire firmware.bin

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

Se il file esiste, avvia il flusso del file nella partizione OTA

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

E seguiamo l’andamento con la relativa chiamata

	  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, riavvio l’esp per consentire la copia del firmware dalla partizione OTA alla flash.

Test

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

#define FIRMWARE_VERSION 0.1

Quindi cambia la versione in 0.2

#define FIRMWARE_VERSION 0.2

Per generare il binario compilato riferiamoci all’articolo “esp8266: flash del firmware binario (.bin) compilato e firmato“.

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 Sketch (Sketch -> Show Sketch Folder), copiarlo sulla SD e rinominarlo come firmware.bin.

Quando reinserisci la SD e fai clic su reset, puoi ottenere questo output dalla seriale.

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

Current firmware version: 0.10

Search for firmware..found!
Try to update!
CALLBACK:  Update process at 0 of 309424 bytes...
CALLBACK:  Update process at 4096 of 309424 bytes...
CALLBACK:  Update process at 8192 of 309424 bytes...
CALLBACK:  Update process at 12288 of 309424 bytes...
CALLBACK:  Update process at 16384 of 309424 bytes...
CALLBACK:  Update process at 20480 of 309424 bytes...
CALLBACK:  Update process at 24576 of 309424 bytes...
CALLBACK:  Update process at 28672 of 309424 bytes...
CALLBACK:  Update process at 32768 of 309424 bytes...
CALLBACK:  Update process at 36864 of 309424 bytes...

[...]

CALLBACK:  Update process at 270336 of 309424 bytes...
CALLBACK:  Update process at 274432 of 309424 bytes...
CALLBACK:  Update process at 278528 of 309424 bytes...
CALLBACK:  Update process at 282624 of 309424 bytes...
CALLBACK:  Update process at 286720 of 309424 bytes...
CALLBACK:  Update process at 290816 of 309424 bytes...
CALLBACK:  Update process at 294912 of 309424 bytes...
CALLBACK:  Update process at 299008 of 309424 bytes...
CALLBACK:  Update process at 303104 of 309424 bytes...
CALLBACK:  Update process at 307200 of 309424 bytes...
CALLBACK:  Update process at 309424 of 309424 bytes...
CALLBACK:  Update process at 309424 of 309424 bytes...
Update finished!
Firmware rename succesfully!

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3460, room 16 
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4 
tail 4
chksum 0xc9
csum 0xc9
v0005b4c0
@cp:B0
ld

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

Current firmware version: 0.20

Search for firmware..not found!

Aggiornare il filesystem da un archivio con la classe Update

È possibile specificare cosa si desidera aggiornare FLASH (firmware) o FS (filesystem).

Ora mostreremo come gestire il filesystem, ma andiamo veloci perché le modifiche sono state minime.

Generare il file con il file system binario

Per gestire il filesystem possiamo usare lo stesso modo, ma prima devi leggere una delle seguenti guide:

WeMos D1 mini (esp8266), file system SPIFFS integrato (obsoleto)

WeMos D1 mini (esp8266), file system LittleFS integrato (consigliato)

Aggiungeremo la directory dei dati alla cartella dello sketch e utilizzeremo il plug-in per caricarlo.

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

Nella console troviamo il comando giusto per generare questo file.

[LittleFS] data    : D:\tmp\testBlink\Blink\data
[LittleFS] size    : 2024
[LittleFS] page    : 256
[LittleFS] block   : 8192
/bombo.png
[LittleFS] upload  : C:\Users\renzo\AppData\Local\Temp\arduino_build_49036/Blink.mklittlefs.bin
[LittleFS] address : 0x200000
[LittleFS] reset   : --before default_reset --after hard_reset
[LittleFS] port    : COM17
[LittleFS] speed   : 921600
[LittleFS] python   : C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\tools\python3\3.7.2-post1\python3.exe
[LittleFS] uploader : C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\tools\upload.py

esptool.py v2.8
Serial port COM17
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 50:02:91:74:fe:11
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 2072576 bytes to 48389...
Wrote 2072576 bytes (48389 compressed) at 0x00200000 in 4.9 seconds (effective 3416.7 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Ora possiamo raccogliere molte informazioni; primo, il file

[LittleFS] upload  : C:\Users\renzo\AppData\Local\Temp\arduino_build_49036/Blink.mklittlefs.bin

Sketch per aggiornare il filesystem con un file nella scheda SD

Riutilizzo lo sketch precedente e aggiungerò una sezione per gestire l’aggiornamento del firmware.

/*
 * Update 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 <SD.h>

// WeMos D1 esp8266: D8 as standard
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

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.");
  }

  FSInfo fs_info;
  SDFS.info(fs_info);

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

  Serial.print("Used bytes: ");
  Serial.println(fs_info.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.reset();
  }else{
	  Serial.println(F("not found!"));
  }

  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_FS);
	  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.reset();
  }else{
	  Serial.println(F("not found!"));
  }


}

void loop(void) {
}

L’informazione rilevanti che puoi trovare qui è questa

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

Ho cambiato U_FLASH in U_FS; questo ha impostato internamente l’indirizzo corretto della sezione flash e da lì ha iniziato ad aggiornare.

Prova lo sketch

Creiamo un file version.txt sulla cartella dei dati dello schizzo 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.
Total bytes: 3967680512
Used bytes: 655360

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

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

Ora inserisci l’SD e controlla l’uscita seriale.

Initializing SD card...Wiring is correct and a card is present.
Total bytes: 3967680512
Used bytes: 2228224

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..found!
Try to update!
CALLBACK:  Update process at 0 of 2072576 bytes...
CALLBACK:  Update process at 4096 of 2072576 bytes...
CALLBACK:  Update process at 8192 of 2072576 bytes...
CALLBACK:  Update process at 12288 of 2072576 bytes...
CALLBACK:  Update process at 16384 of 2072576 bytes...
CALLBACK:  Update process at 20480 of 2072576 bytes...
CALLBACK:  Update process at 24576 of 2072576 bytes...
CALLBACK:  Update process at 28672 of 2072576 bytes...
CALLBACK:  Update process at 32768 of 2072576 bytes...
CALLBACK:  Update process at 36864 of 2072576 bytes...
CALLBACK:  Update process at 40960 of 2072576 bytes...
CALLBACK:  Update process at 45056 of 2072576 bytes...
CALLBACK:  Update process at 49152 of 2072576 bytes...
CALLBACK:  Update process at 53248 of 2072576 bytes...
CALLBACK:  Update process at 57344 of 2072576 bytes...
CALLBACK:  Update process at 61440 of 2072576 bytes...
CALLBACK:  Update process at 65536 of 2072576 bytes...
CALLBACK:  Update process at 69632 of 2072576 bytes...
CALLBACK:  Update process at 73728 of 2072576 bytes...
CALLBACK:  Update process at 77824 of 2072576 bytes...

[...]

CALLBACK:  Update process at 2052096 of 2072576 bytes...
CALLBACK:  Update process at 2056192 of 2072576 bytes...
CALLBACK:  Update process at 2060288 of 2072576 bytes...
CALLBACK:  Update process at 2064384 of 2072576 bytes...
CALLBACK:  Update process at 2068480 of 2072576 bytes...
CALLBACK:  Update process at 2072576 of 2072576 bytes...
CALLBACK:  Update process at 2072576 of 2072576 bytes...
Update finished!
Filesystem rename succesfully!

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x4010f000, len 3460, room 16 
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4 
tail 4
chksum 0xc9
csum 0xc9
v00051e80
~ld

Initializing SD card...Wiring is correct and a card is present.
Total bytes: 3967680512
Used bytes: 2228224

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..not found!

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

Grazie

  1. Firmware and OTA update

Spread the love

Lascia un commento

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