@@ -123,7 +123,7 @@ static void reset_devices(void) {
123
123
#endif
124
124
}
125
125
126
- STATIC void start_mp (supervisor_allocation * heap ) {
126
+ STATIC void start_mp (supervisor_allocation * heap , bool first_run ) {
127
127
autoreload_stop ();
128
128
supervisor_workflow_reset ();
129
129
@@ -171,7 +171,8 @@ STATIC void start_mp(supervisor_allocation *heap) {
171
171
172
172
#if CIRCUITPY_ALARM
173
173
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
174
- shared_alarm_save_wake_alarm (common_hal_alarm_create_wake_alarm ());
174
+ // There is no alarm if this is not the first time code.py or the REPL has been run.
175
+ shared_alarm_save_wake_alarm (first_run ? common_hal_alarm_create_wake_alarm () : mp_const_none );
175
176
// Reset alarm module only after we retrieved the wakeup alarm.
176
177
alarm_reset ();
177
178
#endif
@@ -309,7 +310,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
309
310
}
310
311
}
311
312
312
- STATIC bool run_code_py (safe_mode_t safe_mode ) {
313
+ STATIC bool run_code_py (safe_mode_t safe_mode , bool first_run , bool * simulate_reset ) {
313
314
bool serial_connected_at_start = serial_connected ();
314
315
bool printed_safe_mode_message = false;
315
316
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -348,7 +349,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
348
349
supervisor_allocation * heap = allocate_remaining_memory ();
349
350
350
351
// Prepare the VM state. Includes an alarm check/reset for sleep.
351
- start_mp (heap );
352
+ start_mp (heap , first_run );
352
353
353
354
#if CIRCUITPY_USB
354
355
usb_setup_with_vm ();
@@ -631,6 +632,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
631
632
#if CIRCUITPY_ALARM
632
633
if (fake_sleeping ) {
633
634
board_init ();
635
+ // Pretend that the next run is the first run, as if we were reset.
636
+ * simulate_reset = true;
634
637
}
635
638
#endif
636
639
@@ -652,7 +655,9 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
652
655
// Do USB setup even if boot.py is not run.
653
656
654
657
supervisor_allocation * heap = allocate_remaining_memory ();
655
- start_mp (heap );
658
+
659
+ // true means this is the first set of VM's after a hard reset.
660
+ start_mp (heap , true);
656
661
657
662
#if CIRCUITPY_USB
658
663
// Set up default USB values after boot.py VM starts but before running boot.py.
@@ -729,12 +734,12 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
729
734
#endif
730
735
}
731
736
732
- STATIC int run_repl (void ) {
737
+ STATIC int run_repl (bool first_run ) {
733
738
int exit_code = PYEXEC_FORCED_EXIT ;
734
739
stack_resize ();
735
740
filesystem_flush ();
736
741
supervisor_allocation * heap = allocate_remaining_memory ();
737
- start_mp (heap );
742
+ start_mp (heap , first_run );
738
743
739
744
#if CIRCUITPY_USB
740
745
usb_setup_with_vm ();
@@ -847,28 +852,34 @@ int __attribute__((used)) main(void) {
847
852
supervisor_start_bluetooth ();
848
853
#endif
849
854
850
- // Boot script is finished, so now go into REPL/main mode .
855
+ // Boot script is finished, so now go into REPL or run code.py .
851
856
int exit_code = PYEXEC_FORCED_EXIT ;
852
857
bool skip_repl = true;
853
858
bool first_run = true;
859
+ bool simulate_reset ;
854
860
for (;;) {
861
+ simulate_reset = false;
855
862
if (!skip_repl ) {
856
- exit_code = run_repl ();
863
+ exit_code = run_repl (first_run );
857
864
supervisor_set_run_reason (RUN_REASON_REPL_RELOAD );
858
865
}
859
866
if (exit_code == PYEXEC_FORCED_EXIT ) {
860
867
if (!first_run ) {
861
868
serial_write_compressed (translate ("soft reboot\n" ));
862
869
}
863
- first_run = false;
864
870
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL ) {
865
- skip_repl = run_code_py (safe_mode );
871
+ skip_repl = run_code_py (safe_mode , first_run , & simulate_reset );
866
872
} else {
867
873
skip_repl = false;
868
874
}
869
875
} else if (exit_code != 0 ) {
870
876
break ;
871
877
}
878
+
879
+ // Either the REPL or code.py has run and finished.
880
+ // If code.py did a fake deep sleep, pretend that we are running code.py for
881
+ // the first time after a hard reset. This will preserve any alarm information.
882
+ first_run = simulate_reset ;
872
883
}
873
884
mp_deinit ();
874
885
return 0 ;
0 commit comments