@@ -122,7 +122,7 @@ static void reset_devices(void) {
122122 #endif
123123}
124124
125- STATIC void start_mp (supervisor_allocation * heap ) {
125+ STATIC void start_mp (supervisor_allocation * heap , bool first_run ) {
126126 autoreload_stop ();
127127 supervisor_workflow_reset ();
128128
@@ -170,7 +170,8 @@ STATIC void start_mp(supervisor_allocation *heap) {
170170
171171 #if CIRCUITPY_ALARM
172172 // Record which alarm woke us up, if any. An object may be created so the heap must be functional.
173- shared_alarm_save_wake_alarm (common_hal_alarm_create_wake_alarm ());
173+ // There is no alarm if this is not the first time code.py or the REPL has been run.
174+ shared_alarm_save_wake_alarm (first_run ? common_hal_alarm_create_wake_alarm () : mp_const_none );
174175 // Reset alarm module only after we retrieved the wakeup alarm.
175176 alarm_reset ();
176177 #endif
@@ -308,7 +309,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
308309 }
309310}
310311
311- STATIC bool run_code_py (safe_mode_t safe_mode ) {
312+ STATIC bool run_code_py (safe_mode_t safe_mode , bool first_run , bool * simulate_reset ) {
312313 bool serial_connected_at_start = serial_connected ();
313314 bool printed_safe_mode_message = false;
314315 #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -347,7 +348,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
347348 supervisor_allocation * heap = allocate_remaining_memory ();
348349
349350 // Prepare the VM state. Includes an alarm check/reset for sleep.
350- start_mp (heap );
351+ start_mp (heap , first_run );
351352
352353 #if CIRCUITPY_USB
353354 usb_setup_with_vm ();
@@ -630,6 +631,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
630631 #if CIRCUITPY_ALARM
631632 if (fake_sleeping ) {
632633 board_init ();
634+ // Pretend that the next run is the first run, as if we were reset.
635+ * simulate_reset = true;
633636 }
634637 #endif
635638
@@ -651,7 +654,9 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
651654 // Do USB setup even if boot.py is not run.
652655
653656 supervisor_allocation * heap = allocate_remaining_memory ();
654- start_mp (heap );
657+
658+ // true means this is the first set of VM's after a hard reset.
659+ start_mp (heap , true);
655660
656661 #if CIRCUITPY_USB
657662 // Set up default USB values after boot.py VM starts but before running boot.py.
@@ -728,12 +733,12 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
728733 #endif
729734}
730735
731- STATIC int run_repl (void ) {
736+ STATIC int run_repl (bool first_run ) {
732737 int exit_code = PYEXEC_FORCED_EXIT ;
733738 stack_resize ();
734739 filesystem_flush ();
735740 supervisor_allocation * heap = allocate_remaining_memory ();
736- start_mp (heap );
741+ start_mp (heap , first_run );
737742
738743 #if CIRCUITPY_USB
739744 usb_setup_with_vm ();
@@ -846,28 +851,34 @@ int __attribute__((used)) main(void) {
846851 supervisor_start_bluetooth ();
847852 #endif
848853
849- // Boot script is finished, so now go into REPL/main mode .
854+ // Boot script is finished, so now go into REPL or run code.py .
850855 int exit_code = PYEXEC_FORCED_EXIT ;
851856 bool skip_repl = true;
852857 bool first_run = true;
858+ bool simulate_reset ;
853859 for (;;) {
860+ simulate_reset = false;
854861 if (!skip_repl ) {
855- exit_code = run_repl ();
862+ exit_code = run_repl (first_run );
856863 supervisor_set_run_reason (RUN_REASON_REPL_RELOAD );
857864 }
858865 if (exit_code == PYEXEC_FORCED_EXIT ) {
859866 if (!first_run ) {
860867 serial_write_compressed (translate ("soft reboot\n" ));
861868 }
862- first_run = false;
863869 if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL ) {
864- skip_repl = run_code_py (safe_mode );
870+ skip_repl = run_code_py (safe_mode , first_run , & simulate_reset );
865871 } else {
866872 skip_repl = false;
867873 }
868874 } else if (exit_code != 0 ) {
869875 break ;
870876 }
877+
878+ // Either the REPL or code.py has run and finished.
879+ // If code.py did a fake deep sleep, pretend that we are running code.py for
880+ // the first time after a hard reset. This will preserve any alarm information.
881+ first_run = simulate_reset ;
871882 }
872883 mp_deinit ();
873884 return 0 ;
0 commit comments