52
52
#include "supervisor/memory.h"
53
53
#include "supervisor/port.h"
54
54
#include "supervisor/serial.h"
55
- #include "supervisor/shared/autoreload .h"
55
+ #include "supervisor/shared/reload .h"
56
56
#include "supervisor/shared/safe_mode.h"
57
57
#include "supervisor/shared/stack.h"
58
58
#include "supervisor/shared/status_leds.h"
@@ -124,7 +124,6 @@ static void reset_devices(void) {
124
124
}
125
125
126
126
STATIC void start_mp (supervisor_allocation * heap , bool first_run ) {
127
- autoreload_stop ();
128
127
supervisor_workflow_reset ();
129
128
130
129
// Stack limit should be less than real stack size, so we have a chance
@@ -329,14 +328,20 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
329
328
result .exception = MP_OBJ_NULL ;
330
329
result .exception_line = 0 ;
331
330
332
- bool skip_repl ;
331
+ bool skip_repl = false ;
333
332
bool skip_wait = false;
334
333
bool found_main = false;
335
334
uint8_t next_code_options = 0 ;
336
335
// Collects stickiness bits that apply in the current situation.
337
336
uint8_t next_code_stickiness_situation = SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET ;
338
337
338
+ // Do the filesystem flush check before reload in case another write comes
339
+ // in while we're doing the flush.
339
340
if (safe_mode == NO_SAFE_MODE ) {
341
+ stack_resize ();
342
+ filesystem_flush ();
343
+ }
344
+ if (safe_mode == NO_SAFE_MODE && !autoreload_pending ()) {
340
345
static const char * const supported_filenames [] = STRING_LIST (
341
346
"code.txt" , "code.py" , "main.py" , "main.txt" );
342
347
#if CIRCUITPY_FULL_BUILD
@@ -345,8 +350,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
345
350
"main.txt.py" , "main.py.txt" , "main.txt.txt" ,"main.py.py" );
346
351
#endif
347
352
348
- stack_resize ();
349
- filesystem_flush ();
350
353
supervisor_allocation * heap = allocate_remaining_memory ();
351
354
352
355
// Prepare the VM state. Includes an alarm check/reset for sleep.
@@ -389,13 +392,14 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
389
392
390
393
// Print done before resetting everything so that we get the message over
391
394
// BLE before it is reset and we have a delay before reconnect.
392
- if (reload_requested && result . return_code == PYEXEC_EXCEPTION ) {
393
- serial_write_compressed (translate ("\nCode stopped by auto-reload.\n" ));
395
+ if (( result . return_code & PYEXEC_RELOAD ) && supervisor_get_run_reason () == RUN_REASON_AUTO_RELOAD ) {
396
+ serial_write_compressed (translate ("\nCode stopped by auto-reload. Reloading soon. \n" ));
394
397
} else {
395
398
serial_write_compressed (translate ("\nCode done running.\n" ));
396
399
}
397
400
398
- // Finished executing python code. Cleanup includes a board reset.
401
+
402
+ // Finished executing python code. Cleanup includes filesystem flush and a board reset.
399
403
cleanup_after_vm (heap , result .exception );
400
404
401
405
// If a new next code file was set, that is a reason to keep it (obviously). Stuff this into
@@ -407,8 +411,14 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
407
411
next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET ;
408
412
}
409
413
410
- if (reload_requested ) {
414
+ if (result . return_code & PYEXEC_RELOAD ) {
411
415
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD ;
416
+ // Reload immediately unless the reload is due to autoreload. In that
417
+ // case, we wait below to see if any other writes occur.
418
+ if (supervisor_get_run_reason () != RUN_REASON_AUTO_RELOAD ) {
419
+ skip_repl = true;
420
+ skip_wait = true;
421
+ }
412
422
} else if (result .return_code == 0 ) {
413
423
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS ;
414
424
if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS ) {
@@ -426,7 +436,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
426
436
}
427
437
}
428
438
if (result .return_code & PYEXEC_FORCED_EXIT ) {
429
- skip_repl = reload_requested ;
439
+ skip_repl = false ;
430
440
skip_wait = true;
431
441
}
432
442
}
@@ -466,22 +476,27 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
466
476
size_t total_time = blink_time + LED_SLEEP_TIME_MS ;
467
477
#endif
468
478
479
+ // This loop is waits after code completes. It waits for fake sleeps to
480
+ // finish, user input or autoreloads.
469
481
#if CIRCUITPY_ALARM
470
482
bool fake_sleeping = false;
471
483
#endif
472
484
while (!skip_wait ) {
473
485
RUN_BACKGROUND_TASKS ;
474
486
475
- // If a reload was requested by the supervisor or autoreload, return
476
- if (reload_requested ) {
487
+ // If a reload was requested by the supervisor or autoreload, return.
488
+ if (autoreload_ready () ) {
477
489
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD ;
478
490
// Should the STICKY_ON_SUCCESS and STICKY_ON_ERROR bits be cleared in
479
491
// next_code_stickiness_situation? I can see arguments either way, but I'm deciding
480
492
// "no" for now, mainly because it's a bit less code. At this point, we have both a
481
493
// success or error and a reload, so let's have both of the respective options take
482
494
// effect (in OR combination).
483
- reload_requested = false;
484
495
skip_repl = true;
496
+ // We're kicking off the autoreload process so reset now. If any
497
+ // other reloads trigger after this, then we'll want another wait
498
+ // period.
499
+ autoreload_reset ();
485
500
break ;
486
501
}
487
502
@@ -508,7 +523,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
508
523
#endif
509
524
510
525
// If messages haven't been printed yet, print them
511
- if (!printed_press_any_key && serial_connected ()) {
526
+ if (!printed_press_any_key && serial_connected () && ! autoreload_pending () ) {
512
527
if (!serial_connected_at_start ) {
513
528
print_code_py_status_message (safe_mode );
514
529
}
@@ -627,13 +642,14 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
627
642
}
628
643
}
629
644
645
+ // Done waiting, start the board back up.
646
+
630
647
// free code allocation if unused
631
648
if ((next_code_options & next_code_stickiness_situation ) == 0 ) {
632
649
free_memory (next_code_allocation );
633
650
next_code_allocation = NULL ;
634
651
}
635
652
636
- // Done waiting, start the board back up.
637
653
#if CIRCUITPY_STATUS_LED
638
654
if (led_active ) {
639
655
new_status_color (BLACK );
@@ -757,7 +773,7 @@ STATIC int run_repl(bool first_run) {
757
773
usb_setup_with_vm ();
758
774
#endif
759
775
760
- autoreload_suspend (AUTORELOAD_LOCK_REPL );
776
+ autoreload_suspend (AUTORELOAD_SUSPEND_REPL );
761
777
762
778
// Set the status LED to the REPL color before running the REPL. For
763
779
// NeoPixels and DotStars this will be sticky but for PWM or single LED it
@@ -787,7 +803,7 @@ STATIC int run_repl(bool first_run) {
787
803
status_led_deinit ();
788
804
#endif
789
805
790
- autoreload_resume (AUTORELOAD_LOCK_REPL );
806
+ autoreload_resume (AUTORELOAD_SUSPEND_REPL );
791
807
return exit_code ;
792
808
}
793
809
0 commit comments