Skip to content

Commit ea46bb0

Browse files
committed
pbio/sys/hmi_mpy_env: Compile script with Pybricksdev.
Drop-in for HMI module that simulates sending a multi-mpy file to the hub and then starts it. Used in the simulated hub to test different programs. The script to start is set with an environment variable and compiled with Pybricksdev.
1 parent 96e5ba1 commit ea46bb0

File tree

8 files changed

+106
-9
lines changed

8 files changed

+106
-9
lines changed

.vscode/launch.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,17 @@
9797
"type": "cppdbg",
9898
"request": "launch",
9999
"program": "${workspaceFolder}/bricks/simhub/debug/firmware.elf",
100-
"args": [
101-
"${workspaceFolder}/tests/virtualhub/motor/car.py"
102-
],
103100
"stopAtEntry": false,
104101
"cwd": "${workspaceFolder}",
105102
"environment": [
106103
{
107104
"name": "PBIO_TEST_CONNECT_SOCKET",
108105
"value": "true"
109106
},
107+
{
108+
"name": "TEST_SCRIPT",
109+
"value": "${workspaceFolder}/tests/virtualhub/basics/hello.py"
110+
},
110111
],
111112
"externalConsole": false,
112113
"MIMode": "gdb",

bricks/_common/common.mk

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,9 +706,5 @@ deploy-openocd: $(BUILD)/firmware-base.bin
706706
# Run emulation build on a POSIX system using normal stdio
707707
run: $(BUILD)/firmware.elf
708708
@$(BUILD)/firmware.elf
709-
@echo "Exit status: $$?"
710-
711-
test: $(BUILD)/firmware.elf
712-
$(Q)/usr/bin/printf "print('hello world!', list(x+1 for x in range(10)), end='eol\\\\n')\\r\\n\\004" | $(BUILD)/firmware.elf | tail -n2 | grep "^hello world! \\[1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\]eol"
713709

714710
include $(TOP)/py/mkrules.mk

bricks/_common/sources.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ PBIO_SRC_C = $(addprefix lib/pbio/,\
237237
sys/battery.c \
238238
sys/command.c \
239239
sys/core.c \
240+
sys/hmi_env_mpy.c \
240241
sys/hmi_lcd.c \
241242
sys/hmi_pup.c \
242243
sys/hmi_none.c \

bricks/simhub/make_mpy.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from pybricksdev.compile import compile_multi_file
2+
import asyncio
3+
import argparse
4+
import sys
5+
6+
# Set up argument parser
7+
parser = argparse.ArgumentParser(description="Compile to multi-mpy using pybricksdev.")
8+
parser.add_argument("file", help="The path to the Python file to compile.")
9+
args = parser.parse_args()
10+
11+
# Compile the file
12+
result = asyncio.run(compile_multi_file(args.file, (6, 1)))
13+
14+
# Write the result to stdout
15+
sys.stdout.buffer.write(result)

lib/pbio/platform/sim_hub/pbdrvconfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#define PBDRV_CONFIG_BATTERY_TEST (1)
66

77
#define PBDRV_CONFIG_BLOCK_DEVICE (1)
8-
#define PBDRV_CONFIG_BLOCK_DEVICE_RAM_SIZE (10 * 1024)
8+
#define PBDRV_CONFIG_BLOCK_DEVICE_RAM_SIZE (50 * 1024)
99
#define PBDRV_CONFIG_BLOCK_DEVICE_TEST (1)
1010

1111
#define PBDRV_CONFIG_BLUETOOTH (1)

lib/pbio/platform/sim_hub/pbsysconfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#define PBSYS_CONFIG_HOST_STDIN_BUF_SIZE (21)
1414
#define PBSYS_CONFIG_HMI (1)
1515
#define PBSYS_CONFIG_HMI_STOP_BUTTON (1 << 5) // center
16-
#define PBSYS_CONFIG_HMI_NONE (1)
16+
#define PBSYS_CONFIG_HMI_ENV_MPY (1)
1717
#define PBSYS_CONFIG_HMI_NUM_SLOTS (0)
1818
#define PBSYS_CONFIG_HUB_LIGHT_MATRIX (0)
1919
#define PBSYS_CONFIG_MAIN (1)

lib/pbio/sys/hmi_env_mpy.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2018-2025 The Pybricks Authors
3+
4+
// Drop-in for HMI module that simulates sending a multi-mpy file to the hub
5+
// and then starts it. Used in the simulated hub to test different programs.
6+
// The script to start is set with an environment variable.
7+
8+
#include <pbsys/config.h>
9+
10+
#if PBSYS_CONFIG_HMI_ENV_MPY
11+
12+
#include <pbio/button.h>
13+
#include <pbio/os.h>
14+
#include <pbsys/command.h>
15+
#include <pbsys/main.h>
16+
#include <pbsys/status.h>
17+
#include "storage.h"
18+
19+
#include <errno.h>
20+
#include <signal.h>
21+
#include <stdbool.h>
22+
#include <stddef.h>
23+
#include <stdint.h>
24+
#include <stdio.h>
25+
#include <stdlib.h>
26+
#include <sys/stat.h>
27+
28+
void pbsys_hmi_init(void) {
29+
}
30+
31+
void pbsys_hmi_deinit(void) {
32+
}
33+
34+
pbio_error_t pbsys_hmi_await_program_selection(void) {
35+
36+
pbio_os_run_processes_and_wait_for_event();
37+
38+
// With this HMI, we run a script once and then exit.
39+
static bool ran_once = false;
40+
if (ran_once) {
41+
return PBIO_ERROR_CANCELED;
42+
}
43+
ran_once = true;
44+
45+
// Test if script is provided via environment.
46+
const char *script_path = getenv("TEST_SCRIPT");
47+
if (!script_path) {
48+
// No script given, just start REPL
49+
return pbsys_main_program_request_start(PBIO_PYBRICKS_USER_PROGRAM_ID_REPL, PBSYS_MAIN_PROGRAM_START_REQUEST_TYPE_BOOT);
50+
}
51+
52+
// Pybricksdev helper script, pipes multi-mpy to us.
53+
char command[512];
54+
snprintf(command, sizeof(command), "python ./bricks/simhub/make_mpy.py %s", script_path);
55+
FILE *pipe = popen(command, "r");
56+
if (!pipe) {
57+
perror("Failed to compile program with Pybricksdev\n");
58+
return PBIO_ERROR_CANCELED;
59+
}
60+
61+
// Read the multi-mpy file from pipe.
62+
uint8_t program_buf[PBDRV_CONFIG_BLOCK_DEVICE_RAM_SIZE];
63+
size_t read_size = fread(program_buf, 1, sizeof(program_buf), pipe);
64+
pclose(pipe);
65+
66+
if (read_size == 0) {
67+
perror("Error reading from pipe");
68+
return PBIO_ERROR_CANCELED;
69+
}
70+
71+
// Load the program in storage, as if receiving it.
72+
pbsys_storage_set_program_size(0);
73+
pbsys_storage_set_program_data(0, program_buf, read_size);
74+
pbsys_storage_set_program_size(read_size);
75+
76+
return pbsys_main_program_request_start(PBIO_PYBRICKS_USER_PROGRAM_ID_FIRST_SLOT, PBSYS_MAIN_PROGRAM_START_REQUEST_TYPE_BOOT);
77+
}
78+
79+
#endif // PBSYS_CONFIG_HMI_ENV_MPY

tests/virtualhub/basics/hello.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from pybricks.tools import wait
2+
3+
print("\nHello")
4+
wait(1000)
5+
print("World\n")

0 commit comments

Comments
 (0)