Preserve nRF52 OTA boot result diagnostics

This commit is contained in:
mikecarper committed 2026-08-20 20:32:20 -07:00
1 parent fb78e0f55a
commit eb45e9d4f8
3 files changed
+29 -6

No files matched your search

+9 -6
View File
@@ -419,6 +419,14 @@ void ota_reboot_to_apply() { esp_restart(); } // boots the slot armed by ota_ap
#elif defined(NRF52_PLATFORM) // single-slot: verify + mark APPROVED + hand off to the bootloader
// Capture a real OTAFIX result before board power-management initialization
// consumes GPREGRET2. Ignore shutdown reasons and staging handoff markers that
// share the register but are not bootloader apply results.
static uint8_t g_bootloader_last_rc = 0;
static void __attribute__((constructor(101))) ota_capture_bootloader_last_rc() {
g_bootloader_last_rc = ota_nrf52_boot_result_or_zero((uint8_t)NRF_POWER->GPREGRET2);
}
struct InplacePatchDims {
uint32_t memory = 0;
uint32_t segment = 0;
@@ -465,12 +473,7 @@ void ota_reboot_to_apply() { // public: set the apply magic +
NVIC_SystemReset(); // does not return
}
uint8_t ota_bootloader_last_rc() { // bootloader's last in-place-apply code, stashed in GPREGRET2
uint32_t v = 0;
uint8_t en = 0; sd_softdevice_is_enabled(&en);
if (en) sd_power_gpregret_get(1, &v); else v = NRF_POWER->GPREGRET2;
return (uint8_t)v;
}
uint8_t ota_bootloader_last_rc() { return g_bootloader_last_rc; }
static bool ota_apply_mota_nrf52_impl(const uint8_t* buf, uint32_t len,
const SignerAllowlist& allow,
+5
View File
@@ -99,6 +99,11 @@ bool ota_apply_mota_nrf52(OtaStoreQspiNrf52& store,
// into the slot already armed by ota_apply_detools_mota.
void ota_reboot_to_apply();
inline uint8_t ota_nrf52_boot_result_or_zero(uint8_t value) {
return ((value >= 0x90u && value <= 0x9Fu) ||
(value >= 0xB0u && value <= 0xBCu)) ? value : 0u;
}
// DIAGNOSTIC (nRF52): the bootloader stashes its last in-place-apply bail/progress code in GPREGRET2 (see
// ota_delta.c). Read it back so `ota status` can show why an apply didn't take. 0 / other platforms = n/a.
uint8_t ota_bootloader_last_rc();
+15
View File
@@ -23,6 +23,21 @@ extern "C" {
using namespace mesh::ota;
TEST(OtaBootResult, AcceptsOnlyOtafixApplyDiagnostics) {
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0x90), 0x90);
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0x9F), 0x9F);
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0xB0), 0xB0);
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0xB8), 0xB8);
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0xBC), 0xBC);
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0x00), 0x00);
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0x4C), 0x00); // shutdown reason
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0x51), 0x00); // QSPI handoff
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0xD4), 0x00); // legacy handoff
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0xED), 0x00); // expanded handoff
EXPECT_EQ(ota_nrf52_boot_result_or_zero(0xBD), 0x00);
}
class FakeMotaSeederStream : public Stream {
public:
using Stream::write;