45
45
46
46
#include "mpconfigboard.h"
47
47
#include "supervisor/cpu.h"
48
+ #include "supervisor/memory.h"
48
49
#include "supervisor/port.h"
49
50
#include "supervisor/filesystem.h"
50
51
// TODO(tannewt): Figure out how to choose language at compile time.
51
52
#include "supervisor/messages/en-US.h"
52
53
#include "supervisor/shared/autoreload.h"
53
54
#include "supervisor/shared/rgb_led_status.h"
55
+ #include "supervisor/shared/stack.h"
54
56
#include "supervisor/serial.h"
55
57
56
58
void 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) {
73
75
}
74
76
}
75
77
76
- static char heap [PORT_HEAP_SIZE ];
77
-
78
- void reset_mp (void ) {
78
+ void start_mp (supervisor_allocation * heap ) {
79
79
reset_status_led ();
80
80
autoreload_stop ();
81
81
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
+
82
93
// Sync the file systems in case any used RAM from the GC to cache. As soon
83
94
// as we re-init the GC all bets are off on the cache.
84
95
filesystem_flush ();
@@ -87,7 +98,7 @@ void reset_mp(void) {
87
98
readline_init0 ();
88
99
89
100
#if MICROPY_ENABLE_GC
90
- gc_init (heap , heap + sizeof ( heap ) );
101
+ gc_init (heap -> ptr , heap -> ptr + heap -> length / 4 );
91
102
#endif
92
103
mp_init ();
93
104
mp_obj_list_init (mp_sys_path , 0 );
@@ -99,6 +110,11 @@ void reset_mp(void) {
99
110
100
111
mp_obj_list_init (mp_sys_argv , 0 );
101
112
}
113
+
114
+ void stop_mp (void ) {
115
+
116
+ }
117
+
102
118
#define STRING_LIST (...) {__VA_ARGS__, ""}
103
119
104
120
// 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) {
124
140
return true;
125
141
}
126
142
127
- bool start_mp (safe_mode_t safe_mode ) {
143
+ bool run_code_py (safe_mode_t safe_mode ) {
128
144
bool serial_connected_at_start = serial_connected ();
129
145
#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
130
146
if (serial_connected_at_start ) {
@@ -155,14 +171,20 @@ bool start_mp(safe_mode_t safe_mode) {
155
171
const char * supported_filenames [] = STRING_LIST ("code.txt" , "code.py" , "main.py" , "main.txt" );
156
172
const char * double_extension_filenames [] = STRING_LIST ("code.txt.py" , "code.py.txt" , "code.txt.txt" ,"code.py.py" ,
157
173
"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 );
159
179
found_main = maybe_run_list (supported_filenames , & result );
160
180
if (!found_main ){
161
181
found_main = maybe_run_list (double_extension_filenames , & result );
162
182
if (found_main ) {
163
183
serial_write (MSG_DOUBLE_FILE_EXTENSION );
164
184
}
165
185
}
186
+ stop_mp ();
187
+ free_memory (heap );
166
188
167
189
reset_port ();
168
190
reset_board ();
@@ -291,6 +313,12 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
291
313
}
292
314
#endif
293
315
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
+
294
322
// TODO(tannewt): Re-add support for flashing boot error output.
295
323
bool found_boot = maybe_run_list (boot_py_filenames , NULL );
296
324
(void ) found_boot ;
@@ -306,27 +334,41 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
306
334
// Reset to remove any state that boot.py setup. It should only be used to
307
335
// change internal state that's not in the heap.
308
336
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 ();
310
355
}
356
+ reset_port ();
357
+ reset_board ();
358
+ stop_mp ();
359
+ free_memory (heap );
360
+ autoreload_resume ();
361
+ return exit_code ;
311
362
}
312
363
313
364
int __attribute__((used )) main (void ) {
365
+ memory_init ();
366
+
314
367
// initialise the cpu and peripherals
315
368
safe_mode_t safe_mode = port_init ();
316
369
317
370
rgb_led_status_init ();
318
371
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
-
330
372
// Create a new filesystem only if we're not in a safe mode.
331
373
// A power brownout here could make it appear as if there's
332
374
// no SPI flash filesystem, and we might erase the existing one.
@@ -335,7 +377,6 @@ int __attribute__((used)) main(void) {
335
377
// Reset everything and prep MicroPython to run boot.py.
336
378
reset_port ();
337
379
reset_board ();
338
- reset_mp ();
339
380
340
381
// Turn on autoreload by default but before boot.py in case it wants to change it.
341
382
autoreload_enable ();
@@ -355,24 +396,14 @@ int __attribute__((used)) main(void) {
355
396
bool first_run = true;
356
397
for (;;) {
357
398
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 ();
369
400
}
370
401
if (exit_code == PYEXEC_FORCED_EXIT ) {
371
402
if (!first_run ) {
372
403
serial_write (MSG_SOFT_REBOOT MSG_NEWLINE );
373
404
}
374
405
first_run = false;
375
- skip_repl = start_mp (safe_mode );
406
+ skip_repl = run_code_py (safe_mode );
376
407
} else if (exit_code != 0 ) {
377
408
break ;
378
409
}
0 commit comments