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 | esp8266[^2] | esp32 | rv32imc |
---|---|---|---|---|---|---|
๐ TypeScript^1 | โ โ | โ | โ โ โ | โ ๏ธ[^4] | โ | โ |
๐คฉ C++ | โ โ | โ | โ โ โ | ๐ก | โ | โ |
๐ฆ Rust | โ โ | โ | ๐ก๐กโ | โ ๏ธ[^4] | โ | โ |
๐ค TinyGo | โ โ | โ | ๐ก๐กโ | โ ๏ธ[^4] | โ | โ |
โก Zig | โ โ | โ | โ โ โ | โ ๏ธ[^4] | โ | โ |
โจ Virgil | โ โ | โ | โ โ โ | ๐ก | โ | โ |
โ WAT | โ โ | โ | โ โ โ | ๐ก | โ | โ |
๐จ Coremark | โ โ | ๐ง | โ โ โ | ๐ก | โ | โ |
โ builds and runs OK ๐ก builds OK, doesn't run ๐ง work in progress
[^2]: esp8266
requires the use of esp.set_native_code_location
, and setting WASM_PAGE_SIZE
to 8192
(or need to wait for WASM Custom Page Sizes
)
[^4]: not enough memory to run, need to wait for WASM Custom Page Sizes
179.791
233.918
228.363
271.573
344.293
1911.437
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++ world
The idea is very similar to embedded-wasm-apps:
.a
inputs for mpy_ld
u32
instead of u64
for mem addresses.bss
section as memory (skip indirection)