ESP32 (37) – OTA via https

luca 27/10/2018 14

Nel precedente articolo di questo tutorial, vi ho mostrato come sia possibile effettuare un aggiornamento Over-The-Air grazie alle funzionalità della dashboard Freshen.

Oggi vi spiegherò come aggiornare il firmware in esecuzione sul chip esp32 utilizzando solo il framework esp-idf, senza la necessità di dashboard esterne.

OTA API

Il framework esp-idf mette a disposizione una serie di funzioni native per implementare, in un nostro programma, la capacità di aggiornarsi over the air.

Tali funzioni si trovano nel componente app_update e per utilizzarle dobbiamo includere il relativo header file:

#include "esp_ota_ops.h"

Sebbene non sia complesso l’utilizzo di queste funzioni native (su Github potete trovare un programma di esempio), gli sviluppatori di Espressif hanno aggiunto al framework un componente che rende ancora più facile l’aggiornamento over the air, nel caso in cui il nuovo firmware si trovi su un sito web.

Tale componente si chiama esp_https_ota.

esp_https_ota

Il componente esp_https_ota utilizza le OTA API per aggiornare il firmware, scaricando la nuova versione da un sito web. Come il nome suggerisce, l’unico requisito (per questioni di sicurezza) è che tale sito web sia disponibile con protocollo sicuro (HTTPS).

Il componente è in grado di identificare automaticamente la partizione OTA non in uso nella memoria flash e di caricare in tale partizione il nuovo firmware; configurando infine il chip per effettuare il boot da tale partizione:

https_ota_001

Il suo utilizzo è davvero semplice. Per prima cosa creiamo una struct di tipo esp_http_client_config_t dove configurare l’URL del file che contiene il nuovo firmware e il certificato SSL del server (o della CA che lo ha firmato):

esp_http_client_config_t ota_client_config = {
  .url = "https://mysite.com/newfirmware.bin",
  .cert_pem = server_cert_pem_start,
};

Il certificato deve essere fornito in formato PEM. Per caricarlo all’interno del nostro programma, possiamo utilizzare le funzionalità di embedding binary files del framework come vi ho già spiegato in un precedente tutorial.

Ora è sufficiente il comando:

esp_err_t ret = esp_https_ota(&ota_client_config);

Per avviare il processo di aggiornamento. Se al termine la variabile ret contiene un esito positivo (ESP_OK), possiamo riavviare il chip in modo che il nuovo firmware sia eseguito:

esp_restart();

In una applicazione reale, abbiamo però la necessità di controllare periodicamente se sia disponibile un nuovo firmware e, solo in tal caso, procedere con l’aggiornamento. Come possiamo fare?

Nel programma che ho preparato per questo articolo e che illustro nel video seguente, vi mostro una modalità molto utilizzata anche in progetti commerciali… buona visione ;)

come al solito, il sorgente del programma è disponibile nel mio repository Github e il video contiene sottotitoli in italiano

14 Comments »

  1. Andrew Sweeney 12/12/2018 at 17:08 - Reply

    Really like this Luca. Just what I need! Keep up the good work.

    • Kostas 17/01/2019 at 12:17 - Reply

      Hello Luca. I would like to ask if you know any way to download OTA with HTTPS + mutual authentication. Have you ever tried this before ? I’ve been looking inside “esp_http_client_config_t” but there is no clients cert* only servers cert.

      Regards, Kostas.

      • luca 19/01/2019 at 09:50 - Reply

        hi Kostas, at the moment the http client used by the OTA component seems to not support mutual authentication…

  2. Andrea 07/02/2019 at 22:06 - Reply

    Ciao Luca, complimenti per gli articoli! C’è un modo per sostituire il certificato in formato PEM caricato nel programma con la funzionalità embedding binary files con un altro certificato senza ricompilare il firmware? Ad esempio caricandolo da scheda sd? Ho provato con le funzionalità SPI Flash APIs del framework ma non ho trovato una soluzione…
    Grazie Andrea

    • luca 09/02/2019 at 16:00 - Reply

      Ciao Andrea, se guardi come è fatta la struct, vedrai che il certificato è in una variabile char*, quindi puoi memorizzarlo dove preferisci (flash, sd…). Semplicemente dovrai “leggerlo” dal supporto e memorizzarlo (alla fine è una sequenza di bytes) in una variabile appunto char* che potrai poi passare alla struct.

      • Andrea 10/02/2019 at 15:30 - Reply

        Grazie Luca per il supporto, farò come mi hai detto!

  3. Mattia Berton 12/02/2019 at 18:04 - Reply

    Ciao Luca,
    innanzitutto, complimenti, davvero, per il tuo lavoro. Sei chiaro e “pulito”.
    Sul firmware, ho un piccolo dubbio, nel senso che è un errore che non riesco bene a capire se ce l’ho solo io: se il programma lancia il task di aggiornamento del sistema tante volte, e non trova il firmware corretto, comincia ad avere dei problemi di leakage di memoria.
    Quando anche, diciamo dopo 15 volte, trova il firmware da aggiornare, non riesce più ad aprire correttamente un socket TLS.
    Ho fatto un check sulla heap, ed effettivamente noto un calo della memoria heap disponibile.

    Hai mai avuto modo di approfondire?
    Ciao e buon lavoro,
    Mattia

    • luca 16/02/2019 at 11:22 - Reply

      ciao Mattia… non mi è mai capitato ma effettivamente non ho lasciato girare a lungo il programma. Lanciando il “cleanup” finale dovrebbe liberare tutta la memoria, possibile che sia qualche bug del componente esp_http_client. Stai usando l’ultima versione del firmware?

  4. David 18/02/2019 at 05:12 - Reply

    Luca
    Does the jSON file just contain the firmware version number and the url of the firmware?
    e.g. {1.0: “https://mywebsite/firmware.bin”}

  5. Arun 05/03/2019 at 14:38 - Reply

    hello
    Very nice explanation…

  6. Sarath 26/03/2019 at 10:54 - Reply

    It’s great,
    does this support for nodemcu.because I am doing a project on home automation using nodemcu as a microcontroller.

    • luca 04/04/2019 at 08:11 - Reply

      you can find on the internet some tutorials about how to perform OTA using NodeMCU…

  7. shivani 29/03/2019 at 10:45 - Reply

    Can it be possible from any network? I mean my question is that if I want to update my firmware from other location and that IP is not static, it is dynamic then can I update my firmware.

    • luca 04/04/2019 at 08:09 - Reply

      sure! if the server that hosts your firmware has a dynamic IP address, you have to use a dyndns service to have a “static” name for it

Leave A Response »

Fare clic qui per annullare la risposta.

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi