wasm2mpy enables developers to write code in statically compiled languages and run it on MicroPython-based embedded systems (such as ESP32, Raspberry Pi Pico, STM32, and nRF52) with near-native performance. Since MicroPython is relatively slow for computationally intensive applications, wasm2mpy provides the tools necessary to run demanding software, such as AI models and signal processing algorithms, more efficiently.
| App \ Target | x86/x64 | armv6m | armv7m/+s/+d | esp82661 | esp32 | rv32imc |
|---|---|---|---|---|---|---|
| π TypeScript2 | β β | β | β β β | β | β | |
| π€© C++ | β β | β | β β β | π‘ | β | β |
| π¦ Rust | β β | β | π‘π‘β | β | β | |
| π€ TinyGo | β β | β | π‘π‘β | β | β | |
| β‘ Zig | β β | β | β β β | β | β | |
| β¨ Virgil | β β | β | β β β | π‘ | β | β |
| β WAT | β β | β | β β β | π‘ | β | β |
| π¨ Coremark | β β | π§ | β β β | π‘ | β | β |
β
builds and runs OK
π‘ builds OK, doesn't run
π§ work in progress
- ESP32-C3 160MHz:
179.791 - STM32F405 168MHz:
233.918 - ESP32 240MHz:
228.363 - ESP32-S3 240MHz:
271.573 - BL616 320MHz:
344.293 - iMXRT1062 600MHz:
1911.437 - i5-8250U 1.6GHz:
18696.248
Follow the build instructions
mpremote cp zig.mpy :lib/
mpremote exec "import zig; zig.setup()"
β‘ Zig is running!Note
This requires adding some glue code to the runtime.
Glue code can be auto-generated, but for now it's a manual process.
For example, test/simple.wasm just adds 2 numbers:
(module
(func (export "add") (param i32 i32) (result i32)
(i32.add (local.get 0) (local.get 1))
)
)MicroPython v1.24.0-preview.224.g6c3dc0c0b on 2024-08-22; Raspberry Pi Pico W with RP2040
Type "help()" for more information.
>>> import simple
>>> simple.add(3, 4)
7
>>> simple.add(10, 6)
16
>>> import cpp
>>> cpp.setup()
π€© C++ is running!
>>> cpp._memory[4096:4096+32]
bytearray(b' Blink\x00\xf0\x9f\xa4\xa9 C++ is running!\x00\n\x00\x00\x00')
>>> new_data = b"Hello C++ world"
>>> cpp._memory[4096+12:4096+12+len(new_data)] = new_data
>>> cpp.setup()
π€© Hello C++ worldThe idea is very similar to embedded-wasm-apps:
- Support exports
- Auto-generate exports bindings
- Support imports
- Support memory
- Support
.ainputs formpy_ld - XIP for native modules
- TBD: Support globals
- Add RISC-V support: micropython/micropython#15603
- Optimize codegen
- Use
u32instead ofu64for mem addresses - Use a directly addressable
.bsssection as memory (skip indirection)
- Use
- Implement WASM Custom Page Sizes
- Implement WASM Exceptions
- Implement WASM Stack Switching
- Discussions: GitHub, Hacker News
- wasm2c, w2c2
- MicroPython Native Modules
- Feasibility of WASM for MicroPython
Footnotes
-
esp8266requires the use ofesp.set_native_code_location, and settingWASM_PAGE_SIZEto8192(or need to wait forWASM Custom Page Sizes) β© -
not enough memory to run, need to wait for
WASM Custom Page Sizesβ© β©2 β©3 β©4