Skip to content

Commit 2a50b40

Browse files
committed
bricks/_common/micropython: Use SystemAbort for forced exit.
This is a much cleaner approach. Also restore local nlr buffers instead of a global one used to previously implement the system abort.
1 parent 7e9951d commit 2a50b40

File tree

2 files changed

+11
-26
lines changed

2 files changed

+11
-26
lines changed

bricks/_common/micropython.c

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,11 @@
3232
#include "py/stackctrl.h"
3333
#include "py/stream.h"
3434

35-
// Outermost nlr buffer.
36-
nlr_buf_t nlr_main;
37-
3835
// Implementation for MICROPY_EVENT_POLL_HOOK
3936
void pb_event_poll_hook(void) {
40-
while (pbio_do_one_event()) {
41-
}
4237

43-
// On forced exit, pop back to outer nlr buffer so the exception will
44-
// always be raised and the application program exits cleanly. We also need
45-
// MP_STATE_THREAD(mp_pending_exception) to be the system exit exception
46-
// but we don't check it because it is set along with pyexec_system_exit.
47-
if (pyexec_system_exit == PYEXEC_FORCED_EXIT) {
48-
while (MP_STATE_MAIN_THREAD(nlr_top) != &nlr_main) {
49-
nlr_pop();
50-
}
51-
pyexec_system_exit = 0;
38+
// Drive pbio event loop.
39+
while (pbio_do_one_event()) {
5240
}
5341

5442
mp_handle_pending(true);
@@ -68,7 +56,7 @@ void pbsys_main_stop_program(bool force_stop) {
6856
static mp_obj_exception_t system_exit;
6957

7058
// Schedule SystemExit exception.
71-
system_exit.base.type = &mp_type_SystemExit;
59+
system_exit.base.type = force_stop ? &mp_type_SystemAbort : &mp_type_SystemExit;
7260
system_exit.traceback_alloc = 0;
7361
system_exit.traceback_len = 0;
7462
system_exit.traceback_data = NULL;
@@ -79,11 +67,6 @@ void pbsys_main_stop_program(bool force_stop) {
7967
MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
8068
}
8169
#endif
82-
83-
// IDE stop button and long-press power button will force an exit.
84-
if (force_stop) {
85-
pyexec_system_exit = PYEXEC_FORCED_EXIT;
86-
}
8770
}
8871

8972
bool pbsys_main_stdin_event(uint8_t c) {
@@ -128,15 +111,16 @@ static void mp_vfs_map_minimal_new_reader(mp_reader_t *reader, mp_vfs_map_minima
128111
static void run_repl() {
129112
// Reset REPL history.
130113
readline_init0();
131-
if (nlr_push(&nlr_main) == 0) {
114+
nlr_buf_t nlr;
115+
if (nlr_push(&nlr) == 0) {
132116
// Run the REPL.
133117
pyexec_friendly_repl();
134118
nlr_pop();
135119
} else {
136120
// clear any pending exceptions (and run any callbacks).
137121
mp_handle_pending(false);
138122
// Print which exception triggered this.
139-
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr_main.ret_val);
123+
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
140124
}
141125
}
142126
#endif
@@ -224,7 +208,8 @@ static mpy_info_t *mpy_data_find(qstr name) {
224208
*/
225209
static void run_user_program(void) {
226210

227-
if (nlr_push(&nlr_main) == 0) {
211+
nlr_buf_t nlr;
212+
if (nlr_push(&nlr) == 0) {
228213
mpy_info_t *info = mpy_data_find(MP_QSTR___main__);
229214

230215
if (!info) {
@@ -255,11 +240,11 @@ static void run_user_program(void) {
255240
mp_handle_pending(false);
256241

257242
// Print which exception triggered this.
258-
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr_main.ret_val);
243+
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
259244

260245
#if PYBRICKS_OPT_COMPILER
261246
// On KeyboardInterrupt, drop to REPL for debugging.
262-
if (mp_obj_exception_match((mp_obj_t)nlr_main.ret_val, &mp_type_KeyboardInterrupt)) {
247+
if (mp_obj_exception_match((mp_obj_t)nlr.ret_val, &mp_type_KeyboardInterrupt)) {
263248

264249
// The global scope is preserved to facilitate debugging, but we
265250
// stop active resources like motors and sounds. They are stopped

micropython

0 commit comments

Comments
 (0)