Matter/Thread Feasibility Spike — ESP32-C6

Duration: 2 weeks Target: ESP32-C6 (IEEE 802.15.4 + BLE 5.3 combo SoC) Date: 2026-06-11 Decision: Implemented — co-processor IPC bridge shipped in v1.6


Objective

Determine whether AkiraOS can act as the application OS while running Matter (over Thread) on the same ESP32-C6, and expose a WASM bridge API so AkiraOS apps can interact with the Matter fabric without direct native access.


Findings

RAM Constraint

esp-matter (Espressif’s Matter SDK) requires 800 KB+ RAM in its default configuration. The ESP32-C6 has 512 KB of on-chip SRAM (plus optional PSRAM on some modules). A direct port into the AkiraOS process model is not feasible on most production targets without external PSRAM.

Configuration RAM Budget Verdict
AkiraOS alone (native_sim baseline) ~180 KB OK
AkiraOS + WAMR JIT ~320 KB Tight
AkiraOS + esp-matter (direct) >800 KB Infeasible on C6 without PSRAM
AkiraOS (app OS) + Matter (co-processor) ~320 KB + co-proc RAM Viable

Co-Processor Architecture

AkiraOS runs on the ESP32-C6 HP core (Zephyr). A Thread/Matter co-processor (e.g. ESP32-H2 flashed with esp-matter) connects via UART1 (TX=GPIO4, RX=GPIO5). The co-processor owns the full Matter stack; AkiraOS sends commands and receives events over a lightweight TLV frame protocol.

┌─────────────────────────────┐         ┌──────────────────────┐
│  ESP32-C6 HP core            │  UART1  │  ESP32-H2 (or equiv) │
│  AkiraOS (Zephyr)            │◄───────►│  esp-matter          │
│  WASM runtime                │ 115200  │  Thread/Matter stack │
│  akira_matter_ipc.c          │  baud   │  IEEE 802.15.4 radio │
└─────────────────────────────┘         └──────────────────────┘

Frame Protocol

[0xAC][0xCE][CMD:1][SEQ:1][LEN_H:1][LEN_L:1][PAYLOAD:LEN][CRC16_H:1][CRC16_L:1]
CMD Direction Purpose
0x01 / 0x81 host→coproc / resp Commission device (controller)
0x02 / 0x82 host→coproc / resp Send payload to device (controller)
0x03 / 0x83 host→coproc / resp Subscribe to attribute (controller)
0x04 coproc→host Async attribute event (controller)
0x05 / 0x85 host→coproc / resp Status ping
0x06 / 0x86 host→coproc / resp Register local endpoint (accessory)
0x07 / 0x87 host→coproc / resp Report local attribute (accessory)
0x08 / 0x88 host→coproc / resp Open local pairing window (accessory)
0x09 / 0x89 host→coproc / resp Get this node’s onboarding codes (accessory)
0x0A coproc→host Inbound command to a local endpoint (accessory)

CRC-16/IBM (poly 0x8005, reflect in+out, xorout 0xFFFF). All response payloads begin with a 4-byte big-endian int32 status.

Accessory-direction payload contract

This is the contract the co-processor firmware (or a mock) must honour so AkiraOS can be adopted as a Matter device by Home Assistant, Google Home, Alexa, and Apple Home. All multi-byte fields are big-endian.

CMD Request payload Response payload (after status:4)
0x06 EP_ADD device_type:2, n_clusters:1, cluster:4 × n endpoint_id:1
0x07 ATTR_REPORT endpoint:1, cluster:4, attr:4, len:1, value:len
0x08 PAIR_OPEN timeout_sec:2
0x09 QR_GET qr:cstr\0, manual:cstr\0
0x0A ACC_CMD_EVENT endpoint:1, cluster:4, cmd:4, value:N (coproc→host, unsolicited)

The co-processor maps registered endpoints/clusters onto its esp-matter data model, forwards ATTR_REPORT values into the fabric, and emits ACC_CMD_EVENT when a controller invokes a command (e.g. OnOff/On) on one of our endpoints. A reference implementation lives in tools/matter-coproc-mock/mock_coproc.py and, for on-target testing, in src/connectivity/matter/matter_coproc_mock.c (CONFIG_AKIRA_MATTER_COPROC_MOCK=y).


Implementation

New files

File Description
src/runtime/akira_matter_ipc.h IPC transport interface
src/runtime/akira_matter_ipc.c UART framing + RX state machine thread
src/api/akira_matter_api.h WASM native API declarations
src/api/akira_matter_api.c Capability-guarded WASM bridge

Modified files

File Change
src/runtime/security.h AKIRA_CAP_MATTER = 1ULL << 33
src/runtime/security.c "matter" / "matter.*" string mappings
src/api/akira_export_api.c Register 4 native symbols under CONFIG_AKIRA_WASM_MATTER
AkiraSDK/include/akira_api.h Public SDK declarations for WASM apps
Kconfig CONFIG_AKIRA_MATTER_COPROC_UART + CONFIG_AKIRA_WASM_MATTER
boards/esp32c6_devkitc_esp32c6_hpcore.conf CONFIG_AKIRA_MATTER=n (opt-in)
boards/esp32c6_devkitc_esp32c6_hpcore.overlay UART1 node + matter-coproc-uart alias

WASM API

// Manifest: "capabilities": ["matter"]

// Commission a device (BLE commissioning via co-processor)
int matter_commission(const char *passcode, void *eui64_out);

// Send a raw payload to a commissioned device
int matter_send(const void *eui64, const void *payload, int len);

// Subscribe to attribute change events
int matter_subscribe(const void *eui64, int attr_id);

// Poll for the next incoming event (blocking)
int matter_poll(void *src_eui64, int *attr_id, void *buf, int buf_len, int timeout_ms);

Accessory mode (device-as-endpoint)

Enabled with CONFIG_AKIRA_MATTER_ACCESSORY=y. Lets AkiraOS expose its own hardware as a Matter device that Home Assistant / Google Home / Alexa / Apple Home adopt. The entity/cluster modelling lives in a WASM app; AkiraOS only marshals it to the co-processor. Reference app: AkiraSDK/wasm_apps/generic/matter_rgb/ (PWM RGB → Extended Color Light).

// Manifest: "capabilities": ["matter"]

// Register a local endpoint (device type + server clusters) -> endpoint id
int matter_endpoint_add(int device_type, const unsigned int *clusters, int n_clusters);

// Report a local attribute value outward to the fabric
int matter_report_attr(int endpoint, int cluster, int attr, const void *val, int len);

// Poll for the next inbound command targeting a local endpoint (blocking)
int matter_cmd_poll(int *endpoint, int *cluster, int *cmd, void *buf, int buf_len, int timeout_ms);

// Open this node's commissioning window so a controller can adopt it
int matter_open_pairing(int timeout_sec);

// Fetch this node's onboarding payload (QR string + manual pairing code)
int matter_get_pairing(char *qr, int qr_len, char *manual, int manual_len);

On-device, matter pair / matter status shell commands drive the same path.

Testing without hardware: build with CONFIG_AKIRA_MATTER_COPROC_MOCK=y for an in-firmware responder, or run tools/matter-coproc-mock/mock_coproc.py against a real/PTY UART. See tests/matter_accessory/ for the native_sim integration test.


Enabling on ESP32-C6

In boards/esp32c6_devkitc_esp32c6_hpcore.conf (or a Kconfig fragment):

CONFIG_AKIRA_MATTER=y
CONFIG_AKIRA_MATTER_COPROC_UART=y
CONFIG_AKIRA_WASM_MATTER=y

The UART1 node in the overlay is disabled by default; enabling CONFIG_AKIRA_MATTER_COPROC_UART=y causes the Zephyr DTS fixup to set uart1 to status = "okay".

Connect the co-processor:

  • ESP32-C6 GPIO4 (TX) → ESP32-H2 GPIO4 (RX)
  • ESP32-C6 GPIO5 (RX) → ESP32-H2 GPIO5 (TX)
  • Common GND

Conditions to Extend to Full Matter

  • ESP32-H2 firmware flashed with esp-matter + the AkiraOS co-processor companion firmware (tools/matter-coproc-mock/)
  • Matter commissioner integration tested with Apple Home / Google Home
  • OTA update path for the co-processor firmware (via akira-hub catalogue)

Last updated: 2026-09-14 (AkiraOS v1.6.5)


Copyright © 2026 PenEngineering S.R.L and the AkiraOS Contributors. Licensed under the Apache License 2.0.