3434#include "py/stackctrl.h"
3535#include "py/mphal.h"
3636#include "py/gc.h"
37+ #include "lib/fatfs/ff.h"
3738#include "lib/mp-readline/readline.h"
3839#include "lib/utils/pyexec.h"
3940#include "gccollect.h"
4344
4445STATIC char heap [36 * 1024 ];
4546
47+ bool maybe_run (const char * filename , pyexec_result_t * exec_result ) {
48+ FILINFO fno ;
49+ #if _USE_LFN
50+ fno .lfname = NULL ;
51+ fno .lfsize = 0 ;
52+ #endif
53+ FRESULT res = f_stat (filename , & fno );
54+ if (res != FR_OK || fno .fattrib & AM_DIR ) {
55+ return false;
56+ }
57+ mp_hal_stdout_tx_str (filename );
58+ mp_hal_stdout_tx_str (" output:\r\n" );
59+ pyexec_file (filename , exec_result );
60+ return true;
61+ }
62+
63+ bool serial_active = false;
64+
65+ STATIC bool start_mp (void ) {
66+ pyexec_frozen_module ("_boot.py" );
67+
68+ pyexec_result_t result ;
69+ bool found_boot = maybe_run ("settings.txt" , & result ) ||
70+ maybe_run ("settings.py" , & result ) ||
71+ maybe_run ("boot.py" , & result ) ||
72+ maybe_run ("boot.txt" , & result );
73+
74+ if (!found_boot || !(result .return_code & PYEXEC_FORCED_EXIT )) {
75+ maybe_run ("code.txt" , & result ) ||
76+ maybe_run ("code.py" , & result ) ||
77+ maybe_run ("main.py" , & result ) ||
78+ maybe_run ("main.txt" , & result );
79+ }
80+
81+ if (result .return_code & PYEXEC_FORCED_EXIT ) {
82+ return false;
83+ }
84+
85+ // We can't detect connections so we wait for any character to mark the serial active.
86+ if (!serial_active ) {
87+ mp_hal_stdin_rx_chr ();
88+ serial_active = true;
89+ }
90+ mp_hal_stdout_tx_str ("\r\n\r\n" );
91+ mp_hal_stdout_tx_str ("Press any key to enter the REPL. Use CTRL-D to soft reset.\r\n" );
92+ return mp_hal_stdin_rx_chr () == CHAR_CTRL_D ;
93+ }
94+
4695STATIC void mp_reset (void ) {
4796 mp_stack_set_top ((void * )0x40000000 );
4897 mp_stack_set_limit (8192 );
@@ -65,48 +114,37 @@ STATIC void mp_reset(void) {
65114 readline_init0 ();
66115 dupterm_task_init ();
67116 pwmout_reset ();
68- #if MICROPY_MODULE_FROZEN
69- pyexec_frozen_module ("_boot.py" );
70- pyexec_file ("boot.py" , NULL );
71- pyexec_file ("main.py" , NULL );
72- #endif
73117}
74118
75- void soft_reset (void ) {
119+ bool soft_reset (void ) {
76120 mp_hal_stdout_tx_str ("PYB: soft reboot\r\n" );
77121 mp_hal_delay_us (10000 ); // allow UART to flush output
78122 mp_reset ();
79- #if MICROPY_REPL_EVENT_DRIVEN
80- pyexec_event_repl_init ();
81- #endif
123+ mp_hal_delay_us (1000 ); // Give the RTOS time to do housekeeping.
124+ return start_mp ();
82125}
83126
84127void init_done (void ) {
85- #if MICROPY_REPL_EVENT_DRIVEN
86- uart_task_init ();
87- #endif
88128 mp_reset ();
129+ mp_hal_delay_us (1000 ); // Give the RTOS time to do housekeeping.
130+ bool skip_repl = start_mp ();
89131 mp_hal_stdout_tx_str ("\r\n" );
90- #if MICROPY_REPL_EVENT_DRIVEN
91- pyexec_event_repl_init ();
92- #endif
93132
94- #if !MICROPY_REPL_EVENT_DRIVEN
95- soft_reset :
96- for (;;) {
97- if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL ) {
98- if (pyexec_raw_repl () != 0 ) {
99- break ;
100- }
101- } else {
102- if (pyexec_friendly_repl () != 0 ) {
103- break ;
133+ int exit_code = PYEXEC_FORCED_EXIT ;
134+ while (true) {
135+ if (!skip_repl ) {
136+ if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL ) {
137+ exit_code = pyexec_raw_repl ();
138+ } else {
139+ exit_code = pyexec_friendly_repl ();
104140 }
105141 }
142+ if (exit_code == PYEXEC_FORCED_EXIT ) {
143+ skip_repl = soft_reset ();
144+ } else if (exit_code != 0 ) {
145+ break ;
146+ }
106147 }
107- soft_reset ();
108- goto soft_reset ;
109- #endif
110148}
111149
112150void user_init (void ) {
0 commit comments