Skip to content

Commit

Permalink
RT1020 and RT1060 OTA
Browse files Browse the repository at this point in the history
  • Loading branch information
robert committed Jan 15, 2024
1 parent 0ad4002 commit cc10443
Show file tree
Hide file tree
Showing 12 changed files with 821 additions and 14 deletions.
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,12 @@ mongoose.c: Makefile $(wildcard src/*.c) $(wildcard src/drivers/*.c)
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c src/drivers/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@

mongoose.h: $(HDRS) Makefile
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_ft.h src/net_lwip.h src/net_rl.h src/config.h src/str.h src/queue.h src/fmt.h src/printf.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/sha256.h src/tls_aes128.h src/tls_uecc.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h src/ota.h src/device.h src/net_builtin.h src/profile.h src/drivers/*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_ft.h src/net_lwip.h src/net_rl.h src/config.h src/str.h src/queue.h src/fmt.h src/printf.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/sha256.h src/tls_aes128.h src/tls_uecc.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h src/ota.h src/device.h src/device_imxrt_flexspi.h src/net_builtin.h src/profile.h src/drivers/*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@


clean: clean_examples clean_embedded
rm -rf $(PROG) *.exe *.o *.dSYM *_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* test/packed_fs.c pack
#find examples -maxdepth 3 -name zephyr -prune -o -name Makefile -print | xargs dirname | xargs -n1 make clean -C

clean_embedded:
for X in $(EXAMPLES_EMBEDDED); do test -f $$X/Makefile || continue; $(MAKE) -C $$X clean || exit 1; done

for X in $(EXAMPLES_EMBEDDED); do test -f $$X/Makefile || continue; $(MAKE) -C $$X clean || exit 1; done
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "dcd.h" // pin settings for MIMXRT1020-EVK board
#include "flexspi.h" // peripheral structures
#include "hal.h"
#include "flexspi.h" // peripheral structures

extern uint32_t __isr_vector[];

Expand Down
8 changes: 5 additions & 3 deletions examples/nxp/rt1020-evk-make-baremetal-builtin/link.ld
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ ENTRY(Reset_Handler);
MEMORY {
flash_hdr(rx) : ORIGIN = 0x60000000, LENGTH = 8k
flash_irq(rx) : ORIGIN = 0x60002000, LENGTH = 1k
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8183k
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8179k

itcram(rx) : ORIGIN = 0x00000000, LENGTH = 64k
dtcram(rw) : ORIGIN = 0x20000000, LENGTH = 64k
ocram(rw) : ORIGIN = 0x20200000, LENGTH = 128k
}
__StackTop = ORIGIN(dtcram) + LENGTH(dtcram);

/* TODO(): separate itcram and go back to using dtcram for data and bss when ota is finished */

SECTIONS {
.hdr : { FILL(0xff) ; KEEP(*(.cfg)) . = 0x1000 ; KEEP(*(.ivt)) . = 0x1020 ;
KEEP(*(.dat)) . = 0x1030 ; KEEP(*(.dcd)) . = 0x2000 ;} >flash_hdr
.irq : { KEEP(*(.isr_vector)) } > flash_irq
.text : { *(.text* .text.*) *(.rodata*) ; } > flash_code
.data : { __data_start__ = .; *(.data SORT(.data.*)) __data_end__ = .; } > dtcram AT > flash_code
.data : { __data_start__ = .; *(.data SORT(.data.*)) *(.iram) __data_end__ = .; } > itcram AT > flash_code
__etext = LOADADDR(.data);
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > dtcram
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > itcram
_end = .;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

// See https://mongoose.ws/documentation/#build-options
#define MG_ARCH MG_ARCH_NEWLIB
#define MG_OTA MG_OTA_FLASH
#define MG_DEVICE MG_DEVICE_RT1020

#define MG_ENABLE_TCPIP 1
#define MG_ENABLE_DRIVER_IMXRT 1
Expand Down
8 changes: 5 additions & 3 deletions examples/nxp/rt1060-evk-make-baremetal-builtin/link.ld
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ ENTRY(Reset_Handler);
MEMORY {
flash_hdr(rx) : ORIGIN = 0x60000000, LENGTH = 8k
flash_irq(rx) : ORIGIN = 0x60002000, LENGTH = 1k
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8183k
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8179k

itcram(rx) : ORIGIN = 0x00000000, LENGTH = 128k
dtcram(rw) : ORIGIN = 0x20000000, LENGTH = 128k
ocram(rw) : ORIGIN = 0x20200000, LENGTH = 256k /* Is this cached ? */
}
__StackTop = ORIGIN(dtcram) + LENGTH(dtcram);

/* TODO(): separate itcram and go back to using dtcram for data and bss when ota is finished */

SECTIONS {
.hdr : { FILL(0xff) ; KEEP(*(.cfg)) . = 0x1000 ; KEEP(*(.ivt)) . = 0x1020 ;
KEEP(*(.dat)) . = 0x1030 ; KEEP(*(.dcd)) . = 0x2000 ;} >flash_hdr
.irq : { KEEP(*(.isr_vector)) } > flash_irq
.text : { *(.text* .text.*) *(.rodata*) ; } > flash_code
.data : { __data_start__ = .; *(.data SORT(.data.*)) __data_end__ = .; } > dtcram AT > flash_code
.data : { __data_start__ = .; *(.data SORT(.data.*)) *(.iram) __data_end__ = .; } > itcram AT > flash_code
__etext = LOADADDR(.data);
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > dtcram
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > itcram
_end = .;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

// See https://mongoose.ws/documentation/#build-options
#define MG_ARCH MG_ARCH_NEWLIB
#define MG_OTA MG_OTA_FLASH
#define MG_DEVICE MG_DEVICE_RT1060

#define MG_ENABLE_TCPIP 1
#define MG_ENABLE_DRIVER_IMXRT 1
Expand Down
226 changes: 224 additions & 2 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ void mg_device_reset(void) {
#endif


#if MG_DEVICE == MG_DEVICE_STM32H7 || MG_DEVICE == MG_DEVICE_STM32H5
#if MG_DEVICE == MG_DEVICE_STM32H7 || MG_DEVICE == MG_DEVICE_STM32H5 || \
MG_DEVICE == MG_DEVICE_RT1020 || MG_DEVICE == MG_DEVICE_RT1060
// Flash can be written only if it is erased. Erased flash is 0xff (all bits 1)
// Writes must be mg_flash_write_align() - aligned. Thus if we want to save an
// object, we pad it at the end for alignment.
Expand Down Expand Up @@ -350,7 +351,7 @@ bool mg_flash_save(void *sector, uint32_t key, const void *buf, size_t len) {
while ((n = mg_flash_next(s + ofs, s + ss, NULL, NULL)) > 0) ofs += n;

// If there is not enough space left, cleanup sector and re-eval ofs
if (ofs + needed_aligned > ss) {
if (ofs + needed_aligned >= ss) {
mg_flash_sector_cleanup(s);
ofs = 0;
while ((n = mg_flash_next(s + ofs, s + ss, NULL, NULL)) > 0) ofs += n;
Expand Down Expand Up @@ -409,6 +410,227 @@ bool mg_flash_load(void *sector, uint32_t key, void *buf, size_t len) {
}
#endif

#ifdef MG_ENABLE_LINES
#line 1 "src/device_imxrt.c"
#endif



#if MG_DEVICE == MG_DEVICE_RT1020 || MG_DEVICE == MG_DEVICE_RT1060



static bool s_flash_irq_disabled;

MG_IRAM void *mg_flash_start(void) {
return (void *) 0x60000000;
}
MG_IRAM size_t mg_flash_size(void) {
return 8 * 1024 * 1024;
}
MG_IRAM size_t mg_flash_sector_size(void) {
return 4 * 1024; // 4k
}
MG_IRAM size_t mg_flash_write_align(void) {
return 256;
}
MG_IRAM int mg_flash_bank(void) {
return 0;
}

MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
char *base = (char *) mg_flash_start(), *end = base + mg_flash_size();
volatile char *p = (char *) dst;
return p >= base && p < end && ((p - base) % mg_flash_sector_size()) == 0;
}

// Note: the get_config function below works both for RT1020 and 1060
#if MG_DEVICE == MG_DEVICE_RT1020
MG_IRAM static int flexspi_nor_get_config(struct mg_flexspi_nor_config *config) {
struct mg_flexspi_nor_config default_config = {
.memConfig = {.tag = MG_FLEXSPI_CFG_BLK_TAG,
.version = MG_FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = 1, // ReadSampleClk_LoopbackFromDqsPad
.csHoldTime = 3,
.csSetupTime = 3,
.controllerMiscOption = MG_BIT(4),
.deviceType = 1, // serial NOR
.sflashPadType = 4,
.serialClkFreq = 7, // 133MHz
.sflashA1Size = 8 * 1024 * 1024,
.lookupTable = MG_FLEXSPI_QSPI_LUT},
.pageSize = 256,
.sectorSize = 4 * 1024,
.ipcmdSerialClkFreq = 1,
.blockSize = 64 * 1024,
.isUniformBlockSize = false};

*config = default_config;
return 0;
}
#else
MG_IRAM static int flexspi_nor_get_config(struct mg_flexspi_nor_config *config) {
uint32_t options[] = {0xc0000000, 0x00};

MG_ARM_DISABLE_IRQ();
uint32_t status =
flexspi_nor->get_config(FLEXSPI_NOR_INSTANCE, config, options);
if (!s_flash_irq_disabled) {
MG_ARM_ENABLE_IRQ();
}
if (status) {
MG_ERROR(("Failed to extract flash configuration: status %u", status));
}
return status;
}
#endif

uint32_t mg_flash_init() {
struct mg_flexspi_nor_config config;
if (flexspi_nor_get_config(&config) != 0) {
return false;
}
return flexspi_nor->init(FLEXSPI_NOR_INSTANCE, &config);
}

MG_IRAM bool mg_flash_erase(void *addr) {
struct mg_flexspi_nor_config config;
if (flexspi_nor_get_config(&config) != 0) {
return false;
}
if (flash_page_start(addr) == false) {
MG_ERROR(("%p is not on a sector boundary", addr));
return false;
}

if ((char *) addr < (char *) mg_flash_start()) {
MG_ERROR(("Invalid flash write address: %p", addr));
return false;
}
void *dst = (void *)((char *) addr - (char *) mg_flash_start());

// Note: Interrupts must be disabled before any call to the ROM API on RT1020
// and 1060
MG_ARM_DISABLE_IRQ();
bool ok = (flexspi_nor->erase(FLEXSPI_NOR_INSTANCE, &config, (uint32_t) dst,
mg_flash_sector_size()) == 0);
if (!s_flash_irq_disabled) {
MG_ARM_ENABLE_IRQ(); // // Reenable them after the call
}
MG_DEBUG(("Sector starting at %p erasure: %s", addr, ok ? "ok" : "fail"));
return ok;
}

MG_IRAM bool mg_flash_swap_bank() {
return true;
}

static inline void spin(volatile uint32_t count) {
while (count--) (void) 0;
}

static inline void flash_wait(void) {
while ((*((volatile uint32_t *)(0x402A8000 + 0xE0)) & MG_BIT(1)) == 0) spin(1);
}

MG_IRAM static void *flash_code_location(void) {
return (void *) ((char *) mg_flash_start() + 0x2000);
}

MG_IRAM bool mg_flash_write(void *addr, const void *buf, size_t len) {
struct mg_flexspi_nor_config config;
if (flexspi_nor_get_config(&config) != 0) {
return false;
}
if ((len % mg_flash_write_align()) != 0) {
MG_ERROR(("%lu is not aligned to %lu", len, mg_flash_write_align()));
return false;
}

if ((char *) addr < (char *) mg_flash_start()) {
MG_ERROR(("Invalid flash write address: %p", addr));
return false;
}

uint32_t *dst = (uint32_t *) addr;
uint32_t *src = (uint32_t *) buf;
uint32_t *end = (uint32_t *) ((char *) buf + len);
bool ok = true;

// Note: If we overwrite the flash irq section of the image, we must also
// make sure interrupts are disabled and are not reenabled until we write
// this sector with another irq table.
if ((char *) addr == (char *) flash_code_location()) {
s_flash_irq_disabled = true;
MG_ARM_DISABLE_IRQ();
}

while (ok && src < end) {
if (flash_page_start(dst) && mg_flash_erase(dst) == false) {
break;
}
uint32_t status;
uint32_t dst_ofs = (uint32_t) dst - (uint32_t) mg_flash_start();
if ((char *) buf >= (char *) mg_flash_start()) {
// If we copy from FLASH to FLASH, then we first need to copy the source
// to RAM
size_t tmp_buf_size = mg_flash_write_align() / sizeof(uint32_t);
uint32_t tmp[tmp_buf_size];

for (size_t i = 0; i < tmp_buf_size; i++) {
flash_wait();
tmp[i] = src[i];
}
MG_ARM_DISABLE_IRQ();
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, &config,
(uint32_t) dst_ofs, tmp);
} else {
MG_ARM_DISABLE_IRQ();
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, &config,
(uint32_t) dst_ofs, src);
}
if (!s_flash_irq_disabled) {
MG_ARM_ENABLE_IRQ();
}
src = (uint32_t *) ((char *) src + mg_flash_write_align());
dst = (uint32_t *) ((char *) dst + mg_flash_write_align());
if (status != 0) {
ok = false;
}
}
MG_DEBUG(("Flash write %lu bytes @ %p: %s.", len, dst, ok ? "ok" : "fail"));

if ((char *) addr == (char *) flash_code_location()) {
s_flash_irq_disabled = false;
MG_ARM_ENABLE_IRQ();
}

return ok;
}

MG_IRAM void mg_device_reset(void) {
MG_DEBUG(("Resetting device..."));
*(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
}

#if MG_DEVICE == MG_DEVICE_RT1060
MG_IRAM bool mg_flash_erase_all(void) {
struct mg_flexspi_nor_config config;
if (flexspi_nor_get_config(&config) != 0) {
return false;
}
MG_ARM_DISABLE_IRQ();
bool ok = (flexspi_nor->erase_all(FLEXSPI_NOR_INSTANCE, &config) == 0);
if (!s_flash_irq_disabled) {
MG_ARM_ENABLE_IRQ();
}
MG_DEBUG(("Chip erase: %s", ok ? "Success" : "Failure"));
return ok;
}
#endif

#endif

#ifdef MG_ENABLE_LINES
#line 1 "src/device_stm32h5.c"
#endif
Expand Down
Loading

0 comments on commit cc10443

Please sign in to comment.