How does Micropython work? #16818
Replies: 7 comments 8 replies
-
MicroPython does not copy the whole boot.py / main.py script into RAM before executing it. The script is interpreted line by line . It runs directly from storage, using MicroPython's interpreter to execute each command as needed. When you execute import ujson, MicroPython checks if ujson is a built-in module. If ujson is built into the firmware, it does not get copied to RAM. The functions and code are executed directly from Flash. For more information and some project ideas, you can visit the following links. |
Beta Was this translation helpful? Give feedback.
-
To add to this, Python code that is resident in Flash is stored in compiled form as MicroPython bytecode. Consequently it is executed without invoking the compiler: only the bytecode interpreter is required. If an external library is imported, and that library exists as Python source, the compiler converts this to bytecode which is stored in RAM. A library can be precompiled to bytecode, enabling the on-device compilation stage to be skipped. The above is slightly simplified and does not describe the case where |
Beta Was this translation helpful? Give feedback.
-
The MP firmware itself stays mostly in flash for most ports and is virtually executed there. Only some time critical functions or otherwise critical functions are copied to RAM. This amount of code permanently copied to RAM varies with the amount of RAM available for this optimization. The code address space is usually virtual and mirrored by cache RAM. Code is fetched from a serial flash to the cache when needed. That is a fully transparent hardware mechanism which only gets "visible" through the short delays needed to fill the cache. Only the CC3200 port copies the whole firmware to RAM. |
Beta Was this translation helpful? Give feedback.
-
Thank you all for taking the time to respond - very appreciated. So is the only thing that is extracted (??) from the firmware image and placed into RAM, the bytecode interpreter, in order to meet certain time critical events? Or does this run from Flash as well? I think this also answers another question I had, to do with the term 'frozen code' that I have seen. To reduce RAM usage as much as possible, all libraries are compiled as MP bytecode as part of a single firmware image and so don't need to be occupy valuable RAM space. Then the code is interpreted line by line in boot.py/main.py whilst they reside in Flash. Variables, objects, pointers etc are all created in RAM as a result of the interpreted code? Is there some reading I can do on this subject to avoid taking people's valuable time? I think once I understand the low level mechanics I will feel much more confident in the usage. |
Beta Was this translation helpful? Give feedback.
-
The bytecode interpreter runs for most ports from flash. That one is not very time critical. It's more code like the Interrupt service functions, fast timers, and flash write/erase functions that are executed in RAM.
What resides in flash as frozen bytecode is compiled code, not the source code. Independent from the firmware and frozen bytecode there is Python source code like main.py/boot.py, which resides in a file system and is loaded to RAM, compiled to bytecode, bytecode placed in RAM and executed when needed. The file system may be placed in the same flash device as the firmware, or a separate flash device. That's up to the board hardware. Source code can as well be injected by entering it at the REPL prompt line by line or pasting. Then the source code is temporary stored in RAM. |
Beta Was this translation helpful? Give feedback.
-
I had no idea that so much could be 'run from Flash' - that's very clever. I thought it would be so slow over a serial link (albeit a fast QSPI bus) I think I am pretty much there now - some really clear and succinct answers - thank you so much to the forum experts. For the source code compiling part, is the whole of the source code copied into RAM for compiling into bytecode and subsequent interpretation? So ultimately, the interpreter runs from Flash, but the main program bytecode is in RAM? And I think frozen code means that everything is already compiled into one image - MP, libraries and source code? |
Beta Was this translation helpful? Give feedback.
-
No. As far as I understand, only as much as is needed to compile the actual Python structure is copied to RAM and fed into the parser+compiler, which create bytecode. Bytecode may reside in RAM or as frozen bytecode in flash. You can imagine that as a stream of Python source code flowing into the parse/compile machine, which emits bytecode. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi. I am unclear what happens when an MCU boots - the MP firmware is accessed in non-volatile storage by the bootloader. What happens next? Does the whole firmware image get used to 'create' MP in RAM? Or does only a minimal subset of code run in RAM? Is boot.py and main.py copied into RAM and run or is it interpreted from where it sits in storage?
When there is a command such as 'import ujson' in main.py , (as an example), does this copy this library from the firmware image into RAM in order to support the interpretation of the MP code that follows?
Believe it or not I have been using MP for many years now and have enjoyed writing many useful programs but some of these lower level mechanics have remained a mystery to me and I would like to close this gap in my knowledge now. I have an electronics and hardware background so the software side of things does not come as naturally.
I have tried to find answers to these questions before posting, so please go easy on me. Thank you in advance.
Beta Was this translation helpful? Give feedback.
All reactions