esp32-s3_fota_test_wifi/components/fota_manager/fota_manager.c

93 lines
2.8 KiB
C

#include "fota_manager.h"
#include <stdio.h>
#include "esp_log.h"
#include "esp_system.h"
#include "esp_ota_ops.h"
#include "esp_partition.h"
static const char *TAG = "FOTA_MANAGER";
fota_err_t fota_manager_apply(const char *firmware_path)
{
if (!firmware_path) {
ESP_LOGE(TAG, "Firmware path is NULL");
return FOTA_ERR_OPEN;
}
ESP_LOGI(TAG, "Starting FOTA from file: %s", firmware_path);
FILE *fp = fopen(firmware_path, "rb");
if (!fp) {
ESP_LOGE(TAG, "Failed to open firmware file: %s", firmware_path);
return FOTA_ERR_OPEN;
}
const esp_partition_t *running = esp_ota_get_running_partition();
if (!running) {
ESP_LOGE(TAG, "Failed to get running partition");
fclose(fp);
return FOTA_ERR_NO_UPDATE_PART;
}
ESP_LOGI(TAG, "Running partition: label=%s, addr=0x%lx, size=0x%lx",
running->label, (unsigned long)running->address, (unsigned long)running->size);
const esp_partition_t *update = esp_ota_get_next_update_partition(NULL);
if (!update) {
ESP_LOGE(TAG, "Failed to find update partition");
fclose(fp);
return FOTA_ERR_NO_UPDATE_PART;
}
ESP_LOGI(TAG, "Update partition: label=%s, addr=0x%lx, size=0x%lx",
update->label, (unsigned long)update->address, (unsigned long)update->size);
esp_ota_handle_t ota_handle = 0;
esp_err_t err = esp_ota_begin(update, OTA_SIZE_UNKNOWN, &ota_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_begin failed: %s", esp_err_to_name(err));
fclose(fp);
return FOTA_ERR_OTA_BEGIN;
}
uint8_t buffer[4096];
size_t read_bytes = 0;
size_t total_written = 0;
while ((read_bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
err = esp_ota_write(ota_handle, buffer, read_bytes);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_write failed after %u bytes: %s",
(unsigned)total_written, esp_err_to_name(err));
esp_ota_end(ota_handle);
fclose(fp);
return FOTA_ERR_OTA_WRITE;
}
total_written += read_bytes;
}
fclose(fp);
ESP_LOGI(TAG, "FOTA written %u bytes to partition %s",
(unsigned)total_written, update->label);
err = esp_ota_end(ota_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_end failed: %s", esp_err_to_name(err));
return FOTA_ERR_OTA_END;
}
err = esp_ota_set_boot_partition(update);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed: %s", esp_err_to_name(err));
return FOTA_ERR_SET_BOOT;
}
ESP_LOGI(TAG, "FOTA apply success. Next boot from: label=%s, addr=0x%lx",
update->label, (unsigned long)update->address);
return FOTA_OK;
}