esp32 Update from spiffs

Swagger
Posts: 28
Joined: Tue May 19, 2020 3:06 am

Re: esp32 Update from spiffs

Postby Swagger » Fri Jun 19, 2020 1:58 pm

ESP_Sprite wrote:
Tue Jun 16, 2020 2:10 pm
FYI, the partition table would be *a* reason why this could not work, but given that you now corrected it and you still have the error, it's not that. Perhaps you can show the code you're using? Maybe that helps us.

Please find the attached snippet

Code: Select all

void ota_task(void *pvParameter)
{
    esp_err_t err;
    /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */
    esp_ota_handle_t update_handle = 0;
    const esp_partition_t *update_partition = NULL;

    ESP_LOGI(TAG, "Starting OTA example");

    const esp_partition_t *configured = esp_ota_get_boot_partition();
    const esp_partition_t *running = esp_ota_get_running_partition();

    if (configured != running)
    {
        ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x",
                 configured->address, running->address);
        ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)");
    }
    ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
             running->type, running->subtype, running->address);

    update_partition = esp_ota_get_next_update_partition(NULL);
    ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
             update_partition->subtype, update_partition->address);
    assert(update_partition != NULL);

    int binary_file_length = 0;
    /*deal with all receive packet*/
    bool image_header_was_checked = false;
    int file_size = 0;
    FILE *fd = fopen("/spiffs/firmware.bin", "rb+");
    if (fd == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return;
    }
    else
    {
        ESP_LOGI(TAG, "opened a file for reading");
    }
    struct stat st;
    stat("/spiffs/firmware.bin", &st);
    file_size = st.st_size;
    ESP_LOGI(TAG, "file size %d", file_size);
    size_t byteswritten = 0;
    char *buf = NULL;
    buf = (char *)malloc(1024);
    size_t Nbytes;
    while (1)
    {
        while (Nbytes = fread(ota_write_data, 1024, 1, fd), Nbytes > 0)
        {
            if (Nbytes)
            {
                byteswritten += 1024;
            }
            if (byteswritten < 0)
            {
                ESP_LOGE(TAG, "Error: data read error");
                task_fatal_error();
            }
            else if (Nbytes > 0)
            {
                if (image_header_was_checked == false)
                {
                    esp_app_desc_t new_app_info;
                    if (byteswritten > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t))
                    {
                        // check current version with downloading
                        memcpy(&new_app_info, &ota_write_data[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));
                        ESP_LOGI(TAG, "New firmware version: %s", new_app_info.version);

                        esp_app_desc_t running_app_info;
                        if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK)
                        {
                            ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);
                        }

                        const esp_partition_t *last_invalid_app = esp_ota_get_last_invalid_partition();
                        esp_app_desc_t invalid_app_info;
                        if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK)
                        {
                            ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version);
                        }

                        // check current version with last invalid partition
                        if (last_invalid_app != NULL)
                        {
                            if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0)
                            {
                                ESP_LOGW(TAG, "New version is the same as invalid version.");
                                ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version);
                                ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");
                            }
                        }

                        if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0)
                        {
                            ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
                            // return;
                            vTaskDelete(NULL);
                        }

                        image_header_was_checked = true;

                        err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
                        if (err != ESP_OK)
                        {
                            ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
                            task_fatal_error();
                        }
                        ESP_LOGI(TAG, "esp_ota_begin succeeded");
                    }
                    else
                    {
                        ESP_LOGE(TAG, "received package is not fit len");
                        task_fatal_error();
                    }
                }
                err = esp_ota_write(update_handle, (const void *)ota_write_data, strlen(ota_write_data));
                if (err != ESP_OK)
                {
                    task_fatal_error();
                }

                binary_file_length += byteswritten;
                ESP_LOGD(TAG, "Written image length %d", binary_file_length);
            }
            Nbytes = 0;
        }
        ESP_LOGI(TAG, "completed");
        break;
    }
    ESP_LOGI(TAG, "Total Write binary data length : %d", binary_file_length);

    if (esp_ota_end(update_handle) != ESP_OK)
    {
        ESP_LOGE(TAG, "esp_ota_end failed%s", esp_err_to_name(esp_ota_end(update_handle)));
        task_fatal_error();
    }

    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));
        task_fatal_error();
    }
    ESP_LOGI(TAG, "Prepare to restart system!");
    esp_restart();
    return;
}


