mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
feat(app_update): Add auto-confirmation of OTA updates
Enable rollback auto-confirmation by default
This commit is contained in:
committed by
Konstantin Kondrashov
parent
dce5812654
commit
de1e5035b5
@@ -5,6 +5,7 @@ if(${target} STREQUAL "linux")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "esp_ota_ops.c"
|
||||
"ota_auto_confirm.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES partition_table bootloader_support
|
||||
esp_app_format esp_bootloader_format esp_partition
|
||||
@@ -16,6 +17,12 @@ idf_component_register(SRCS "esp_ota_ops.c"
|
||||
# link time without app_update forcing mbedtls in by itself.
|
||||
idf_component_optional_requires(PRIVATE mbedtls)
|
||||
|
||||
if(CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP)
|
||||
# ota_auto_confirm.c has no other externally referenced symbol, so force the linker to pull
|
||||
# it in from the archive to override the weak esp_ota_confirm_rollback_hook() in freertos.
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_ota_confirm_rollback_hook")
|
||||
endif()
|
||||
|
||||
idf_define_esp_err_codes(HEADERS include/esp_ota_ops.h)
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
@@ -127,7 +127,7 @@ static esp_err_t image_validate(const esp_partition_t *partition, esp_image_load
|
||||
|
||||
static esp_ota_img_states_t set_new_state_otadata(void)
|
||||
{
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
ESP_LOGD(TAG, "Monitoring the first boot of the app is enabled.");
|
||||
return ESP_OTA_IMG_NEW;
|
||||
#else
|
||||
@@ -176,7 +176,7 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp
|
||||
return ESP_ERR_OTA_PARTITION_CONFLICT;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
esp_ota_img_states_t ota_state_running_part;
|
||||
if (esp_ota_get_state_partition(running_partition, &ota_state_running_part) == ESP_OK) {
|
||||
if (ota_state_running_part == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
@@ -221,7 +221,7 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
if (is_ota_partition(partition)) {
|
||||
esp_ota_invalidate_inactive_ota_data_slot();
|
||||
}
|
||||
@@ -259,7 +259,7 @@ esp_err_t esp_ota_resume(const esp_partition_t *partition, const size_t erase_si
|
||||
return ESP_ERR_OTA_PARTITION_CONFLICT;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
// Mirror esp_ota_begin(): refuse to resume an OTA into an app slot while the running
|
||||
// app is still pending verification, otherwise the rollback target could be
|
||||
// overwritten during the unconfirmed window.
|
||||
@@ -1376,7 +1376,7 @@ esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_i
|
||||
|
||||
const esp_partition_t *running_app_part = esp_ota_get_running_partition();
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
esp_ota_img_states_t running_app_state;
|
||||
ret = esp_ota_get_state_partition(running_app_part, &running_app_state);
|
||||
if (ret != ESP_OK) {
|
||||
|
||||
45
components/app_update/ota_auto_confirm.c
Normal file
45
components/app_update/ota_auto_confirm.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
ESP_LOG_ATTR_TAG(TAG, "ota_auto_confirm");
|
||||
|
||||
// Strong override of the weak hook declared in components/freertos/app_startup.c
|
||||
void esp_ota_confirm_rollback_hook(void)
|
||||
{
|
||||
esp_ota_img_states_t ota_state;
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
|
||||
if (esp_ota_get_state_partition(running, &ota_state) != ESP_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
ESP_LOGI(TAG, "Auto-confirming OTA application as valid");
|
||||
|
||||
} else if (ota_state == ESP_OTA_IMG_NEW) {
|
||||
/* The bootloader does not support rollback: it did not transition
|
||||
* the OTA state from ESP_OTA_IMG_NEW to ESP_OTA_IMG_PENDING_VERIFY.
|
||||
* Mark as VALID to keep the state consistent. */
|
||||
ESP_LOGW(TAG, "Bootloader is not capable of rollback");
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_ota_mark_app_valid_cancel_rollback();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to mark app valid: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP */
|
||||
@@ -4,6 +4,7 @@ components/app_update/test_apps:
|
||||
enable:
|
||||
- if: CONFIG_NAME == "defaults" and IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c5", "esp32c6", "esp32c61", "esp32h2", "esp32p4", "esp32s2", "esp32s3"]
|
||||
- if: CONFIG_NAME == "rollback" and IDF_TARGET in ["esp32", "esp32c3", "esp32s3", "esp32p4"]
|
||||
- if: CONFIG_NAME == "rollback_disabled" and IDF_TARGET in ["esp32", "esp32c3", "esp32s3", "esp32p4"]
|
||||
- if: CONFIG_NAME == "xip_psram" and SOC_SPIRAM_XIP_SUPPORTED == 1
|
||||
# S2 doesn't have ROM for flash
|
||||
- if: CONFIG_NAME == "xip_psram_with_rom_impl" and (SOC_SPIRAM_XIP_SUPPORTED == 1 and IDF_TARGET != "esp32s2")
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "bootloader_common.h"
|
||||
#include "../bootloader_flash/include/bootloader_flash_priv.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "unity.h"
|
||||
#include "utils_update.h"
|
||||
#include "sdkconfig.h"
|
||||
@@ -248,6 +249,7 @@ static void test_flow5(void)
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][reset=SW_CPU_RESET, SW_CPU_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
static void test_rollback1(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
@@ -265,7 +267,7 @@ static void test_rollback1(void)
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
@@ -277,7 +279,7 @@ static void test_rollback1(void)
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
@@ -329,7 +331,9 @@ static void test_rollback1_1(void)
|
||||
// 4 Stage: run OTA0 -> check it -> esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
static void test_rollback2(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
@@ -347,7 +351,7 @@ static void test_rollback2(void)
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
@@ -359,7 +363,7 @@ static void test_rollback2(void)
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
@@ -370,7 +374,7 @@ static void test_rollback2(void)
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
@@ -382,7 +386,7 @@ static void test_rollback2(void)
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
|
||||
#else
|
||||
@@ -416,7 +420,7 @@ static void test_rollback2_1(void)
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(invalid_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_INVALID, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_ABORTED, ota_state);
|
||||
@@ -430,7 +434,9 @@ static void test_rollback2_1(void)
|
||||
// 4 Stage: run OTA1 -> check it -> PENDING_VERIFY/esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run OTA0(rollback) -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
static void test_erase_last_app_flow(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
@@ -484,7 +490,9 @@ static void test_erase_last_app_rollback(void)
|
||||
// 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
static void test_flow6(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
@@ -515,6 +523,7 @@ static void test_flow6(void)
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0 using esp_ota_write_with_offset", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow6, test_flow6);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
TEST_CASE("Test esp_partition_get_sha256 returns ESP_ERR_IMAGE_INVALID when image is invalid", "[partitions]")
|
||||
{
|
||||
@@ -538,6 +547,7 @@ TEST_CASE("Test esp_partition_get_sha256 returns ESP_ERR_IMAGE_INVALID when imag
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same");
|
||||
}
|
||||
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
static void test_rollback3(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
@@ -567,7 +577,7 @@ static void test_rollback3(void)
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
|
||||
update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
// two partitions are valid
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
esp_ota_img_states_t ota_state;
|
||||
@@ -578,7 +588,7 @@ static void test_rollback3(void)
|
||||
esp_ota_handle_t update_handle = 0;
|
||||
TEST_ESP_OK(esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle));
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
// After esp_ota_begin, the only one partition is valid
|
||||
// ota data slots do not have an entry about the update_partition.
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
@@ -610,7 +620,7 @@ static void test_rollback3_1(void)
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
const esp_partition_t* next_update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_NULL(next_update_partition);
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
// ota data slots do not have an entry about the next_update_partition.
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_ota_get_state_partition(next_update_partition, &ota_state));
|
||||
#endif
|
||||
@@ -618,7 +628,9 @@ static void test_rollback3_1(void)
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. Updated partition invalidated after esp_ota_begin", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback3, test_rollback3, test_rollback3, test_rollback3_1);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
static void test_rollback4(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
@@ -643,7 +655,7 @@ static void test_rollback4(void)
|
||||
// This will not change the running partition since we haven't rebooted.
|
||||
// The esp_rewrite_otadata() will update the otadata for the non-running partition only.
|
||||
app_update();
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
// The last call to esp_rewrite_otadata should have updated the otadata for the non-running partition only.
|
||||
// Therefore, calling esp_ota_get_state_partition on the running partition should succeed and not return ESP_ERR_NOT_FOUND
|
||||
const esp_partition_t* running_partition;
|
||||
@@ -666,3 +678,41 @@ static void test_rollback4(void)
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("Test esp_rewrite_otadata. Updated sequence number for non-running partition always", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback4, test_rollback4, test_rollback4);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
static void test_ota_auto_confirm(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
boot_count++;
|
||||
set_boot_count_in_nvs(boot_count);
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory: writing OTA0 and rebooting");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
app_update();
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0: verifying OTA app was auto-confirmed during startup");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> verify OTA app was auto-confirmed, state is VALID -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test OTA auto-confirm during startup (PENDING_VERIFY -> VALID)", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_ota_auto_confirm, test_ota_auto_confirm);
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
@@ -288,7 +288,7 @@ void reset_output_pin(uint32_t num_pin)
|
||||
|
||||
void mark_app_valid(void)
|
||||
{
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ def test_app_update_xip_psram_rom_impl(dut: Dut) -> None:
|
||||
'config',
|
||||
[
|
||||
'rollback',
|
||||
'rollback_disabled',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
|
||||
@@ -1 +1 @@
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP=y
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Covers the CONFIG_BOOTLOADER_APP_ROLLBACK=n code paths, no longer exercised by any other config.
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK=n
|
||||
@@ -1,20 +1,51 @@
|
||||
menu "Application Rollback"
|
||||
|
||||
config BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
bool "Enable app rollback support"
|
||||
default n
|
||||
config BOOTLOADER_APP_ROLLBACK
|
||||
bool "Enable application rollback"
|
||||
default y
|
||||
help
|
||||
After updating the app, the bootloader runs a new app with the "ESP_OTA_IMG_PENDING_VERIFY" state set.
|
||||
This state prevents the re-run of this app. After the first boot of the new app in the user code, the
|
||||
function should be called to confirm the operability of the app or vice versa about its non-operability.
|
||||
If the app is working, then it is marked as valid. Otherwise, it is marked as not valid and rolls back to
|
||||
the previous working app. A reboot is performed, and the app is booted before the software update.
|
||||
Note: If during the first boot a new app the power goes out or the WDT works, then roll back will happen.
|
||||
Rollback is possible only between the apps with the same security versions.
|
||||
After an OTA update, the bootloader starts the new application in the
|
||||
ESP_OTA_IMG_PENDING_VERIFY state. If the application resets, crashes, or
|
||||
loses power before being confirmed valid, the bootloader marks it as
|
||||
aborted on the next boot and selects the previously working application
|
||||
instead.
|
||||
|
||||
Disabling this option removes the automatic recovery path after a
|
||||
failed OTA update: a failed update can leave the device with an
|
||||
unbootable application.
|
||||
|
||||
choice BOOTLOADER_APP_ROLLBACK_CONFIRM_MODE
|
||||
prompt "Rollback confirmation checkpoint"
|
||||
depends on BOOTLOADER_APP_ROLLBACK
|
||||
default BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
|
||||
config BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP
|
||||
bool "Confirm app automatically during system startup"
|
||||
help
|
||||
The application is marked valid near the end of system startup,
|
||||
immediately before app_main is called. Reaching app_main is treated
|
||||
as a successful boot; this confirms IDF startup completed but does
|
||||
not verify application-specific functionality.
|
||||
|
||||
Since the state is already ESP_OTA_IMG_VALID by the time app_main
|
||||
runs, application code cannot use esp_ota_get_state_partition() to
|
||||
detect the first boot of a new application.
|
||||
|
||||
config BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP
|
||||
bool "Application decides the confirmation checkpoint"
|
||||
help
|
||||
The application must confirm itself valid during its first boot by
|
||||
calling esp_ota_mark_app_valid_cancel_rollback(), or reject the
|
||||
update with esp_ota_mark_app_invalid_rollback_and_reboot(). If
|
||||
neither is called before a reset, the bootloader marks the app as
|
||||
aborted and rolls back to the previous working application.
|
||||
|
||||
Rollback is possible only between apps with the same security version.
|
||||
endchoice
|
||||
|
||||
config BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
bool "Enable app anti-rollback support"
|
||||
depends on BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
depends on BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP
|
||||
default n
|
||||
help
|
||||
This option prevents rollback to previous firmware/application image with lower security version.
|
||||
|
||||
@@ -9,7 +9,8 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO CONFIG_BOOTLOADER_LO
|
||||
CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG
|
||||
CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE
|
||||
|
||||
CONFIG_APP_ROLLBACK_ENABLE CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
CONFIG_APP_ROLLBACK_ENABLE CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP
|
||||
CONFIG_APP_ANTI_ROLLBACK CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
CONFIG_APP_SECURE_VERSION CONFIG_BOOTLOADER_APP_SECURE_VERSION
|
||||
CONFIG_APP_SECURE_VERSION_SIZE_EFUSE_FIELD CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
|
||||
|
||||
@@ -390,7 +390,7 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
|
||||
ESP_LOGD(TAG, "otadata[0]: sequence values 0x%08"PRIx32, otadata[0].ota_seq);
|
||||
ESP_LOGD(TAG, "otadata[1]: sequence values 0x%08"PRIx32, otadata[1].ota_seq);
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
bool write_encrypted = esp_efuse_is_flash_encryption_enabled();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (otadata[i].ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
@@ -440,13 +440,13 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
|
||||
uint32_t ota_seq = otadata[active_otadata].ota_seq - 1; // Raw OTA sequence number. May be more than # of OTA slots
|
||||
boot_index = ota_seq % bs->app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "Mapping seq %"PRIu32" -> OTA slot %d", ota_seq, boot_index);
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
if (otadata[active_otadata].ota_state == ESP_OTA_IMG_NEW) {
|
||||
ESP_LOGD(TAG, "otadata[%d] is selected as new and marked PENDING_VERIFY state", active_otadata);
|
||||
otadata[active_otadata].ota_state = ESP_OTA_IMG_PENDING_VERIFY;
|
||||
write_otadata(&otadata[active_otadata], bs->ota_info.offset + FLASH_SECTOR_SIZE * active_otadata, write_encrypted);
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#endif // CONFIG_BOOTLOADER_APP_ROLLBACK
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
if (otadata[active_otadata].ota_state == ESP_OTA_IMG_VALID) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -197,6 +197,12 @@ static void main_task(void* args)
|
||||
ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config));
|
||||
#endif // CONFIG_ESP_TASK_WDT
|
||||
|
||||
// app_update overrides it to auto-confirm an OTA rollback right before app_main.
|
||||
void __attribute__((weak)) esp_ota_confirm_rollback_hook(void);
|
||||
if (esp_ota_confirm_rollback_hook != NULL) {
|
||||
esp_ota_confirm_rollback_hook();
|
||||
}
|
||||
|
||||
/*
|
||||
Note: Be careful when changing the "Calling app_main()" log below as multiple pytest scripts expect this log as a
|
||||
start-of-application marker.
|
||||
|
||||
@@ -38,13 +38,24 @@ The OTA data partition is two flash sectors (0x2000 bytes) in size, to prevent p
|
||||
App Rollback
|
||||
------------
|
||||
|
||||
The main purpose of the application rollback is to keep the device working after the update. This feature allows you to roll back to the previous working application in case a new application has critical errors. When the rollback process is enabled and an OTA update provides a new version of the app, one of three things can happen:
|
||||
The main purpose of application rollback is to keep the device working after an update. This feature allows the device to return to the previous working application if a new application has critical errors.
|
||||
|
||||
Application rollback is enabled by default via :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK`. Disabling this option removes the automatic recovery path after a failed OTA update, and the confirmation mode choice described below is not available.
|
||||
|
||||
Application rollback supports two confirmation modes. Both modes enable rollback and start a new OTA application in the ``ESP_OTA_IMG_PENDING_VERIFY`` state. They differ only in when the application is confirmed:
|
||||
|
||||
* **Confirm app automatically during system startup** (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP>`) is the default. ESP-IDF marks the application as valid after IDF component initialization completes and immediately before calling ``app_main``.
|
||||
* **Application decides the confirmation checkpoint** (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP>`) leaves the application pending until it explicitly confirms or rejects the update. This allows application code to detect the first boot, run self-tests, and choose its own confirmation point.
|
||||
|
||||
Switching between these confirmation modes does not change the bootloader rollback behavior; it only changes the confirmation point in the application. Therefore, a rollback-capable bootloader does not need to be rebuilt or updated when switching between automatic and application-controlled confirmation.
|
||||
|
||||
If the application resets, crashes, or loses power before the selected confirmation point, the bootloader rolls back to the previous working application on the next boot. When rollback is enabled and an OTA update provides a new version of the application, one of three things can happen:
|
||||
|
||||
* The application works fine, :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` marks the running application with the state ``ESP_OTA_IMG_VALID``. There are no restrictions on booting this application.
|
||||
* The application has critical errors and further work is not possible, a rollback to the previous application is required, :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` marks the running application with the state ``ESP_OTA_IMG_INVALID`` and reset. This application will not be selected by the bootloader for boot and will boot the previously working application.
|
||||
* If the :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is set, and a reset occurs without calling either function then the application is rolled back.
|
||||
* If a reset occurs before the application is confirmed, the application is rolled back.
|
||||
|
||||
The following code serves detect the initial boot for an application after the OTA update. Upon the first boot, the application checks its state and performs diagnostics. If the diagnostics are successful, the application should call :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` to confirm the operability of the application. If the diagnostics fail, the application should call :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` to roll back to the previous working application.
|
||||
The following code shows application-controlled confirmation (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP>`). On the first boot after an OTA update, the application observes the ``ESP_OTA_IMG_PENDING_VERIFY`` state and performs diagnostics. If the diagnostics are successful, the application should call :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` to confirm its operability. If the diagnostics fail, the application should call :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` to roll back to the previous working application.
|
||||
|
||||
If the application is not able to boot or execute this code due to an abort/reboot/power loss error, the bootloader marks this application as ``ESP_OTA_IMG_INVALID`` in the next booting attempt and rolls back to the previous working application.
|
||||
|
||||
@@ -84,23 +95,23 @@ States control the process of selecting a boot app:
|
||||
ESP_OTA_IMG_UNDEFINED None restriction. Will be selected.
|
||||
ESP_OTA_IMG_INVALID Will not be selected.
|
||||
ESP_OTA_IMG_ABORTED Will not be selected.
|
||||
ESP_OTA_IMG_NEW If :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is set it will
|
||||
ESP_OTA_IMG_NEW When application rollback is enabled, it will
|
||||
be selected only once. In bootloader the state immediately changes to
|
||||
``ESP_OTA_IMG_PENDING_VERIFY``.
|
||||
ESP_OTA_IMG_PENDING_VERIFY If :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is set it will
|
||||
ESP_OTA_IMG_PENDING_VERIFY When application rollback is enabled, it will
|
||||
not be selected, and the state will change to ``ESP_OTA_IMG_ABORTED``.
|
||||
============================= ======================================================================
|
||||
|
||||
If :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is not enabled (by default), then the use of the following functions :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` and :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` are optional, and ``ESP_OTA_IMG_NEW`` and ``ESP_OTA_IMG_PENDING_VERIFY`` states are not used.
|
||||
If application rollback is disabled, then the use of the following functions :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` and :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` is optional, and ``ESP_OTA_IMG_NEW`` and ``ESP_OTA_IMG_PENDING_VERIFY`` states are not used. Disabling rollback is strongly discouraged for production devices, as it removes the automatic recovery path after a failed OTA update.
|
||||
|
||||
An option in Kconfig :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` allows you to track the first boot of a new application. In this case, the application must confirm its operability by calling :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` function, otherwise the application will be rolled back upon reboot. It allows you to control the operability of the application during the boot phase. Thus, a new application has only one attempt to boot successfully.
|
||||
With application-controlled confirmation, the application can track the first boot of a new application. It must confirm its operability by calling :cpp:func:`esp_ota_mark_app_valid_cancel_rollback`; otherwise, it will be rolled back upon reboot. A new application therefore has only one attempt to reach its confirmation point successfully.
|
||||
|
||||
.. _ota_rollback:
|
||||
|
||||
Rollback Process
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The description of the rollback process when :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled:
|
||||
The application-controlled confirmation process works as follows:
|
||||
|
||||
* The new application is successfully downloaded and :cpp:func:`esp_ota_set_boot_partition` function makes this partition bootable and sets the state ``ESP_OTA_IMG_NEW``. This state means that the application is new and should be monitored for its first boot.
|
||||
* Reboot :cpp:func:`esp_restart`.
|
||||
@@ -112,6 +123,38 @@ The description of the rollback process when :menuitem:`CONFIG_BOOTLOADER_APP_RO
|
||||
* If the self-test fails, then call :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` function to roll back to the previous working application, while the invalid application is set ``ESP_OTA_IMG_INVALID`` state.
|
||||
* If the application has not been confirmed, the state remains ``ESP_OTA_IMG_PENDING_VERIFY``, and the next boot it will be changed to ``ESP_OTA_IMG_ABORTED``, which prevents re-boot of this application. There will be a rollback to the previous working application.
|
||||
|
||||
.. _ota_auto_confirm:
|
||||
|
||||
Automatic OTA Confirmation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Automatic confirmation is the default confirmation mode. Use it when reaching ``app_main``
|
||||
is sufficient to consider an OTA update valid. Select application-controlled confirmation
|
||||
instead when the application must confirm the update at an application-defined checkpoint.
|
||||
|
||||
In this mode, ESP-IDF calls :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` near the end
|
||||
of system startup, after IDF component initialization has completed and immediately before
|
||||
calling ``app_main``. Reaching this point is treated as a successful first boot. If startup
|
||||
fails before this point, the application remains unconfirmed and the bootloader selects the
|
||||
previously working application on the next boot.
|
||||
|
||||
Automatic confirmation does not validate application-specific initialization or
|
||||
diagnostics performed in ``app_main``. It also changes the OTA state to
|
||||
``ESP_OTA_IMG_VALID`` before application code runs. Consequently,
|
||||
:cpp:func:`esp_ota_get_state_partition` cannot be used from application code to determine
|
||||
whether this is the first boot of the new application. Select
|
||||
application-controlled confirmation to detect the first boot by checking for
|
||||
``ESP_OTA_IMG_PENDING_VERIFY``, perform self-tests, and then call
|
||||
:cpp:func:`esp_ota_mark_app_valid_cancel_rollback` or
|
||||
:cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot`. Alternatively, the application
|
||||
can maintain its own persistent marker for the last application image it ran.
|
||||
|
||||
.. note::
|
||||
|
||||
Automatic confirmation is unavailable with anti-rollback. Applications using
|
||||
anti-rollback must confirm the new version explicitly at an application-defined
|
||||
checkpoint.
|
||||
|
||||
Unexpected Reset
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -138,11 +181,11 @@ Where the States Are Set
|
||||
A brief description of where the states are set:
|
||||
|
||||
* ``ESP_OTA_IMG_VALID`` state is set by :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` function.
|
||||
* ``ESP_OTA_IMG_UNDEFINED`` state is set by :cpp:func:`esp_ota_set_boot_partition` function if :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is not enabled.
|
||||
* ``ESP_OTA_IMG_NEW`` state is set by :cpp:func:`esp_ota_set_boot_partition` function if :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled.
|
||||
* ``ESP_OTA_IMG_UNDEFINED`` state is set by :cpp:func:`esp_ota_set_boot_partition` if application rollback is disabled.
|
||||
* ``ESP_OTA_IMG_NEW`` state is set by :cpp:func:`esp_ota_set_boot_partition` if application rollback is enabled.
|
||||
* ``ESP_OTA_IMG_INVALID`` state is set by function :cpp:func:`esp_ota_mark_app_invalid_rollback` or :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot`.
|
||||
* ``ESP_OTA_IMG_ABORTED`` state is set if there was no confirmation of the application operability and occurs reboots (if :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled).
|
||||
* ``ESP_OTA_IMG_PENDING_VERIFY`` state is set in a bootloader if :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled and selected app has ``ESP_OTA_IMG_NEW`` state.
|
||||
* ``ESP_OTA_IMG_ABORTED`` state is set if the application reboots before confirmation while application rollback is enabled.
|
||||
* ``ESP_OTA_IMG_PENDING_VERIFY`` state is set by the bootloader if application rollback is enabled and the selected application has the ``ESP_OTA_IMG_NEW`` state.
|
||||
|
||||
.. _anti-rollback:
|
||||
|
||||
@@ -155,7 +198,7 @@ Anti-rollback prevents rollback to application with security version lower than
|
||||
|
||||
This function works if set :menuitem:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK` option. In the bootloader, when selecting a bootable application, an additional security version check is added which is on the chip and in the application image. The version in the bootable firmware must be greater than or equal to the version in the chip.
|
||||
|
||||
:menuitem:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK` and :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` options are used together. In this case, rollback is possible only on the security version which is equal or higher than the version in the chip.
|
||||
Anti-rollback uses application-controlled confirmation. In this case, rollback is possible only to an application whose security version is equal to or higher than the version in the chip.
|
||||
|
||||
|
||||
A Typical Anti-rollback Scheme Is
|
||||
|
||||
@@ -7,3 +7,4 @@ Migration from 6.1 to 6.2
|
||||
:maxdepth: 1
|
||||
|
||||
security
|
||||
system
|
||||
|
||||
33
docs/en/migration-guides/release-6.x/6.2/system.rst
Normal file
33
docs/en/migration-guides/release-6.x/6.2/system.rst
Normal file
@@ -0,0 +1,33 @@
|
||||
System
|
||||
======
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
OTA Updates
|
||||
-----------
|
||||
|
||||
Application Rollback Enabled by Default
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:ref:`app_rollback` is now enabled by default, using automatic confirmation (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP>`). Previously, rollback (``CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE``) was disabled by default and required the application to call :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` itself.
|
||||
|
||||
The new default applies to new projects and to any project whose configuration is derived from ``sdkconfig.defaults``. It also applies to projects with a fixed, checked-in ``sdkconfig`` file, unless that file already recorded an explicit rollback setting:
|
||||
|
||||
- ``CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y`` is automatically migrated to :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP>`, keeping the previous explicit-confirmation behavior unchanged.
|
||||
- A project that left rollback at its previous default (disabled) has no deprecated option to migrate from, so it picks up the new default and gets rollback with automatic confirmation, the same as a new project.
|
||||
|
||||
Projects that must keep application rollback disabled need to explicitly disable :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK` (*Bootloader config* > *Application Rollback* > *Enable application rollback*).
|
||||
|
||||
Impact on Devices with an Existing Bootloader
|
||||
"""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Application rollback is implemented jointly by the second stage bootloader and the application. Enabling it in the application is not sufficient on devices where the bootloader was already deployed without rollback support.
|
||||
|
||||
On such devices, updating to an application built with rollback enabled does not restore the safety net: the bootloader never transitions the OTA state from ``ESP_OTA_IMG_NEW`` to ``ESP_OTA_IMG_PENDING_VERIFY``, so a crash on the first boot after the update is not detected, and the device does not roll back to the previous working application. The application detects this situation at startup and marks the application valid to keep the OTA state consistent, but this does not provide rollback protection by itself.
|
||||
|
||||
To get the safety net on devices already in the field, the bootloader itself must be rebuilt with rollback support and reflashed.
|
||||
|
||||
Code Size Impact
|
||||
"""""""""""""""""
|
||||
|
||||
Enabling application rollback with automatic confirmation by default adds a small amount of code compared to the previous default (rollback disabled). Measured on :example:`system/ota/native_ota_example` for ESP32, the bootloader grows by approximately 80 bytes, and the application by approximately 350 bytes. The exact numbers depend on the target and application configuration.
|
||||
@@ -38,13 +38,24 @@ OTA 数据分区的容量是 2 个 flash 扇区的大小(0x2000 字节),
|
||||
应用程序回滚
|
||||
------------
|
||||
|
||||
应用程序回滚的主要目的是确保设备在更新后正常工作。如果新版应用程序出现严重错误,该功能可使设备回滚到之前正常运行的应用版本。在使能回滚并且 OTA 升级应用程序至新版本后,可能出现的结果如下:
|
||||
应用程序回滚的主要目的是确保设备在更新后正常工作。如果新版应用程序出现严重错误,该功能可使设备回滚到之前正常运行的应用版本。
|
||||
|
||||
应用程序回滚默认通过 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK` 启用。禁用该选项将移除 OTA 更新失败后的自动恢复路径,且下文所述的确认模式选项将不可用。
|
||||
|
||||
应用程序回滚支持两种确认模式。两种模式都会启用回滚,并以 ``ESP_OTA_IMG_PENDING_VERIFY`` 状态启动新的 OTA 应用程序,区别仅在于确认应用程序的时间:
|
||||
|
||||
* **确认应用程序在系统启动时自动确认** (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP>`) 为默认模式。ESP-IDF 在 IDF 组件初始化完成后、调用 ``app_main`` 前将应用程序标记为有效。
|
||||
* **由应用程序决定确认时机** (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP>`) 会保持待确认状态,直到应用程序显式确认或拒绝更新。应用程序可以通过这种方式检测首次启动、执行自测并选择确认时间。
|
||||
|
||||
在这两种确认模式之间切换不会改变引导加载程序的回滚行为,只会改变应用程序中的确认点。因此,在自动确认和应用程序控制确认之间切换时,无需重新构建或更新已支持回滚的引导加载程序。
|
||||
|
||||
如果应用程序在所选确认点之前复位、崩溃或掉电,引导加载程序会在下次启动时回滚到之前正常运行的应用程序。在使能回滚并且 OTA 升级应用程序至新版本后,可能出现的结果如下:
|
||||
|
||||
* 应用程序运行正常,:cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 将正在运行的应用程序状态标记为 ``ESP_OTA_IMG_VALID``,启动此应用程序无限制。
|
||||
* 应用程序出现严重错误,无法继续工作,必须回滚到此前的版本,:cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 将正在运行的版本标记为 ``ESP_OTA_IMG_INVALID`` 然后复位。引导加载程序不会选取此版本,而是启动此前正常运行的版本。
|
||||
* 如果 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能,则无需调用函数便可复位,回滚至之前的应用版本。
|
||||
* 如果应用程序在确认前复位,则回滚至之前的应用版本。
|
||||
|
||||
可使用以下代码检测 OTA 更新后应用程序的首次启动。首次启动时,应用程序会检查其状态并执行检测。如果检测成功,应用程序调用 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 函数,确认应用运行成功。如果检测失败,应用程序调用 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 函数,回滚至之前的应用版本。
|
||||
以下代码展示了应用程序控制确认 (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP>`)。OTA 更新后的首次启动时,应用程序会检查其状态并执行检测。如果检测成功,应用程序调用 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 函数,确认应用运行成功。如果检测失败,应用程序调用 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 函数,回滚至之前的应用版本。
|
||||
|
||||
如果应用程序由于中止、重启或掉电无法启动或运行上述代码,引导加载程序在下一次启动尝试中会将该应用程序的状态标记为 ``ESP_OTA_IMG_INVALID``,并回滚至之前的应用版本。
|
||||
|
||||
@@ -84,23 +95,22 @@ OTA 数据分区的容量是 2 个 flash 扇区的大小(0x2000 字节),
|
||||
ESP_OTA_IMG_UNDEFINED 没有限制,可以选取。
|
||||
ESP_OTA_IMG_INVALID 不会选取。
|
||||
ESP_OTA_IMG_ABORTED 不会选取。
|
||||
ESP_OTA_IMG_NEW 如使能 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE`,
|
||||
则仅会选取一次。在引导加载程序中,状态立即变为
|
||||
ESP_OTA_IMG_NEW 如使能应用程序回滚,则仅会选取一次。在引导加载程序中,状态立即变为
|
||||
``ESP_OTA_IMG_PENDING_VERIFY``。
|
||||
ESP_OTA_IMG_PENDING_VERIFY 如使能 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE`,
|
||||
则不会选取,状态变为 ``ESP_OTA_IMG_ABORTED``。
|
||||
ESP_OTA_IMG_PENDING_VERIFY 如使能应用程序回滚,则不会选取,状态变为
|
||||
``ESP_OTA_IMG_ABORTED``。
|
||||
============================= ========================================================
|
||||
|
||||
如果 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 没有使能(默认情况),则 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 和 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 为可选功能,``ESP_OTA_IMG_NEW`` 和 ``ESP_OTA_IMG_PENDING_VERIFY`` 不会使用。
|
||||
如果禁用应用程序回滚,则 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 和 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 为可选功能,且不会使用 ``ESP_OTA_IMG_NEW`` 和 ``ESP_OTA_IMG_PENDING_VERIFY`` 状态。不建议在生产设备中禁用回滚,因为这会移除 OTA 更新失败后的自动恢复机制。
|
||||
|
||||
Kconfig 中的 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用户追踪新版应用程序的第一次启动。应用程序需调用 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 函数确认可以运行,否则将会在重启时回滚至旧版本。该功能可让用户在启动阶段控制应用程序的可操作性。新版应用程序仅有一次机会尝试是否能成功启动。
|
||||
使用应用程序控制确认时,可以追踪新版应用程序的第一次启动。应用程序需调用 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 函数确认可以运行,否则将在重启时回滚至旧版本。新版应用程序仅有一次机会成功到达确认点。
|
||||
|
||||
.. _ota_rollback:
|
||||
|
||||
回滚过程
|
||||
^^^^^^^^
|
||||
|
||||
:menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能时,回滚过程如下:
|
||||
应用程序控制确认的回滚过程如下:
|
||||
|
||||
* 新版应用程序下载成功,:cpp:func:`esp_ota_set_boot_partition` 函数将分区设为可启动,状态设为 ``ESP_OTA_IMG_NEW``。该状态表示应用程序为新版本,第一次启动需要监测。
|
||||
* 重新启动 :cpp:func:`esp_restart`。
|
||||
@@ -112,6 +122,21 @@ Kconfig 中的 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用
|
||||
* 若未通过自测,则调用函数 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot`,回滚至之前能正常工作的应用程序版本,同时将无效的新版本应用程序设置为 ``ESP_OTA_IMG_INVALID``。
|
||||
* 如果新版应用程序可操作性没有确认,则状态一直为 ``ESP_OTA_IMG_PENDING_VERIFY``。下一次启动时,状态变更为 ``ESP_OTA_IMG_ABORTED``,阻止其再次启动,之后回滚到之前的版本。
|
||||
|
||||
.. _ota_auto_confirm:
|
||||
|
||||
自动确认 OTA 应用程序
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
自动确认是默认的确认模式。如果应用程序到达 ``app_main`` 即可视为 OTA 更新有效,请使用此模式。如果应用程序必须在自行定义的检查点确认更新,请改用应用程序控制确认。
|
||||
|
||||
在此模式下,ESP-IDF 会在系统启动即将完成时,即 IDF 组件初始化完成后、调用 ``app_main`` 前,调用 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback`。到达此处即视为首次启动成功。如果在此之前启动失败,应用程序将保持未确认状态,引导加载程序会在下次启动时选择之前正常运行的应用程序。
|
||||
|
||||
自动确认不会验证在 ``app_main`` 中执行的应用程序特定初始化或诊断。自动确认还会在应用程序代码运行前将 OTA 状态更改为 ``ESP_OTA_IMG_VALID``。因此,应用程序代码无法使用 :cpp:func:`esp_ota_get_state_partition` 判断当前是否为新应用程序的首次启动。如需通过检查 ``ESP_OTA_IMG_PENDING_VERIFY`` 检测首次启动、执行自测,然后调用 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 或 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot`,请选择应用程序控制确认。应用程序也可以自行维护持久化标记,记录上次运行的应用程序镜像。
|
||||
|
||||
.. note::
|
||||
|
||||
防回滚机制不支持自动确认。使用防回滚机制的应用程序必须在自行定义的检查点显式确认新版本。
|
||||
|
||||
意外复位
|
||||
^^^^^^^^
|
||||
|
||||
@@ -138,11 +163,11 @@ Kconfig 中的 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用
|
||||
下文简单描述了如何设置应用程序状态:
|
||||
|
||||
* ``ESP_OTA_IMG_VALID`` 由函数 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` 设置。
|
||||
* 如果 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 没有使能,``ESP_OTA_IMG_UNDEFINED`` 由函数 :cpp:func:`esp_ota_set_boot_partition` 设置。
|
||||
* 如果 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能,``ESP_OTA_IMG_NEW`` 由函数 :cpp:func:`esp_ota_set_boot_partition` 设置。
|
||||
* 如果禁用应用程序回滚,``ESP_OTA_IMG_UNDEFINED`` 由函数 :cpp:func:`esp_ota_set_boot_partition` 设置。
|
||||
* 如果使能应用程序回滚,``ESP_OTA_IMG_NEW`` 由函数 :cpp:func:`esp_ota_set_boot_partition` 设置。
|
||||
* ``ESP_OTA_IMG_INVALID`` 由函数 :cpp:func:`esp_ota_mark_app_invalid_rollback` 或 :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` 设置。
|
||||
* 如果应用程序的可操作性无法确认,发生重启(:menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能),则设置 ``ESP_OTA_IMG_ABORTED``。
|
||||
* 如果 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 使能,选取的应用程序状态为 ``ESP_OTA_IMG_NEW``,则在引导加载程序中设置 ``ESP_OTA_IMG_PENDING_VERIFY``。
|
||||
* 如果使能应用程序回滚,并且应用程序在确认前重启,则设置 ``ESP_OTA_IMG_ABORTED``。
|
||||
* 如果使能应用程序回滚,且所选应用程序的状态为 ``ESP_OTA_IMG_NEW``,则引导加载程序将状态设置为 ``ESP_OTA_IMG_PENDING_VERIFY``。
|
||||
|
||||
.. _anti-rollback:
|
||||
|
||||
@@ -155,7 +180,7 @@ Kconfig 中的 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 可以帮助用
|
||||
|
||||
设置 :menuitem:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK`,启动防回滚机制。在引导加载程序中选取可启动的应用程序,会额外检查芯片和应用程序镜像的安全版本号。可启动固件中的应用安全版本号必须等于或高于芯片中的应用安全版本号。
|
||||
|
||||
:menuitem:`CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK` 和 :menuitem:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` 一起使用。此时,只有安全版本号等于或高于芯片中的应用安全版本号时才会回滚。
|
||||
防回滚机制使用应用程序控制确认。此时,只有安全版本号等于或高于芯片中的应用安全版本号时才会回滚。
|
||||
|
||||
|
||||
典型的防回滚机制
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
:maxdepth: 1
|
||||
|
||||
security
|
||||
system
|
||||
|
||||
33
docs/zh_CN/migration-guides/release-6.x/6.2/system.rst
Normal file
33
docs/zh_CN/migration-guides/release-6.x/6.2/system.rst
Normal file
@@ -0,0 +1,33 @@
|
||||
系统
|
||||
====
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
OTA 更新
|
||||
--------
|
||||
|
||||
默认启用应用程序回滚
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:ref:`app_rollback` 现在默认启用,并使用自动确认模式 (:ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_ON_STARTUP>`)。此前,回滚功能 (``CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE``) 默认是禁用的,需要应用程序自行调用 :cpp:func:`esp_ota_mark_app_valid_cancel_rollback`。
|
||||
|
||||
新的默认设置适用于新建项目,以及配置来自 ``sdkconfig.defaults`` 的项目。对于使用固定的、已提交版本控制的 ``sdkconfig`` 文件的项目,新默认设置同样适用,除非该文件中已经记录了明确的回滚配置:
|
||||
|
||||
- 若已设置 ``CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y``,该配置会自动迁移为 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP <CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP>`,此前的应用程序控制确认行为保持不变。
|
||||
- 若项目此前将回滚保留为默认值(禁用),由于不存在可迁移的旧配置项,该项目会采用新的默认设置,与新建项目一样启用自动确认的回滚功能。
|
||||
|
||||
如需保持应用程序回滚为禁用状态,请在 *Bootloader config* > *Application Rollback* > *Enable application rollback* 中显式禁用 :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK`。
|
||||
|
||||
对已部署引导加载程序设备的影响
|
||||
""""""""""""""""""""""""""""""
|
||||
|
||||
应用程序回滚功能由第二阶段引导加载程序和应用程序共同实现。如果设备已部署的引导加载程序本身并未支持回滚功能,仅在应用程序中启用回滚是不够的。
|
||||
|
||||
在此类设备上,更新为已启用回滚功能的应用程序并不能恢复该安全机制:引导加载程序不会将 OTA 状态从 ``ESP_OTA_IMG_NEW`` 转换为 ``ESP_OTA_IMG_PENDING_VERIFY``,因此更新后首次启动时发生的崩溃不会被检测到,设备也不会回滚至此前正常运行的应用程序。应用程序会在启动时检测到这种情况,并将自身标记为有效,以保持 OTA 状态的一致性,但这本身并不能提供回滚保护。
|
||||
|
||||
要为已部署到现场的设备提供该安全机制,必须重新构建支持回滚功能的引导加载程序并将其重新烧录到设备中。
|
||||
|
||||
代码大小影响
|
||||
""""""""""""
|
||||
|
||||
与此前的默认配置(禁用回滚)相比,默认启用自动确认的应用程序回滚功能会略微增加代码大小。在 ESP32 上测试 :example:`system/ota/native_ota_example` 示例,引导加载程序大约增加 80 字节,应用程序大约增加 350 字节。具体数值因目标芯片和应用配置而异。
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generic config
|
||||
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
|
||||
CONFIG_EXAMPLE_EXT1_WAKEUP=n
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
|
||||
CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=y
|
||||
CONFIG_RTC_CLK_SRC_INT_RC=y
|
||||
|
||||
@@ -138,9 +138,9 @@ If you want to rollback to the `factory` app after the upgrade (or to the first
|
||||
|
||||
## Supporting Rollback
|
||||
|
||||
This feature allows you to roll back to a previous firmware if new image is not usable. The menuconfig option `CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` allows you to track the first boot of the application (see the ``Over The Air Updates (OTA)`` article).
|
||||
This feature allows you to roll back to a previous firmware if new image is not usable. The menuconfig option `CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP` allows you to track the first boot of the application (see the ``Over The Air Updates (OTA)`` article).
|
||||
|
||||
The ``native_ota_example`` contains code to demonstrate how a rollback works. To use it, enable the `CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option in the `Example Configuration` submenu of menuconfig to set `Number of the GPIO input for diagnostic` to manipulate the rollback process.
|
||||
The ``native_ota_example`` contains code to demonstrate how a rollback works. To use it, enable the `CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP` option in the `Example Configuration` submenu of menuconfig to set `Number of the GPIO input for diagnostic` to manipulate the rollback process.
|
||||
|
||||
To trigger a rollback, this GPIO must be pulled low while the message `Diagnostics (5 sec)...` is displayed during the first boot.
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ void app_main(void)
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE)
|
||||
#if defined(CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP)
|
||||
/**
|
||||
* We are treating successful WiFi connection as a checkpoint to cancel rollback
|
||||
* process and mark newly updated firmware image as active. For production cases,
|
||||
|
||||
@@ -8,7 +8,7 @@ CONFIG_PARTITION_TABLE_FILENAME="anti_rollback_partition.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0xd000
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP=y
|
||||
CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y
|
||||
CONFIG_BOOTLOADER_APP_SECURE_VERSION=1
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
|
||||
@@ -141,7 +141,7 @@ static esp_err_t unsafe_bootloader_ota_update(esp_https_ota_config_t *ota_config
|
||||
const esp_partition_t *primary_bootloader;
|
||||
ESP_ERROR_CHECK(register_partition(ESP_PRIMARY_BOOTLOADER_OFFSET, ESP_BOOTLOADER_SIZE, "PrimaryBTLDR", ESP_PARTITION_TYPE_BOOTLOADER, ESP_PARTITION_SUBTYPE_BOOTLOADER_PRIMARY, &primary_bootloader));
|
||||
const esp_partition_t *ota_partition = esp_ota_get_next_update_partition(NULL); // free app ota partition will be used for downloading a new image
|
||||
#if CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
#if CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP
|
||||
// Check if the passive OTA app partition is not needed for rollback before using it for other partitions.
|
||||
// The same can be done for partition table and storage updates.
|
||||
esp_ota_img_states_t ota_state;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Enable Rollback and Anti rollback
|
||||
#
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP=y
|
||||
CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y
|
||||
|
||||
#
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_CONFIRM_BY_APP=y
|
||||
CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
|
||||
@@ -4,4 +4,4 @@ CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE=y
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL=5
|
||||
CONFIG_LOG_DEFAULT_LEVEL_VERBOSE=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL=5
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0xA000
|
||||
|
||||
Reference in New Issue
Block a user