Skip to content

Commit 71157b1

Browse files
committed
bricks/_common/micropython: Gracefully stop on stop button.
The stop button adds the traceback to the output window which can quickly push relevant output away. It also looks like an unexpected error for new programmers. The stop traceback is almost never needed, and if it is, the user can always press CTRL+C to see it.
1 parent 2a50b40 commit 71157b1

File tree

3 files changed

+18
-24
lines changed

3 files changed

+18
-24
lines changed

bricks/_common/micropython.c

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,7 @@ void pb_event_poll_hook(void) {
4747

4848
// callback for when stop button is pressed in IDE or on hub
4949
void pbsys_main_stop_program(bool force_stop) {
50-
51-
static const mp_obj_tuple_t args = {
52-
.base = { .type = &mp_type_tuple },
53-
.len = 1,
54-
.items = { MP_ROM_QSTR(MP_QSTR_stop_space_button_space_pressed) },
55-
};
56-
static mp_obj_exception_t system_exit;
57-
58-
// Schedule SystemExit exception.
59-
system_exit.base.type = force_stop ? &mp_type_SystemAbort : &mp_type_SystemExit;
60-
system_exit.traceback_alloc = 0;
61-
system_exit.traceback_len = 0;
62-
system_exit.traceback_data = NULL;
63-
system_exit.args = (mp_obj_tuple_t *)&args;
64-
MP_STATE_MAIN_THREAD(mp_pending_exception) = MP_OBJ_FROM_PTR(&system_exit);
65-
#if MICROPY_ENABLE_SCHEDULER
66-
if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) {
67-
MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
68-
}
69-
#endif
50+
mp_sched_system_exit_or_abort(force_stop);
7051
}
7152

7253
bool pbsys_main_stdin_event(uint8_t c) {
@@ -107,6 +88,19 @@ static void mp_vfs_map_minimal_new_reader(mp_reader_t *reader, mp_vfs_map_minima
10788
reader->close = mp_vfs_map_minimal_close;
10889
}
10990

91+
// Prints the exception that ended the program.
92+
static void print_final_exception(mp_obj_t exc) {
93+
// Handle graceful stop with button or shutdown.
94+
if (mp_obj_exception_match(exc, &mp_type_SystemAbort) ||
95+
mp_obj_exception_match(exc, &mp_type_SystemExit)) {
96+
mp_printf(&mp_plat_print, "Stop button pressed.\n");
97+
return;
98+
}
99+
100+
// Print unhandled exception with traceback.
101+
mp_obj_print_exception(&mp_plat_print, exc);
102+
}
103+
110104
#if PYBRICKS_OPT_COMPILER
111105
static void run_repl() {
112106
// Reset REPL history.
@@ -120,7 +114,7 @@ static void run_repl() {
120114
// clear any pending exceptions (and run any callbacks).
121115
mp_handle_pending(false);
122116
// Print which exception triggered this.
123-
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
117+
print_final_exception(nlr.ret_val);
124118
}
125119
}
126120
#endif
@@ -239,8 +233,7 @@ static void run_user_program(void) {
239233
mp_hal_set_interrupt_char(-1);
240234
mp_handle_pending(false);
241235

242-
// Print which exception triggered this.
243-
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
236+
print_final_exception(nlr.ret_val);
244237

245238
#if PYBRICKS_OPT_COMPILER
246239
// On KeyboardInterrupt, drop to REPL for debugging.

bricks/_common/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#define MICROPY_ENABLE_SOURCE_LINE (1)
5151
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED)
5252
#endif
53+
#define MICROPY_ENABLE_SYSTEM_ABORT (1)
5354
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
5455
#define MICROPY_PY_ASYNC_AWAIT (0)
5556
#define MICROPY_MULTIPLE_INHERITANCE (0)

0 commit comments

Comments
 (0)