-
Notifications
You must be signed in to change notification settings - Fork 501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MicroPython: Avoid heap allocations in all C++ modules. #711
Conversation
This is a pre-requisite to bumping all of our MicroPython builds to the latest edge commit and - indeed - keeping ahead of MicroPython changes so we can incorporate Bluetooth when it arrives. Once merged, relevant commits from https://github.com/pimoroni/badger2040/tree/test/micropython-edge can be moved to pimoroni/badger2040#2 (and the GitHub actions .yml targeted back at the main branch here) |
dfc696f
to
c529bd6
Compare
a16fb8e
to
210a06b
Compare
Pico RGB Keypad, Pico Scroll and Pico Unicorn have all been converted to MicroPython class-style modules. import picounicorn
picounicorn.init() Would become: from picounicorn import PicoUnicorn
picounicorn = PicoUnicorn() |
Looks like |
The result of GET_STR_DATA_LEN should be null terminated, so converting to a std::string and then using .c_str() is both redundant and need s heap.
MicroPython's GET_STR_DATA_LEN macro returns a const byte array and len, which std::string would copy into heap. Using string_view lets us wrap the existing const values.
Because `mp_tracked_calloc` does not survive a soft reset but the memory region will, resulting in half-initialised frankenclasses that behave unpredictably. Using the class pattern fixes this since it's always guaranteed to be initialised when a user instantiates it, and __del__ can handle cleanup.
Borrow heavily from Galactic/Cosmic Unicorn for the PIO/chained-DMA setup.
a6b5747
to
eb0de91
Compare
eb0de91
to
b83bdbf
Compare
Remove builds for Badger 2040 and Badger 2040 W, these now live at: https://github.com/pimoroni/badger2040/
As of micropython/micropython@c80e7c1 MicroPython's linker script includes a "greedy" heap, which attempts to use all free system RAM for MicroPython's heap.
Whereas previously we carefully avoided large heap allocations due to the very limited amount of heap available to C++ extensions, we must now avoid all allocations.
This changeset cleans up some uses of
std::string
which were implicitly allocating strings on heap. It does this by switching tostring_view
, wrapping the existing byte array and length returned byGET_STR_DATA_LEN
instead of copying them into astd::string
.Additionally
set_font()
performs Hershey font lookups via a newif/else
table, since thestd::map<std::string, const *font_t>
lookup table could not be used without constructing a string and risking a heap allocation.Finally I have removed the completely ridiculous and unnecessary conversion to/from a
std::string
in our jpegdec binding'sopen_file
functionality.To make
string_view
available, all MicroPython builds needed to be forced to use C++17, this is achieved in their respective CMake files.In all cases I believe
std::string
will implicitly cast tostd::string_view
so our examples will not break, and C++ code has always been set to C++17.