mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-01 05:52:32 +07:00
Merge pull request #3644 from cesanta/mcxupresso-ota-rollback
Add ARCH_MCUXPRESSO and OTA rollback for IMXRT boards
This commit is contained in:
+27
-25
@@ -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;
|
||||
|
||||
+153
@@ -46,6 +46,7 @@ extern "C" {
|
||||
#define MG_ARCH_RTTHREAD 14 // RT-Thread RTOS
|
||||
#define MG_ARCH_ARMCGT 15 // Texas Semi ARM-CGT
|
||||
#define MG_ARCH_CUBE 16 // STM32Cube environment
|
||||
#define MG_ARCH_MCUXPRESSO 17 // MCUXpresso environment
|
||||
|
||||
#define MG_ARCH_NEWLIB MG_ARCH_ARMGCC // Alias, deprecate in 2025
|
||||
|
||||
@@ -410,6 +411,158 @@ static inline uint32_t mg_ota_esp32_state_set(uint32_t state) {
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ARCH == MG_ARCH_MCUXPRESSO
|
||||
#define _POSIX_TIMERS
|
||||
|
||||
#include <ctype.h>
|
||||
#if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// MCUXpresso-generated header, includes the SoC peripheral definitions.
|
||||
// NOTE: use angle brackets to prevent amalgamator ditching it
|
||||
#include <fsl_device_registers.h>
|
||||
|
||||
#ifndef MG_PATH_MAX
|
||||
#define MG_PATH_MAX 100
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_DIRLIST
|
||||
#define MG_ENABLE_DIRLIST 0
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_TCPIP
|
||||
#define MG_ENABLE_TCPIP 1 // Enable built-in TCP/IP stack
|
||||
#endif
|
||||
|
||||
#if MG_ENABLE_TCPIP && !defined(MG_ENABLE_DRIVER_IMXRT10) && \
|
||||
!defined(MG_ENABLE_DRIVER_IMXRT11)
|
||||
#if defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
|
||||
defined(CPU_MIMXRT1042XJM5B) || defined(CPU_MIMXRT1052DVL6B) || \
|
||||
defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1064DVL6B) || \
|
||||
defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1064DVL6A) || \
|
||||
defined(CPU_MIMXRT1062DVMAA_cm7) || defined(CPU_MIMXRT1062DVL6A_cm7) || \
|
||||
defined(CPU_MIMXRT1062DVL6B_cm7) || defined(_MIMXRT1021_H_) || \
|
||||
defined(_MIMXRT1024_H_) || defined(_MIMXRT1042_H_) || \
|
||||
defined(_MIMXRT1052_H_) || defined(_MIMXRT1062_H_) || \
|
||||
defined(_MIMXRT1064_H_)
|
||||
#define MG_ENABLE_DRIVER_IMXRT10 1
|
||||
#elif defined(CPU_MIMXRT1176DVMAA_cm7) || defined(CPU_MIMXRT1176DVMAA_cm4) || \
|
||||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_)
|
||||
#define MG_ENABLE_DRIVER_IMXRT11 1
|
||||
#else
|
||||
#error Select an Ethernet driver in mongoose_config.h
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_TLS
|
||||
#define MG_TLS MG_TLS_BUILTIN
|
||||
#endif
|
||||
|
||||
#if !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
|
||||
defined(_MIMXRT1021_H_) || defined(_MIMXRT1024_H_))
|
||||
#define MG_OTA MG_OTA_RT1020
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1052DVL6B) || defined(_MIMXRT1052_H_))
|
||||
#define MG_OTA MG_OTA_RT1050
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1062DVL6A) || \
|
||||
defined(CPU_MIMXRT1042XJM5B) || defined(_MIMXRT1042_H_) || \
|
||||
defined(CPU_MIMXRT1062DVMAA_cm7) || defined(CPU_MIMXRT1062DVL6A_cm7) || \
|
||||
defined(CPU_MIMXRT1062DVL6B_cm7) || defined(_MIMXRT1062_H_))
|
||||
#define MG_OTA MG_OTA_RT1060
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1064DVL6B) || defined(CPU_MIMXRT1064DVL6A) || \
|
||||
defined(_MIMXRT1064_H_))
|
||||
#define MG_OTA MG_OTA_RT1064
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1176DVMAA_cm7) || defined(CPU_MIMXRT1176DVMAA_cm4) || \
|
||||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_))
|
||||
#define MG_OTA MG_OTA_RT1170
|
||||
#endif
|
||||
|
||||
#ifndef MG_IRAM
|
||||
#define MG_IRAM __attribute__((noinline, section(".data_RAM2")))
|
||||
#endif
|
||||
|
||||
#ifndef MG_SET_MAC_ADDRESS
|
||||
#if defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11
|
||||
#define MG_OCOTP_FUSES ((volatile uint32_t *) 0x40cac900)
|
||||
#else
|
||||
#define MG_OCOTP_FUSES ((volatile uint32_t *) 0x401f4410)
|
||||
#endif
|
||||
#define MG_SET_MAC_ADDRESS(mac) \
|
||||
do { \
|
||||
mac[0] = 2; \
|
||||
mac[1] = (MG_OCOTP_FUSES[0] >> 0) & 255; \
|
||||
mac[2] = (MG_OCOTP_FUSES[0] >> 10) & 255; \
|
||||
mac[3] = ((MG_OCOTP_FUSES[0] >> 19) ^ (MG_OCOTP_FUSES[4] >> 19)) & 255; \
|
||||
mac[4] = (MG_OCOTP_FUSES[4] >> 10) & 255; \
|
||||
mac[5] = (MG_OCOTP_FUSES[4] >> 0) & 255; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef MG_IMXRT_WDOG1_TIMEOUT_MS
|
||||
#define MG_IMXRT_WDOG1_TIMEOUT_MS 10000
|
||||
#endif
|
||||
|
||||
#define MG_IMXRT_WDOG1_FEED() \
|
||||
do { \
|
||||
WDOG1->WSR = 0x5555; \
|
||||
WDOG1->WSR = 0xaaaa; \
|
||||
} while (0)
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_START
|
||||
#define MG_OTA_ROLLBACK_TIMER_START() \
|
||||
do { \
|
||||
uint16_t wt_ = (uint16_t) ((MG_IMXRT_WDOG1_TIMEOUT_MS / 500) - 1); \
|
||||
if ((WDOG1->WCR & WDOG_WCR_WDE_MASK) == 0) { \
|
||||
WDOG1->WMCR = 0; \
|
||||
WDOG1->WCR = (uint16_t) (WDOG_WCR_WDZST_MASK | WDOG_WCR_WDBG_MASK | \
|
||||
WDOG_WCR_WDE_MASK | WDOG_WCR_WDT_MASK | \
|
||||
WDOG_WCR_SRS_MASK | WDOG_WCR_WDW_MASK | \
|
||||
WDOG_WCR_WT(wt_)); \
|
||||
} \
|
||||
MG_IMXRT_WDOG1_FEED(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_FEED
|
||||
#define MG_OTA_ROLLBACK_TIMER_FEED() MG_IMXRT_WDOG1_FEED()
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_STATE_GET
|
||||
#define MG_OTA_STATE_GET() SNVS->LPGPR[0]
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_STATE_SET
|
||||
#define MG_OTA_STATE_SET(v) \
|
||||
do { \
|
||||
if (SNVS->LPSR & (1u << 3)) { \
|
||||
SNVS->LPLVDR = 0x41736166u; \
|
||||
SNVS->LPSR = 1u << 3; \
|
||||
} \
|
||||
SNVS->LPGPR[0] = (uint32_t) (v); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ARCH == MG_ARCH_PICOSDK
|
||||
#if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
|
||||
#include <errno.h>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define MG_ARCH_RTTHREAD 14 // RT-Thread RTOS
|
||||
#define MG_ARCH_ARMCGT 15 // Texas Semi ARM-CGT
|
||||
#define MG_ARCH_CUBE 16 // STM32Cube environment
|
||||
#define MG_ARCH_MCUXPRESSO 17 // MCUXpresso environment
|
||||
|
||||
#define MG_ARCH_NEWLIB MG_ARCH_ARMGCC // Alias, deprecate in 2025
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
|
||||
#if MG_ARCH == MG_ARCH_MCUXPRESSO
|
||||
#define _POSIX_TIMERS
|
||||
|
||||
#include <ctype.h>
|
||||
#if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// MCUXpresso-generated header, includes the SoC peripheral definitions.
|
||||
// NOTE: use angle brackets to prevent amalgamator ditching it
|
||||
#include <fsl_device_registers.h>
|
||||
|
||||
#ifndef MG_PATH_MAX
|
||||
#define MG_PATH_MAX 100
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_DIRLIST
|
||||
#define MG_ENABLE_DIRLIST 0
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_TCPIP
|
||||
#define MG_ENABLE_TCPIP 1 // Enable built-in TCP/IP stack
|
||||
#endif
|
||||
|
||||
#if MG_ENABLE_TCPIP && !defined(MG_ENABLE_DRIVER_IMXRT10) && \
|
||||
!defined(MG_ENABLE_DRIVER_IMXRT11)
|
||||
#if defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
|
||||
defined(CPU_MIMXRT1042XJM5B) || defined(CPU_MIMXRT1052DVL6B) || \
|
||||
defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1064DVL6B) || \
|
||||
defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1064DVL6A) || \
|
||||
defined(CPU_MIMXRT1062DVMAA_cm7) || defined(CPU_MIMXRT1062DVL6A_cm7) || \
|
||||
defined(CPU_MIMXRT1062DVL6B_cm7) || defined(_MIMXRT1021_H_) || \
|
||||
defined(_MIMXRT1024_H_) || defined(_MIMXRT1042_H_) || \
|
||||
defined(_MIMXRT1052_H_) || defined(_MIMXRT1062_H_) || \
|
||||
defined(_MIMXRT1064_H_)
|
||||
#define MG_ENABLE_DRIVER_IMXRT10 1
|
||||
#elif defined(CPU_MIMXRT1176DVMAA_cm7) || defined(CPU_MIMXRT1176DVMAA_cm4) || \
|
||||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_)
|
||||
#define MG_ENABLE_DRIVER_IMXRT11 1
|
||||
#else
|
||||
#error Select an Ethernet driver in mongoose_config.h
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_TLS
|
||||
#define MG_TLS MG_TLS_BUILTIN
|
||||
#endif
|
||||
|
||||
#if !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
|
||||
defined(_MIMXRT1021_H_) || defined(_MIMXRT1024_H_))
|
||||
#define MG_OTA MG_OTA_RT1020
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1052DVL6B) || defined(_MIMXRT1052_H_))
|
||||
#define MG_OTA MG_OTA_RT1050
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1062DVL6A) || \
|
||||
defined(CPU_MIMXRT1042XJM5B) || defined(_MIMXRT1042_H_) || \
|
||||
defined(CPU_MIMXRT1062DVMAA_cm7) || defined(CPU_MIMXRT1062DVL6A_cm7) || \
|
||||
defined(CPU_MIMXRT1062DVL6B_cm7) || defined(_MIMXRT1062_H_))
|
||||
#define MG_OTA MG_OTA_RT1060
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1064DVL6B) || defined(CPU_MIMXRT1064DVL6A) || \
|
||||
defined(_MIMXRT1064_H_))
|
||||
#define MG_OTA MG_OTA_RT1064
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1176DVMAA_cm7) || defined(CPU_MIMXRT1176DVMAA_cm4) || \
|
||||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_))
|
||||
#define MG_OTA MG_OTA_RT1170
|
||||
#endif
|
||||
|
||||
#ifndef MG_IRAM
|
||||
#define MG_IRAM __attribute__((noinline, section(".data_RAM2")))
|
||||
#endif
|
||||
|
||||
#ifndef MG_SET_MAC_ADDRESS
|
||||
#if defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11
|
||||
#define MG_OCOTP_FUSES ((volatile uint32_t *) 0x40cac900)
|
||||
#else
|
||||
#define MG_OCOTP_FUSES ((volatile uint32_t *) 0x401f4410)
|
||||
#endif
|
||||
#define MG_SET_MAC_ADDRESS(mac) \
|
||||
do { \
|
||||
mac[0] = 2; \
|
||||
mac[1] = (MG_OCOTP_FUSES[0] >> 0) & 255; \
|
||||
mac[2] = (MG_OCOTP_FUSES[0] >> 10) & 255; \
|
||||
mac[3] = ((MG_OCOTP_FUSES[0] >> 19) ^ (MG_OCOTP_FUSES[4] >> 19)) & 255; \
|
||||
mac[4] = (MG_OCOTP_FUSES[4] >> 10) & 255; \
|
||||
mac[5] = (MG_OCOTP_FUSES[4] >> 0) & 255; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef MG_IMXRT_WDOG1_TIMEOUT_MS
|
||||
#define MG_IMXRT_WDOG1_TIMEOUT_MS 10000
|
||||
#endif
|
||||
|
||||
#define MG_IMXRT_WDOG1_FEED() \
|
||||
do { \
|
||||
WDOG1->WSR = 0x5555; \
|
||||
WDOG1->WSR = 0xaaaa; \
|
||||
} while (0)
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_START
|
||||
#define MG_OTA_ROLLBACK_TIMER_START() \
|
||||
do { \
|
||||
uint16_t wt_ = (uint16_t) ((MG_IMXRT_WDOG1_TIMEOUT_MS / 500) - 1); \
|
||||
if ((WDOG1->WCR & WDOG_WCR_WDE_MASK) == 0) { \
|
||||
WDOG1->WMCR = 0; \
|
||||
WDOG1->WCR = (uint16_t) (WDOG_WCR_WDZST_MASK | WDOG_WCR_WDBG_MASK | \
|
||||
WDOG_WCR_WDE_MASK | WDOG_WCR_WDT_MASK | \
|
||||
WDOG_WCR_SRS_MASK | WDOG_WCR_WDW_MASK | \
|
||||
WDOG_WCR_WT(wt_)); \
|
||||
} \
|
||||
MG_IMXRT_WDOG1_FEED(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_FEED
|
||||
#define MG_OTA_ROLLBACK_TIMER_FEED() MG_IMXRT_WDOG1_FEED()
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_STATE_GET
|
||||
#define MG_OTA_STATE_GET() SNVS->LPGPR[0]
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_STATE_SET
|
||||
#define MG_OTA_STATE_SET(v) \
|
||||
do { \
|
||||
if (SNVS->LPSR & (1u << 3)) { \
|
||||
SNVS->LPLVDR = 0x41736166u; \
|
||||
SNVS->LPSR = 1u << 3; \
|
||||
} \
|
||||
SNVS->LPGPR[0] = (uint32_t) (v); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+27
-25
@@ -491,10 +491,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;
|
||||
@@ -550,16 +546,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);
|
||||
}
|
||||
|
||||
@@ -568,25 +588,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;
|
||||
|
||||
Reference in New Issue
Block a user