Обновление ESP32 OTA через MQTT с помощью "update.h"

Я пытаюсь выполнить OTA через MQTT с помощью обновления.библиотека h. Я публикую файл прошивки через MQTT в указанном размере. Файл получен в конце ESP32. Я предоставляю полученные данные для обновления.пишите. В начале ~150 пакетов успешно записаны. Но после этого update.write начал выдавать ошибку Неправильного магического байта.

Вот фрагмент кода, который я использую внутри ESP32

#include "mqtt_handler.h"
StaticJsonDocument <256> root;
uint8_t temp[100] = {0};
size_t length ;
void otaHandler(byte *msg, unsigned int len)
{
deserializeJson(root,msg);
String command = root["command"];
if (command.equals("ota.start"))
{
    Serial.println("OTA.START via MQTT");
    if (!Update.begin(UPDATE_SIZE_UNKNOWN))
    {
        Update.printError(Serial);
    }
}
else if (command.equals("ota.write"))
{
    Serial.println("OTA.WRITE via MQTT");
    memset(temp, 0, 100);
    length = root["length"];
    String data = root["data"]; 
    for (int i = 0; i < length; i++)
    {
        temp[i] = data[i];
    }
    

    Serial.println(data);
    if (Update.write(temp, length) != length)
    {
        Update.printError(Serial);
    }
}
else if (command.equals("ota.end"))
{
    Serial.println("OTA.END via MQTT");
    if (Update.end(true))
    {
        Serial.printf("Update Success \nRebooting...\n");
    }
    else
    {
        Update.printError(Serial);
    }
}
else
{
    Serial.println("Something went worng");
}
}
void callback(char* topic, byte* message, unsigned int length) {
otaHandler(message,length);
}

В этом коде обратный вызов-это метод, который вызывается при поступлении сообщения MQTT.Это соответствующий код, при необходимости я могу поделиться полным кодом.

Сообщение, отправленное приложением python, выглядит следующим образом:

{"command" : "ota.start"}
{"command": "ota.write", "length": length, "data": data})
{"command" : "ota.end"}

Ниже приведен снимок данных, отправленных приложением Python в вышеприведенном сообщении ota.write:

Ниже приведен снимок того, как выглядит мой файл прошивки:

Я делюсь этим снимком, чтобы показать формат данных, в котором я публикую файл прошивки.

Ниже приведен снимок последовательного монитора:

Пожалуйста, подскажите мне, если я чего-то не понимаю в этом вопросе.

Спасибо

, 👍2

Обсуждение

Это сообщение в основном означает, что вы неправильно отформатировали данные изображения. Первый байт всегда должен быть 0xE9 (как на картинке вашей прошивки). Я подозреваю, что вы отправляете некоторое представление данных в формате ASCII, а не конвертируете их обратно в двоичный файл, как следовало бы., @Majenko

При более внимательном рассмотрении кажется, что вы просто уничтожаете десятичное ASCII-представление данных, которые было бы абсолютно невозможно проанализировать., @Majenko

Да, я отправляю десятичный ASCII, например, 0XE9 равно 233. В каком формате он ожидает данные ?? Двоичный ??, @Abhishek bhatia

Он ожидает двоичные данные. Вы несете ответственность за то, чтобы вернуть ваше текстовое представление в двоичный формат, с которого оно начиналось. Я бы предложил использовать шестнадцатеричный в качестве транспортного уровня, а не десятичный, и использовать заполнение нуля. Например, вы не можете определить, равен 3224465 32 244 65 или 3 224 46 5. Сохраняйте его в шестнадцатеричном формате и всегда по 2 символа на байт, затем в коде C возьмите каждую пару шестнадцатеричных символов и преобразуйте их обратно в двоичный код., @Majenko


1 ответ


2

Вы просто запускаете в свой код непространственный поток десятичных представлений ASCII двоичных данных, а затем записываете эти данные ASCII дословно во флэш-память. Это никогда не сработает.

Вместо этого вам нужно выбрать ASCII-представление ваших данных, которое на самом деле поддается синтаксическому анализу (я бы предложил придерживаться шестнадцатеричного представления и всегда использовать 2 цифры, поэтому обозначайте 0x6 как "06"), затем, когда вы получаете пакет, вы должны преобразовать содержимое обратно в двоичный код перед отправкой его в библиотеку обновлений.

Как есть, вы берете байт (например, 0xE9) и преобразуете его в десятичный код ASCII, который равен 223. Затем вы записываете 2, 2 и 3 в виде отдельных байтов во флэш - память в формате ASCII, в результате чего получается 0x32,0x32,0x33-или печатаете десятичным числом в неразрешимом потоке 505051.

,