Home

Awesome

<img height="48px" src="/logo.png"> wasm2mpy

StandWithUkraine Build status GitHub license Support vshymanskyy

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.

Status

App \ Targetx86/x64armv6marmv7m/+s/+desp82661esp32rv32imc
๐Ÿš€ TypeScript2โœ…โœ…โœ…โœ…โœ…โœ…โš ๏ธ3โœ…โœ…
๐Ÿคฉ C++โœ…โœ…โœ…โœ…โœ…โœ…๐ŸŸกโœ…โœ…
๐Ÿฆ€ Rustโœ…โœ…โœ…๐ŸŸก๐ŸŸกโœ…โš ๏ธ3โœ…โœ…
๐Ÿค– TinyGoโœ…โœ…โœ…๐ŸŸก๐ŸŸกโœ…โš ๏ธ3โœ…โœ…
โšก Zigโœ…โœ…โœ…โœ…โœ…โœ…โš ๏ธ3โœ…โœ…
โœจ Virgilโœ…โœ…โœ…โœ…โœ…โœ…๐ŸŸกโœ…โœ…
โš™ WATโœ…โœ…โœ…โœ…โœ…โœ…๐ŸŸกโœ…โœ…
๐Ÿ‡จ Coremarkโœ…โœ…๐Ÿšงโœ…โœ…โœ…๐ŸŸกโœ…โœ…

โœ… builds and runs OK
๐ŸŸก builds OK, doesn't run
๐Ÿšง work in progress

CoreMark results

Upload and Run

Follow the build instructions

mpremote cp zig.mpy :lib/
mpremote exec "import zig; zig.setup()"
โšก Zig is running!

Run any exported function

[!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

Access WASM module memory

>>> 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

How It Works?

The idea is very similar to embedded-wasm-apps:

image

TODO

Further reading

Footnotes

  1. 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) โ†ฉ

  2. AssemblyScript โ†ฉ

  3. not enough memory to run, need to wait for WASM Custom Page Sizes โ†ฉ โ†ฉ2 โ†ฉ3 โ†ฉ4