[closed] updating the bootloader via OTA -- is it possible?

DrMickeyLauer
Posts: 132
Joined: Sun May 22, 2022 2:42 pm

Re: [closed] updating the bootloader via OTA -- is it possible?

Postby DrMickeyLauer » Thu Mar 14, 2024 11:05 am

Excellent, thanks all. It works fine for me now. Here comes the usual disclaimer: DON'T DO IT, IF YOU DON'T NEED ABSOLUTELY NEED IT.

FWIW, I'm using the following code, in case anyone is interested:

Code: Select all

#pragma once

#include "bootloader.h"

#include "esp_log.h"
#include "esp_ota_ops.h"
#include "esp_flash.h"
#include "esp_task_wdt.h"

#include "sdkconfig.h"

DRAM_ATTR char DRAM_BUF_32K[32768] = {0};

class BootloaderHandler {
public:
    static bool needsUpdate() {

        ESP_LOGD(TAG, "Checking if bootloader needs update");
        esp_bootloader_desc_t bootloader_desc;
        if (esp_err_t err = esp_ota_get_bootloader_description(NULL, &bootloader_desc); err != ESP_OK) {
            ESP_LOGE(TAG, "Failed to get bootloader description (%d). Assuming no update needed", err);
            return false;
        }
        ESP_LOGD(TAG, "Bootloader programmed version: %ld, bootloader available version: %ld", bootloader_desc.version, build_bootloader_bootloader_version);
        return bootloader_desc.version < build_bootloader_bootloader_version;
    }

    static bool performUpdate() {

        ESP_LOGI(TAG, "Performing bootloader update");
        ESP_LOGI(TAG, "Erasing bootloader partition");

        if (auto err = esp_flash_erase_region(esp_flash_default_chip, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, CONFIG_PARTITION_TABLE_OFFSET - CONFIG_BOOTLOADER_OFFSET_IN_FLASH); err != ESP_OK) {
            ESP_LOGE(TAG, "Failed to erase bootloader partition (%d). Can't proceed!", err);
            return false;
        }
        uint8_t attempts = 3;

        while (attempts > 0) {

            ESP_LOGI(TAG, "Writing bootloader partition");
            if (auto err = esp_flash_write(esp_flash_default_chip, build_bootloader_bootloader_bin, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, build_bootloader_bootloader_bin_len); err != ESP_OK) {
                ESP_LOGE(TAG, "Failed to write bootloader partition (%d). Can't proceed!", err);
                return false;
            }

            vTaskDelay(1000 / portTICK_PERIOD_MS);
            
            ESP_LOGI(TAG, "Reading bootloader partition");
            if (auto err = esp_flash_read(esp_flash_default_chip, DRAM_BUF_32K, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, build_bootloader_bootloader_bin_len); err != ESP_OK) {
                ESP_LOGE(TAG, "Failed to read bootloader partition (%d). Can't proceed!", err);
                return false;
            }

            ESP_LOGI(TAG, "Verifying bootloader partition");
            if (memcmp(DRAM_BUF_32K, build_bootloader_bootloader_bin, build_bootloader_bootloader_bin_len) != 0) {
                ESP_LOGE(TAG, "Failed to verify bootloader partition. Retrying...");
                attempts--;
                continue;
            }
            ESP_LOGI(TAG, "Bootloader partition verified");
            return true;
        }

        ESP_LOGE(TAG, "Bootloader update failed, can't proceed!");
        return false;
    }
private:
    static constexpr const char* TAG = "BootloaderHandler";
};

Who is online

Users browsing this forum: DrMickeyLauer and 138 guests