Skip to content

Commit

Permalink
pbsys/main: Generalize and clean up program start commands.
Browse files Browse the repository at this point in the history
This brings the waiting process for the main program to start to the
main.c loop, which makes it easier to follow.

This also generalized the commands to start builtin and user programs
with an optional identifier. For now, this will be used to start either the
REPL or Port View. In the future, it can be used to start programs on
different slots.

This also adds a hook for verifying the program at the application level
so we can verify MicroPython-specific validity and avoid hardcoding such
checks at the pbio level.

pbio/sys/config: Consolidate app config.

The separate placement of these settings was a bit contrived. We can have it
at the pbsys config level since the definitions exist at the pbio protocol level anyway.

This lets us use them as defined feature guards.
  • Loading branch information
laurensvalk committed Sep 2, 2024
1 parent 6d49992 commit 7bda223
Show file tree
Hide file tree
Showing 32 changed files with 210 additions and 237 deletions.
28 changes: 27 additions & 1 deletion bricks/_common/micropython.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
#include <pbio/button.h>
#include <pbio/main.h>
#include <pbio/util.h>
#include <pbio/protocol.h>
#include <pbsys/main.h>
#include <pbsys/program_stop.h>
#include <pbsys/storage.h>

#include <pybricks/common.h>
#include <pybricks/util_mp/pb_obj_helper.h>
Expand Down Expand Up @@ -293,6 +295,30 @@ static void run_user_program(void) {
nlr_set_abort(NULL);
}

pbio_error_t pbsys_main_program_validate(pbsys_main_program_t *program) {

#if !PYBRICKS_OPT_COMPILER
if (program->type == PBSYS_MAIN_PROGRAM_TYPE_BUILTIN) {
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.
}
return PBIO_SUCCESS;
}

