mcpField
W
wendy-lite

wendy-lite

github.com/wendylabsincDevelopment6265 installsUpdated 5w ago
Repository

About wendy-lite

Wendy Lite is firmware for running WebAssembly applications on ESP32-C6 microcontrollers. It is aimed at developers who want to build device apps in several languages and access hardware through host imports.

Key features

  1. 01WAMR-based WASM runtime
  2. 02Apps written in C, Rust, Swift, Zig, TypeScript, or WAT
  3. 03GPIO, I2C, SPI, UART, and other hardware APIs
  4. 04USB CDC and WiFi app upload
  5. 05Flash persistence and boot-time loading
  6. 06Callbacks for asynchronous events

Use cases

  1. 01Run WASM apps on an ESP32-C6 device
  2. 02Build embedded apps in supported languages
  3. 03Control GPIO, buses, and peripherals from WASM
  4. 04Upload and run firmware apps over USB or WiFi

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/wendylabsinc/claude-skills --skill wendy-lite

After installing, type/wendy-litein Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
firmware-config.md
swift-sdk.md
wasm-api.md

Details

From the project README

Wendy Lite

Wendy Lite is a WebAssembly (WASM) runtime firmware for ESP32-C6 microcontrollers. It enables developers to write apps in C, Rust, Swift, Zig, TypeScript, or WAT, compile them to WASM, and run them on the device with full hardware access.

Key Concepts

  • WAMR Runtime: Uses WebAssembly Micro Runtime to execute WASM binaries
  • Host Imports: WASM apps import functions from the "wendy" module to access hardware
  • Callback System: Async events (GPIO interrupts, timers, BLE) dispatched via exported wendy_handle_callback
  • Flash Persistence: WASM binaries stored in flash partition wasm_a (2MB), auto-loaded on boot
  • Multi-language: Apps can be written in C, Rust, Swift 6.0+, Zig, TypeScript, or raw WAT

Project Structure

wendy-lite/
├── main/wendy_main.c              # Firmware entry point, WASM lifecycle manager
├── components/
│   ├── wendy_wasm/                # WAMR integration (load, run, stop modules)
│   ├── wendy_hal/                 # Hardware: GPIO, I2C, RMT, NeoPixel, Timer
│   ├── wendy_hal_export/          # Registers HAL as WASM host imports
│   ├── wendy_usb/                 # USB CDC wire protocol for app upload
│   ├── wendy_wifi/                # WiFi station + HTTP binary download
│   ├── wendy_ble_prov/            # BLE WiFi provisioning ("Wendy-XXXX")
│   ├── wendy_cloud_prov/          # Cloud device certificate provisioning
│   ├── wendy_callback/            # Async ISR-safe event dispatch (max 32 handlers)
│   ├── wendy_storage/             # NVS key-value storage for apps
│   ├── wendy_uart/                # UART serial communication
│   ├── wendy_spi/                 # SPI bus master
│   ├── wendy_sys/                 # System: reboot, uptime, device ID
│   ├── wendy_otel/                # OpenTelemetry: logs, metrics, traces
│   ├── wendy_ble/                 # BLE peripheral/central (optional)
│   ├── wendy_net/                 # TCP/UDP sockets, DNS, TLS (optional)
│   ├── wendy_wasi_shim/           # WASI compatibility layer
│   ├── wendy_safety/              # Memory safety
│   └── wendy_app_usb/             # USB from WASM app perspective (optional)
├── wasm_apps/                     # Example WASM applications
│   ├── include/wendy.h            # App API header (all host imports)
│   ├── Makefile                   # Build system for all app languages
│   ├── blink/                     # C: GPIO LED blink
│   ├── i2c_sensor/                # C: BMP280 I2C sensor reader
│   ├── swift_display/             # Swift 6.0+ embedded WASM app
│   ├── rust_blink/                # Rust WASM app
│   ├── zig_blink/                 # Zig WASM app
│   └── wat_blink/                 # Raw WebAssembly Text
├── partitions.csv                 # Flash layout (nvs, factory, wasm_a, storage)
├── sdkconfig.defaults             # ESP-IDF + WAMR + feature flags
└── diagram.json                   # Wokwi simulator circuit

Writing WASM Apps

C (Recommended for Getting Started)
#include "wendy.h"

void _start(void) {
    gpio_configure(2, WENDY_GPIO_OUTPUT, WENDY_GPIO_PULL_NONE);
    for (int i = 0; i < 10; i++) {
        gpio_write(2, 1);
        timer_delay_ms(500);
        gpio_write(2, 0);
        timer_delay_ms(500);
    }
}

Build:

cd wasm_apps
make blink

Or manually:

clang --target=wasm32 -O2 -nostdlib -I include \
  -Wl,--no-entry -Wl,--export=_start -Wl,--allow-undefined \
  -o app.wasm app.c
Swift (Recommended for App Development)

Swift apps use the WendyLite Swift package from https://github.com/wendylabsinc/wendy-lite, which provides type-safe wrappers around all WASM host imports.

See references/swift-sdk.md for the complete Swift API reference, Package.swift setup, and examples.

Key points:

  • Requires Swift 6.0+ with Embedded Swift support
  • Uses @_cdecl("_start") for the WASM entry point
  • No heap allocation — use stack-allocated tuple buffers
  • StaticString only — no runtime string construction
  • Cast UnsafePointer<UInt8> to UnsafePointer<CChar> via UnsafeRawPointer for API calls
  • Build and deploy with wendy run

Quick start:

import WendyLite

@_cdecl("_start")
func start() {
    GPIO.configure(pin: 2, mode: .output)
    GPIO.write(pin: 2, level: 1)
    System.sleepMs(1000)
    GPIO.write(pin: 2, level: 0)
}
Other Languages
LanguageBuild CommandRequirements
Rustmake rust_blinkrustup (not Homebrew Rust)
Zigmake zig_blinkZig 0.13+
WATmake wat_blinkWABT (wat2wasm)
App Requirements
  1. Export a _start function as the entry point
  2. Import host functions from the "wendy" module
  3. For async callbacks, export wendy_handle_callback(int handler_id, int arg0, int arg1, int arg2)
  4. Call sys_yield() to allow callback dispatch

Hardware Access Summary

SubsystemKey FunctionsNotes
GPIOgpio_configure, gpio_read, gpio_write, gpio_set_pwm, gpio_analog_read, gpio_set_interruptSupports input, output, PWM, ADC, interrupts
I2Ci2c_init, i2c_scan, i2c_write, i2c_read, i2c_write_readBus 0 pre-initialized by firmware
NeoPixelneopixel_init, neopixel_set, neopixel_clearWS2812 RGB LEDs via RMT
Timertimer_delay_ms, timer_millis, timer_set_timeout, timer_set_intervalBlocking delay + async callbacks
UARTuart_open, uart_write, uart_read, uart_set_on_receiveSerial ports with callbacks
SPIspi_open, spi_transfer, spi_closeFull-duplex master
Storagestorage_get, storage_set, storage_delete, storage_existsPersistent NVS key-value
Systemsys_reboot, sys_uptime_ms, sys_device_id, sys_yieldDevice info and control
OTelotel_log, otel_metric_*, otel_span_*Structured logging, metrics, tracing
BLEble_init, ble_advertise_start, ble_gatts_*, ble_gattc_*Optional, disabled by default
WiFiwifi_connect, wifi_status, wifi_get_ip, wifi_ap_startApp-facing WiFi control
Socketsnet_socket, net_connect, net_send, net_recvTCP/UDP, optional
TLStls_connect, tls_send, tls_recvSecure connections
Consolewendy_printOutput to UART + USB

Boot & Lifecycle

  1. Firmware initializes NVS, WAMR pool, HAL, USB, BLE provisioning, WiFi
  2. WASM manager thread starts, registers all HAL exports
  3. Auto-loads WASM from flash partition wasm_a (if present)
  4. Runs WASM _start() in dedicated thread (8KB stack)
  5. Event loop handles: upload, run, stop, reset requests

Uploading WASM Binaries

  • WiFi: HTTP download via UDP listener after WiFi provisioning
  • USB CDC: Wire protocol with PING, UPLOAD (START/CHUNK/DONE), RUN, STOP, RESET messages
  • Flash: Written to wasm_a partition with 4-byte size header, persists across reboots

BLE Provisioning

Device advertises as "Wendy-XXXX" over BLE. A client can:

  1. Discover the device via BLE scan
  2. Send WiFi SSID/password via GATT characteristics
  3. Device connects to WiFi and starts mDNS + UDP listener

Building the Firmware

# Requires ESP-IDF (v5.x) with ESP32-C6 support
idf.py set-target esp32c6
idf.py build
idf.py flash monitor

Wokwi Simulator

The project includes wokwi.toml and diagram.json for hardware simulation without a physical board.

Memory Constraints

  • WAMR pool: 229KB (pre-allocated before WiFi/BLE)
  • WASM stack: 8KB, heap: 8KB
  • Flash: 4MB total (1.875MB firmware, 2MB WASM, 64KB app storage)
  • WiFi/PHY IRAM offloaded to flash to free ~15-25KB DIRAM

Reference Files

Load these files as needed for specific topics:

  • references/swift-sdk.md - WendyLite Swift package: Package.swift setup, complete Swift API reference, Embedded Swift constraints, stack buffer patterns, code examples
  • references/wasm-api.md - Complete WASM app API: all host imports, constants, callback system, per-subsystem function signatures and usage (C-level)
  • references/firmware-config.md - ESP-IDF sdkconfig options, partition table, feature flags, memory tuning, component enable/disable

Comments

Markdown supported