Goals Accomplished


Technical Approach


Running WAMR on Zephyr OS.

First, we got familiar with compiling applications for embedded systems. Getting a Blinky project running on Zephyr took the most time. We were inexperienced with interacting so closely with build tools and most installed software needed to be adjusted to work. All this was further complicated by the fact that the latest version of CMake was buggy (zephyr#30232). However, Zephyr developers in their Slack channel helped us out.

WAMR already supports Zephyr OS and it has a mini-product available too. We had a Nordic nRF52840 DK board available, and so we decided to run WAMR on it. The mini-product is a sample program that sets-up the WAMR runtime, calls its main function and exits. Setting up a running baseline made us understand these key concepts about WAMR:


Compiling to WASM Modules

Once we had the WASM program provided with WAMR running on Zephyr, we wanted to run our own WASM programs. We learned that WASI-SDK comes with a CLang compiler that can produce WASM bytecode from C programs. Also, appropriate flags were needed to be set so that the linker does not complain of missing main() when it is not needed, and also to export other functions. There exported functions have their definition missing from the WASM module. WAMR runtime can link functions from the native program to these exported functions. This allows the WASM program to call any needed native functions to, for example, blink an LED.


Porting WAMR to Mbed


Comparing Different WASM Interpreters

With WAMR interpreter now available on Mbed devices, we wrote a recursive Fibonacci function for all the boards we had:

WASM3 supports Arduino Nano 33 and is available to use through Arduino IDE. However, it only consists of an interpreter, while our WAMR porting to Mbed can be extended to allow WAMR JIT, WAMR AoT, and WAMR's libraries are also available on targets supported by Mbed.

Results


The forks of WAMR and Mbed-CMake with commits to make the porting work are described in our Github repo's README. Scripts to aid in the development process are also available.

The builds/ folder in the repo contains two binaries with WAMR. Both of them were successfully compiled using our build system for Mbed and WAMR. Both are built from the same native and WASM program, but are target to two different boards: STM32 Nucleo and Arduino Nano 33.

We were able to verify implementation by running it on a STM32 Nucleo board. Results and details are added in the Github repo. Since the STM32 Nucleo board is Mbed-enabled, we were able to run our binary without worrying about the bootloader. The output demonstrated that WAMR is now running on the Mbed device using Mbed's libraries.

› See output from provided mini-product for Mbed

stm32_mbed_wamr.cpp set up WAMR to run WASM module of fib_timed.c on a STM32F411 Nucleo board.

Performance Comparison


We used the benchmark of measuring the execution time of computing 24th Fibonacci number recursively. This computation when performed by any WASM interpreter was much slower when compared to native. This was expected. However, it was surprising that WAMR had little overhead to set up, and most of the extra time taken was while doing the computation.

› Execution time of WASM interpreter on various boards

WASM3 claims to be the fastest WASM interpreter. We could not run WASM3 and WAMR on the same board and directly compare them, as WASM3 is not supported on SMT32 Nucleo board and we could not flash to Arduino Nano 33 without using Arduino IDE. However, we indirectly attempted to compare WASM3 with WAMR, by measuring how many times slower was the interpreter in doing its computation as compared to natively calculating it. WASM3 indeed slowed down less as compared to WAMR. However, WASM3 is only an interpreter, while WAMR AoT support can be implemented for Mbed which should be faster than WASM3.

› How slow are WAMR and WASM3 compared to native?

Strengths and Possible Improvements


Strengths:

Possible Improvements:

Existing Literature on WAMR


WebAssembly's popularity has increased and with that so has the research into other applications of the binary instruction format. Despite its benefits, WebAssembly has been shown to be 45% slower than its native commponent [1] .

This project invokes WAMR, but other run-times also exist. WASI has been created to be the run time that accesses and executes systems calls [2] . Work such as the IoT OS, Wasmachine has been created to be "a secure runtime/OS aiming to run WebAssembly applications faster than bare-metal machine" [2] .

While beneficial in terms of timing using its ahead-of-time approach, it could be some time before Wasmachine could be deployed. In additional research work has been made by the partnership of Mozill, Red Hat, Intel, and Fastly. Together, the Bytecode Alliance, has made progress in areas of code generation, run-time, and micro-runtime. Their work with the WebAssembly MicroRuntime (WAMR) has been created for Linux, macOS, Zephyr, AliOS Things, and VxWorks and has support for x86_32, x86_64, Arm, and MIPS [3] . Like Wasmachine, it uses an AOT approach to improve speed. This project's work uses the WAMR Porting Guide to port WAMR to a non-supported platform, Mbed OS.

Team Members and Contributions


Thanks a lot to Botong Ou for answering so many of our questions about working with WAMR and Zephyr.