OTA: the firmware rolls itself back; the bootloader doesn't

A deliberately crashing update looped forever on the device: the
prebuilt bootloader ignores ESP_OTA_IMG_PENDING_VERIFY despite the
app-side rollback config. UpdateService::bootGuard() now runs first in
setup(): it counts starts on Probation in NVS and, on the second
unconfirmed start, marks the image invalid and reboots into the
previous one. Confirming (or the Wi-Fi rollback) resets the counter.
ADR 0003 records the limit: a crash in the first milliseconds still
needs USB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-03 21:48:39 +02:00
co-authored by Claude Opus 5.5
parent de5931210f
commit 45542dcbff
6 changed files with 34 additions and 1 deletions
+7
View File
@@ -278,6 +278,12 @@ void test_probation_rolls_back_when_wifi_never_comes() {
TEST_ASSERT_EQUAL(kConfirm, judge(500000, true, false, false)); // no Wi-Fi configured: fine
}
void test_rollback_at_boot_after_an_unconfirmed_start() {
TEST_ASSERT_FALSE(Probation::rollBackAtBoot(true, 0)); // first start of new firmware
TEST_ASSERT_TRUE(Probation::rollBackAtBoot(true, 1)); // it died before confirming
TEST_ASSERT_FALSE(Probation::rollBackAtBoot(false, 3)); // confirmed firmware: never
}
int main() {
UNITY_BEGIN();
RUN_TEST(test_sha256_known_vectors);
@@ -298,5 +304,6 @@ int main() {
RUN_TEST(test_probation_waits_30_seconds_and_a_first_frame);
RUN_TEST(test_probation_needs_wifi_when_it_is_configured);
RUN_TEST(test_probation_rolls_back_when_wifi_never_comes);
RUN_TEST(test_rollback_at_boot_after_an_unconfirmed_start);
return UNITY_END();
}