From 1228b3b04d04d89613399911ce0b6dc37a12a1fd Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Thu, 25 Jul 2024 17:01:06 +0200 Subject: [PATCH] micropython: Add hook for builtin programs. --- CHANGELOG.md | 2 + bricks/_common/micropython.c | 70 ++++++++++++++------ bricks/_common/modules/.gitignore | 2 +- bricks/_common/modules/_builtin_port_view.py | 1 + 4 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 bricks/_common/modules/_builtin_port_view.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bf714e3e..971f6d4ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ the hub ([pybricks-micropython#250]). - Improved font for the digits ``0--9`` when displaying them with `hub.display.char(str(x))` ([pybricks-micropython#253]). +- Added an optional 32-bit program identifier payload to the protocol commands + for starting a builtin or user program. ### Fixed - Fixed not able to connect to new Technic Move hub with `LWP3Device()`. diff --git a/bricks/_common/micropython.c b/bricks/_common/micropython.c index 162ad49b4..92af68b43 100644 --- a/bricks/_common/micropython.c +++ b/bricks/_common/micropython.c @@ -295,27 +295,47 @@ static void run_user_program(void) { nlr_set_abort(NULL); } +/** + * Builtin Pybricks MicroPython program identifiers. + */ +typedef enum { + /** + * The MicroPython REPL. + */ + PYBRICKS_MICROPYTHON_BUILTIN_PROGRAM_ID_REPL = 0, + /** + * Program that detects attached devices, displays sensor values, and + * relays sensor data to host if connected. + */ + PYBRICKS_MICROPYTHON_BUILTIN_PROGRAM_ID_PORT_VIEW = 1, + /** + * The number of builtin programs. + */ + PYBRICKS_MICROPYTHON_BUILTIN_PROGRAM_NUMBER_OF_PROGRAMS, +} pybricks_micropython_builtin_program_id_t; + pbio_error_t pbsys_main_program_validate(pbsys_main_program_t *program) { - #if !PYBRICKS_OPT_COMPILER + // Validate builtin programs for existence. if (program->type == PBSYS_MAIN_PROGRAM_TYPE_BUILTIN) { + #if PBSYS_CONFIG_APP_BUILTIN_PROGRAMS + if (program->id < PYBRICKS_MICROPYTHON_BUILTIN_PROGRAM_NUMBER_OF_PROGRAMS) { + return PBIO_SUCCESS; + } + #endif return PBIO_ERROR_NOT_SUPPORTED; } - #endif - if (program->type == PBSYS_MAIN_PROGRAM_TYPE_USER) { - - // If requesting a user program, ensure that it exists and is valid. - // Currently, only programs on slot 0 are supported. - uint32_t program_size = program->code_end - program->code_start; - if (program->id != 0 || program_size == 0 || program_size > PBSYS_STORAGE_MAX_PROGRAM_SIZE) { - return PBIO_ERROR_NOT_SUPPORTED; - } - - // TODO: Now that we have moved these checks to the MicroPython - // application code, we can check that a valid program is in fact - // present by checking the MicroPython format. + // If requesting a user program, ensure that it exists and is valid. + // Currently, only programs on slot 0 are supported. + uint32_t program_size = program->code_end - program->code_start; + if (program->id != 0 || program_size == 0 || program_size > PBSYS_STORAGE_MAX_PROGRAM_SIZE) { + return PBIO_ERROR_NOT_SUPPORTED; } + + // TODO: Now that we have moved these checks to the MicroPython + // application code, we can check that a valid program is in fact + // present by checking the MicroPython format. return PBIO_SUCCESS; } @@ -345,15 +365,25 @@ void pbsys_main_run_program(pbsys_main_program_t *program) { if (program->type == PBSYS_MAIN_PROGRAM_TYPE_USER) { // Init Pybricks package without auto-import. pb_package_pybricks_init(false); - // Run loaded program. + // Run loaded user program. run_user_program(); } - #if PYBRICKS_OPT_COMPILER + #if PBSYS_CONFIG_APP_BUILTIN_PROGRAMS else { - // For MicroPython, the builtin program is the REPL. - // Run it with everything auto-imported. - pb_package_pybricks_init(true); - run_repl(); + switch (program->id) { + case PYBRICKS_MICROPYTHON_BUILTIN_PROGRAM_ID_REPL: + // Run REPL with everything auto-imported. + pb_package_pybricks_init(true); + run_repl(); + break; + case PYBRICKS_MICROPYTHON_BUILTIN_PROGRAM_ID_PORT_VIEW: + pyexec_frozen_module("_builtin_port_view.py", false); + break; + default: + // Existence was already validated above, so just quietly exit + // since we can't get here. + break; + } } #endif // PYBRICKS_OPT_COMPILER diff --git a/bricks/_common/modules/.gitignore b/bricks/_common/modules/.gitignore index 9114ca262..aed42152a 100644 --- a/bricks/_common/modules/.gitignore +++ b/bricks/_common/modules/.gitignore @@ -1,3 +1,3 @@ *.py !_hub_extra.py -!_robotics_extra.py +!_builtin_port_view.py diff --git a/bricks/_common/modules/_builtin_port_view.py b/bricks/_common/modules/_builtin_port_view.py new file mode 100644 index 000000000..0bd1562b1 --- /dev/null +++ b/bricks/_common/modules/_builtin_port_view.py @@ -0,0 +1 @@ +print("Port View")