OTA 更新 ESP32 时出现问题。字节丢失

问题描述 投票:0回答:1

下午好,我希望有人能帮助我解决以下问题。

情况: 我有一个 flutter 应用程序通过 links2004/websockets 库连接到托管在 esp32 上的 websockets 服务器(https://github.com/Links2004/arduinoWebSockets)。 我尝试以二进制方式通过套接字传递固件,这个过程是正确的,我还添加了一个标识符字节(以知道我正在更新)和下一个以知道它是否是最后一个,最后我添加了一个计算帧校验和的结果是末尾的字节。

在两端我检查校验和和数据量,但出现以下错误:

提前结束:res:0,pos:864256/1966080

最相关的代码和调试跟踪:

    esp_err_t Updater::handleUpdateData(const uint8_t *data, size_t length)
    {
    //debug vars.
    static int k;
    static int j;
    if (!isUpdateInProgress)
    {
        logger().log("Fatal error, the update isn't started", debug_info_t::WARNING_D);
        return ESP_FAIL;
    }
    if (length < 3)
    {   
        //As I said, I add 3 bytes, therefore at least the frame must contain 3 bytes
        logger().log("Frame length is incosistent, frame is broken", debug_info_t::WARNING_D);
        return ESP_FAIL;
    }
    //To check that it is the last frame, I mark it with the 0xff flag
    bool isLastFragment = (data[1] == 0xFF);

    //the last byte of the frame contains the checksum
    uint8_t receivedChecksum = data[length - 1];
    uint8_t calculatedChecksum = getChecksum(data + 2, length - 3);

    if (calculatedChecksum != receivedChecksum)
    {
        //At this point, if the checksum does not match it would throw an error
        logger().log("Checksum mismatch.", debug_info_t::WARNING_D);
        return ESP_FAIL;
    }

    k+=length-3;
    logger().log(std::to_string(k).c_str());    
    //We write the data to the OTA partition and store its result, to verify that it is exactly           
    //the length received minus the 3 bytes that are not from the firmware
    size_t result=Update.write(const_cast<uint8_t *>(data) + 2, length - 3);
    if ( result!= length - 3) 
    {
      
        logger().log("Failed to write OTA update data.", debug_info_t::WARNING_D);
        return ESP_FAIL;
    }else{
        //debug to check how many bytes are being written to each packet
        std::string s="Packet"+std::to_string(j)+" writted"+ std::to_string(result);
        j++;
        logger().log(s.c_str());
    }

    if (isLastFragment)
    {
        
        std::string lastPacket="Last packet length: "+std::to_string(length-3);
        logger().log(lastPacket.c_str());
        if (!Update.end())
        {
            logger().log("Failed to finalize OTA update.", debug_info_t::WARNING_D);
            return ESP_FAIL;
        }
        else if (Update.isFinished())
        {
            logger().log("OTA update completed successfully.", debug_info_t::DEBUG_D);
           
            ESP.restart(); 
        }
        else
        {
            logger().log("OTA update not finished.", debug_info_t::WARNING_D);
            return ESP_FAIL;
        }
    }

    return ESP_OK;
    }
Debug traces flutter side:
I/flutter ( 5132):packet 0=> 10048

.....
I/flutter ( 5132):packet 85=> 864128
I/flutter ( 5132):packet 86=> 865712

Debug traces ESP32 side:

[INFO]: Packet0 writted=>10048
[INFO]: total=>10048
....
[INFO]: Packet85 writted=>10048
[INFO]: total=> 864128
[INFO]: Packet86 writted=>1584
[INFO]: total=> 865712

根据OS explorer(liux)查看我的firmware.bin文件的属性,固件占用865712字节。

所以我收到以下错误消息: [19662][E][Updater.cpp:284] end():提前结束:res:0,pos:864256/1966080

1456 字节已丢失,我不明白为什么。

如果有人可以帮助我,我将非常感激。

c++ esp32 ota
1个回答
0
投票

经过几次密集的测试,我终于明白了,我离开了课程的实现,以防它对某人有帮助,无论如何,非常感谢。 请记住,我在开头使用 2 个字节,在结尾使用 1 个字节作为校验和。

#include "update_ota.h"
#include "log/log_service.h"

bool Updater::initializeOta(const esp_partition_t **update_partition, 
esp_ota_handle_t *ota_handle, char *log_buffer)
{
*update_partition = esp_ota_get_next_update_partition(nullptr);
if (*update_partition == nullptr)
{
    logger().log("No OTA partition found");
    return false;
}
isUpdateInProgress = true;

esp_err_t err = esp_ota_begin(*update_partition, OTA_SIZE_UNKNOWN, 
ota_handle);
if (err != ESP_OK)
{
    snprintf(log_buffer, sizeof(log_buffer), "esp_ota_begin failed (%s)", 
esp_err_to_name(err));
    logger().log(log_buffer);
    return false;
}

return true;
}
bool Updater::isLastFragment(const uint8_t *data)
{
return data[1] == 0xFF;
}


bool Updater::writeOtaData(esp_ota_handle_t ota_handle, const uint8_t 
*data, 
size_t length, char *log_buffer)
{
esp_err_t err = esp_ota_write(ota_handle, data + 2, length - 3);
if (err != ESP_OK)
{
    snprintf(log_buffer, sizeof(log_buffer), "esp_ota_write failed (%s)", 
esp_err_to_name(err));
    logger().log(log_buffer);
    esp_ota_abort(ota_handle);
    return false;
}
return true;
}

esp_err_t Updater::finalizeOta(esp_ota_handle_t ota_handle, const 
esp_partition_t *update_partition, char *log_buffer)
{
esp_err_t err = esp_ota_end(ota_handle);
if (err != ESP_OK)
{
    snprintf(log_buffer, sizeof(log_buffer), "esp_ota_end failed (%s)", 
esp_err_to_name(err));
    logger().log(log_buffer);
    return ESP_FAIL;
}

err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK)
{
    snprintf(log_buffer, sizeof(log_buffer), "esp_ota_set_boot_partition 
failed (%s)", esp_err_to_name(err));
    logger().log(log_buffer);
    return ESP_FAIL;
}

logger().log("OTA update completed successfully, rebooting...");
vTaskDelay(pdMS_TO_TICKS(1000));
esp_restart();
return ESP_OK;
}

bool Updater::validatePacket(const uint8_t *data, size_t length, char 
*log_buffer, esp_ota_handle_t ota_handle)
{
if (length < 3)
{
    logger().log("Received packet size is too small");
    return false;
}
bool isLastFragment = (data[1] == 0xFF);
uint8_t receivedChecksum = data[length - 1];
uint8_t calculatedChecksum = getChecksum(data + 2, length - 3);
if (calculatedChecksum != receivedChecksum)
{
    logger().log("Checksum mismatch");
    esp_ota_abort(ota_handle);
    return false;
}
return true;
}
esp_err_t Updater::handleUpdateData(const uint8_t *data, size_t length)
{
static const esp_partition_t *update_partition = nullptr;
static esp_ota_handle_t ota_handle;

char log_buffer[128];

if (!isUpdateInProgress)
{
    if (!initializeOta(&update_partition, &ota_handle, log_buffer))
    {
        return ESP_FAIL;
    }
}

if (!validatePacket(data, length, log_buffer, ota_handle))
{
    return ESP_FAIL;
}

if (!writeOtaData(ota_handle, data, length, log_buffer))
{
    return ESP_FAIL;
}

if (isLastFragment(data))
{
    return finalizeOta(ota_handle, update_partition, log_buffer);
}

return ESP_OK;
}
© www.soinside.com 2019 - 2024. All rights reserved.