Repository navigation
MicroPython: LVGL's memory pools on ESP32, opt-in - #15
Merged
Merged
Conversation
ESP32 builds were meant to keep LVGL's allocations in pools held in GC blocks, but the pool code compiled in only when MICROPY_MALLOC_USES_ALLOCATED_SIZE was 1, which the esp32 port leaves at 0, so every LVGL allocation still walked the GC allocation table (#10). ESP32 now uses the same TLSF pools as other ports, on by default, and LVMP_POOL_TLSF=0 turns them off. The switch keys on CONFIG_IDF_TARGET, which mpconfigport.h brings in from sdkconfig.h, not on ESP_PLATFORM: the esp32 port compiles user C modules a second time without ESP_PLATFORM, and that copy is the one linked.
gc.collect() scans a pool whole, used or not. With one 256 KB pool, a collection on a fresh ESP32-P4 heap took 11.4 ms against 2.9 ms without pools, while LVGL kept about 30 KB in it. Pools now start at 32 KB and double up to 256 KB, with ten of them (about 2 MB) before allocations go back to gc_alloc().
Even with a 32 KB first pool, gc.collect() on a fresh ESP32-P4 heap took 6.1 ms with the pools against 2.9 ms without, too much to impose on every ESP32 build for faster LVGL allocation on a fragmented heap. A build turns them on with LVMP_POOL_TLSF=1, set where the root-pointer scan sees it (mpconfigboard.h, or CFLAGS_EXTRA on make ports).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #10. ESP32 firmware can now keep LVGL's allocations in pools held in GC blocks, opt-in with
LVMP_POOL_TLSF=1as on the other ports. Until now the ESP32 pool code compiled in only whenMICROPY_MALLOC_USES_ALLOCATED_SIZEwas 1, which the esp32 port leaves at 0, so it never reached a firmware.ESP32 now uses the same TLSF pools as the other ports (#6), and the multi_heap branch goes. The allocator's aliases are renamed, since ESP-IDF's own
multi_heap.his already in scope on ESP32 and its type clashed with them. SetLVMP_POOL_TLSFwhere MicroPython's root-pointer scan sees it too: in the board'smpconfigboard.h, or inCFLAGS_EXTRAon a make port. A definition that reaches only the compiler leaves the pools' root pointer unregistered and the build fails. On the esp32 port, test for the target withCONFIG_IDF_TARGET, notESP_PLATFORM: the port compiles user C modules a second time withoutESP_PLATFORM, and that copy is the one linked.The first pool is now 32 KB, and each new one doubles up to 256 KB, ten pools (about 2 MB) in all.
gc.collect()scans a pool whole, used or not, so one 256 KB pool made every collection pay for room LVGL wasn't using.I built ESP32_GENERIC_P4 (16 MB, the Waveshare ESP32-P4-WIFI6-DEV-KIT with a 5" DSI panel, about 31 MB of GC heap in PSRAM) from one tree three ways: no pools, one 256 KB pool, and growing pools from 32 KB. Then I ran the
heap_layout.pyscript from #6 on the board, two runs per build (ranges over both):gc.collect(), no poolsThe median refresh was 63.4-64.0 ms in every build and layout: drawing dominates it on this board.
LVGL's own allocations stay flat on a fragmented heap with the pools and get three times slower without them, the same shape as the STM32 runs in #6. The growing pools keep that and halve the collection cost, but a collection on a fresh heap still takes about twice as long (this screen filled the 32 KB pool and opened a 64 KB one). That's too much to impose on every ESP32 build, so the pools stay opt-in: worth turning on for a long-running app that builds and tears down widgets, not by default. The last firmware, from this branch's head with the pools off, boots and runs its apps. I didn't test an ESP32 without PSRAM.