diff --git a/docs/environment.rst b/docs/environment.rst index 4bf89bf774a..dcdf7fe886f 100644 --- a/docs/environment.rst +++ b/docs/environment.rst @@ -93,6 +93,24 @@ Larger values will reserve more RAM for python use and prevent the supervisor an from large allocations of their own. Smaller values will likely grow sooner than large start sizes. +CIRCUITPY_HEAP_SRAM_SIZE (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +On boards where the python heap is normally placed in external PSRAM, allocate the heap's +*initial* segment (of this many bytes) from internal RAM instead. Later heap growth still +comes from PSRAM, so allocations made early in a program run at internal-RAM speed while +the total capacity is unchanged. If the requested size does not fit, the setting is +ignored and the heap starts in PSRAM as usual. Unset by default. + +When this setting is satisfied it fully defines the initial segment and +``CIRCUITPY_HEAP_START_SIZE`` is not consulted; ``CIRCUITPY_HEAP_START_SIZE`` applies +only when this setting is unset or its internal-RAM allocation fails. + +The internal pool is shared with DMA buffers (displays, audio). Buffers allocated at boot +coexist with this setting, but *re-allocating* a large buffer later (for example switching +a framebuffer display to a higher resolution at runtime) may fail, because the freed space +cannot merge across the live heap segment. With this setting, choose such sizes at boot +(e.g. via ``CIRCUITPY_DISPLAY_WIDTH``/``HEIGHT``) rather than switching at runtime. + CIRCUITPY_PYSTACK_SIZE (integer) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sets the size of the python stack. Must be a multiple of 4. The default value is currently 1536. diff --git a/main.c b/main.c index 2020cb8c307..f3c8148ac65 100644 --- a/main.c +++ b/main.c @@ -197,7 +197,25 @@ static void start_mp(safe_mode_t safe_mode) { #if MICROPY_ENABLE_GC size_t heap_size = 0; - _heap = _allocate_memory(safe_mode, "CIRCUITPY_HEAP_START_SIZE", CIRCUITPY_HEAP_START_SIZE, &heap_size); + // If CIRCUITPY_HEAP_SRAM_SIZE is set, try to place the heap's START segment in the + // internal (dma-capable) pool. On boards whose default heap lives in external PSRAM + // this puts early/hot allocations in fast RAM, while the heap still grows into PSRAM + // via MP_PLAT_ALLOC_HEAP. Unset (the default) keeps the current behavior; if the + // requested size does not fit the internal pool, we fall back to it as well. + #if CIRCUITPY_SETTINGS_TOML + if (safe_mode == SAFE_MODE_NONE) { + mp_int_t sram_size; + if (settings_get_int("CIRCUITPY_HEAP_SRAM_SIZE", &sram_size) == SETTINGS_OK && sram_size > 0) { + _heap = port_malloc((size_t)sram_size, true); + if (_heap != NULL) { + heap_size = (size_t)sram_size; + } + } + } + #endif + if (_heap == NULL) { + _heap = _allocate_memory(safe_mode, "CIRCUITPY_HEAP_START_SIZE", CIRCUITPY_HEAP_START_SIZE, &heap_size); + } gc_init(_heap, _heap + heap_size); #endif mp_init();