,

WebAssembly on Zephyr

Golioth’s own Dan Mangum presented a talk at this year’s Embedded Open Source Summit detailing how to use WebAssembly with Zephyr RTOS. For those unfamiliar with WebAssembly, it was conceived as a replacement for JavaScript. So what is it doing in microcontrollers? Dan takes on that question, and covers how to validate whether Wasm on Zephyr is a viable solution for you.

What is WebAssembly?

WebAssembly–aka Wasm–is a portable binary format that can be executed on myriad different systems and architectures. Platforms that support Wasm have a runtime that makes execution possible and this is the case for Zephyr.

The WebAssembly Micro Runtime (wamr for those in the know) already has a Zephyr port that you can try out right now. Wamr delivers a runtime optimized for embedded systems that sandboxes the the Wasm code it is running.

Just build the runtime into your firmware, then supply a new Wasm binary whenever you want to change how that part of the application works. You now have a way to update programs in a safe way without a full firmware update and even without rebooting the hardware.

Why Use Wasm with Zephyr (or any embedded system)?

Dan spends the first half of his talk discussing the criteria used to evaluate tradeoffs in play with WebAssembly. You’re always going to use more resources and take a speed hit compared to native code, that’s no surprise. But especially in cases where dynamic code execution is needed, Wasm checks a lot of boxes like portability and security.

The demonstration implements a temperature threshold mechanism that triggers an alert when readings rise above a certain level. This is basically a hello-world example that shows how native firmware can pass a primitive value into the runtime, and the Wasm code can call native functions (a high-temperature alert log message).

But the secret sauce is the the Wasm binary itself. You could implement a complex algorithmic processing and change that algorithm without a full OTA firmware update. In fact, Dan’s just passing the Wasm binary as a base64-encoded string and restarting the runtime without rebooting the microcontroller. This is done using the Golioth Settings service so it’s available to the entire fleet, but targetable by device or groups of devices.

However, this real time update ability is not the only trick Wasm can pull off.

The Portability of WebAssembly

Sure, it’s very cool to be able to perform a bit of brain surgery on your firmware by loading a new Wasm binary. What boggles the mind is the ability to run that binary on just about any platform imaginable.

A typical IoT installation that uses Golioth has embedded devices in the field, a server with which those devices interact (authentication, data routing, control, etc), and a cloud component to use the data and issue directives to the fleet. Your Wasm binary can be moved and executed on a different part of this system depending on need. While the demo is first run on a Nordic nRF52840 microcontroller, the same binary is shown running on the cloud, and inside of a browser.

Whether during initial development, or to meet changing device constraints or customer needs, sliding the compute from one place to another without major engineering work is a pretty interesting tool to have in your arsenal.

A Wasm Deep Dive

The proof of concept is already there for you to build your own Zephyr-based Wasm experiments. We hope you’ll give Golioth a try for deploying the binary updates to your devices.

For those who want to deeper dive into the world of WebAssembly, Dan’s been busy in that area. Checkout out his post on Understanding Every Byte in a WASM Module.

Talk with an Expert

Implementing an IoT project takes a team of people, and we want to help out as part of your team. If you want to troubleshoot a current problem or talk through a new project idea, we're here for you.

Start the discussion at forum.golioth.io