From f2d8b3c8d0b9b67546d4476d5b7acbf8800ed0d8 Mon Sep 17 00:00:00 2001 From: Rahix Date: Fri, 16 Oct 2020 21:42:03 +0200 Subject: [PATCH 1/6] chore(pycardium): Refactor header printing code Always print the pycardium header and a short message afterwards what pycardium is about to do. Signed-off-by: Rahix --- pycardium/main.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pycardium/main.c b/pycardium/main.c index 3aec0491..2943b126 100644 --- a/pycardium/main.c +++ b/pycardium/main.c @@ -32,11 +32,19 @@ int main(void) pycardium_hal_init(); + epic_uart_write_str(header, sizeof(header)); + if (cnt < 0) { printf("pycardium: Error fetching args: %d\n", cnt); - } else if (cnt > 0) { - epic_uart_write_str(header, sizeof(header)); + + /* Go to REPL instead. */ + cnt = 0; + } + + if (cnt > 0) { printf(" Loading %s ...\n", script_name); + } else { + printf(" Entering REPL ...\n\n"); } mp_stack_set_top(&__StackTop); -- GitLab From 2b725986178b28504c7cc5365667ec4c44618da9 Mon Sep 17 00:00:00 2001 From: Rahix Date: Fri, 16 Oct 2020 21:43:20 +0200 Subject: [PATCH 2/6] feat(pycardium): Always reload pycardium before going to REPL Remove the big endless loop from pycardium main and instead use epic_exec("") to switch to REPL. This way, any MicroPython state is reset and also all hardware will be in a clean reinitialized state. This also means that pycard10.py will now run scripts in a clean environment that is not tainted by whatever was running before. Fixes #212. Signed-off-by: Rahix --- pycardium/main.c | 65 +++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/pycardium/main.c b/pycardium/main.c index 2943b126..7aa12618 100644 --- a/pycardium/main.c +++ b/pycardium/main.c @@ -50,44 +50,41 @@ int main(void) mp_stack_set_top(&__StackTop); mp_stack_set_limit((mp_int_t)&__StackLimit); - while (1) { - gc_init(&__HeapBase + 1024 * 10, &__HeapLimit); - - mp_init(); - - readline_init0(); - interrupt_init0(); - - /* request by badge.team */ - mp_obj_list_init(mp_sys_path, 0); - mp_obj_list_append(mp_sys_path, MP_ROM_QSTR(MP_QSTR_)); - mp_obj_list_append( - mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib) - ); - mp_obj_list_append( - mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_apps) - ); - - if (cnt > 0) { - pyexec_file_if_exists(script_name); - } + gc_init(&__HeapBase + 1024 * 10, &__HeapLimit); + + mp_init(); + + readline_init0(); + interrupt_init0(); + + /* request by badge.team */ + mp_obj_list_init(mp_sys_path, 0); + mp_obj_list_append(mp_sys_path, MP_ROM_QSTR(MP_QSTR_)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_apps)); + + if (cnt > 0) { + pyexec_file_if_exists(script_name); - epic_uart_write_str(header, sizeof(header)); - - for (;;) { - if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { - if (pyexec_raw_repl() != 0) { - break; - } - } else { - if (pyexec_friendly_repl() != 0) { - break; - } + /* Drop to REPL by reloading Pycardium */ + epic_exec(""); + } + + for (;;) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + if (pyexec_raw_repl() != 0) { + break; + } + } else { + if (pyexec_friendly_repl() != 0) { + break; } } - - mp_deinit(); } + + mp_deinit(); + + epic_exit(0); } void HardFault_Handler(void) -- GitLab From 46901642b2b751569fe6a9ff4c42b78e61049295 Mon Sep 17 00:00:00 2001 From: Rahix Date: Fri, 16 Oct 2020 21:47:57 +0200 Subject: [PATCH 3/6] feat(pycardium): Return to menu when a script ends cleanly Instead of dropping to REPL and silently requiring the user to return to menu via button-press, directly call epic_exit(0) when a script terminates execution normally (i.e. not via exception). Signed-off-by: Rahix --- pycardium/main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pycardium/main.c b/pycardium/main.c index 7aa12618..f6c2933b 100644 --- a/pycardium/main.c +++ b/pycardium/main.c @@ -64,10 +64,22 @@ int main(void) mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_apps)); if (cnt > 0) { - pyexec_file_if_exists(script_name); + int ret = pyexec_file_if_exists(script_name); + + if (ret == 0) { + /* + * The script was aborted via uncaught exception; Sadly + * we can't find out what happened so let's hope it was + * a KeyboardInterrupt and drop to REPL. + * + * In the future it might be interesting to rework this + * so any other exception will lead to epic_exit(1). + */ + epic_exec(""); + } - /* Drop to REPL by reloading Pycardium */ - epic_exec(""); + /* The script ended execution normally; return to menu */ + epic_exit(0); } for (;;) { -- GitLab From 518d2a881e1d105c6d46f977080c814fa27375d1 Mon Sep 17 00:00:00 2001 From: Rahix Date: Mon, 5 Oct 2020 21:40:19 +0200 Subject: [PATCH 4/6] fix(pycardium): Return when aborting Calls to abort() shouldn't make core 1 busy-spin; call epic_exit() instead. Fixes #76. Signed-off-by: Rahix --- pycardium/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pycardium/main.c b/pycardium/main.c index f6c2933b..947f072c 100644 --- a/pycardium/main.c +++ b/pycardium/main.c @@ -104,6 +104,11 @@ void HardFault_Handler(void) epic_exit(255); } +void _exit(void) +{ + epic_exit(254); +} + void gc_collect(void) { void *sp = (void *)__get_MSP(); -- GitLab From a9c9d6669b85f685d0d293c0bee2ee44bd1a11aa Mon Sep 17 00:00:00 2001 From: Rahix Date: Fri, 16 Oct 2020 21:53:27 +0200 Subject: [PATCH 5/6] fix(pycardium): Return on nlr_jump_fail() Instead of "rebooting" Pycardium, hand over control to core 0, notifying it of a severe failure via epic_exit(253). Signed-off-by: Rahix --- pycardium/mphalport.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pycardium/mphalport.c b/pycardium/mphalport.c index 4dc043f7..0c5c5b2c 100644 --- a/pycardium/mphalport.c +++ b/pycardium/mphalport.c @@ -283,14 +283,12 @@ mp_uint_t mp_hal_ticks_us(void) * Fatal Errors */ -extern NORETURN void *Reset_Handler(void); - void NORETURN nlr_jump_fail(void *val) { char msg[] = " >>> nlr_jump_fail <<<\r\n"; epic_uart_write_str(msg, sizeof(msg)); - Reset_Handler(); + epic_exit(253); } /****************************************************************************** -- GitLab From 260dc5b3af8c0dcfcba4d6de1cc51fc877766ab7 Mon Sep 17 00:00:00 2001 From: Rahix Date: Sat, 17 Oct 2020 14:12:33 +0200 Subject: [PATCH 6/6] fix(pycard10): Make pycard10 reset pycardium via os.exec("") This will result in more reliably reaching a clean state. Co-Authored-By: schneider Signed-off-by: Rahix --- tools/pycard10.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/pycard10.py b/tools/pycard10.py index a0ce7419..5f0a870c 100755 --- a/tools/pycard10.py +++ b/tools/pycard10.py @@ -130,10 +130,12 @@ class PyCard10(Pyboard): None """ - self.soft_reset() - self.serial.write(b"\x03\x03") # ctrl-C twice: interrupt any running program + self.serial.write(b"\x02") # ctrl-B: ensue it's the normal mode + + self.serial.write(b'__import__("os").exec("")\r') # Reset to REPL + # flush input (without relying on serial.flushInput()) n = self.serial.inWaiting() while n > 0: @@ -176,8 +178,6 @@ class PyCard10(Pyboard): self.serial.write(b"\x04") # ctrl-D: do the reset - time.sleep(1) # Give epicardium some time to cycle pycardium - n = self.serial.inWaiting() while n > 0: self.serial.read(n) -- GitLab