Skip to content

How to use OTA Rollback? [ QUESTION ] #7422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
zekageri opened this issue Nov 1, 2022 · 5 comments
Closed
1 task done

How to use OTA Rollback? [ QUESTION ] #7422

zekageri opened this issue Nov 1, 2022 · 5 comments
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@zekageri
Copy link

zekageri commented Nov 1, 2022

Board

ESP32-Wrover-E

Device Description

custom

Hardware Configuration

custom

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

Windows 11

Flash frequency

80mhz

PSRAM enabled

yes

Upload speed

115200

Description

I use OTA heavily. If i upload a new sketch which crashes at some point, how to roll back to the previous update?
I tracked some issues and forums but i couldn't find any example related to arduino.

  1. Rollback with Arduino as ESP-IDF Component #5871
  2. https://esp32.com/viewtopic.php?t=10096
  3. https://stackoverflow.com/questions/55644842/how-do-i-use-the-rollback-feature-of-esp32-efficiently
  4. App rollback /w Arduino as an ESP-IDF component #3318

How to enable OTA rollback feature?
How to overwrite verifyRollbackLater() or verifyOTA() ?

Sketch

void checkFirmware(){
    const esp_partition_t *running = esp_ota_get_running_partition();
    esp_ota_img_states_t ota_state;
    if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
        if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
            if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {
                ESP_LOGI(TAG, "App is valid, rollback cancelled successfully");
            } else {
                ESP_LOGE(TAG, "Failed to cancel rollback");
            }
        }
    }
}

Debug Message

src/drivers/system/Sys.cpp: In member function 'void Sys::checkFirmware()':
src/drivers/system/Sys.cpp:382:38: error: 'esp_ota_get_running_partition' was not declared in this scope
     const esp_partition_t *running = esp_ota_get_running_partition();      
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/drivers/system/Sys.cpp:383:5: error: 'esp_ota_img_states_t' was not declared in this scope
     esp_ota_img_states_t ota_state;
     ^~~~~~~~~~~~~~~~~~~~
src/drivers/system/Sys.cpp:383:5: note: suggested alternative: 'esp_spiram_test'
     esp_ota_img_states_t ota_state;
     ^~~~~~~~~~~~~~~~~~~~
     esp_spiram_test
