10000 esp32: Enable automatic Python heap growth. · micropython/micropython@4f67e09 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4f67e09

Browse files
committed
esp32: Enable automatic Python heap growth.
Via MICROPY_GC_SPLIT_HEAP_AUTO feature flag added in previous commit. Tested on ESP32 GENERIC_SPIRAM and GENERIC_S3 configurations, with some worst-case allocation patterns and the standard test suite. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent c4ea541 commit 4f67e09

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

docs/library/esp32.rst

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,20 @@ Functions
5151
buffers and other data. This data is useful to get a sense of how much memory
5252
is available to ESP-IDF and the networking stack in particular. It may shed
5353
some light on situations where ESP-IDF operations fail due to allocation failures.
54-
The information returned is *not* useful to troubleshoot Python allocation failures,
55-
use `micropython.mem_info()` instead.
5654

5755
The capabilities parameter corresponds to ESP-IDF's ``MALLOC_CAP_XXX`` values but the
5856
two most useful ones are predefined as `esp32.HEAP_DATA` for data heap regions and
5957
`esp32.HEAP_EXEC` for executable regions as used by the native code emitter.
6058

59+
Free IDF heap memory in the `esp32.HEAP_DATA` region is available to be
60+
automatically added to the MicroPython heap to prevent a MicroPython
61+
allocation from failing. However, the information returned here is otherwise
62+
*not* useful to troubleshoot Python allocation failures, use
63+
`micropython.mem_info()` instead. The "max new split" value in
64+
`micropython.mem_info()` output corresponds to the largest free block of
65+
ESP-IDF heap that could be automatically added on demand to the MicroPython
66+
heap.
67+
6168
The return value is a list of 4-tuples, where each 4-tuple corresponds to one heap
6269
and contains: the total bytes, the free bytes, the largest free block, and
6370
the minimum free seen over time.

ports/esp32/gccollect.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,15 @@ void gc_collect(void) {
8080
}
8181

8282
#endif
83+
84+
#if MICROPY_GC_SPLIT_HEAP_AUTO
85+
86+
size_t gc_get_max_new_split(void) {
87+
// Need to allow some overhead for heap block metadata.
88+
// Am choosing a conservative value as TLSF impl is a bit opaque.
89+
static const size_t HEAP_METADATA_OVERHEAD = 64;
90+
size_t largest = heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT);
91+
return largest < HEAP_METADATA_OVERHEAD ? 0 : largest - HEAP_METADATA_OVERHEAD;
92+
}
93+
94+
#endif

ports/esp32/main.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,9 @@ void mp_task(void *pvParameter) {
100100
ESP_LOGE("esp_init", "can't create event loop: 0x%x\n", err);
101101
}
102102

103-
// Allocate the uPy heap using malloc and get the largest available region,
104-
// limiting to 1/2 total available memory to leave memory for the OS.
105-
// When SPIRAM is enabled, this will allocate from SPIRAM.
106-
uint32_t caps = MALLOC_CAP_8BIT;
107-
size_t heap_total = heap_caps_get_total_size(caps);
108-
size_t mp_task_heap_size = MIN(heap_caps_get_largest_free_block(caps), heap_total / 2);
109-
void *mp_task_heap = heap_caps_malloc(mp_task_heap_size, caps);
103+
/* Heap size starts small, grows on demand */
104+
const size_t mp_task_heap_size = 64 * 1024;
105+
void *mp_task_heap = MP_PLAT_ALLOC_HEAP(mp_task_heap_size);
110106

111107
soft_reset:
112108
// initialise the stack pointer for the main thread

ports/esp32/mpconfigport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868
#define MICROPY_PY_THREAD_GIL (1)
6969
#define MICROPY_PY_THREAD_GIL_VM_DIVISOR (32)
7070

71+
#define MICROPY_GC_SPLIT_HEAP (1)
72+
#define MICROPY_GC_SPLIT_HEAP_AUTO (1)
73+
7174
// extended modules
7275
#ifndef MICROPY_ESPNOW
7376
#define MICROPY_ESPNOW (1)

0 commit comments

Comments
 (0)
0