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

