mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #2029 from openmv/refactor_boot_script_code
ports/all: Refactor common boot code.
This commit is contained in:
commit
1e454f4022
@ -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/, \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,34 +1,38 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2022 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2022 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* Copyright (c) 2013-2023 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2023 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Factory reset util functions.
|
||||
* Boot util functions.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
||||
16
src/omv/common/boot_utils.h
Normal file
16
src/omv/common/boot_utils.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2023 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2023 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* 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__
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2022 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2022 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* 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__ */
|
||||
@ -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) {
|
||||
|
||||
@ -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/, \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 \
|
||||
)
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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/, \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user