ESP_Sprite
Posts: 9772
Joined: Thu Nov 26, 2015 4:08 am

Re: esp32 Update from spiffs

Postby ESP_Sprite » Fri Jun 19, 2020 5:57 pm

I see at least two issues casually browsing through your code. There may be more, but these I noticed:
Minor but potentially killing: You use fread in such a way that it fails to read the last bytes of data if the size of the update file is not a multiple of 1024. (nmemb vs size arguments)
Major and certainly killing: you're using strlen to figure out the size of a binary string that can contain zero bytes.

Swagger
Posts: 28
Joined: Tue May 19, 2020 3:06 am

Re: esp32 Update from spiffs

Postby Swagger » Sun Jun 21, 2020 6:30 am

ESP_Sprite wrote:
Fri Jun 19, 2020 5:57 pm
I see at least two issues casually browsing through your code. There may be more, but these I noticed:
Minor but potentially killing: You use fread in such a way that it fails to read the last bytes of data if the size of the update file is not a multiple of 1024. (nmemb vs size arguments)
Major and certainly killing: you're using strlen to figure out the size of a binary string that can contain zero bytes.
hi, thanks for your reply. That was the issue causing. I am was able to solve it. But after solving it it went on to another error.

I (183648) OTA: Total Write binary data length : 254115840
I (183658) boot_comm: chip revision: 1, min. application chip revision: 0
I (183668) esp_image: segment 0: paddr=0x00110020 vaddr=0x3f400020 size=0x1e5d4
(124372) map
I (183708) esp_image: segment 1: paddr=0x0012e5fc vaddr=0x3ffbdb60 size=0x01a14
( 6676)
I (183718) esp_image: segment 2: paddr=0x00130018 vaddr=0x400d0018 size=0x7c030
(507952) map
0x400d0018: _stext at ??:?

I (183888) esp_image: segment 3: paddr=0x001ac050 vaddr=0x3ffbf574 size=0x014bc
( 5308)
I (183898) esp_image: segment 4: paddr=0x001ad514 vaddr=0x40080000 size=0x00400
( 1024)
0x40080000: _WindowOverflow4 at C:/msys32/home/Dotnet/esp/esp-idf/components/fre
ertos/xtensa_vectors.S:1778

I (183908) esp_image: segment 5: paddr=0x001ad91c vaddr=0x40080400 size=0x12814
( 75796)
E (183938) esp_image: Checksum failed. Calculated 0xb0 read 0xff
E (183938) OTA: esp_ota_end failedESP_ERR_NOT_FOUND
E (183938) OTA: Exiting task due to fatal error...

chegewara
Posts: 2378
Joined: Wed Jun 14, 2017 9:00 pm

Re: esp32 Update from spiffs

Postby chegewara » Sun Jun 21, 2020 8:08 am

Swagger wrote: I (183648) OTA: Total Write binary data length : 254115840
This is big problem. esp-idf is supporting binary up to 3MB if i remember, for sure much less than 250MB.

Swagger
Posts: 28
Joined: Tue May 19, 2020 3:06 am

Re: esp32 Update from spiffs

Postby Swagger » Sun Jun 21, 2020 11:01 am

Hi, Thanks, bro. my mistake. I had corrected the code.
Attaching the working snippet. not a tidy code. just for functionality testing.

Code: Select all

