Merge pull request #3644 from cesanta/mcxupresso-ota-rollback

Add ARCH_MCUXPRESSO and OTA rollback for IMXRT boards
This commit is contained in:
Sergey Lyubka authored and GitHub committed 2026-07-27 11:32:56 +01:00
commit d8fa55e1d6
5 files changed
+360 -50

No files matched your search

+27 -25
View File
@@ -11369,10 +11369,6 @@ MG_IRAM static bool mg_imxrt_erase(void *addr) {
}
#endif
MG_IRAM bool mg_imxrt_swap(void) {
return true;
}
MG_IRAM static bool mg_imxrt_write(void *addr, const void *buf, size_t len) {
struct mg_flexspi_nor_config config, *config_ptr = &config;
bool ok = false;
@@ -11428,16 +11424,40 @@ fwxit:
return ok;
}
// just overwrite instead of swap
MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
// no stdlib calls here
char *scratch = p2 + s;
for (size_t ofs = 0; ofs < s; ofs += ss) {
MG_OTA_ROLLBACK_TIMER_FEED();
mg_imxrt_write(scratch, p1 + ofs, ss);
MG_OTA_ROLLBACK_TIMER_FEED();
mg_imxrt_write(p1 + ofs, p2 + ofs, ss);
MG_OTA_ROLLBACK_TIMER_FEED();
mg_imxrt_write(p2 + ofs, scratch, ss);
}
*(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
}
MG_IRAM static bool mg_imxrt_swap(void) {
size_t ss = s_mg_flash_imxrt.secsz;
char *p1 = (char *) s_mg_flash_imxrt.start;
char *p2 = p1 + s_mg_flash_imxrt.size / 2;
size_t s = s_mg_flash_imxrt.size / 2 - ss;
MG_INFO(("Swapping partitions, %u bytes", s));
MG_INFO(("Do NOT power off..."));
MG_OTA_ROLLBACK_TIMER_FEED();
mg_log_level = MG_LL_NONE;
s_flash_irq_disabled = true;
single_bank_swap(p1, p2, s, ss);
return true; // unreachable
}
bool mg_ota_begin(size_t new_firmware_size) {
size_t max = s_mg_flash_imxrt.size / 2 - s_mg_flash_imxrt.secsz;
if (new_firmware_size > max) {
MG_ERROR(("Firmware %lu too big for single-bank OTA, max %lu",
new_firmware_size, max));
return false;
}
return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_imxrt);
}
@@ -11446,25 +11466,7 @@ bool mg_ota_write(const void *buf, size_t len) {
}
bool mg_ota_end(void) {
if (mg_ota_flash_end(&s_mg_flash_imxrt)) {
if (0) { // is_dualbank()
// TODO(): no devices so far
*(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
} else {
// Swap partitions. Pray power does not go away
MG_INFO(("Swapping partitions, size %u (%u sectors)",
s_mg_flash_imxrt.size,
s_mg_flash_imxrt.size / s_mg_flash_imxrt.secsz));
MG_INFO(("Do NOT power off..."));
mg_log_level = MG_LL_NONE;
s_flash_irq_disabled = true;
// Runs in RAM, will reset when finished
single_bank_swap(
(char *) s_mg_flash_imxrt.start,
(char *) s_mg_flash_imxrt.start + s_mg_flash_imxrt.size / 2,
s_mg_flash_imxrt.size / 2, s_mg_flash_imxrt.secsz);
}
}
mg_ota_flash_end(&s_mg_flash_imxrt);
return false;
}
struct mg_flash *mg_flash = &s_mg_flash_imxrt;