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.
@@ -73,12 +74,21 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
7374 }
7475}
7576
76- static char heap [PORT_HEAP_SIZE ];
77-
78- void reset_mp (void ) {
77+ void start_mp (supervisor_allocation * heap ) {
7978 reset_status_led ();
8079 autoreload_stop ();
8180
81+ // Stack limit should be less than real stack size, so we have a chance
82+ // to recover from limit hit. (Limit is measured in bytes.)
83+ mp_stack_ctrl_init ();
84+ mp_stack_set_limit ((char * )& _estack - (char * )& _ebss - 1024 );
85+
86+ #if MICROPY_MAX_STACK_USAGE
87+ // _ezero (same as _ebss) is an int, so start 4 bytes above it.
88+ mp_stack_set_bottom (& _ezero + 1 );
89+ mp_stack_fill_with_sentinel ();
90+ #endif
91+
8292 // Sync the file systems in case any used RAM from the GC to cache. As soon
8393 // as we re-init the GC all bets are off on the cache.
8494 filesystem_flush ();
@@ -87,7 +97,7 @@ void reset_mp(void) {
8797 readline_init0 ();
8898
8999 #if MICROPY_ENABLE_GC
90- gc_init (heap , heap + sizeof ( heap ) );
100+ gc_init (heap -> ptr , heap -> ptr + heap -> length );
91101 #endif
92102 mp_init ();
93103 mp_obj_list_init (mp_sys_path , 0 );
@@ -99,6 +109,11 @@ void reset_mp(void) {
99109
100110 mp_obj_list_init (mp_sys_argv , 0 );
101111}
112+
113+ void stop_mp (void ) {
114+
115+ }
116+
102117#define STRING_LIST (...) {__VA_ARGS__, ""}
103118
104119// Look for the first file that exists in the list of filenames, using mp_import_stat().
@@ -124,7 +139,7 @@ bool maybe_run_list(const char ** filenames, pyexec_result_t* exec_result) {
124139 return true;
125140}
126141
127- bool start_mp (safe_mode_t safe_mode ) {
142+ bool run_code_py (safe_mode_t safe_mode ) {
128143 bool serial_connected_at_start = serial_connected ();
129144 #ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
130145 if (serial_connected_at_start ) {
@@ -155,14 +170,18 @@ bool start_mp(safe_mode_t safe_mode) {
155170 const char * supported_filenames [] = STRING_LIST ("code.txt" , "code.py" , "main.py" , "main.txt" );
156171 const char * double_extension_filenames [] = STRING_LIST ("code.txt.py" , "code.py.txt" , "code.txt.txt" ,"code.py.py" ,
157172 "main.txt.py" , "main.py.txt" , "main.txt.txt" ,"main.py.py" );
158- reset_mp ();
173+
174+ supervisor_allocation * heap = allocate_remaining_memory ();
175+ start_mp (heap );
159176 found_main = maybe_run_list (supported_filenames , & result );
160177 if (!found_main ){
161178 found_main = maybe_run_list (double_extension_filenames , & result );
162179 if (found_main ) {
163180 serial_write (MSG_DOUBLE_FILE_EXTENSION );
164181 }
165182 }
183+ stop_mp ();
184+ free_memory (heap );
166185
167186 reset_port ();
168187 reset_board ();
@@ -306,27 +325,36 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
306325 // Reset to remove any state that boot.py setup. It should only be used to
307326 // change internal state that's not in the heap.
308327 reset_port ();
309- reset_mp ();
310328 }
311329}
312330
331+ int run_repl (void ) {
332+ int exit_code = PYEXEC_FORCED_EXIT ;
333+ supervisor_allocation * heap = allocate_remaining_memory ();
334+ start_mp (heap );
335+ autoreload_suspend ();
336+ new_status_color (REPL_RUNNING );
337+ if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL ) {
338+ exit_code = pyexec_raw_repl ();
339+ } else {
340+ exit_code = pyexec_friendly_repl ();
341+ }
342+ reset_port ();
343+ reset_board ();
344+ stop_mp ();
345+ free_memory (heap );
346+ autoreload_resume ();
347+ return exit_code ;
348+ }
349+
313350int __attribute__((used )) main (void ) {
351+ memory_init ();
352+
314353 // initialise the cpu and peripherals
315354 safe_mode_t safe_mode = port_init ();
316355
317356 rgb_led_status_init ();
318357
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-
330358 // Create a new filesystem only if we're not in a safe mode.
331359 // A power brownout here could make it appear as if there's
332360 // no SPI flash filesystem, and we might erase the existing one.
@@ -335,7 +363,6 @@ int __attribute__((used)) main(void) {
335363 // Reset everything and prep MicroPython to run boot.py.
336364 reset_port ();
337365 reset_board ();
338- reset_mp ();
339366
340367 // Turn on autoreload by default but before boot.py in case it wants to change it.
341368 autoreload_enable ();
@@ -355,24 +382,14 @@ int __attribute__((used)) main(void) {
355382 bool first_run = true;
356383 for (;;) {
357384 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 ();
385+ exit_code = run_repl ();
369386 }
370387 if (exit_code == PYEXEC_FORCED_EXIT ) {
371388 if (!first_run ) {
372389 serial_write (MSG_SOFT_REBOOT MSG_NEWLINE );
373390 }
374391 first_run = false;
375- skip_repl = start_mp (safe_mode );
392+ skip_repl = run_code_py (safe_mode );
376393 } else if (exit_code != 0 ) {
377394 break ;
378395 }
0 commit comments