背景对于资源受限的esp32官方给的factory和双ota方案是不现实的。目前固件是1.3m总flash大小是4m。所以需要调整分区表。环境目前手上这块esp32是移植了openharmony 5.1.0的系统。是有很多修改点的。方案目前采用的升级方案是wifihttp的形式。调整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.csvsdkconfig.gni 修改# # Partition Table # # CONFIG_PARTITION_TABLE_SINGLE_APPtrue # CONFIG_PARTITION_TABLE_TWO_OTA is not set CONFIG_PARTITION_TABLE_TWO_OTAtrue # CONFIG_PARTITION_TABLE_CUSTOM is not set CONFIG_PARTITION_TABLE_CUSTOM_FILENAMEpartitions.csv CONFIG_PARTITION_TABLE_FILENAMEpartitions_ota.csv CONFIG_PARTITION_TABLE_OFFSET0x8000 CONFIG_PARTITION_TABLE_MD5true # 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, addr0x%08x, size0x%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, addr0x%08x, size0x%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, addr0x00010000, size0x180000 I (281) OTA: Update partition : ota_1, addr0x00190000, size0x180000第二次升级输出I (272) OTA: Running partition: ota_1, addr0x00190000, size0x180000 I (281) OTA: Update partition : ota_0, addr0x00010000, size0x180000【注意】分区表信息中type不要搞错不然升级检索可用ota时会找不到可用的ota。