Skip to content

Commit fa302b2

Browse files
committed
Now works on reload.
1 parent 2077bb9 commit fa302b2

1 file changed

Lines changed: 48 additions & 54 deletions

File tree

main.c

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,45 @@
122122
uint8_t value_out = 0;
123123
#endif
124124

125-
#if MICROPY_ENABLE_PYSTACK && CIRCUITPY_OS_GETENV
125+
#if MICROPY_ENABLE_PYSTACK
126+
supervisor_allocation *pystack;
127+
mp_int_t pystack_size = 0; // 0 indicated 'not allocated'
128+
#if CIRCUITPY_OS_GETENV
126129
#include "shared-module/os/__init__.h"
127130
#endif
131+
#endif
128132

129133
static void reset_devices(void) {
130134
#if CIRCUITPY_BLEIO_HCI
131135
bleio_reset();
132136
#endif
133137
}
134138

135-
STATIC void start_mp(supervisor_allocation *heap, supervisor_allocation *pystack, int pystack_size) {
139+
#if MICROPY_ENABLE_PYSTACK
140+
STATIC void alloc_pystack(void) {
141+
mp_int_t old_pystack_size = pystack_size;
142+
pystack_size = CIRCUITPY_PYSTACK_SIZE; // Use build default for now.
143+
// Fetch value if exists from settings.toml
144+
#if CIRCUITPY_OS_GETENV
145+
// Leaves size to build default on any failure
146+
(void)common_hal_os_getenv_int("CIRCUITPY_PYSTACK_SIZE", &pystack_size);
147+
// Check if value is valid
148+
if ((CIRCUITPY_PYSTACK_SIZE != pystack_size) && ((pystack_size < 1) || (pystack_size % sizeof(size_t) != 0))) {
149+
pystack_size = CIRCUITPY_PYSTACK_SIZE; // Reset to build default
150+
// TODO: Find a way to inform the user about it.
151+
// Perhaps safemode? Or is it too much?
152+
}
153+
#endif
154+
if (old_pystack_size != pystack_size) {
155+
if (old_pystack_size != 0) {
156+
free_memory(pystack);
157+
}
158+
pystack = allocate_memory(pystack_size, false, false);
159+
}
160+
}
161+
#endif
162+
163+
STATIC void start_mp(supervisor_allocation *heap) {
136164
supervisor_workflow_reset();
137165

138166
// Stack limit should be less than real stack size, so we have a chance
@@ -363,7 +391,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
363391
}
364392
}
365393

366-
STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset, supervisor_allocation *pystack, int pystack_size) {
394+
STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
367395
bool serial_connected_at_start = serial_connected();
368396
bool printed_safe_mode_message = false;
369397
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -399,13 +427,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset, supervisor_
399427
};
400428
#endif
401429

430+
#if MICROPY_ENABLE_PYSTACK
431+
alloc_pystack();
432+
#endif
402433
supervisor_allocation *heap = allocate_remaining_memory();
403-
404-
// Prepare the VM state.
405-
#pragma GCC diagnostic push
406-
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // stackless doesn't want allocations.
407-
start_mp(heap, pystack, pystack_size);
408-
#pragma GCC diagnostic pop
434+
start_mp(heap);
409435

410436
#if CIRCUITPY_USB
411437
usb_setup_with_vm();
@@ -733,7 +759,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset, supervisor_
733759

734760
vstr_t *boot_output;
735761

