From 560988e12173033981c2ecf6607aa9e422f100c2 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Tue, 7 Oct 2025 16:48:19 +0200 Subject: [PATCH] micropython: Bring back running program from storage RAM. This was missed in 65d519679ed2327abaf2d1669e521c3857819d30 when upgrading MicroPython. This would lead to programs being copied to RAM before running. How it was found: If all slots were full, then the program would not run as there would not be enough heap to load yet another program. Also, MicroPython has a hardcoded test for mp_reader_mem_readbyte in mp_reader_try_read_rom, so it would ignore our reader even with MICROPY_VFS_ROM enabled. Fixes https://github.com/pybricks/support/issues/2382 --- bricks/_common/micropython.c | 36 +++-------------------------------- bricks/_common/mpconfigport.h | 3 ++- 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/bricks/_common/micropython.c b/bricks/_common/micropython.c index 6dab17042..a71280593 100644 --- a/bricks/_common/micropython.c +++ b/bricks/_common/micropython.c @@ -34,6 +34,7 @@ #include "py/mphal.h" #include "py/objmodule.h" #include "py/persistentcode.h" +#include "py/reader.h" #include "py/repl.h" #include "py/runtime.h" #include "py/stackctrl.h" @@ -74,35 +75,6 @@ bool pbsys_main_stdin_event(uint8_t c) { return false; } -// The following defines a reader for use by micropython/py/persistentcode.c. -typedef struct _mp_vfs_map_minimal_t { - const byte *cur; - const byte *end; -} mp_vfs_map_minimal_t; - -mp_uint_t mp_vfs_map_minimal_readbyte(void *data) { - mp_vfs_map_minimal_t *blob = (mp_vfs_map_minimal_t *)data; - return (blob->cur < blob->end) ? *blob->cur++ : MP_READER_EOF; -} - -const uint8_t *mp_vfs_map_minimal_read_bytes(mp_reader_t *reader, size_t len) { - mp_vfs_map_minimal_t *blob = (mp_vfs_map_minimal_t *)reader->data; - const uint8_t *ptr = blob->cur; - blob->cur += len; - return ptr; -} - -static void mp_vfs_map_minimal_close(void *data) { -} - -static void mp_vfs_map_minimal_new_reader(mp_reader_t *reader, mp_vfs_map_minimal_t *data, const byte *buf, size_t len) { - data->cur = buf; - data->end = buf + len; - reader->data = data; - reader->readbyte = mp_vfs_map_minimal_readbyte; - reader->close = mp_vfs_map_minimal_close; -} - // Prints the exception that ended the program. static void print_final_exception(mp_obj_t exc, int ret) { nlr_buf_t nlr; @@ -270,8 +242,7 @@ static void run_user_program(void) { // This is similar to __import__ except we don't push/pop globals mp_reader_t reader; - mp_vfs_map_minimal_t data; - mp_vfs_map_minimal_new_reader(&reader, &data, mpy_data_get_buf(info), pbio_get_uint32_le(info->mpy_size)); + mp_reader_new_mem(&reader, mpy_data_get_buf(info), pbio_get_uint32_le(info->mpy_size), MP_READER_IS_ROM); mp_module_context_t *context = m_new_obj(mp_module_context_t); context->module.globals = mp_globals_get(); mp_compiled_module_t compiled_module; @@ -472,8 +443,7 @@ mp_obj_t pb_builtin_import(size_t n_args, const mp_obj_t *args) { if (info) { // Parse the static script data. mp_reader_t reader; - mp_vfs_map_minimal_t data; - mp_vfs_map_minimal_new_reader(&reader, &data, mpy_data_get_buf(info), pbio_get_uint32_le(info->mpy_size)); + mp_reader_new_mem(&reader, mpy_data_get_buf(info), pbio_get_uint32_le(info->mpy_size), MP_READER_IS_ROM); // Create new module and execute in its own context. mp_obj_t module_obj = mp_obj_new_module(module_name_qstr); diff --git a/bricks/_common/mpconfigport.h b/bricks/_common/mpconfigport.h index b12ca47c1..d36cb82b8 100644 --- a/bricks/_common/mpconfigport.h +++ b/bricks/_common/mpconfigport.h @@ -116,7 +116,8 @@ #define MICROPY_PERSISTENT_CODE_LOAD (1) #define MICROPY_ENABLE_EXTERNAL_IMPORT (0) #define MICROPY_HAS_FILE_READER (0) -#define MICROPY_VFS_MAP_MINIMAL (1) +#define MICROPY_VFS_ROM (1) +#define MICROPY_VFS_ROM_IOCTL (0) #if PYBRICKS_OPT_CUSTOM_IMPORT #define mp_builtin___import__ pb_builtin_import #endif