void esp32_ota_task(void *pvParameter)
{
    esp_err_t err;
    /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */
    esp_ota_handle_t update_handle = 0;
    const esp_partition_t *update_partition = NULL;

    ESP_LOGI(TAG, "Starting OTA example");

    const esp_partition_t *configured = esp_ota_get_boot_partition();
    const esp_partition_t *running = esp_ota_get_running_partition();

    if (configured != running)
    {
        ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x",
                 configured->address, running->address);
        ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)");
    }
    ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
             running->type, running->subtype, running->address);

    update_partition = esp_ota_get_next_update_partition(NULL);
    ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
             update_partition->subtype, update_partition->address);
    assert(update_partition != NULL);

    int binary_file_length = 0;
    /*deal with all receive packet*/
    bool image_header_was_checked = false;
    int file_size = 0;
    FILE *fd = fopen("/spiffs/firmware.bin", "rb+");
    if (fd == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return;
    }
    else
    {
        ESP_LOGI(TAG, "opened file for reading");
    }
    struct stat st;
    stat("/spiffs/firmware.bin", &st);
    file_size = st.st_size;
    int number = (int)file_size / 1024;
    int size = 1024;
    ESP_LOGI(TAG, "file size %d", file_size);
    size_t byteswritten = 0;
    char *buf = NULL;
    buf = (char *)malloc(1024);
    size_t Nbytes;

    while (!feof(fd)) // to read file
    {

        while (Nbytes = fread(ota_write_data, size, 1, fd), Nbytes > 0)
        {
            byteswritten += size;
            if (byteswritten < 0)
            {
                ESP_LOGE(TAG, "Error: data read error");
                task_fatal_error();
            }
            else if (Nbytes > 0)
            {
                if (image_header_was_checked == false)
                {
  
                    esp_app_desc_t new_app_info;
                    if (byteswritten > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t))
                    {
                        // check current version with downloading
                        memcpy(&new_app_info, &ota_write_data[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));
                        ESP_LOGI(TAG, "New firmware version: %s", new_app_info.version);

                        esp_app_desc_t running_app_info;
                        if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK)
                        {
                            ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);
                        }

                        const esp_partition_t *last_invalid_app = esp_ota_get_last_invalid_partition();
                        esp_app_desc_t invalid_app_info;
                        if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK)
                        {
                            ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version);
                        }

                        // check current version with last invalid partition
                        if (last_invalid_app != NULL)
                        {
                            if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0)
                            {
                                ESP_LOGW(TAG, "New version is the same as invalid version.");
                                ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version);
                                ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");
                            }
                        }

                        if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0)
                        {
                            ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
                            // return;
                            vTaskDelete(NULL);
                        }

                        image_header_was_checked = true;

                        err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
                        if (err != ESP_OK)
                        {
                            ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
                            task_fatal_error();
                        }
                        ESP_LOGI(TAG, "esp_ota_begin succeeded");
                    }
                    else
                    {
                        ESP_LOGE(TAG, "received package is not fit len");
                        task_fatal_error();
                    }
                }
                err = esp_ota_write(update_handle, (const void *)ota_write_data, size);
                if (err != ESP_OK)
                {
                    task_fatal_error();
                }
                ESP_LOGD(TAG, "Written image length %d", byteswritten);
            }
            Nbytes = 0;
            number -= 1;
            if (number == 0)
            {
                size = file_size % 1024;
            }
        }
        ESP_LOGI(TAG, "completed");
        break;
    }
    fclose(fd);
    binary_file_length = byteswritten;
    ESP_LOGI(TAG, "Total Write binary data length : %d", binary_file_length);

    if (esp_ota_end(update_handle) != ESP_OK)
    {
        ESP_LOGE(TAG, "esp_ota_end failed%s", esp_err_to_name(esp_ota_end(update_handle)));
        task_fatal_error();
    }

    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));
        task_fatal_error();
    }
    ESP_LOGI(TAG, "Prepare to restart system!");
    esp_restart();
    return;
}

georgeman93
Posts: 1
Joined: Mon Feb 21, 2022 4:49 am

Re: esp32 Update from spiffs

Postby georgeman93 » Mon Feb 21, 2022 4:51 am

Did you solve this? I am having the same problem except with OTA via HTTP GET instead of reading from SPIFFS.

Who is online

Users browsing this forum: No registered users and 77 guests