From 2fe47234b320ae12e8962a0c52bd7db9735cebb2 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 26 Nov 2023 14:47:33 +0100 Subject: [PATCH 1/5] misc: Refactor common boot code. --- src/omv/Makefile | 6 +- .../common/{factoryreset.c => boot_utils.c} | 66 ++++++++++++++----- src/omv/common/boot_utils.h | 16 +++++ src/omv/common/factoryreset.h | 14 ---- 4 files changed, 68 insertions(+), 34 deletions(-) rename src/omv/common/{factoryreset.c => boot_utils.c} (50%) create mode 100644 src/omv/common/boot_utils.h delete mode 100644 src/omv/common/factoryreset.h diff --git a/src/omv/Makefile b/src/omv/Makefile index 245e77ad1..a9d098369 100644 --- a/src/omv/Makefile +++ b/src/omv/Makefile @@ -17,16 +17,16 @@ SRCS += $(addprefix alloc/, \ SRCS += $(addprefix common/, \ array.c \ - file_utils.c \ ini.c \ ringbuf.c \ trace.c \ mutex.c \ + vospi.c \ usbdbg.c \ tinyusb_debug.c \ + file_utils.c \ + boot_utils.c \ sensor_utils.c \ - factoryreset.c \ - vospi.c \ ) SRCS += $(addprefix sensors/, \ diff --git a/src/omv/common/factoryreset.c b/src/omv/common/boot_utils.c similarity index 50% rename from src/omv/common/factoryreset.c rename to src/omv/common/boot_utils.c index 23b8de112..d8d65063e 100644 --- a/src/omv/common/factoryreset.c +++ b/src/omv/common/boot_utils.c @@ -1,34 +1,38 @@ /* * This file is part of the OpenMV project. * - * Copyright (c) 2013-2022 Ibrahim Abdelkader - * Copyright (c) 2013-2022 Kwabena W. Agyeman + * Copyright (c) 2013-2023 Ibrahim Abdelkader + * Copyright (c) 2013-2023 Kwabena W. Agyeman * * This work is licensed under the MIT license, see the file LICENSE for details. * - * Factory reset util functions. + * Boot util functions. */ #include #include "py/runtime.h" #include "py/mperrno.h" #include "py/mphal.h" -#include "omv_boardconfig.h" - +#include "py/objstr.h" +#include "shared/runtime/pyexec.h" #if MICROPY_HW_USB_MSC #include "extmod/vfs.h" #include "extmod/vfs_fat.h" -#include "common/factoryreset.h" - // Fresh filesystem templates. #include "main_py.h" #include "readme_txt.h" -#if (OMV_ENABLE_SELFTEST == 1) -#include "selftest_py.h" #endif +#include "omv_boardconfig.h" +#include "usbdbg.h" +#if OMV_ENABLE_WIFIDBG +#include "wifidbg.h" +#endif +#include "file_utils.h" +#include "boot_utils.h" +#if MICROPY_VFS_FAT extern void __fatal_error(); -int factoryreset_create_filesystem(fs_user_mount_t *vfs) { +int bootutils_init_filesystem(fs_user_mount_t *vfs) { FIL fp; UINT n; uint8_t working_buf[FF_MAX_SS]; if (f_mkfs(&vfs->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf)) != FR_OK) { @@ -51,13 +55,41 @@ int factoryreset_create_filesystem(fs_user_mount_t *vfs) { f_write(&fp, fresh_readme_txt, sizeof(fresh_readme_txt) - 1 /* don't count null terminator */, &n); f_close(&fp); - #if (OMV_ENABLE_SELFTEST == 1) - // Create default selftest.py - f_open(&vfs->fatfs, &fp, "/selftest.py", FA_WRITE | FA_CREATE_ALWAYS); - f_write(&fp, fresh_selftest_py, sizeof(fresh_selftest_py) - 1 /* don't count null terminator */, &n); - f_close(&fp); - #endif - return 0; } #endif + +bool bootutils_exec_bootscript(const char *path, bool interruptible, bool wifidbg_enabled) { + nlr_buf_t nlr; + bool interrupted = false; + + if (nlr_push(&nlr) == 0) { + // Enable IDE interrupts if allowed. + if (interruptible) { + usbdbg_set_irq_enabled(true); + usbdbg_set_script_running(true); + #if OMV_ENABLE_WIFIDBG + wifidbg_set_irq_enabled(wifidbg_enabled); + #endif + } + + // Parse, compile and execute the script. + pyexec_file_if_exists(path, true); + nlr_pop(); + } else { + interrupted = true; + } + + // Disable IDE interrupts + usbdbg_set_irq_enabled(false); + usbdbg_set_script_running(false); + #if OMV_ENABLE_WIFIDBG + wifidbg_set_irq_enabled(false); + #endif + + if (interrupted) { + mp_obj_print_exception(&mp_plat_print, (mp_obj_t) nlr.ret_val); + } + + return interrupted; +} diff --git a/src/omv/common/boot_utils.h b/src/omv/common/boot_utils.h new file mode 100644 index 000000000..913b10b77 --- /dev/null +++ b/src/omv/common/boot_utils.h @@ -0,0 +1,16 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2013-2023 Ibrahim Abdelkader + * Copyright (c) 2013-2023 Kwabena W. Agyeman + * + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Boot util functions. + */ +#ifndef __BOOT_UTILS_H__ +#define __BOOT_UTILS_H__ +typedef struct _fs_user_mount_t fs_user_mount_t; +int bootutils_init_filesystem(fs_user_mount_t *vfs); +bool bootutils_exec_bootscript(const char *path, bool interruptible, bool wifidbg_enabled); +#endif // __BOOT_UTILS_H__ diff --git a/src/omv/common/factoryreset.h b/src/omv/common/factoryreset.h deleted file mode 100644 index a8bfbc6b9..000000000 --- a/src/omv/common/factoryreset.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2022 Ibrahim Abdelkader - * Copyright (c) 2013-2022 Kwabena W. Agyeman - * - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * Factory reset util functions. - */ -#ifndef __FACTORY_RESET_H__ -#define __FACTORY_RESET_H__ -int factoryreset_create_filesystem(fs_user_mount_t *vfs); -#endif /* __FACTORY_RESET_H__ */ From 861ee0b9b26b369f496cbf0153de43ee4d30bf53 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 26 Nov 2023 14:48:31 +0100 Subject: [PATCH 2/5] ports/mimxrt: Refactor common boot code. --- src/omv/ports/mimxrt/main.c | 57 +++++++------------------- src/omv/ports/mimxrt/omv_portconfig.mk | 5 ++- 2 files changed, 18 insertions(+), 44 deletions(-) diff --git a/src/omv/ports/mimxrt/main.c b/src/omv/ports/mimxrt/main.c index f4d0fbc0f..ce121c9b2 100644 --- a/src/omv/ports/mimxrt/main.c +++ b/src/omv/ports/mimxrt/main.c @@ -50,7 +50,6 @@ #include "extmod/vfs.h" #include "extmod/vfs_fat.h" -#include "common/factoryreset.h" #include "omv_boardconfig.h" #include "framebuffer.h" @@ -60,36 +59,11 @@ #include "fb_alloc.h" #include "dma_alloc.h" #include "file_utils.h" +#include "boot_utils.h" #include "mimxrt_hal.h" extern uint8_t _sstack, _estack, _heap_start, _heap_end; -void exec_boot_script(const char *path, bool interruptible) { - nlr_buf_t nlr; - bool interrupted = false; - if (nlr_push(&nlr) == 0) { - // Enable IDE interrupts if allowed. - if (interruptible) { - usbdbg_set_irq_enabled(true); - usbdbg_set_script_running(true); - } - - // Parse, compile and execute the script. - pyexec_file_if_exists(path, true); - nlr_pop(); - } else { - interrupted = true; - } - - // Disable IDE interrupts - usbdbg_set_irq_enabled(false); - usbdbg_set_script_running(false); - - if (interrupted) { - mp_obj_print_exception(&mp_plat_print, (mp_obj_t) nlr.ret_val); - } -} - int main(void) { bool sdcard_detected = false; bool sdcard_mounted = false; @@ -101,9 +75,7 @@ int main(void) { pendsv_init(); soft_reset: - #if defined(MICROPY_HW_LED1) led_init(); - #endif // Initialise stack extents and GC heap. mp_stack_set_top(&_estack); @@ -178,9 +150,8 @@ soft_reset: #endif #if MICROPY_PY_SENSOR - if (first_soft_reset - && sensor_init() != 0) { - printf("sensor init failed!\n"); + if (first_soft_reset) { + sensor_init(); } #endif @@ -211,7 +182,7 @@ soft_reset: } else { // Create a fresh filesystem. fs_user_mount_t *vfs = MP_OBJ_TYPE_GET_SLOT(&mp_fat_vfs_type, make_new) (&mp_fat_vfs_type, 1, 0, &bdev); - if (factoryreset_create_filesystem(vfs) == 0) { + if (bootutils_init_filesystem(vfs) == 0) { if (mp_vfs_mount_and_chdir_protected(bdev, mount_point) == 0) { mimxrt_msc_medium = &mimxrt_flash_type; } @@ -219,19 +190,21 @@ soft_reset: } } - // Deferred tusb_init to allow the filesystem to be mounted/created before MSC. + // Mark the filesystem as an OpenMV storage. + file_ll_touch(".openmv_disk"); + + // Initialize TinyUSB after the filesystem is mounted. if (!tusb_inited()) { tusb_init(); } - // Mark FS as OpenMV disk. - file_ll_touch(".openmv_disk"); + // Run boot.py script. + bool interrupted = bootutils_exec_bootscript("boot.py", true, false); - // Execute user scripts. - exec_boot_script("boot.py", false); - - if (first_soft_reset) { - exec_boot_script("main.py", true); + // Run main.py script on first soft-reset. + if (first_soft_reset && !interrupted && mp_vfs_import_stat("main.py")) { + bootutils_exec_bootscript("main.py", true, false); + goto soft_reset_exit; } // If there's no script ready, just re-exec REPL @@ -279,6 +252,7 @@ soft_reset: } } +soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); machine_pin_irq_deinit(); machine_rtc_irq_deinit(); @@ -300,7 +274,6 @@ soft_reset: mp_deinit(); first_soft_reset = false; goto soft_reset; - return 0; } void gc_collect(void) { diff --git a/src/omv/ports/mimxrt/omv_portconfig.mk b/src/omv/ports/mimxrt/omv_portconfig.mk index 97d7f5a30..d028c6c3d 100644 --- a/src/omv/ports/mimxrt/omv_portconfig.mk +++ b/src/omv/ports/mimxrt/omv_portconfig.mk @@ -41,6 +41,7 @@ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/lib/lwip/src/include/ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/ports/mimxrt/ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/ports/mimxrt/lwip_inc/ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/shared/runtime/ +MPY_CFLAGS += -DMICROPY_VFS_FAT=1 ifeq ($(MICROPY_PY_LWIP), 0) MICROPY_ARGS += MICROPY_PY_LWIP=0 MICROPY_PY_USSL=0 @@ -127,7 +128,6 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/alloc/, \ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/common/, \ array.o \ - file_utils.o \ ini.o \ ringbuf.o \ trace.o \ @@ -135,8 +135,9 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/common/, \ vospi.o \ usbdbg.o \ tinyusb_debug.o \ + file_utils.o \ + boot_utils.o \ sensor_utils.o \ - factoryreset.o \ ) FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \ From c7457f11ed7d1e75209306062f28aa1708c0e9c7 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 26 Nov 2023 14:48:52 +0100 Subject: [PATCH 3/5] ports/rp2: Refactor common boot code. --- .../imlib_config.h | 3 +- src/omv/ports/rp2/main.c | 61 +++++++------------ src/omv/ports/rp2/omv_portconfig.cmake | 4 +- 3 files changed, 25 insertions(+), 43 deletions(-) diff --git a/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/imlib_config.h b/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/imlib_config.h index 56c810a3d..40516ed5c 100644 --- a/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/imlib_config.h +++ b/src/omv/boards/ARDUINO_NANO_RP2040_CONNECT/imlib_config.h @@ -15,8 +15,7 @@ //#define IMLIB_ENABLE_IMAGE_IO // Enable Image File I/O -// Not filesystem yet -//#define IMLIB_ENABLE_IMAGE_FILE_IO +#define IMLIB_ENABLE_IMAGE_FILE_IO // Enable LAB LUT //#define IMLIB_ENABLE_LAB_LUT diff --git a/src/omv/ports/rp2/main.c b/src/omv/ports/rp2/main.c index 0d73ebb46..0edf6d491 100644 --- a/src/omv/ports/rp2/main.c +++ b/src/omv/ports/rp2/main.c @@ -74,8 +74,8 @@ #if MICROPY_VFS_FAT && MICROPY_HW_USB_MSC #include "extmod/vfs.h" #include "extmod/vfs_fat.h" -#include "common/factoryreset.h" #endif +#include "boot_utils.h" extern uint8_t __StackTop, __StackBottom; static char OMV_ATTR_SECTION(OMV_ATTR_ALIGNED(gc_heap[OMV_HEAP_SIZE], 4), ".heap"); @@ -108,32 +108,6 @@ void pico_reset_to_bootloader(size_t n_args, const void *args_in) { reset_usb_boot(0, 0); } -void exec_boot_script(const char *path, bool interruptible) { - nlr_buf_t nlr; - bool interrupted = false; - if (nlr_push(&nlr) == 0) { - // Enable IDE interrupts if allowed. - if (interruptible) { - usbdbg_set_irq_enabled(true); - usbdbg_set_script_running(true); - } - - // Parse, compile and execute the script. - pyexec_file_if_exists(path, true); - nlr_pop(); - } else { - interrupted = true; - } - - // Disable IDE interrupts - usbdbg_set_irq_enabled(false); - usbdbg_set_script_running(false); - - if (interrupted) { - mp_obj_print_exception(&mp_plat_print, (mp_obj_t) nlr.ret_val); - } -} - int main(int argc, char **argv) { bool first_soft_reset = true; @@ -145,7 +119,6 @@ int main(int argc, char **argv) { #if MICROPY_HW_ENABLE_USBDEV bi_decl(bi_program_feature("USB REPL")) - tusb_init(); #endif #if MICROPY_PY_THREAD @@ -170,12 +143,6 @@ int main(int argc, char **argv) { OMV_UNIQUE_ID_ADDR = pico_unique_id.id; pico_get_unique_board_id(&pico_unique_id); - // Install Tinyusb CDC debugger IRQ handler. - irq_set_enabled(USBCTRL_IRQ, false); - irq_remove_handler(USBCTRL_IRQ, irq_get_vtable_handler(USBCTRL_IRQ)); - irq_set_exclusive_handler(USBCTRL_IRQ, OMV_USB1_IRQ_HANDLER); - irq_set_enabled(USBCTRL_IRQ, true); - soft_reset: // Initialise stack extents and GC heap. mp_stack_set_top(&__StackTop); @@ -219,7 +186,7 @@ soft_reset: if (mp_vfs_mount_and_chdir_protected(bdev, mount_point) == -MP_ENODEV) { // Create a fresh filesystem. fs_user_mount_t *vfs = MP_OBJ_TYPE_GET_SLOT(&mp_fat_vfs_type, make_new) (&mp_fat_vfs_type, 1, 0, &bdev); - if (factoryreset_create_filesystem(vfs) == 0) { + if (bootutils_init_filesystem(vfs) == 0) { mp_vfs_mount_and_chdir_protected(bdev, mount_point); } } @@ -227,11 +194,26 @@ soft_reset: pyexec_frozen_module("_boot.py", false); #endif - // Execute user scripts. - exec_boot_script("boot.py", false); + // Mark the filesystem as an OpenMV storage. + file_ll_touch(".openmv_disk"); - if (first_soft_reset) { - exec_boot_script("main.py", true); + // Initialize TinyUSB after the filesystem has been mounted. + if (!tusb_inited()) { + tusb_init(); + + // Install Tinyusb CDC debugger IRQ handler. + irq_set_enabled(USBCTRL_IRQ, false); + irq_remove_handler(USBCTRL_IRQ, irq_get_vtable_handler(USBCTRL_IRQ)); + irq_set_exclusive_handler(USBCTRL_IRQ, OMV_USB1_IRQ_HANDLER); + } + + // Run boot.py script. + bool interrupted = bootutils_exec_bootscript("boot.py", true, false); + + // Run main.py script on first soft-reset. + if (first_soft_reset && !interrupted && mp_vfs_import_stat("main.py")) { + bootutils_exec_bootscript("main.py", true, false); + goto soft_reset_exit; } // If there's no script ready, just re-exec REPL @@ -282,6 +264,7 @@ soft_reset: } } +soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); #if MICROPY_PY_AUDIO py_audio_deinit(); diff --git a/src/omv/ports/rp2/omv_portconfig.cmake b/src/omv/ports/rp2/omv_portconfig.cmake index 4ddb16770..438de1ed6 100644 --- a/src/omv/ports/rp2/omv_portconfig.cmake +++ b/src/omv/ports/rp2/omv_portconfig.cmake @@ -93,15 +93,15 @@ target_sources(${MICROPY_TARGET} PRIVATE ${TOP_DIR}/${OMV_DIR}/alloc/unaligned_memcpy.c ${TOP_DIR}/${OMV_DIR}/common/array.c - ${TOP_DIR}/${OMV_DIR}/common/file_utils.c ${TOP_DIR}/${OMV_DIR}/common/ini.c ${TOP_DIR}/${OMV_DIR}/common/ringbuf.c ${TOP_DIR}/${OMV_DIR}/common/trace.c ${TOP_DIR}/${OMV_DIR}/common/mutex.c ${TOP_DIR}/${OMV_DIR}/common/usbdbg.c ${TOP_DIR}/${OMV_DIR}/common/tinyusb_debug.c + ${TOP_DIR}/${OMV_DIR}/common/file_utils.c + ${TOP_DIR}/${OMV_DIR}/common/boot_utils.c ${TOP_DIR}/${OMV_DIR}/common/sensor_utils.c - ${TOP_DIR}/${OMV_DIR}/common/factoryreset.c ${TOP_DIR}/${OMV_DIR}/sensors/ov2640.c ${TOP_DIR}/${OMV_DIR}/sensors/ov5640.c From d57086e1b79d2eec585001a1cf69e336aa778773 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 26 Nov 2023 15:23:45 +0100 Subject: [PATCH 4/5] ports/stm32: Refactor common boot code. --- src/omv/ports/stm32/main.c | 235 +++++++++----------------- src/omv/ports/stm32/omv_portconfig.mk | 11 +- 2 files changed, 87 insertions(+), 159 deletions(-) diff --git a/src/omv/ports/stm32/main.c b/src/omv/ports/stm32/main.c index b560165e3..1e46d1b08 100644 --- a/src/omv/ports/stm32/main.c +++ b/src/omv/ports/stm32/main.c @@ -92,7 +92,7 @@ #include "extmod/vfs.h" #include "extmod/vfs_fat.h" -#include "common/factoryreset.h" +#include "boot_utils.h" int errno; extern char _vfs_buf[]; @@ -215,73 +215,6 @@ int ini_handler_callback(void *user, const char *section, const char *name, cons #undef MATCH } -FRESULT exec_boot_script(const char *path, bool selftest, bool interruptible, bool wifidbg_enabled) { - nlr_buf_t nlr; - bool interrupted = false; - FRESULT f_res = FR_NO_FILE; - - if (nlr_push(&nlr) == 0) { - // Enable IDE interrupts if allowed. - if (interruptible) { - usbdbg_set_irq_enabled(true); - usbdbg_set_script_running(true); - #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 - wifidbg_set_irq_enabled(wifidbg_enabled); - #endif - } - - // Try to run the frozen module first. - if (pyexec_frozen_module(path, true) == false) { - // No frozen module, try the filesystem. - f_res = file_ll_stat(path, NULL); - if (f_res == FR_OK) { - // Parse, compile and execute the script. - pyexec_file(path, true); - } - } - nlr_pop(); - } else { - interrupted = true; - } - - // Disable IDE interrupts - usbdbg_set_irq_enabled(false); - usbdbg_set_script_running(false); - #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 - wifidbg_set_irq_enabled(false); - #endif - - if (interrupted) { - if (selftest) { - // Get the exception message. TODO: might be a hack. - mp_obj_str_t *str = mp_obj_exception_get_value((mp_obj_t) nlr.ret_val); - // If any of the self-tests fail log the exception message - // and loop forever. Note: IDE exceptions will not be caught. - __fatal_error((const char *) str->data); - } else { - mp_obj_print_exception(&mp_plat_print, (mp_obj_t) nlr.ret_val); - if (nlr_push(&nlr) == 0) { - flash_error(3); - nlr_pop(); - }// If this gets interrupted again ignore it. - } - } - - if (selftest && f_res == FR_OK) { - // Remove self tests script and flush cache - file_ll_unlink(path); - storage_flush(); - - #ifdef OMV_SELF_TEST_SWD_ADDR - // Set flag for SWD debugger. - // Note: main.py does not use the frame buffer. - OMV_SELF_TEST_SWD_ADDR = 0xDEADBEEF; - #endif - } - - return f_res; -} - int main(void) { #if MICROPY_HW_SDRAM_SIZE bool sdram_ok = false; @@ -470,7 +403,7 @@ soft_reset: if (res == FR_NO_FILESYSTEM) { // Create a fresh filesystem. led_state(LED_RED, 1); - factoryreset_create_filesystem(vfs_fat); + bootutils_init_filesystem(vfs_fat); led_state(LED_RED, 0); // Flush storage storage_flush(); @@ -505,7 +438,7 @@ else { MP_STATE_VM(vfs_mount_table) = vfs; MP_STATE_PORT(vfs_cur) = vfs; - // Mark FS as OpenMV disk. + // Mark the filesystem as an OpenMV storage. file_ll_touch("/.openmv_disk"); // Parse OpenMV configuration file. @@ -523,21 +456,6 @@ else { openmv_config.wifidbg = false; #endif - // Execute frozen _boot.py (if any) for early system setup. - pyexec_frozen_module("_boot.py", false); - - // Run boot script(s) - if (first_soft_reset) { - // Execute the boot.py script before initializing the USB dev to - // override the USB mode if required, otherwise VCP+MSC is used. - exec_boot_script("boot.py", false, false, false); - #if (OMV_ENABLE_SELFTEST == 1) - // Execute the selftests.py script before the filesystem is mounted - // to avoid corrupting the filesystem when selftests.py is removed. - exec_boot_script("selftest.py", true, false, false); - #endif - } - // Init USB device to default setting if it was not already configured if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) { pyb_usb_dev_init(pyb_usb_dev_detect(), MICROPY_HW_USB_VID, @@ -558,80 +476,89 @@ else { led_state(LED_GREEN, 0); led_state(LED_BLUE, 0); - // Run main script if it exists. - if (first_soft_reset) { - exec_boot_script("main.py", false, true, openmv_config.wifidbg); - } else { - do { - usbdbg_init(); - if (openmv_config.wifidbg == true) { - // Need to reinit imlib in WiFi debug mode. - imlib_deinit_all(); - imlib_init_all(); - } + // Run boot.py script. + bool interrupted = bootutils_exec_bootscript("boot.py", true, false); - // If there's no script ready, just re-exec REPL - while (!usbdbg_script_ready()) { - nlr_buf_t nlr; - - if (nlr_push(&nlr) == 0) { - // enable IDE interrupt - usbdbg_set_irq_enabled(true); - #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 - wifidbg_set_irq_enabled(openmv_config.wifidbg); - #endif - - // run REPL - if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { - if (pyexec_raw_repl() != 0) { - break; - } - } else { - if (pyexec_friendly_repl() != 0) { - break; - } - } - - nlr_pop(); - } - } - - if (usbdbg_script_ready()) { - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - // Enable IDE interrupts - usbdbg_set_irq_enabled(true); - #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 - wifidbg_set_irq_enabled(openmv_config.wifidbg); - #endif - // Execute the script. - pyexec_str(usbdbg_get_script(), true); - // Disable IDE interrupts - usbdbg_set_irq_enabled(false); - nlr_pop(); - } else { - mp_obj_print_exception(&mp_plat_print, (mp_obj_t) nlr.ret_val); - } - - if (usbdbg_is_busy() && nlr_push(&nlr) == 0) { - // Enable IDE interrupt - usbdbg_set_irq_enabled(true); - #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 - wifidbg_set_irq_enabled(openmv_config.wifidbg); - #endif - // Wait for the current command to finish. - usbdbg_wait_for_command(1000); - // Disable IDE interrupts - usbdbg_set_irq_enabled(false); - nlr_pop(); - } - } - - } while (openmv_config.wifidbg == true); + // Run main.py script on first soft-reset. + if (first_soft_reset && !interrupted && mp_vfs_import_stat("main.py")) { + bootutils_exec_bootscript("main.py", true, openmv_config.wifidbg); + goto soft_reset_exit; } + do { + usbdbg_init(); + + if (openmv_config.wifidbg == true) { + // Need to reinit imlib in WiFi debug mode. + imlib_deinit_all(); + imlib_init_all(); + } + + // If there's no script ready, just re-exec REPL + while (!usbdbg_script_ready()) { + nlr_buf_t nlr; + + if (nlr_push(&nlr) == 0) { + // enable IDE interrupt + usbdbg_set_irq_enabled(true); + #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + wifidbg_set_irq_enabled(openmv_config.wifidbg); + #endif + + // run REPL + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + if (pyexec_raw_repl() != 0) { + break; + } + } else { + if (pyexec_friendly_repl() != 0) { + break; + } + } + + nlr_pop(); + } + } + + if (usbdbg_script_ready()) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + // Enable IDE interrupts + usbdbg_set_irq_enabled(true); + #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + wifidbg_set_irq_enabled(openmv_config.wifidbg); + #endif + // Execute the script. + pyexec_str(usbdbg_get_script(), true); + // Disable IDE interrupts + usbdbg_set_irq_enabled(false); + nlr_pop(); + } else { + mp_obj_print_exception(&mp_plat_print, (mp_obj_t) nlr.ret_val); + } + + if (usbdbg_is_busy() && nlr_push(&nlr) == 0) { + // Enable IDE interrupt + usbdbg_set_irq_enabled(true); + #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + wifidbg_set_irq_enabled(openmv_config.wifidbg); + #endif + // Wait for the current command to finish. + usbdbg_wait_for_command(1000); + // Disable IDE interrupts + usbdbg_set_irq_enabled(false); + nlr_pop(); + } + } + + } while (openmv_config.wifidbg == true); + +soft_reset_exit: // soft reset + mp_printf(&mp_plat_print, "MPY: soft reboot\n"); + + // Flush filesystem storage. storage_flush(); // Call GC sweep first, before deinitializing networking drivers diff --git a/src/omv/ports/stm32/omv_portconfig.mk b/src/omv/ports/stm32/omv_portconfig.mk index 2d019fd50..75830e52d 100644 --- a/src/omv/ports/stm32/omv_portconfig.mk +++ b/src/omv/ports/stm32/omv_portconfig.mk @@ -27,7 +27,8 @@ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/ports/stm32/usbdev/core/inc/ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/ports/stm32/usbdev/class/inc/ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/ports/stm32/lwip_inc/ MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/shared/runtime/ -MPY_CFLAGS += -DMICROPY_PY_USSL=1 -DMICROPY_SSL_MBEDTLS=1 -DMICROPY_STREAMS_POSIX_API=1 +MPY_CFLAGS += -DMICROPY_PY_USSL=1 -DMICROPY_SSL_MBEDTLS=1 -DMICROPY_STREAMS_POSIX_API=1 -DMICROPY_VFS_FAT=1 + MICROPY_ARGS += MICROPY_PY_USSL=1 MICROPY_SSL_MBEDTLS=1 MICROPY_PY_BTREE=1\ STM32LIB_CMSIS_DIR=$(TOP_DIR)/$(CMSIS_DIR) STM32LIB_HAL_DIR=$(TOP_DIR)/$(HAL_DIR) @@ -144,15 +145,15 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/alloc/, \ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/common/, \ array.o \ - file_utils.o \ ini.o \ ringbuf.o \ trace.o \ mutex.o \ - usbdbg.o \ - sensor_utils.o \ - factoryreset.o \ vospi.o \ + usbdbg.o \ + file_utils.o \ + boot_utils.o \ + sensor_utils.o \ ) FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \ From 7094a6940177cd992caae08e28eb7aa483c2aabb Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 26 Nov 2023 16:41:21 +0100 Subject: [PATCH 5/5] ports/nrf: Refactor common boot code. --- src/omv/ports/nrf/main.c | 56 ++++++++++++++--------------- src/omv/ports/nrf/omv_portconfig.mk | 3 +- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/omv/ports/nrf/main.c b/src/omv/ports/nrf/main.c index 21a9a2e27..4a4c60d70 100644 --- a/src/omv/ports/nrf/main.c +++ b/src/omv/ports/nrf/main.c @@ -90,6 +90,7 @@ #include "omv_boardconfig.h" #include "omv_i2c.h" #include "sensor.h" +#include "boot_utils.h" uint32_t HAL_GetHalVersion() { // Hard-coded because it's not defined in SDK @@ -122,6 +123,8 @@ STATIC int vfs_mount_and_chdir(mp_obj_t bdev, mp_obj_t mount_point) { #endif int main(int argc, char **argv) { + bool first_soft_reset = true; + soft_reset: #if defined(MICROPY_BOARD_EARLY_INIT) MICROPY_BOARD_EARLY_INIT(); @@ -132,50 +135,41 @@ soft_reset: #endif led_init(); - led_state(1, 1); // MICROPY_HW_LED_1 aka MICROPY_HW_LED_RED mp_stack_set_top(&_ram_end); - // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. (Limit is measured in bytes.) mp_stack_set_limit((char *) &_ram_end - (char *) &_heap_end - 400); - machine_init(); - + // GC init gc_init(&_heap_start, &_heap_end); + machine_init(); mp_init(); - readline_init0(); - #if MICROPY_PY_MACHINE_HW_SPI spi_init0(); #endif - #if MICROPY_PY_MACHINE_I2C i2c_init0(); #endif - #if MICROPY_PY_MACHINE_ADC adc_init0(); #endif - #if MICROPY_PY_MACHINE_HW_PWM pwm_init0(); #endif - #if MICROPY_PY_MACHINE_RTCOUNTER rtc_init0(); #endif - #if MICROPY_PY_MACHINE_TIMER timer_init0(); #endif - #if MICROPY_PY_MACHINE_UART uart_init0(); #endif + pin_init0(); fb_alloc_init0(); framebuffer_init0(); @@ -185,18 +179,14 @@ soft_reset: #endif #if (MICROPY_PY_BLE_NUS == 0) && (MICROPY_HW_USB_CDC == 0) - { - mp_obj_t args[2] = { - MP_OBJ_NEW_SMALL_INT(0), - MP_OBJ_NEW_SMALL_INT(115200), - }; - MP_STATE_PORT(board_stdio_uart) = machine_hard_uart_type.make_new( - (mp_obj_t) &machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args); - } + mp_obj_t args[2] = { + MP_OBJ_NEW_SMALL_INT(0), + MP_OBJ_NEW_SMALL_INT(115200), + }; + MP_STATE_PORT(board_stdio_uart) = machine_hard_uart_type.make_new( + (mp_obj_t) &machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args); #endif - pin_init0(); - #if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE flashbdev_init(); @@ -280,15 +270,20 @@ soft_reset: usb_cdc_init(); #endif - #if MICROPY_VFS || MICROPY_MBFS || MICROPY_MODULE_FROZEN - // run boot.py and main.py if they exist. - pyexec_file_if_exists("boot.py", false); - pyexec_file_if_exists("main.py", false); - #endif - usbdbg_init(); pendsv_init(); + #if MICROPY_VFS || MICROPY_MBFS || MICROPY_MODULE_FROZEN + // Run boot.py script. + bool interrupted = bootutils_exec_bootscript("boot.py", true, false); + + // Run main.py script on first soft-reset. + if (first_soft_reset && !interrupted && mp_vfs_import_stat("main.py")) { + bootutils_exec_bootscript("main.py", true, false); + goto soft_reset_exit; + } + #endif + // If there's no script ready, just re-exec REPL while (!usbdbg_script_ready()) { nlr_buf_t nlr; @@ -337,6 +332,7 @@ soft_reset: } } +soft_reset_exit: printf("MPY: soft reboot\n"); #if MICROPY_PY_MACHINE_HW_PWM pwm_deinit_all(); @@ -351,9 +347,9 @@ soft_reset: MICROPY_BOARD_DEINIT(); #endif mp_deinit(); - goto soft_reset; - return 0; + first_soft_reset = false; + goto soft_reset; } #if !MICROPY_VFS diff --git a/src/omv/ports/nrf/omv_portconfig.mk b/src/omv/ports/nrf/omv_portconfig.mk index f2b365b6c..8cfe54693 100644 --- a/src/omv/ports/nrf/omv_portconfig.mk +++ b/src/omv/ports/nrf/omv_portconfig.mk @@ -100,13 +100,14 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/alloc/, \ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/common/, \ array.o \ - file_utils.o \ ini.o \ ringbuf.o \ trace.o \ mutex.o \ usbdbg.o \ tinyusb_debug.o \ + file_utils.o \ + boot_utils.o \ sensor_utils.o \ )