[SOLVED]OTA over SD SPI

minze25
Posts: 2
Joined: Sat Feb 06, 2021 11:16 am

[SOLVED]OTA over SD SPI

Postby minze25 » Sat Feb 06, 2021 5:13 pm

Hello, I've been trying to update the firmware of the esp32 with an sd-spi card with ota.
What i've tried it's to read the whole .bin file as a binary and store it on a char * buffer but... it doesn't work.

Code: Select all

void try_update() {
    esp_ota_handle_t update_handle = 0;
    const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
    esp_err_t err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
    ESP_LOGI(TAG, "esp_begin result = %d", err);
    binary_data_t *data = readFile(MOUNT_POINT"/update.bin");
    err = esp_ota_write(update_handle, data->data, data->size);
    ESP_LOGI(TAG, "Ota result = %d", err);
    err = esp_ota_end(update_handle);
    if (err != ESP_OK) {
        if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
            ESP_LOGE(TAG, "Image validation failed, image is corrupted");
        }
        ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err));
    }

    err = esp_ota_set_boot_partition(update_partition);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
    }
    ESP_LOGI(TAG, "Prepare to restart system!");
    esp_restart();
}
Any idea on what to do?
Last edited by minze25 on Sun Feb 07, 2021 1:20 pm, edited 1 time in total.

minze25
Posts: 2
Joined: Sat Feb 06, 2021 11:16 am

Re: OTA over SD SPI

Postby minze25 » Sun Feb 07, 2021 1:20 pm

I have solved it myself, the problem was too little ram.

Code: Select all

typedef struct binary_data_t {
    unsigned long size;
    unsigned long remaining_size;
    void *data;
} binary_data_t;

size_t fpread(void *buffer, size_t size, size_t nitems, size_t offset, FILE *fp) {
    if (fseek(fp, offset, SEEK_SET) != 0)
        return 0;
    return fread(buffer, size, nitems, fp);
}


void try_update() {
    esp_ota_handle_t update_handle = 0;
    const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
    esp_err_t err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
    ESP_LOGI(TAG, "esp_begin result = %d", err);
    binary_data_t data;
    FILE *file = fopen(MOUNT_POINT"/update.bin", "rb");
    //Get file length
    fseek(file, 0, SEEK_END);
    data.size = ftell(file);
    data.remaining_size = data.size;
    fseek(file, 0, SEEK_SET);
    ESP_LOGI(TAG, "size %lu", data.size);
    data.data = (char *) malloc(BUFFER_SIZE);
    while (data.remaining_size > 0) {
        size_t size = data.remaining_size <= BUFFER_SIZE ? data.remaining_size : BUFFER_SIZE;
        fpread(data.data, size, 1,
               data.size - data.remaining_size, file);
        err = esp_ota_write(update_handle, data.data, size);
        if (data.remaining_size <= BUFFER_SIZE) {
            break;
        }
        data.remaining_size -= BUFFER_SIZE;
    }

    ESP_LOGI(TAG, "Ota result = %d", err);
    err = esp_ota_end(update_handle);
    if (err != ESP_OK) {
        if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
            ESP_LOGE(TAG, "Image validation failed, image is corrupted");
        }
        ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err));
    }

    err = esp_ota_set_boot_partition(update_partition);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
    }
    ESP_LOGI(TAG, "Prepare to restart system!");
    esp_restart();
}

trombitafolyondar
Posts: 1
Joined: Sun Jul 09, 2023 2:47 pm

Re: [SOLVED]OTA over SD SPI

Postby trombitafolyondar » Sun Jul 09, 2023 2:57 pm

Hey,
Did not you intend to pass "size" and "1" the other way around to fpread?
Like this:

Code: Select all

fpread(data.data, 1, size,
               data.size - data.remaining_size, file);

DreadNaught
Posts: 8
Joined: Thu May 09, 2024 1:17 am

Re: OTA over SD SPI

Postby DreadNaught » Tue Jul 02, 2024 2:20 pm

minze25 wrote:
Sun Feb 07, 2021 1:20 pm
I have solved it myself, the problem was too little ram.

Code: Select all

typedef struct binary_data_t {
    unsigned long size;
    unsigned long remaining_size;
    void *data;
} binary_data_t;

size_t fpread(void *buffer, size_t size, size_t nitems, size_t offset, FILE *fp) {
    if (fseek(fp, offset, SEEK_SET) != 0)
        return 0;
    return fread(buffer, size, nitems, fp);
}


void try_update() {
    esp_ota_handle_t update_handle = 0;
    const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
    esp_err_t err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
    ESP_LOGI(TAG, "esp_begin result = %d", err);
    binary_data_t data;
    FILE *file = fopen(MOUNT_POINT"/update.bin", "rb");
    //Get file length
    fseek(file, 0, SEEK_END);
    data.size = ftell(file);
    data.remaining_size = data.size;
    fseek(file, 0, SEEK_SET);
    ESP_LOGI(TAG, "size %lu", data.size);
    data.data = (char *) malloc(BUFFER_SIZE);
    while (data.remaining_size > 0) {
        size_t size = data.remaining_size <= BUFFER_SIZE ? data.remaining_size : BUFFER_SIZE;
        fpread(data.data, size, 1,
               data.size - data.remaining_size, file);
        err = esp_ota_write(update_handle, data.data, size);
        if (data.remaining_size <= BUFFER_SIZE) {
            break;
        }
        data.remaining_size -= BUFFER_SIZE;
    }

    ESP_LOGI(TAG, "Ota result = %d", err);
    err = esp_ota_end(update_handle);
    if (err != ESP_OK) {
        if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
            ESP_LOGE(TAG, "Image validation failed, image is corrupted");
        }
        ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err));
    }

    err = esp_ota_set_boot_partition(update_partition);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
    }
    ESP_LOGI(TAG, "Prepare to restart system!");
    esp_restart();
}
Thank you for this!!
I read everything I could on doing a SD card update and still didn't see the full picture.
However, your code connected all the dots for me!

I was a little confused about using esp_ota_begin() for a SD card update, but it makes sense now. :)

Who is online

Users browsing this forum: No registered users and 85 guests