// Runs MicroPython with the given program data.
void pbsys_main_run_program(pbsys_main_program_t *program) {

Expand All @@ -316,7 +342,7 @@ void pbsys_main_run_program(pbsys_main_program_t *program) {
mp_init();

// Check for run type.
if (!program->run_builtin) {
if (program->type == PBSYS_MAIN_PROGRAM_TYPE_USER) {
// Init Pybricks package without auto-import.
pb_package_pybricks_init(false);
// Run loaded program.
Expand Down
1 change: 0 additions & 1 deletion bricks/_common/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ PBIO_SRC_C = $(addprefix lib/pbio/,\
sys/storage.c \
sys/storage_settings.c \
sys/supervisor.c \
sys/user_program.c \
)

# MicroPython math library
Expand Down
2 changes: 0 additions & 2 deletions bricks/cityhub/pbsys_app_config.h

This file was deleted.

2 changes: 0 additions & 2 deletions bricks/essentialhub/pbsys_app_config.h

This file was deleted.

2 changes: 0 additions & 2 deletions bricks/ev3/pbsys_app_config.h

This file was deleted.

2 changes: 1 addition & 1 deletion bricks/ev3rt/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void main_task(intptr_t unused) {

while (true) {
pbsys_main_program_t program = {
.run_builtin = true,
.type = PBSYS_MAIN_PROGRAM_TYPE_BUILTIN,
.code_end = heap,
.data_end = heap + sizeof(heap),
};
Expand Down
2 changes: 0 additions & 2 deletions bricks/movehub/pbsys_app_config.h

This file was deleted.

2 changes: 0 additions & 2 deletions bricks/primehub/pbsys_app_config.h

This file was deleted.

2 changes: 0 additions & 2 deletions bricks/technichub/pbsys_app_config.h

This file was deleted.

4 changes: 2 additions & 2 deletions lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <pbio/task.h>
#include <pbio/util.h>
#include <pbio/version.h>
#include <pbsys/app.h>
#include <pbsys/config.h>
#include <pbsys/storage.h>

#include <contiki.h>
Expand Down Expand Up @@ -1078,7 +1078,7 @@ static PT_THREAD(init_pybricks_service(struct pt *pt)) {
PT_WAIT_WHILE(pt, write_xfer_size);
{
uint8_t buf[PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE];
pbio_pybricks_hub_capabilities(buf, ATT_MTU - 3, PBSYS_APP_HUB_FEATURE_FLAGS, PBSYS_STORAGE_MAX_PROGRAM_SIZE);
pbio_pybricks_hub_capabilities(buf, ATT_MTU - 3, PBSYS_CONFIG_APP_FEATURE_FLAGS, PBSYS_STORAGE_MAX_PROGRAM_SIZE);
aci_gatt_update_char_value_begin(pybricks_service_handle, pybricks_hub_capabilities_char_handle,
0, PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE, buf);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <pbio/task.h>
#include <pbio/util.h>
#include <pbio/version.h>
#include <pbsys/app.h>
#include <pbsys/config.h>
#include <pbsys/storage.h>

#include <contiki.h>
Expand Down Expand Up @@ -1480,7 +1480,7 @@ static void handle_event(uint8_t *packet) {
uint8_t buf[PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE];

// REVISIT: this assumes connection_handle == conn_handle
pbio_pybricks_hub_capabilities(buf, conn_mtu - 3, PBSYS_APP_HUB_FEATURE_FLAGS, PBSYS_STORAGE_MAX_PROGRAM_SIZE);
pbio_pybricks_hub_capabilities(buf, conn_mtu - 3, PBSYS_CONFIG_APP_FEATURE_FLAGS, PBSYS_STORAGE_MAX_PROGRAM_SIZE);
rsp.len = sizeof(buf);
rsp.pValue = buf;
ATT_ReadRsp(connection_handle, &rsp);
Expand Down
4 changes: 2 additions & 2 deletions lib/pbio/drv/bluetooth/pybricks_service_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
#include <pbio/int_math.h>
#include <pbio/protocol.h>

#include <pbsys/app.h>
#include <pbsys/config.h>
#include <pbsys/storage.h>

#include "btstack_defines.h"
Expand Down Expand Up @@ -89,7 +89,7 @@ static uint16_t pybricks_service_read_callback(hci_con_handle_t con_handle, uint
if (attribute_handle == pybricks_hub_capabilities_value_handle) {
if (buffer && buffer_size >= PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE) {
pbio_pybricks_hub_capabilities(buffer, pbio_int_math_min(att_server_get_mtu(con_handle) - 3, 512),
PBSYS_APP_HUB_FEATURE_FLAGS, PBSYS_STORAGE_MAX_PROGRAM_SIZE);
PBSYS_CONFIG_APP_FEATURE_FLAGS, PBSYS_STORAGE_MAX_PROGRAM_SIZE);
}
return PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE;
}
Expand Down
29 changes: 22 additions & 7 deletions lib/pbio/include/pbio/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,36 @@ typedef enum {
PBIO_PYBRICKS_COMMAND_STOP_USER_PROGRAM = 0,

/**
* Requests that the user program should be started.
* Requests that a specified user program should be started.
*
* Parameters:
* - id (optional): The identifier of the user program (32-bit little-endian unsigned integer).
* Defaults to 0 if no identifier is provided.
* This optional parameter was introduced in Pybricks Profile v1.4.0
*
* Errors:
* - ::PBIO_PYBRICKS_ERROR_BUSY if another program is already running.
* - ::PBIO_PYBRICKS_ERROR_BUSY if a program is already running.
* - ::PBIO_PYBRICKS_ERROR_INVALID_COMMAND if the builtin program is not available (Since Pybricks Profile v1.4.0).
*
* @since Pybricks Profile v1.2.0
*/
PBIO_PYBRICKS_COMMAND_START_USER_PROGRAM = 1,

/**
* Requests that the REPL should be started.
* Requests that a specified builtin program should be started.
*
* Parameters:
* - id (optional): The identifier of the builtin program (32-bit little-endian unsigned integer).
* Defaults to 0 if no identifier is provided.
* This optional parameter was introduced in Pybricks Profile v1.4.0
*
* Errors:
* - ::PBIO_PYBRICKS_ERROR_BUSY if another program is already running.
* - ::PBIO_PYBRICKS_ERROR_BUSY if a program is already running.
* - ::PBIO_PYBRICKS_ERROR_INVALID_COMMAND if the builtin program is not available (Since Pybricks Profile v1.4.0).
*
* @since Pybricks Profile v1.2.0
*/
PBIO_PYBRICKS_COMMAND_START_REPL = 2,
PBIO_PYBRICKS_COMMAND_START_BUILTIN_PROGRAM = 2,

/**
* Requests to write user program metadata.
Expand Down Expand Up @@ -298,11 +310,14 @@ typedef enum {
// NB: the values are part of the protocol, so don't change the values!

/**
* Hub support interactive REPL.
* Hub supports builtin programs, such as an interactive REPL or Port View.
*
* Prior to version 1.4.0 this flag was exclusively used to indicate REPL
* support since there were no other builtin programs.
*
* @since Pybricks Profile v1.2.0.
*/
PBIO_PYBRICKS_FEATURE_REPL = 1 << 0,
PBIO_PYBRICKS_FEATURE_BUILTIN_PROGRAMS = 1 << 0,
/**
* Hub supports user program with multiple MicroPython .mpy files ABI v6
*
Expand Down
31 changes: 0 additions & 31 deletions lib/pbio/include/pbsys/app.h

This file was deleted.

8 changes: 8 additions & 0 deletions lib/pbio/include/pbsys/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@

#include "pbsysconfig.h"

#include <pbio/protocol.h>

#define PBSYS_CONFIG_APP_FEATURE_FLAGS (0 \
+ PBSYS_CONFIG_APP_BUILTIN_PROGRAMS * PBIO_PYBRICKS_FEATURE_BUILTIN_PROGRAMS \
+ PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6 * PBIO_PYBRICKS_FEATURE_USER_PROG_FORMAT_MULTI_MPY_V6 \
+ PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE * PBIO_PYBRICKS_FEATURE_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE \
)

// When set to (1) PBSYS_CONFIG_STATUS_LIGHT indicates that a hub has a hub status light
#ifndef PBSYS_CONFIG_STATUS_LIGHT
#error "Must define PBSYS_CONFIG_STATUS_LIGHT in pbsysconfig.h"
Expand Down
56 changes: 55 additions & 1 deletion lib/pbio/include/pbsys/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@
#ifndef _PBSYS_MAIN_H_
#define _PBSYS_MAIN_H_

#include <pbio/error.h>

#include <pbsys/config.h>

#include <stdbool.h>
#include <stdint.h>

/**
* Main program types.
*/
typedef enum {
PBSYS_MAIN_PROGRAM_TYPE_USER, // User-defined program
PBSYS_MAIN_PROGRAM_TYPE_BUILTIN // Built-in program
} pbsys_main_program_type_t;

/**
* Main application program data information.
*/
Expand All @@ -30,13 +40,34 @@ typedef struct _pbsys_main_program_t {
* Ending address of user RAM.
*/
void *data_end;
/**
* Program identifier (selects one user program or one of the builtins).
*/
uint32_t id;
/**
* Whether to run an application-specific builtin program instead of the
* program given by the data. The builtin program may still use the data.
*/
bool run_builtin;
pbsys_main_program_type_t type;
/**
* Whether a request was made to start the program.
*/
bool start_requested;
} pbsys_main_program_t;

#if PBSYS_CONFIG_MAIN

pbio_error_t pbsys_main_program_request_start(pbsys_main_program_type_t type, uint32_t id);

/**
* Validates the program that is being requested to start.
*
* @param [in] program The program that is about to start.
* @returns ::PBIO_ERROR_NOT_SUPPORTED if the program is not available.
* Otherwise ::PBIO_SUCCESS.
*/
pbio_error_t pbsys_main_program_validate(pbsys_main_program_t *program);

/**
* Runs the main application program.
*
Expand Down Expand Up @@ -68,6 +99,29 @@ void pbsys_main_stop_program(bool force_stop);
*/
bool pbsys_main_stdin_event(uint8_t c);

#else // PBSYS_CONFIG_MAIN

static inline pbio_error_t pbsys_main_program_request_start(pbsys_main_program_type_t type, uint32_t id) {
return PBIO_ERROR_NOT_SUPPORTED;
}

static inline pbio_error_t pbsys_main_program_validate(pbsys_main_program_t *program) {
return PBIO_ERROR_NOT_SUPPORTED;
}

static inline void pbsys_main_run_program(pbsys_main_program_t *program) {
}

static inline void pbsys_main_stop_program(bool force_stop) {
}

static inline bool pbsys_main_stdin_event(uint8_t c) {
return false;
}

#endif // PBSYS_CONFIG_MAIN


#endif // _PBSYS_MAIN_H_

/** @} */
3 changes: 3 additions & 0 deletions lib/pbio/platform/city_hub/pbsysconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#include "pbdrvconfig.h"

#define PBSYS_CONFIG_APP_BUILTIN_PROGRAMS (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6 (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE (0)
#define PBSYS_CONFIG_BATTERY_CHARGER (0)
#define PBSYS_CONFIG_BLUETOOTH (1)
#define PBSYS_CONFIG_HUB_LIGHT_MATRIX (0)
Expand Down
3 changes: 3 additions & 0 deletions lib/pbio/platform/essential_hub/pbsysconfig.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2023 The Pybricks Authors

#define PBSYS_CONFIG_APP_BUILTIN_PROGRAMS (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6 (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE (1)
#define PBSYS_CONFIG_BATTERY_CHARGER (1)
#define PBSYS_CONFIG_BLUETOOTH (1)
#define PBSYS_CONFIG_HUB_LIGHT_MATRIX (0)
Expand Down
3 changes: 3 additions & 0 deletions lib/pbio/platform/ev3/pbsysconfig.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2024 The Pybricks Authors

#define PBSYS_CONFIG_APP_BUILTIN_PROGRAMS (0)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6 (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE (0)
#define PBSYS_CONFIG_MAIN (1)
#define PBSYS_CONFIG_STORAGE (1)
#define PBSYS_CONFIG_STORAGE_RAM_SIZE (10 * 1024)
Expand Down
3 changes: 3 additions & 0 deletions lib/pbio/platform/ev3rt/pbsysconfig.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2023 The Pybricks Authors

#define PBSYS_CONFIG_APP_BUILTIN_PROGRAMS (0)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6 (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE (0)
#define PBSYS_CONFIG_BATTERY_CHARGER (0)
#define PBSYS_CONFIG_BLUETOOTH (0)
#define PBSYS_CONFIG_HUB_LIGHT_MATRIX (0)
Expand Down
3 changes: 3 additions & 0 deletions lib/pbio/platform/move_hub/pbsysconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#include "pbdrvconfig.h"

#define PBSYS_CONFIG_APP_BUILTIN_PROGRAMS (0)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6 (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE (0)
#define PBSYS_CONFIG_BATTERY_CHARGER (0)
#define PBSYS_CONFIG_BLUETOOTH (1)
#define PBSYS_CONFIG_HUB_LIGHT_MATRIX (0)
Expand Down
3 changes: 3 additions & 0 deletions lib/pbio/platform/prime_hub/pbsysconfig.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2023 The Pybricks Authors

#define PBSYS_CONFIG_APP_BUILTIN_PROGRAMS (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6 (1)
#define PBSYS_CONFIG_APP_USER_PROG_FORMAT_MULTI_MPY_V6_1_NATIVE (1)
#define PBSYS_CONFIG_BATTERY_CHARGER (1)
#define PBSYS_CONFIG_BLUETOOTH (1)
#define PBSYS_CONFIG_BLUETOOTH_TOGGLE (1)
Expand Down
Loading

0 comments on commit 7bda223

Please sign in to comment.