736-
STATIC void run_boot_py(safe_mode_t safe_mode, supervisor_allocation *pystack, int pystack_size) {
762+
STATIC void run_boot_py(safe_mode_t safe_mode) {
737763
if (safe_mode == NO_HEAP) {
738764
return;
739765
}
@@ -749,11 +775,11 @@ STATIC void run_boot_py(safe_mode_t safe_mode, supervisor_allocation *pystack, i
749775

750776
// Do USB setup even if boot.py is not run.
751777

778+
#if MICROPY_ENABLE_PYSTACK
779+
alloc_pystack();
780+
#endif
752781
supervisor_allocation *heap = allocate_remaining_memory();
753-
#pragma GCC diagnostic push
754-
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // stackless doesn't want allocations.
755-
start_mp(heap, pystack, pystack_size);
756-
#pragma GCC diagnostic pop
782+
start_mp(heap);
757783

758784
#if CIRCUITPY_USB
759785
// Set up default USB values after boot.py VM starts but before running boot.py.
@@ -850,15 +876,15 @@ STATIC void run_boot_py(safe_mode_t safe_mode, supervisor_allocation *pystack, i
850876
#endif
851877
}
852878

853-
STATIC int run_repl(supervisor_allocation *pystack, int pystack_size) {
879+
STATIC int run_repl(void) {
854880
int exit_code = PYEXEC_FORCED_EXIT;
855881
stack_resize();
856882
filesystem_flush();
883+
#if MICROPY_ENABLE_PYSTACK
884+
alloc_pystack();
885+
#endif
857886
supervisor_allocation *heap = allocate_remaining_memory();
858-
#pragma GCC diagnostic push
859-
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // stackless doesn't want allocations.
860-
start_mp(heap, pystack, pystack_size);
861-
#pragma GCC diagnostic pop
887+
start_mp(heap);
862888

863889
#if CIRCUITPY_USB
864890
usb_setup_with_vm();
@@ -978,38 +1004,6 @@ int __attribute__((used)) main(void) {
9781004
alarm_reset();
9791005
#endif
9801006

981-
// Pystack variables have to exist even in stackless for the function calls
982-
supervisor_allocation *pystack;
983-
mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE; // Use build default for now.
984-
#if MICROPY_ENABLE_PYSTACK
985-
// Allocate default at least temporarily, needed for getenv
986-
pystack = allocate_memory(CIRCUITPY_PYSTACK_SIZE, false, false);
987-
988-
// Fetch value if exists from settings.toml
989-
#if CIRCUITPY_OS_GETENV
990-
// Init needed.
991-
supervisor_allocation *heap = allocate_remaining_memory();
992-
993-
// Leaves size to build default on any failure
994-
(void)common_hal_os_getenv_int("CIRCUITPY_PYSTACK_SIZE", &pystack_size);
995-
free_memory(heap);
996-
// Convert frame count to allocation size, 384 is the default for 1536 bytes
997-
pystack_size = pystack_size * sizeof(size_t);
998-
999-
// Check if value is valid
1000-
if ((CIRCUITPY_PYSTACK_SIZE != pystack_size) && (pystack_size < 1)) {
1001-
pystack_size = CIRCUITPY_PYSTACK_SIZE; // Reset to build default
1002-
// TODO: Find a way to inform the user about it.
1003-
// Perhaps safemode?
1004-
}
1005-
1006-
if (CIRCUITPY_PYSTACK_SIZE != pystack_size) {
1007-
free_memory(pystack); // Free the temporary
1008-
pystack = allocate_memory(pystack_size, false, false); // Allocate new pystack
1009-
}
1010-
#endif
1011-
#endif
1012-
10131007
// Reset everything and prep MicroPython to run boot.py.
10141008
reset_port();
10151009
// Port-independent devices, like CIRCUITPY_BLEIO_HCI.
@@ -1032,7 +1026,7 @@ int __attribute__((used)) main(void) {
10321026
filesystem_set_internal_concurrent_write_protection(true);
10331027
filesystem_set_internal_writable_by_usb(CIRCUITPY_USB == 1);
10341028

1035-
run_boot_py(safe_mode, pystack, pystack_size);
1029+
run_boot_py(safe_mode);
10361030

10371031
supervisor_workflow_start();
10381032

@@ -1046,7 +1040,7 @@ int __attribute__((used)) main(void) {
10461040
bool simulate_reset = true;
10471041
for (;;) {
10481042
if (!skip_repl) {
1049-
exit_code = run_repl(pystack, pystack_size);
1043+
exit_code = run_repl();
10501044
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
10511045
}
10521046
if (exit_code == PYEXEC_FORCED_EXIT) {
@@ -1057,7 +1051,7 @@ int __attribute__((used)) main(void) {
10571051
// If code.py did a fake deep sleep, pretend that we
10581052
// are running code.py for the first time after a hard
10591053
// reset. This will preserve any alarm information.
1060-
skip_repl = run_code_py(safe_mode, &simulate_reset, pystack, pystack_size);
1054+
skip_repl = run_code_py(safe_mode, &simulate_reset);
10611055
} else {
10621056
skip_repl = false;
10631057
}

0 commit comments

Comments
 (0)