@@ -204,6 +204,32 @@ STATIC void stop_mp(void) {
204
204
gc_deinit ();
205
205
}
206
206
207
+ STATIC const char * _last_executing_filename = NULL ;
208
+ STATIC const char * _current_executing_filename = NULL ;
209
+
210
+ STATIC pyexec_result_t _exec_result = {0 , MP_OBJ_NULL , 0 };
211
+ STATIC int _last_return_code = 0 ;
212
+ STATIC int _last_exception_line = 0 ;
213
+
214
+ bool supervisor_execution_status_dirty (void ) {
215
+ return _last_executing_filename != _current_executing_filename ||
216
+ _last_return_code != _exec_result .return_code ||
217
+ _last_exception_line != _exec_result .exception_line ;
218
+ }
219
+
220
+ void supervisor_execution_status (void ) {
221
+ mp_obj_exception_t * exception = MP_OBJ_TO_PTR (_exec_result .exception );
222
+ if ((_exec_result .return_code & PYEXEC_EXCEPTION ) != 0 &&
223
+ exception != NULL ) {
224
+ mp_printf (& mp_plat_print , "@%d %q" , _exec_result .exception_line , exception -> base .type -> name );
225
+ } else if (_current_executing_filename != NULL ) {
226
+ serial_write (_current_executing_filename );
227
+ }
228
+ _last_executing_filename = _current_executing_filename ;
229
+ _last_return_code = _exec_result .return_code ;
230
+ _last_exception_line = _exec_result .exception_line ;
231
+ }
232
+
207
233
#define STRING_LIST (...) {__VA_ARGS__, ""}
208
234
209
235
// Look for the first file that exists in the list of filenames, using mp_import_stat().
@@ -218,17 +244,23 @@ STATIC const char *first_existing_file_in_list(const char *const *filenames) {
218
244
return NULL ;
219
245
}
220
246
221
- STATIC bool maybe_run_list (const char * const * filenames , pyexec_result_t * exec_result ) {
222
- const char * filename = first_existing_file_in_list (filenames );
223
- if (filename == NULL ) {
247
+ STATIC bool maybe_run_list (const char * const * filenames ) {
248
+ _exec_result .return_code = 0 ;
249
+ _exec_result .exception = MP_OBJ_NULL ;
250
+ _exec_result .exception_line = 0 ;
251
+ _current_executing_filename = first_existing_file_in_list (filenames );
252
+ if (_current_executing_filename == NULL ) {
224
253
return false;
225
254
}
226
- mp_hal_stdout_tx_str (filename );
255
+ mp_hal_stdout_tx_str (_current_executing_filename );
227
256
serial_write_compressed (translate (" output:\n" ));
228
- pyexec_file (filename , exec_result );
257
+ supervisor_title_bar_request_update (false);
258
+ pyexec_file (_current_executing_filename , & _exec_result );
229
259
#if CIRCUITPY_ATEXIT
230
- shared_module_atexit_execute (exec_result );
260
+ shared_module_atexit_execute (& _exec_result );
231
261
#endif
262
+ _current_executing_filename = "Done" ;
263
+ supervisor_title_bar_request_update (false);
232
264
return true;
233
265
}
234
266
@@ -347,12 +379,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
347
379
}
348
380
#endif
349
381
350
- pyexec_result_t result ;
351
-
352
- result .return_code = 0 ;
353
- result .exception = MP_OBJ_NULL ;
354
- result .exception_line = 0 ;
355
-
356
382
bool skip_repl = false;
357
383
bool skip_wait = false;
358
384
bool found_main = false;
@@ -391,7 +417,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
391
417
if (((next_code_info_t * )next_code_allocation -> ptr )-> filename [0 ] != '\0' ) {
392
418
const char * next_list [] = {((next_code_info_t * )next_code_allocation -> ptr )-> filename , "" };
393
419
// This is where the user's python code is actually executed:
394
- found_main = maybe_run_list (next_list , & result );
420
+ found_main = maybe_run_list (next_list );
395
421
if (!found_main ) {
396
422
serial_write (((next_code_info_t * )next_code_allocation -> ptr )-> filename );
397
423
serial_write_compressed (translate (" not found.\n" ));
@@ -401,11 +427,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
401
427
// Otherwise, default to the standard list of filenames
402
428
if (!found_main ) {
403
429
// This is where the user's python code is actually executed:
404
- found_main = maybe_run_list (supported_filenames , & result );
430
+ found_main = maybe_run_list (supported_filenames );
405
431
// If that didn't work, double check the extensions
406
432
#if CIRCUITPY_FULL_BUILD
407
433
if (!found_main ) {
408
- found_main = maybe_run_list (double_extension_filenames , & result );
434
+ found_main = maybe_run_list (double_extension_filenames );
409
435
if (found_main ) {
410
436
serial_write_compressed (translate ("WARNING: Your code filename has two extensions\n" ));
411
437
}
@@ -417,15 +443,15 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
417
443
418
444
// Print done before resetting everything so that we get the message over
419
445
// BLE before it is reset and we have a delay before reconnect.
420
- if ((result .return_code & PYEXEC_RELOAD ) && supervisor_get_run_reason () == RUN_REASON_AUTO_RELOAD ) {
446
+ if ((_exec_result .return_code & PYEXEC_RELOAD ) && supervisor_get_run_reason () == RUN_REASON_AUTO_RELOAD ) {
421
447
serial_write_compressed (translate ("\nCode stopped by auto-reload. Reloading soon.\n" ));
422
448
} else {
423
449
serial_write_compressed (translate ("\nCode done running.\n" ));
424
450
}
425
451
426
452
427
453
// Finished executing python code. Cleanup includes filesystem flush and a board reset.
428
- cleanup_after_vm (heap , result .exception );
454
+ cleanup_after_vm (heap , _exec_result .exception );
429
455
430
456
// If a new next code file was set, that is a reason to keep it (obviously). Stuff this into
431
457
// the options because it can be treated like any other reason-for-stickiness bit. The
@@ -436,15 +462,15 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
436
462
next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET ;
437
463
}
438
464
439
- if (result .return_code & PYEXEC_RELOAD ) {
465
+ if (_exec_result .return_code & PYEXEC_RELOAD ) {
440
466
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD ;
441
467
// Reload immediately unless the reload is due to autoreload. In that
442
468
// case, we wait below to see if any other writes occur.
443
469
if (supervisor_get_run_reason () != RUN_REASON_AUTO_RELOAD ) {
444
470
skip_repl = true;
445
471
skip_wait = true;
446
472
}
447
- } else if (result .return_code == 0 ) {
473
+ } else if (_exec_result .return_code == 0 ) {
448
474
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS ;
449
475
if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS ) {
450
476
skip_repl = true;
@@ -455,12 +481,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
455
481
// Deep sleep cannot be skipped
456
482
// TODO: settings in deep sleep should persist, using a new sleep memory API
457
483
if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_ERROR
458
- && !(result .return_code & PYEXEC_DEEP_SLEEP )) {
484
+ && !(_exec_result .return_code & PYEXEC_DEEP_SLEEP )) {
459
485
skip_repl = true;
460
486
skip_wait = true;
461
487
}
462
488
}
463
- if (result .return_code & PYEXEC_FORCED_EXIT ) {
489
+ if (_exec_result .return_code & PYEXEC_FORCED_EXIT ) {
464
490
skip_repl = false;
465
491
skip_wait = true;
466
492
}
@@ -478,12 +504,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
478
504
uint8_t blink_count ;
479
505
bool led_active = false;
480
506
#if CIRCUITPY_ALARM
481
- if (result .return_code & PYEXEC_DEEP_SLEEP ) {
507
+ if (_exec_result .return_code & PYEXEC_DEEP_SLEEP ) {
482
508
color = BLACK ;
483
509
blink_count = 0 ;
484
510
} else
485
511
#endif
486
- if (result .return_code != PYEXEC_EXCEPTION ) {
512
+ if (_exec_result .return_code != PYEXEC_EXCEPTION ) {
487
513
if (safe_mode == NO_SAFE_MODE ) {
488
514
color = ALL_DONE ;
489
515
blink_count = ALL_DONE_BLINKS ;
@@ -568,7 +594,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
568
594
569
595
// Sleep until our next interrupt.
570
596
#if CIRCUITPY_ALARM
571
- if (result .return_code & PYEXEC_DEEP_SLEEP ) {
597
+ if (_exec_result .return_code & PYEXEC_DEEP_SLEEP ) {
572
598
const bool awoke_from_true_deep_sleep =
573
599
common_hal_mcu_processor_get_reset_reason () == RESET_REASON_DEEP_SLEEP_ALARM ;
574
600
@@ -730,8 +756,6 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
730
756
usb_set_defaults ();
731
757
#endif
732
758
733
- pyexec_result_t result = {0 , MP_OBJ_NULL , 0 };
734
-
735
759
if (ok_to_run ) {
736
760
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
737
761
vstr_t boot_text ;
@@ -742,7 +766,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
742
766
// Write version info
743
767
mp_printf (& mp_plat_print , "%s\nBoard ID:%s\n" , MICROPY_FULL_VERSION_INFO , CIRCUITPY_BOARD_ID );
744
768
745
- bool found_boot = maybe_run_list (boot_py_filenames , & result );
769
+ bool found_boot = maybe_run_list (boot_py_filenames );
746
770
(void )found_boot ;
747
771
748
772
@@ -792,7 +816,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
792
816
usb_get_boot_py_data (usb_boot_py_data , size );
793
817
#endif
794
818
795
- cleanup_after_vm (heap , result .exception );
819
+ cleanup_after_vm (heap , _exec_result .exception );
796
820
797
821
#if CIRCUITPY_USB
798
822
// Now give back the data we saved from the heap going away.
0 commit comments