Executing natmod .mpy from flash #12811
Replies: 3 comments 5 replies
-
Interesting application! In terms of loading directly from ram, the only existing methods I know involve freezing the code into the firmware, which requires compiling the codebase. I'm pretty sure that doesn't currently work with natmods either. I suspect the feature you're pretty much looking for is #8381 which is intended to allow loading files of any type onto a "virtual" filesystem such that it can be flashed separately to a standard firmware download. |
Beta Was this translation helpful? Give feedback.
-
Hi @andrewleech . Thanks for taking time to check out my question.
That's on import, and I think I've figured out what's taking up so much space, after reading this comment from @jimmo:
For context, I'm targeting an ESP32 for my experiments. Indeed, I had to pull out a bunch of object files from libgcc.a and libc.a and add them to the build to get everything to link. This amounts to a major duplication of code, as all this stuff is already in the MicroPython firmware proper. I just have no way of linking against it in my .mpy.
On that note, I went ahead and implemented my code as an "extmod", despite the drawbacks I mentioned in my original post. This went much more smoothly. I can communicate with a Notecard over I2C as with the natmod approach, and I can pull in all of note-c without running out of memory. I don't have to manually add in any .o files from libc.a or libgcc.a. I also don't have to modify the note-c source code at all; with the natmod approach, I had to move everything that would typically wind up in .data sections to .bss and initialize the relevant variables at runtime instead of compile-time (a limitation that's noted in the docs). So that's all great, but it's probably untenable for our use case to distribute a bunch of different MicroPython firmware binaries for many combinations of MicroPython version and target hardware. Asking our users to build MicroPython from source is also a non-starter, due to complexity of that process.
I saw that PR while I was researching. It seems like a potentially good middle ground between the two approaches I've tried so far. I do think that, even with this approach, I'd be duplicating a bunch of libc and libgcc code in my .mpy, which is unfortunate, but it might be unavoidable. |
Beta Was this translation helpful? Give feedback.
-
@haydenroche5 Andrew is right that #8381 would be very useful unfortunately this does not support native code in .mpy files, only bytecode. The problem is relocation. In theory it is possible to generate truly position-independent code (where references to both code and data are PI). i.e. it's more than just using The problem was, I'm not sure this mode of code generation is possible for non-ARM targets like esp32/xtensa. (But maybe that's changed since we last looked at this) See also: And also, like you say, this doesn't solve the duplication of e.g. the floating point routines... |
Beta Was this translation helpful? Give feedback.
-
Hi,
I'm one of the main developers of note-python, a Python library for communicating with a Blues Notecard. note-python supports regular old CPython, MicroPython, and CircuitPython. We have an analogous library written in C, note-c.
At this moment, note-python and note-c are completely separate projects. When we implement a feature in note-c, we eventually come around and implement it in note-python. For awhile, we've wanted to be able to consume note-c in note-python such that when we add a feature to note-c, we get it (mostly) for free in note-python. This isn't terribly difficult in the CPython case via CFFI.
I've been hacking on a PoC of this approach for MicroPython. One major advantage of note-python as it exists now is that it doesn't require the user to rebuild and flash new MicroPython firmware onto their target. The user can simply copy note-python over to the target's filesystem and begin using it. In order to retain as much of this convenience as possible, I went down the "natmod" path. This approach will require us to distribute architecture-specific .mpy files for note-python, but it won't require a rebuild and reflash of MicroPython firmware. So far, I've managed to communicate with a Notecard over I2C using note-c in the resulting .mpy file, which is great. However, as I've begun to pull in more note-c functionality, the .mpy file has grown, and now when I attempt to import it, I'm running out of RAM for the code (i.e.
MemoryError: memory allocation failed, allocating 24920 bytes
).So that got me thinking, is there a way to get this code into the flash storage of the target instead? There's the "extmod" approach, but if we go that route, we'll have to get our users to build and flash new MicroPython firmware to use note-python, which is a potential dealbreaker.
I've seen several GH issues and some MicroPython forums archive posts over the years discussing this topic, but, from what I can tell, there's no way to do what I'm trying to do, yet (i.e. execute a natmod .mpy from flash).
I would love any thoughts on how I might approach this problem.
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions