a653lib is an ARINC 653 scheduler
library for Linux (POSIX-based). It supports both native partition execution (compiled C
binaries) and WebAssembly partition execution via the
WAMR and
Wasmtime runtimes.
- ARINC 653 compliant process/partition scheduling on Linux
- Inter-partition communication via ARINC 653 ports (sampling & queuing)
- Native partition execution via POSIX fork
- WebAssembly partition execution via WAMR or Wasmtime (sandboxed, portable)
When built with -DA653LIB_BUILD_WASM=ON, the project compiles additional targets:
| Target | Description |
|---|---|
p_wamr |
Partition launcher using WAMR (libiwasm) |
p_wasmtime |
Partition launcher using Wasmtime (C API) |
*_wasm |
Per-partition .wasm guest binaries (wasm32-wasip1) |
The host ARINC 653 functions (sampling/queuing ports, processes, time, semaphores, etc.) are exposed to the Wasm module via the runtime's import mechanism.
Because the Wasm guest may run as a 32-bit module on a 64-bit host, and because
both little-endian and big-endian architectures must be supported, struct layout
and alignment cannot be assumed to match between guest and host. To handle this
correctly, accessor getters/setters are generated by
c-abi-lens directly from the
ARINC 653 headers;
the Wasm APEX host functions use these accessors internally when marshalling
data across the guest/host boundary.
This code demonstrates that WAMR and Wasmtime can support ARINC 653 APEX interfaces as host functions. The proof-of-concept also targets correctness on both little-endian and big-endian architectures (such as PowerPC, still represented in avionics).
Notable: This is believed to be the first implementation of ARINC 653 APEX interfaces as WebAssembly host functions that runs on two independent runtimes (WAMR and Wasmtime). This satisfies the key advancement criterion of the WebAssembly W3C standardization process, which requires "two or more Web VMs have implemented the feature" to progress a proposal to Phase 4 (standardization). While this implementation cannot be fully WASI-compliant due to the inherent incompatibilities between the APEX interface conventions and the WebAssembly standard (see APEX / WebAssembly Compliance Caveats), it fulfils the spirit of the dual-runtime portability requirement that underpins the WASI standardization track.
graph TD
subgraph scheduler["a653lib Scheduler (process)"]
subgraph partitions["Partitions"]
PA["Partition A\n(.wasm instance / POSIX fork)"]
PB["Partition B\n(.wasm instance / POSIX fork)"]
end
ports["ARINC 653 Port Layer\n(sampling & queuing ports)"]
PA <-.->|"APEX (native mode)"| ports
PB <-.->|"APEX (native mode)"| ports
subgraph runtimes["Wasm Runtimes (A653LIB_BUILD_WASM=ON)"]
WAMR["WAMR (p_wamr)"]
WT["Wasmtime (p_wasmtime)"]
end
PA <-->|"APEX 'WIT' (Wasm mode)"| runtimes
PB <-->|"APEX 'WIT' (Wasm mode)"| runtimes
runtimes <-->|"APEX host functions"| ports
end
scheduler --> posix["POSIX / Linux"]
In native mode, partitions run as forked POSIX processes. In Wasm mode, each
partition is instantiated as a Wasm module inside the launcher (p_wamr or
p_wasmtime), with ARINC 653 host functions injected via the runtime's import API.
The WebAssembly specification states that functions take a sequence of values as parameters and return a sequence of values as results, and that host functions are expressed outside WebAssembly but passed to a module as an import.
There are a few reasons why ARINC 653 APEX interfaces cannot be 100% compliant with the WebAssembly standard:
- WIT bindgen incompatibility — APEX interfaces defined in WIT will not
generate the proper standardised APEX function signatures via
wit-bindgen. The APEX interface is therefore exposed as a plain C header that Wasm guest sources compile against directly. - Function pointers —
CREATE_PROCESS()andCREATE_ERROR_HANDLER()pass aSYSTEM_ADDRESS_TYPEfunction pointer, which cannot comply with the WebAssembly standard. - Output via pointer parameters — Wasm specifies that return values are passed through a function's return; APEX interfaces instead use plain pointers as output parameters.
As long as C, C++, and Ada remain the primary partition languages, none of the above pose a practical concern.
Tested on ArchLinux, Ubuntu (see CI), and RHEL7 (native mode only). Expected to work on any Linux 64-bit host.
| Mode | OS | Notes |
|---|---|---|
| Native | Linux 32/64 | POSIX, C99 |
| Wasm (WAMR) | Linux 64 | Requires libiwasm |
| Wasm (Wasmtime) | Linux 64 | Requires Wasmtime C API |
- CMake ≥ 3.23, C99 compiler (GCC or Clang)
awk,sed(for ARINC header processing)- ARINC 653 header archive (auto-downloaded from AEEC, or supplied via
-DARINC653_ZIP=<path>for offline/Nix builds)
wasi-sysroot— set via-DWASI_SYSROOT=(default:/usr/share/wasi-sysroot)clangwithwasm32-wasip1target — set via-DWASM_CLANG=- WAMR launcher:
libiwasm— auto-detected, or set via-DIWASM_LIBRARY= - Wasmtime launcher:
libwasmtime— auto-detected, or set via-DWASMTIME_LIBRARY= - c-abi-lens (Rust/Cargo) — auto-fetched and built, or supply a prebuilt
binary via
-DC_ABI_LENS_EXECUTABLE=; disable auto-fetch with-DA653LIB_FETCH_C_ABI_LENS=OFF
yay -S clang lld wasi-libc wasi-compiler-rt libwasmtime iwasmNote: The
iwasmAUR PKGBUILD must be patched to not strip the static library. See the iwasm AUR package.
Install base dependencies:
sudo apt-get update
sudo apt-get install -y curl cmake cargo clang llvm libclang-dev gawkInstall WAMR (libiwasm) from source (WAMR-2.4.4):
git clone https://github.com/bytecodealliance/wasm-micro-runtime.git ~/wasm-micro-runtime
cd ~/wasm-micro-runtime && git checkout WAMR-2.4.4
mkdir build && cd build
cmake .. \
-DWAMR_BUILD_LIBC_BUILTIN=1 \
-DWAMR_BUILD_LIBC_WASI=1 \
-DWAMR_BUILD_SHARED_MEMORY=1 \
-DCMAKE_BUILD_TYPE=Release
make && sudo make installInstall Wasmtime C API (v45.0.0):
curl -L https://github.com/bytecodealliance/wasmtime/releases/download/v45.0.0/wasmtime-v45.0.0-x86_64-linux-c-api.tar.xz \
-o wasmtime-c-api.tar.xz
tar -xf wasmtime-c-api.tar.xz
cd wasmtime-v45.0.0-x86_64-linux-c-api
sudo cp -a include/. /usr/local/include/
sudo cp -a lib/. /usr/local/lib/
sudo ldconfigInstall wasi-sdk (sdk-33):
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-33/wasi-sdk-33.0-x86_64-linux.deb \
-o wasi-sdk.deb
sudo dpkg -i wasi-sdk.debThe sysroot will be at /opt/wasi-sdk/share/wasi-sysroot.
cmake -S . -B build
cmake --build buildThe following files will be present in the build/ directory:
a653lib_mainliba653lib.aliba653lib_partition_init.aMakefilepartition_apartition_b- ...
cmake -S . -B build-wasm \
-DA653LIB_BUILD_WASM=ON \
-DWASI_SYSROOT=/opt/wasi-sdk/share/wasi-sysroot \
-DWASM_CLANG=/opt/wasi-sdk/bin/clang
cmake --build build-wasm
cmake --build build-wasm --target wasm # builds p_wamr, p_wasmtime + .wasm guests| Option | Default | Description |
|---|---|---|
A653LIB_BUILD_WASM |
OFF |
Enable Wasm guest and launcher targets |
A653LIB_FETCH_C_ABI_LENS |
ON |
Auto-clone and build c-abi-lens |
WASI_SYSROOT |
/usr/share/wasi-sysroot |
WASI sysroot for guest compilation |
WASM_CLANG |
clang |
Clang used for wasm32-wasip1 guest compilation |
IWASM_LIBRARY |
(auto-detected) | Path to libiwasm.a or shared lib |
WASMTIME_LIBRARY |
(auto-detected) | Path to libwasmtime |
C_ABI_LENS_EXECUTABLE |
(built from source) | Path to a prebuilt c-abi-lens binary |
ARINC653_ZIP |
(downloaded) | Path to a pre-fetched arinc653.h.zip |
./build/a653lib_mainthis will generate the following output:
pid: 578773 <1702486050.317812578>: Current local time and date: Wed Dec 13 17:47:30 2023
pid: 578773 <1702486050.318212993>: a653_shm id: 0x63801e ptr: 0x7f5e57802000
pid: 578773 <1702486050.318233554>: > taskset --cpu-list 0 ./partition_a & :
pid: 578773 <1702486050.349241033>: a653 start (other pid) 578775
pid: 578773 <1702486050.349254883>: > taskset --cpu-list 1 ./partition_b & :
cd ./build-wasm
ln -sf p_wamr wasm32_rt
./a653_main_wasmcd ./build-wasm
ln -sf p_wasmtime wasm32_rt
./a653_main_wasmThe build produces a bin/ directory. Switch the wasm32_rt symlink between
p_wamr and p_wasmtime to select the WebAssembly runtime.
- Not all APEX functions are implemented; the demonstration covers partitions with processes using sampling and queuing ports. Unimplemented functions are stubbed as empty and will be added incrementally as needed.
- Linux only (no bare-metal or RTOS support)
- WebAssembly mode requires a 64-bit host (little-endian or big-endian)
- Ensure Wasm is also handled through NixOS CI builds
- Improve threading model — see dev/add-wasm-apex-proc-alloc
See CONTRIBUTING.md.
SPDX-License-Identifier: Apache-2.0 OR MIT
See LICENSE.