@@ -122,7 +122,7 @@ static void reset_devices(void) {
122
122
#endif
123
123
}
124
124
125
- STATIC void start_mp (supervisor_allocation * heap ) {
125
+ STATIC void start_mp (supervisor_allocation * heap , bool first_run ) {
126
126
autoreload_stop ();
127
127
supervisor_workflow_reset ();
128
128
@@ -170,7 +170,8 @@ STATIC void start_mp(supervisor_allocation *heap) {
170
170
171
171
#if CIRCUITPY_ALARM
172
172
// 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 );
174
175
// Reset alarm module only after we retrieved the wakeup alarm.
175
176
alarm_reset ();
176
177
#endif
@@ -308,7 +309,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
308
309
}
309
310
}
310
311
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 ) {
312
313
bool serial_connected_at_start = serial_connected ();
313
314
bool printed_safe_mode_message = false;
314
315
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -347,7 +348,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
347
348
supervisor_allocation * heap = allocate_remaining_memory ();
348
349
349
350
// Prepare the VM state. Includes an alarm check/reset for sleep.
350
- start_mp (heap );
351
+ start_mp (heap , first_run );
351
352
352
353
#if CIRCUITPY_USB
353
354
usb_setup_with_vm ();
@@ -630,6 +631,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
630
631
#if CIRCUITPY_ALARM
631
632
if (fake_sleeping ) {
632
633
board_init ();
634
+ // Pretend that the next run is the first run, as if we were reset.
635
+ * simulate_reset = true;
633
636
}
634
637
#endif
635
638
@@ -651,7 +654,9 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
651
654
// Do USB setup even if boot.py is not run.
652
655
653
656
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);
655
660
656
661
#if CIRCUITPY_USB
657
662
// 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) {
728
733
#endif
729
734
}
730
735
731
- STATIC int run_repl (void ) {
736
+ STATIC int run_repl (bool first_run ) {
732
737
int exit_code = PYEXEC_FORCED_EXIT ;
733
738
stack_resize ();
734
739
filesystem_flush ();
735
740
supervisor_allocation * heap = allocate_remaining_memory ();
736
- start_mp (heap );
741
+ start_mp (heap , first_run );
737
742
738
743
#if CIRCUITPY_USB
739
744
usb_setup_with_vm ();
@@ -846,28 +851,34 @@ int __attribute__((used)) main(void) {
846
851
supervisor_start_bluetooth ();
847
852
#endif
848
853
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 .
850
855
int exit_code = PYEXEC_FORCED_EXIT ;
851
856
bool skip_repl = true;
852
857
bool first_run = true;
858
+ bool simulate_reset ;
853
859
for (;;) {
860
+ simulate_reset = false;
854
861
if (!skip_repl ) {
855
- exit_code = run_repl ();
862
+ exit_code = run_repl (first_run );
856
863
supervisor_set_run_reason (RUN_REASON_REPL_RELOAD );
857
864
}
858
865
if (exit_code == PYEXEC_FORCED_EXIT ) {
859
866
if (!first_run ) {
860
867
serial_write_compressed (translate ("soft reboot\n" ));
861
868
}
862
- first_run = false;
863
869
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 );
865
871
} else {
866
872
skip_repl = false;
867
873
}
868
874
} else if (exit_code != 0 ) {
869
875
break ;
870
876
}
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 ;
871
882
}
872
883
mp_deinit ();
873
884
return 0 ;
0 commit comments