ESP32 openharmony 下双ota升级方案
·
背景:对于资源受限的esp32,官方给的factory和双ota方案是不现实的。目前固件是1.3m,总flash大小是4m。所以需要调整分区表。
环境:目前手上这块esp32是移植了openharmony 5.1.0的系统。是有很多修改点的。
方案:目前采用的升级方案是wifi+http的形式。
调整sdkconfig.h和sdkconfig.gni文件,这是必须要同时调整的,不然用的分区表还是旧的。
修改后分区表如下:
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x180000,
ota_1, app, ota_1, 0x190000, 0x180000,
otadata, data, ota, 0x310000, 0x2000,
storage, data, spiffs, 0x312000, 0xd0000,
sdkconfig.h 修改如下:
// #define CONFIG_PARTITION_TABLE_SINGLE_APP 1
#define CONFIG_PARTITION_TABLE_TWO_OTA 1
#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv"
// #define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv"
#define CONFIG_PARTITION_TABLE_FILENAME "partitions_ota.csv"
sdkconfig.gni 修改:
#
# Partition Table
#
# CONFIG_PARTITION_TABLE_SINGLE_APP=true
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
CONFIG_PARTITION_TABLE_TWO_OTA=true
# CONFIG_PARTITION_TABLE_CUSTOM is not set
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_ota.csv"
CONFIG_PARTITION_TABLE_OFFSET="0x8000"
CONFIG_PARTITION_TABLE_MD5=true
# end of Partition Table
重新编译烧录,烧录前要擦除所有flash,防止之前的分区信息残留。
升级方案程序:接收数据处理部分程序不公开。
static esp_err_t ota_upgrade_handler(httpd_req_t *req)
{
// 检查 Content-Length 是否有效
if (req->content_len <= 0) {
httpd_resp_send_err(req, HTTPD_411_LENGTH_REQUIRED, "Content-Length required");
return ESP_FAIL;
}
const esp_partition_t *running = esp_ota_get_running_partition();
ESP_LOGI("OTA", "Running partition: %s, addr=0x%08x, size=0x%x",
running->label, running->address, running->size);
// 获取下一个可用的 OTA 分区
const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
if (update_partition == NULL) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "No OTA partition found");
return ESP_FAIL;
}
ESP_LOGI("OTA", "Update partition : %s, addr=0x%08x, size=0x%x",
update_partition->label, update_partition->address, update_partition->size);
esp_ota_handle_t ota_handle = 0;
esp_err_t err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &ota_handle);
if (err != ESP_OK) {
ESP_LOGI("OTA", "esp_ota_begin FAILED: %s", esp_err_to_name(err));
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA begin failed");
return ESP_FAIL;
}
// ..... 接收部分不公开
// 完成 OTA 写入
err = esp_ota_end(ota_handle);
if (err != ESP_OK) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA end failed");
return ESP_FAIL;
}
// 设置启动分区为新固件
err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Set boot partition failed");
return ESP_FAIL;
}
ESP_LOGI("OTA", "OTA update complete, restarting...");
// 返回成功响应
httpd_resp_set_type(req, "application/json");
httpd_resp_sendstr(req, "{\"result\":\"upgrading\"}");
// 延迟 2 秒后重启,确保响应已发送
osDelay(200);
g_restart = true;
// 不会执行到这里
return ESP_OK;
}
最终串口运行输出是:
第一次升级输出:
I (272) OTA: Running partition: ota_0, addr=0x00010000, size=0x180000
I (281) OTA: Update partition : ota_1, addr=0x00190000, size=0x180000
第二次升级输出:
I (272) OTA: Running partition: ota_1, addr=0x00190000, size=0x180000
I (281) OTA: Update partition : ota_0, addr=0x00010000, size=0x180000
【注意】分区表信息中type不要搞错,不然升级检索可用ota时会找不到可用的ota。
更多推荐
所有评论(0)