src/drivers/system/Sys.cpp:384:47: error: 'ota_state' was not declared in this scope
     if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {      
                                               ^~~~~~~~~
src/drivers/system/Sys.cpp:384:47: note: suggested alternative: 'setstate'  
     if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {      
                                               ^~~~~~~~~
                                               setstate
src/drivers/system/Sys.cpp:384:9: error: 'esp_ota_get_state_partition' was not declared in this scope
     if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {      
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
src/drivers/system/Sys.cpp:384:9: note: suggested alternative: 'esp_timer_start_periodic'
     if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {      
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
         esp_timer_start_periodic
src/drivers/system/Sys.cpp:385:26: error: 'ESP_OTA_IMG_PENDING_VERIFY' was not declared in this scope
         if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~
src/drivers/system/Sys.cpp:386:17: error: 'esp_ota_mark_app_valid_cancel_rollback' was not declared in this scope
             if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {      
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** [.pio\build\esp-wrover-kit\src\drivers\system\Sys.cpp.o] Error 1
======================= [FAILED] Took 25.64 seconds =======================

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@zekageri zekageri added the Status: Awaiting triage Issue is waiting for triage label Nov 1, 2022
@zekageri
Copy link
Author

zekageri commented Nov 1, 2022

If i include #include "esp_ota_ops.h"

It compiles but esp_ota_img_states_t ota_state; is always ESP_OTA_IMG_VALID.

void checkFirmware(){
    Serial.printf("[SYSTEM] - Checking firmware...\n");
    const esp_partition_t *running = esp_ota_get_running_partition();
    esp_ota_img_states_t ota_state;
    if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
        const char* otaState = ota_state == ESP_OTA_IMG_NEW ? "ESP_OTA_IMG_NEW"
            : ota_state == ESP_OTA_IMG_PENDING_VERIFY ? "ESP_OTA_IMG_PENDING_VERIFY"
            : ota_state == ESP_OTA_IMG_VALID ? "ESP_OTA_IMG_VALID"
            : ota_state == ESP_OTA_IMG_INVALID ? "ESP_OTA_IMG_INVALID"
            : ota_state == ESP_OTA_IMG_ABORTED ? "ESP_OTA_IMG_ABORTED"
            : "ESP_OTA_IMG_UNDEFINED";
        Serial.printf("[System] - Ota state: %s\n",otaState);

        if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
            if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {
                Serial.printf("[System] - App is valid, rollback cancelled successfully\n");
            } else {
                Serial.printf("[System] - Failed to cancel rollback\n");
            }
        }
    }else{
        Serial.printf("[System] - OTA partition has no record in OTA data\n");
    }
}

Debug:

[SYSTEM] - Checking firmware...
[System] - Ota state: ESP_OTA_IMG_VALID

every time

@zekageri
Copy link
Author

zekageri commented Nov 1, 2022

#include "esp_ota_ops.h"
#define CONFIG_APP_ROLLBACK_ENABLE

// Redefine function to return true instead of false??
// Not working?? 
// Commit: https://github.com/espressif/arduino-esp32/pull/6779/commits/b9b4f07a01b461c782ea79af5b84767d915fb2c5
boolean verifyRollbackLater(){
    return true;
}

void checkFirmware(){
    Serial.printf("[SYSTEM] - Checking firmware...\n");
    const esp_partition_t *running = esp_ota_get_running_partition();
    esp_ota_img_states_t ota_state;
    if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
        const char* otaState = ota_state == ESP_OTA_IMG_NEW ? "ESP_OTA_IMG_NEW"
            : ota_state == ESP_OTA_IMG_PENDING_VERIFY ? "ESP_OTA_IMG_PENDING_VERIFY"
            : ota_state == ESP_OTA_IMG_VALID ? "ESP_OTA_IMG_VALID"
            : ota_state == ESP_OTA_IMG_INVALID ? "ESP_OTA_IMG_INVALID"
            : ota_state == ESP_OTA_IMG_ABORTED ? "ESP_OTA_IMG_ABORTED"
            : "ESP_OTA_IMG_UNDEFINED";
        Serial.printf("[System] - Ota state: %s\n",otaState);

        if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
            if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {
                Serial.printf("[System] - App is valid, rollback cancelled successfully\n");
            } else {
                Serial.printf("[System] - Failed to cancel rollback\n");
            }
        }
    }else{
        Serial.printf("[System] - OTA partition has no record in OTA data\n");
    }
}

void setup(){
    Serial.begin(115200);
    checkFirmware();
}

void loop(){
}

@zekageri
Copy link
Author

zekageri commented Nov 1, 2022

This PR https://github.com/espressif/arduino-esp32/pull/6779/files

Does not work.

bool verifyRollbackLater(){
    return true;
}

void Sys::verifyFirmware(){
    if( !shouldCheckFirmware ){ return; }
    if( (millis() - startMS) <= FIRMWARE_CHECK_MS ){ return; }
    shouldCheckFirmware = false;
    debug.print(DEBUG_INFO,"[SYSTEM] - Verifying firmware...\n");
    const esp_partition_t *running = esp_ota_get_running_partition();
    esp_ota_img_states_t ota_state;
    if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
        const char* otaState = ota_state == ESP_OTA_IMG_NEW ? "ESP_OTA_IMG_NEW"
            : ota_state == ESP_OTA_IMG_PENDING_VERIFY ? "ESP_OTA_IMG_PENDING_VERIFY"
            : ota_state == ESP_OTA_IMG_VALID ? "ESP_OTA_IMG_VALID"
            : ota_state == ESP_OTA_IMG_INVALID ? "ESP_OTA_IMG_INVALID"
            : ota_state == ESP_OTA_IMG_ABORTED ? "ESP_OTA_IMG_ABORTED"
            : "ESP_OTA_IMG_UNDEFINED";
        debug.print(DEBUG_INFO, "[System] - Ota state: %s\n",otaState);

        if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
            if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {
                debug.print(DEBUG_INFO, "[System] - App is valid, rollback cancelled successfully\n");
            } else {
                debug.print(DEBUG_WARN, "[System] - Failed to cancel rollback\n");
            }
        }
    }else{
        debug.print(DEBUG_ERROR,"[System] - OTA partition has no record in OTA data\n");
    }
}

I always get:

[SYSTEM] - Verifying firmware...
[System] - Ota state: ESP_OTA_IMG_VALID

@zekageri
Copy link
Author

zekageri commented Nov 1, 2022

Opened a clear ticket

#7423

@zekageri zekageri closed this as not planned Won't fix, can't repro, duplicate, stale Nov 1, 2022
@MicSG-dev
Copy link

MicSG-dev commented Jan 24, 2025

just call esp_ota_mark_app_invalid_rollback_and_reboot(). You are only responsible for checking if your firmware is suitable, otherwise you can revert to the previous firmware.

You need to include #include "esp_ota_ops.h".

Source (documentation):
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ota.html#app-rollback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

No branches or pull requests

2 participants