Building Your First WASM App
Create, build, and deploy a “Hello World” WebAssembly application on AkiraOS.
Prerequisites
- AkiraOS firmware flashed and running on a device (or
native_simbuilt) - WASI SDK installed (see below)
- Basic C programming knowledge
Install WASI SDK
WASI_VERSION=24
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_VERSION}/wasi-sdk-${WASI_VERSION}.0-x86_64-linux.tar.gz
sudo tar xvf wasi-sdk-${WASI_VERSION}.0-x86_64-linux.tar.gz -C /opt
sudo ln -sf /opt/wasi-sdk-${WASI_VERSION}.0 /opt/wasi-sdk
Note: Install to
/opt/wasi-sdk(the default path all sample Makefiles expect) or setWASI_SDK=/your/path.
Hello World App
The AkiraSDK/ submodule contains ready-to-build sample apps in AkiraSDK/wasm_apps/. The fastest way to get started is to copy an existing app as a template.
Step 1: Create your project
cp -r ~/akira-workspace/AkiraOS/AkiraSDK/wasm_apps/hello_world ~/my_hello_world
cd ~/my_hello_world
Step 2: Write the code
Apps include a single header — all APIs are declared there:
main.c:
#include "akira_api.h"
int main(void) {
printf("Hello from AkiraOS WASM!");
display_clear(COLOR_BLACK);
display_text(10, 10, "Hello AkiraOS!", COLOR_WHITE);
display_flush();
while (1) {
delay(1000000); // idle — yield every 1 second
}
return 0;
}
Key rules:
- Use
printf()fromakira_api.h— do not include<stdio.h>- All API functions are
extern— they are provided by AkiraOS at runtime, not linked from a library- Always call
display_flush()after drawing, or the screen stays blank- Always
delay()in your loop — spinning without yielding burns 100% CPU
Step 3: Create the manifest
manifest.json:
{
"name": "hello_world",
"version": "1.0.0",
"capabilities": ["display.write"],
"memory_quota": 65536
}
The manifest is automatically embedded into the .wasm binary by embed_manifest.py (called by the Makefile).
Step 4: Build
# Using the SDK build script (recommended)
cd ~/akira-workspace/AkiraOS/AkiraSDK/wasm_apps
./build.sh hello_world # single app → bin/hello_world.wasm
./build.sh # all apps
# Or with Make directly from your app directory
cd ~/my_hello_world
make
Verify the output:
ls -lh bin/hello_world.wasm # should be ~2–5 KB
file bin/hello_world.wasm # "WebAssembly (wasm) binary module"
Deploy to Hardware
Upload via HTTP (recommended)
The device must be connected to WiFi. Find its IP from the serial console (net iface).
curl -X POST -F "file=@bin/hello_world.wasm" http://<device-ip>/upload
Run from the shell
# Connect to serial console
west espmonitor
# In the shell:
AkiraOS:~$ wasm load /apps/hello_world.wasm
AkiraOS:~$ wasm start hello_world
Expected output:
[00:00:10.523] <inf> wasm: Loading: /apps/hello_world.wasm
[00:00:10.687] <inf> wasm: App loaded: hello_world
[00:00:10.692] <inf> app: Hello from AkiraOS WASM!
Next Steps
Read a sensor
#include "akira_api.h"
int main(void) {
int raw = sensor_read(SENSOR_CHAN_AMBIENT_TEMP);
if (raw == AKIRA_SENSOR_ERROR) {
printf("sensor unavailable");
} else {
// raw = 23500 → 23.5 °C; divide by 1000 for whole degrees
printf("Temp: %d.%d C", raw / 1000, (raw % 1000) / 100);
}
return 0;
}
Capability required: "sensor.read"
Read a GPIO input
#include "akira_api.h"
#define BTN_PIN 0 // adjust to your hardware
int main(void) {
gpio_configure(BTN_PIN, GPIO_INPUT | GPIO_PULL_DOWN);
while (1) {
if (gpio_read(BTN_PIN) == 1) {
printf("button pressed!");
}
delay(10000); // poll every 10 ms
}
return 0;
}
Capability required: "gpio.read"
Write to persistent storage
#include "akira_api.h"
int main(void) {
int fd = storage_open("message.txt", STORAGE_O_WRITE);
if (fd >= 0) {
storage_write(fd, "Hello, filesystem!", 18);
storage_close(fd);
printf("saved");
}
return 0;
}
Capability required: "storage.write"
Troubleshooting
“Failed to load WASM” — check the file exists:
AkiraOS:~$ fs ls /apps
“capability denied” — add the required capability to manifest.json:
{ "capabilities": ["display.write", "sensor.read"] }
“Out of memory” — increase the quota in manifest.json:
{ "memory_quota": 131072 }
Screen stays black — you forgot display_flush() after your draw calls.
Function not found at build time — do not include <stdio.h> or other stdlib headers. All functions come from akira_api.h.
Related Documentation
- SDK API Reference — every function with examples
- Best Practices — main loop patterns, memory, display
- Manifest Format — capability specification
- Building Apps — AOT compilation and advanced topics