Skip to content

Commit 7ae6b94

Browse files
committed
Move simulated deep sleep restart to main.c
1 parent 72fa7d8 commit 7ae6b94

File tree

7 files changed

+32
-15
lines changed

7 files changed

+32
-15
lines changed

lib/utils/pyexec.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,16 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input
128128
if (exec_flags & EXEC_FLAG_PRINT_EOF) {
129129
mp_hal_stdout_tx_strn("\x04", 1);
130130
}
131-
// check for SystemExit
132-
if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) {
131+
// check for program termination exceptions: SystemExit and deep sleep.
132+
const mp_obj_type_t *exception_type = mp_obj_get_type((mp_obj_t)nlr.ret_val);
133+
if (mp_obj_is_subclass_fast(exception_type, &mp_type_SystemExit)) {
133134
// at the moment, the value of SystemExit is unused
134135
ret = pyexec_system_exit;
135136
#if CIRCUITPY_ALARM
136-
} else if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_DeepSleepRequest)) {
137-
ret = PYEXEC_DEEP_SLEEP;
137+
} else if (mp_obj_is_subclass_fast(exception_type, &mp_type__DeepSleepRequest)) {
138+
ret = PYEXEC_DEEP_SLEEP_REQUEST;
139+
} else if (mp_obj_is_subclass_fast(exception_type, &mp_type__DeepSleepRestart)) {
140+
ret = PYEXEC_DEEP_SLEEP_RESTART;
138141
#endif
139142
} else {
140143
if ((mp_obj_t) nlr.ret_val != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {

lib/utils/pyexec.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ extern pyexec_mode_kind_t pyexec_mode_kind;
4646
// It will reset to 0 at the start of each execution (eg each REPL entry).
4747
extern int pyexec_system_exit;
4848

49-
#define PYEXEC_FORCED_EXIT (0x100)
50-
#define PYEXEC_SWITCH_MODE (0x200)
51-
#define PYEXEC_EXCEPTION (0x400)
52-
#define PYEXEC_DEEP_SLEEP (0x800)
49+
// These constants are meant to be or'd into the argument <n> in sys.exit(<n>)
50+
// <n> is usually restricted to 0-127 in CPython, so they start above that.
51+
#define PYEXEC_FORCED_EXIT (0x0100)
52+
#define PYEXEC_SWITCH_MODE (0x0200)
53+
#define PYEXEC_EXCEPTION (0x0400)
54+
#define PYEXEC_DEEP_SLEEP_REQUEST (0x0800)
55+
#define PYEXEC_DEEP_SLEEP_RESTART (0x1000)
5356

5457
int pyexec_raw_repl(void);
5558
int pyexec_friendly_repl(void);

main.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,18 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
301301
}
302302

303303
#if CIRCUITPY_ALARM
304-
if (result.return_code & PYEXEC_DEEP_SLEEP) {
304+
if (result.return_code & PYEXEC_DEEP_SLEEP_REQUEST) {
305+
// alarm.exit_and_deep_sleep_until_alarms() has requested a deep sleep.
305306
common_hal_alarm_enter_deep_sleep();
306307
// Does not return.
307308
}
309+
// alarm.exit_and_deep_sleep_until_alarms() simulated a deep sleep.
310+
// After that, do a restart, to simulate the board being reset.
311+
// We don't actually reset so we can preserve a connection to the host computer.
312+
if (result.return_code & PYEXEC_DEEP_SLEEP_RESTART) {
313+
supervisor_set_run_reason(RUN_REASON_STARTUP);
314+
return true;
315+
}
308316
#endif
309317
}
310318

ports/esp32s2/common-hal/alarm/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp
184184
setup_sleep_alarms(n_alarms, alarms);
185185

186186
// Raise an exception, which will be processed in main.c.
187-
mp_raise_arg1(&mp_type_DeepSleepRequest, NULL);
187+
mp_raise_arg1(&mp_type__DeepSleepRequest, NULL);
188188
}
189189

190190
void common_hal_alarm_prepare_for_deep_sleep(void) {

py/obj.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,8 @@ extern const mp_obj_type_t mp_type_ValueError;
641641
extern const mp_obj_type_t mp_type_ViperTypeError;
642642
extern const mp_obj_type_t mp_type_ZeroDivisionError;
643643
#if CIRCUITPY_ALARM
644-
extern const mp_obj_type_t mp_type_DeepSleepRequest;
644+
extern const mp_obj_type_t mp_type__DeepSleepRequest;
645+
extern const mp_obj_type_t mp_type__DeepSleepRestart;
645646
#endif
646647

647648

py/objexcept.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,10 @@ MP_DEFINE_EXCEPTION(Exception, BaseException)
320320
//TODO: Implement more UnicodeError subclasses which take arguments
321321
#endif
322322
#if CIRCUITPY_ALARM
323-
MP_DEFINE_EXCEPTION(DeepSleepRequest, BaseException)
323+
// These are prefixed with underscore because they should not be used from Python.
324+
// They are a mechanism to communicate deep sleep state to main.c.
325+
MP_DEFINE_EXCEPTION(_DeepSleepRequest, BaseException)
326+
MP_DEFINE_EXCEPTION(_DeepSleepRestart, BaseException)
324327
#endif
325328
MP_DEFINE_EXCEPTION(MpyError, ValueError)
326329
/*

shared-bindings/alarm/__init__.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,8 @@ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o
164164
if (supervisor_workflow_active()) {
165165
// Simulate deep sleep by waiting for an alarm and then restarting when done.
166166
common_hal_alarm_wait_until_alarms(n_args, args);
167-
reload_requested = true;
168-
supervisor_set_run_reason(RUN_REASON_STARTUP);
169-
mp_raise_reload_exception();
167+
// Raise an exception, which will be processed in main.c.
168+
mp_raise_arg1(&mp_type__DeepSleepRestart, NULL);
170169
} else {
171170
common_hal_alarm_exit_and_deep_sleep_until_alarms(n_args, args);
172171
// Does not return.

0 commit comments

Comments
 (0)