下午好,我希望有人能帮助我解决以下问题。
情况: 我有一个 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 字节已丢失,我不明白为什么。
如果有人可以帮助我,我将非常感激。
经过几次密集的测试,我终于明白了,我离开了课程的实现,以防它对某人有帮助,无论如何,非常感谢。 请记住,我在开头使用 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;
}