micropython icon indicating copy to clipboard operation
micropython copied to clipboard

microbit: Enable loading of .mpy files.

Open dpgeorge opened this issue 6 years ago • 2 comments

This allows to load .mpy files from the filesystem on the micro:bit.

With this commit code size is increased by about 1k bytes. Heap usage is similar to before this commit: on a test suite of large example programs, those that could run before can still run, and those that couldn't run still can't run. But all those that couldn't run before can now run if they are precompiled to a .mpy.

dpgeorge avatar Oct 12 '18 07:10 dpgeorge

Note that this will execute upon boot a main.mpy file if it finds that (but main.py takes preference over main.mpy, and main.mpy over any appended script).

To compile .py to .mpy requires v1.9.2 of mpy-cross, which can be build from the upstream repository by checking out v1.9.2 of that repo. The icing on the cake would be to provide an in-browser version of mpy-cross built with Emscripten, so users can compile .py to .mpy via their browser. But that is a fair bit of extra work.

dpgeorge avatar Oct 12 '18 07:10 dpgeorge

@dpgeorge - in my fork of this bbcmicrobit/micropython repo, I've rebased this PR onto the current tip of master and compiled the new runtime to include mpy support. I've also built v1.9.2 of mpy-cross as noted above and converted our modules for testing.

All works well (thank you so much!) except using the new mpy-capable runtime with two .py modules (not their .mpy form) in the filesystem causes an error: RuntimeError: maximum recursion depth exceeded.

I've boiled the problem down to the simplest code I could: 7 statements total across 3 scripts/modules. Everything is available in our release post and explained below.

userscript.py

import ref

ref.py (module)

import mod

mod.py (module)

from microbit import i2c
i2c.read(93,1)
class nada():
	def nothing():
		sleep(1)

The above causes (upon entering REPL):

soft reboot
Traceback (most recent call last):
  File "__main__", line 1, in <module>
  File "ref.py", line 1, in <module>
  File "mod.py", line 3, in <module>
 RuntimeError: maximum recursion depth exceeded
MicroPython v1.9.2-34-gd64154c73 on 2017-09-01; micro:bit v1.0.1 with nRF51822

The same code does not cause errors when one or both of ref and mod are converted to .mpy.

The same code does not cause errors when using a MicroPython binary without support for .mpy modules (ie: the tip of master: a92ca9b).

If you import mod (instead of ref) from userscript (ie: only 1 module in the chain), no error occurs.

If you use all 3 (as given above) but simply remove i2c.read(93,1) from mod.py, no error occurs.

If you use all 3 (as given above) but simply remove

class nada():
	def nothing():
		sleep(1)

from mod.py, no error occurs.

PropGit avatar Sep 03 '19 20:09 PropGit