ESP32 (37) – https OTA

luca 27/10/2018 10

In the previous post of this tutorial, I explained how it is possible to update your board Over-The-Air thanks to a feature of the Freshen IoT dashboard.

Today I’ll show you how to update the firmware running on an esp32 chip using only components included in the esp-idf framework, without the need of any external tools or platforms.

OTA API

The esp-idf framework offers a set of native functions to implement, in your program, the ability to be updated over the air.

Those functions are grouped in the app_update component and to use them in your program you have to include the corresponding header file:

#include "esp_ota_ops.h"

Altough the use of the native functions is not very difficult (on Github you can find an example program), Espressif developers have added a component to the framework that makes it even easier the over the air update if the new firmware is located on a web site.

The component is named esp_https_ota.

esp_https_ota

The esp_https_ota component uses the OTA API to update the firmware of your board, downloading the binary file that contains the new firmware from a web site. As the name suggests, the only requirement (for security reason) is that the web site supports the secure version of the protocol (HTTPS).

The component is able to automatically identify an OTA partition in the flash memory that is not in use and to save the new firmware in that partition. It then configures the chip to boot from that partition:

https_ota_001

The use is very simple. First create an esp_http_client_config_t struct to configure the URL of the file with the new firmware and the SSL certificate of the server (or the certificate of the CA that signed it):

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

You have to provide the certificate in PEM format. To store the certificate in your program, you can leverage the embedding binary files functionality of the firmware, as I already explained in a previous tutorial.

Then you only have to call the function:

esp_err_t ret = esp_https_ota(&ota_client_config);

to start the update process. If – when the process is complete – the ret variable contains a positive result (ESP_OK), you can reboot the chip to run the new firmware:

esp_restart();

A real application would probably need to periodically check if a new firmware is available and, only in that case, to start the update process. How can it be done?

In the program I wrote for this post and that is explained in the video below, I’m going to show a way widely used also in commercial products… enjoy the show ;)

as usual, the source code of the program is available in my Github repository

10 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…

Leave A Response »

This website uses cookies to ensure you get the best experience on our website 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