I'm trying to implement an OTA operation from a USB drive. The ESP32-S3 module I'm using reads the contents of the USB drive correctly (I tested it with other files) and detects the OTA binary when present.
The OTA operation however fails with a cryptic message about an MPI timeout:
Code: Select all
I (29915) esp_image: segment 0: paddr=002a0020 vaddr=3c070020 size=1bb5ch (113500) map
I (29933) esp_image: segment 1: paddr=002bbb84 vaddr=3fc95600 size=0264ch ( 9804)
I (29936) esp_image: segment 2: paddr=002be1d8 vaddr=40374000 size=01e40h ( 7744)
I (29941) esp_image: segment 3: paddr=002c0020 vaddr=42000020 size=607a0h (395168) map
I (30002) esp_image: segment 4: paddr=003207c8 vaddr=40375e40 size=0f744h ( 63300)
I (30011) esp_image: segment 5: paddr=0032ff14 vaddr=00000000 size=000bch ( 188)
I (30013) esp_image: Verifying image signature...
I (30015) secure_boot_v2: Take trusted digest key(s) from running app
I (30025) secure_boot_v2: #0 app key digest == #0 trusted key digest
I (30029) secure_boot_v2: Verifying with RSA-PSS...
E (32084) MPI: Timed out waiting for completion of MPI Interrupt
E (32084) secure_boot_v2_rsa: mbedtls_rsa_public failed, err: -17025
E (32087) esp_image: Secure boot signature verification failed
I (32093) esp_image: Calculating simple hash to check for corruption...
W (32149) esp_image: image valid, signature bad
The operation is successful if I disable secure boot.
The whole OTA code is as follows:
Code: Select all
uint8_t fup_proceed(void) {
FILE *f = fopen(FUP_BIN, "r");
if (f == NULL) {
ESP_LOGE(TAG, "Unable to open %s: %s", FUP_BIN, strerror(errno));
return 0;
}
const esp_partition_t *update_partition = NULL;
esp_ota_handle_t update_handle;
update_partition = esp_ota_get_next_update_partition(NULL);
if (update_partition == NULL) {
ESP_LOGE(TAG, "esp_ota_get_next_update_partition failed!");
fclose(f);
return 0;
}
fseek(f, 0L, SEEK_END);
size_t size = ftell(f);
rewind(f);
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%lX, update size %zu", update_partition->subtype,
update_partition->address, size);
// The following call takes about 1000ms, it should be made async (or buffered)
esp_err_t err = ESP_OK;
if ((err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle) != ESP_OK)) {
ESP_LOGE(TAG, "esp_ota_begin failed (0x%04X)!", err);
fclose(f);
return 0;
}
int bytes_read = 0;
const size_t buffer_size = 2048;
uint8_t *buffer = malloc(buffer_size);
if (buffer == NULL) {
ESP_LOGE(TAG, "Unable to allocate memory!");
return 0;
}
size_t total_bytes = 0;
while ((bytes_read = fread(buffer, 1, buffer_size, f)) > 0) {
if ((err = esp_ota_write(update_handle, buffer, bytes_read)) != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_write failed (0x%04X)!", err);
fclose(f);
free(buffer);
return 0;
} else {
total_bytes += bytes_read;
esp_task_wdt_reset();
ESP_LOGI(TAG, "Update: [%8zu/%8zu]", total_bytes, size);
}
}
free(buffer);
fclose(f);
if ((err = esp_ota_end(update_handle)) != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_end failed (0x%04X)!", err);
return 0;
}
if ((ESP_OK == err) && (err = esp_ota_set_boot_partition(update_partition) != ESP_OK)) {
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (0x%04X)!", err);
return 0;
}
esp_restart();
return 1;
}