2

Before starting working, I am just researching around how can I achieve OTA over MQTT in ESP32 in using Arduino IDE. The process I understand the esp listen to MQTT messages and then received that file over MQTT(not fully at once may be in chunks). And then stored that in flash at specific address. And then change boot loader configuration for executing new firmware.

Here I am confused how can I change boot loader configuration settings to execute the new firmware memory address ?? Any help is appreciated.

is there any out of box library available for this work? Please share reference. I can take reference from there.

Thanks

1 Answers1

2

I am not familiar with OTA for ESP32 but with SAMD21 using ArduinoOTA library and there the download is not done over MQTT but HTTPS.

Link to download is sent over MQTT but that's where it ends, download over HTTPS, verification of received data using checksum and bytes count and once InternalStorage.apply() executed it swaps the program downloaded with the older version and reboot.

EDIT:

As per Juraj request, I am adding the code as a guide you can use to get ideas. You can't run it as is, you would need to add variable declaration and wrap it in a function.

As updating wrong file will most likely brick your board, I would just add that before running this code I check the filename to make sure it is the correct BIN for the board downloading it, I am using constants like WIFI, GSM, and board name and expect to see them in the filename.

I also send the file length from the server as part of the MQTT update request and check it against my own bytes count and I am not relying on TCP to provide an error on corrupted data and do a my own checksum test.

#include <ArduinoOTA.h>  // https://github.com/jandrassy/ArduinoOTA

// Access the file HttpClient client(*transport, upgradeServer, upgradePort); client.get(upgradePath);

int statusCode = client.responseStatusCode(); /* 0 HTTP_SUCCESS -1 HTTP_ERROR_CONNECTION_FAILED The end of the headers has been reached. This consumes the '\n' Could not connect to the server -2 HTTP_ERROR_API This call was made when the HttpClient class wasn't expecting it to be called. Usually indicates your code is using the class incorrectly -3 HTTP_ERROR_TIMED_OUT Spent too long waiting for a reply -4 HTTP_ERROR_INVALID_RESPONSE The response from the server is invalid, is it definitely an HTTP server? */

if (statusCode != 200) { client.stop(); // here you can do something with statusCode like notifying over MQTT }

long length = client.contentLength(); if (length == HttpClient::kNoContentLengthHeader) { client.stop(); //Server didn't provide Content-length header, abort. return; }

if (!InternalStorage.open(length)) { client.stop(); // Not enough space to store the file, abort. return; }

// Start update, length holds the file size in bytes

client.setTimeout(5000); byte b; bool ok; long fileLength = length; unsigned long otaStartMillis = millis(); int localChecksum = 0;

while (length > 0) {

ok = client.readBytes(&b, 1); if (!ok) { // Abort, stopped after ((millis() - otaStartMillis)/1000) Sec return; }

InternalStorage.write(b); int bValue = (int)b; localChecksum = localChecksum + bValue;

length--; }

InternalStorage.close(); client.stop();

if (localChecksum != remoteCkecksum) { // Checksum mismatch, abort. return; }

if (length > 0) { // Timeout at byte length, abort. return; }

InternalStorage.apply(); // this doesn't return, board should restart

Serial.println("Update failed"); //shown only if update failed

Another opportunity to thank Jurak for this library!

Nino
  • 411
  • 4
  • 9