4545
4646#include "mpconfigboard.h"
4747#include "supervisor/cpu.h"
48+ #include "supervisor/memory.h"
4849#include "supervisor/port.h"
4950#include "supervisor/filesystem.h"
5051// TODO(tannewt): Figure out how to choose language at compile time.
5152#include "supervisor/messages/en-US.h"
5253#include "supervisor/shared/autoreload.h"
5354#include "supervisor/shared/rgb_led_status.h"
55+ #include "supervisor/shared/stack.h"
5456#include "supervisor/serial.h"
5557
5658void do_str (const char * src , mp_parse_input_kind_t input_kind ) {
@@ -73,12 +75,21 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
7375 }
7476}
7577
76- static char heap [PORT_HEAP_SIZE ];
77-
78- void reset_mp (void ) {
78+ void start_mp (supervisor_allocation * heap ) {
7979 reset_status_led ();
8080 autoreload_stop ();
8181
82+ // Stack limit should be less than real stack size, so we have a chance
83+ // to recover from limit hit. (Limit is measured in bytes.)
84+ mp_stack_ctrl_init ();
85+ mp_stack_set_limit (stack_alloc -> length - 1024 );
86+
87+ #if MICROPY_MAX_STACK_USAGE
88+ // _ezero (same as _ebss) is an int, so start 4 bytes above it.
89+ mp_stack_set_bottom (stack_alloc -> ptr );
90+ mp_stack_fill_with_sentinel ();
91+ #endif
92+
8293 // Sync the file systems in case any used RAM from the GC to cache. As soon
8394 // as we re-init the GC all bets are off on the cache.
8495 filesystem_flush ();
@@ -87,7 +98,7 @@ void reset_mp(void) {
8798 readline_init0 ();
8899
89100 #if MICROPY_ENABLE_GC
90- gc_init (heap , heap + sizeof ( heap ) );
101+ gc_init (heap -> ptr , heap -> ptr + heap -> length / 4 );
91102 #endif
92103 mp_init ();
93104 mp_obj_list_init (mp_sys_path , 0 );
@@ -99,6 +110,11 @@ void reset_mp(void) {
99110
100111 mp_obj_list_init (mp_sys_argv , 0 );
101112}
113+
114+ void stop_mp (void ) {
115+
116+ }
117+
102118#define STRING_LIST (...) {__VA_ARGS__, ""}
103119
104120// Look for the first file that exists in the list of filenames, using mp_import_stat().
@@ -124,7 +140,7 @@ bool maybe_run_list(const char ** filenames, pyexec_result_t* exec_result) {
124140 return true;
125141}
126142
127- bool start_mp (safe_mode_t safe_mode ) {
143+ bool run_code_py (safe_mode_t safe_mode ) {
128144 bool serial_connected_at_start = serial_connected ();
129145 #ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
130146 if (serial_connected_at_start ) {
@@ -155,14 +171,20 @@ bool start_mp(safe_mode_t safe_mode) {
155171 const char * supported_filenames [] = STRING_LIST ("code.txt" , "code.py" , "main.py" , "main.txt" );
156172 const char * double_extension_filenames [] = STRING_LIST ("code.txt.py" , "code.py.txt" , "code.txt.txt" ,"code.py.py" ,
157173 "main.txt.py" , "main.py.txt" , "main.txt.txt" ,"main.py.py" );
158- reset_mp ();
174+
175+ stack_resize ();
176+ filesystem_flush ();
177+ supervisor_allocation * heap = allocate_remaining_memory ();
178+ start_mp (heap );
159179 found_main = maybe_run_list (supported_filenames , & result );
160180 if (!found_main ){
161181 found_main = maybe_run_list (double_extension_filenames , & result );
162182 if (found_main ) {
163183 serial_write (MSG_DOUBLE_FILE_EXTENSION );
164184 }
165185 }
186+ stop_mp ();
187+ free_memory (heap );
166188
167189 reset_port ();
168190 reset_board ();
@@ -291,6 +313,12 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
291313 }
292314 #endif
293315
316+ stack_init ();
317+ // TODO(tannewt): Allocate temporary space to hold custom usb descriptors.
318+ filesystem_flush ();
319+ supervisor_allocation * heap = allocate_remaining_memory ();
320+ start_mp (heap );
321+
294322 // TODO(tannewt): Re-add support for flashing boot error output.
295323 bool found_boot = maybe_run_list (boot_py_filenames , NULL );
296324 (void ) found_boot ;
@@ -306,27 +334,41 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
306334 // Reset to remove any state that boot.py setup. It should only be used to
307335 // change internal state that's not in the heap.
308336 reset_port ();
309- reset_mp ();
337+ reset_board ();
338+ stop_mp ();
339+ free_memory (heap );
340+ }
341+ }
342+
343+ int run_repl (void ) {
344+ int exit_code = PYEXEC_FORCED_EXIT ;
345+ stack_resize ();
346+ filesystem_flush ();
347+ supervisor_allocation * heap = allocate_remaining_memory ();
348+ start_mp (heap );
349+ autoreload_suspend ();
350+ new_status_color (REPL_RUNNING );
351+ if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL ) {
352+ exit_code = pyexec_raw_repl ();
353+ } else {
354+ exit_code = pyexec_friendly_repl ();
310355 }
356+ reset_port ();
357+ reset_board ();
358+ stop_mp ();
359+ free_memory (heap );
360+ autoreload_resume ();
361+ return exit_code ;
311362}
312363
313364int __attribute__((used )) main (void ) {
365+ memory_init ();
366+
314367 // initialise the cpu and peripherals
315368 safe_mode_t safe_mode = port_init ();
316369
317370 rgb_led_status_init ();
318371
319- // Stack limit should be less than real stack size, so we have a chance
320- // to recover from limit hit. (Limit is measured in bytes.)
321- mp_stack_set_top ((char * )& _estack );
322- mp_stack_set_limit ((char * )& _estack - (char * )& _ebss - 1024 );
323-
324- #if MICROPY_MAX_STACK_USAGE
325- // _ezero (same as _ebss) is an int, so start 4 bytes above it.
326- mp_stack_set_bottom (& _ezero + 1 );
327- mp_stack_fill_with_sentinel ();
328- #endif
329-
330372 // Create a new filesystem only if we're not in a safe mode.
331373 // A power brownout here could make it appear as if there's
332374 // no SPI flash filesystem, and we might erase the existing one.
@@ -335,7 +377,6 @@ int __attribute__((used)) main(void) {
335377 // Reset everything and prep MicroPython to run boot.py.
336378 reset_port ();
337379 reset_board ();
338- reset_mp ();
339380
340381 // Turn on autoreload by default but before boot.py in case it wants to change it.
341382 autoreload_enable ();
@@ -355,24 +396,14 @@ int __attribute__((used)) main(void) {
355396 bool first_run = true;
356397 for (;;) {
357398 if (!skip_repl ) {
358- reset_mp ();
359- autoreload_suspend ();
360- new_status_color (REPL_RUNNING );
361- if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL ) {
362- exit_code = pyexec_raw_repl ();
363- } else {
364- exit_code = pyexec_friendly_repl ();
365- }
366- autoreload_resume ();
367- reset_port ();
368- reset_board ();
399+ exit_code = run_repl ();
369400 }
370401 if (exit_code == PYEXEC_FORCED_EXIT ) {
371402 if (!first_run ) {
372403 serial_write (MSG_SOFT_REBOOT MSG_NEWLINE );
373404 }
374405 first_run = false;
375- skip_repl = start_mp (safe_mode );
406+ skip_repl = run_code_py (safe_mode );
376407 } else if (exit_code != 0 ) {
377408 break ;
378409 }
0 commit comments