Configuration-driven firmware generation for IoT devices with KiCAD integration.
Oasis Firmware is a unified hardware management framework that supports:
- Multi-platform: ESP32, Raspberry Pi, Arduino, STM32
- Declarative config: Define devices in YAML, generate firmware code
- Simulation: Wokwi simulation configs for ESP32
- KiCAD integration: Import PCB designs, export scaffolds, junction advisor
- Legacy support: Preserved Python RPi toolkit and Arduino sensor templates
oasis-firmware/
├── src/ # Rust firmware generator (oasis-build CLI)
├── examples/ # device.yaml examples (greenhouse, drone)
├── docs/ # Schema docs, deployment guide, desktop app design
├── kicad_bridge/ # Python KiCAD integration tools
└── legacy/
├── rpi/ # Original Python RPi toolkit (oasis-grow)
└── ino/ # Arduino sensor templates (oasis-ino)
- Define your device in YAML (see
examples/):
device:
id: my-greenhouse
board: { platform: mcu, model: esp32_devkit }
sensors:
- name: temp_humidity
type: dht22
pins: { data: 4 }- Validate and generate firmware:
cargo run --bin oasis-build -- validate --config device.yaml
cargo run --bin oasis-build -- generate --config device.yaml --output ./build/- Flash to device (see
docs/DEPLOYMENT.md)
cd kicad_bridge && pip install -e .
# Import existing PCB to device.yaml
oasis-kicad import ./my-project.kicad_pro --output device.yaml
# Generate KiCAD scaffold from device.yaml
oasis-kicad scaffold --config device.yaml --output ./kicad/
# Get connector/cable/enclosure recommendations
oasis-kicad review --config device.yamlThe original Python-based RPi toolkit is preserved in legacy/rpi/:
cd legacy/rpi
. install.sh
. start.shSee legacy/rpi/README.md for full documentation.
- Device Schema - YAML configuration reference
- Deployment Guide - Flashing and deployment techniques
- Desktop App Design - Planned egui desktop application
| Platform | Generator | Simulation | Deployment |
|---|---|---|---|
| ESP32 | Rust (embassy) | Wokwi | espflash, OTA |
| RPi | Rust (tokio) | mock_gpio | SSH, systemd |
| Arduino | C++ templates | - | arduino-cli |
| STM32 | Rust (embassy) | - | probe-rs |
We encourage users to contribute device definitions, example apps, and platform drivers. See CONTRIBUTING.md for guidelines.
The current architecture separates concerns across three layers:
| Layer | Component | Language | Purpose |
|---|---|---|---|
| Build | oasis-build CLI |
Rust | YAML → firmware code generation |
| Runtime (RPi) | Launcher + app folder | Rust + egui | Sandboxed app execution via systemd |
| Runtime (MCU) | oasis-mcu |
C++ (Arduino) | Compile-time app composition with menu system |
| Desktop | oasis-manager |
Rust + egui | SD flashing, Arduino flashing, app repository |
| Simulation | BehavioralRuntime | Python | Hardware-in-the-loop testing, MCP server |
See SIMPLIFIED_ARCHITECTURE.md for the full design rationale and FIRMWARE_ANALYSIS_AND_ROADMAP.md for current status and roadmap.
Simple sensor/actuator programs (greenhouse, irrigation) map cleanly onto the declarative YAML schema. Programs with tight real-time control loops, state machines, or custom hardware interfaces — such as robot arms, drone flight controllers, and motor driver stacks — require a different approach.
The device.yaml schema works well when:
- Sensors publish measurements on a fixed interval
- Actuators respond to threshold or PID triggers
- No inter-component timing dependencies tighter than ~100ms
For robots and drones, write a custom RPi app or custom MCU sketch and register it with the launcher:
Create /opt/oasis-apps/my-robot/:
my-robot/
├── manifest.json # app metadata + dependencies
├── run.sh # entrypoint — launcher calls this
├── stop.sh # graceful shutdown
└── robot_control.py # your control logic
manifest.json:
{
"id": "my-robot",
"name": "Robot Arm Controller",
"version": "1.0.0",
"runtime": "python3",
"entrypoint": "run.sh",
"requires": ["smbus2", "RPi.GPIO", "numpy"]
}run.sh (launcher invokes this):
#!/bin/bash
cd "$(dirname "$0")"
pip install -r requirements.txt --quiet
exec python3 robot_control.pyThe launcher manages the process lifecycle (start, stop, restart on crash) via systemd. Your app gets full GPIO, I2C, SPI, and UART access.
For drone ESC control or motor driver timing (where microsecond precision matters), write a standard app.ino and register it under the correct platform:
oasis-mcu/
└── platforms/
└── esp32_devkit/
└── drone_controller/
├── manifest.json
└── app.ino ← your sketch here
The oasis-mcu build system will compile and link it correctly. For multi-app boards, the menu system handles runtime selection without recompiling.
For programs that require a specific Python environment, system packages, or config files to be present before the app first runs, use the pre-flash bootstrap script:
# scripts/bootstrap_device.sh
# Run this once after flashing the SD card, before first boot
DEVICE_MOUNT="/Volumes/bootfs" # macOS; adjust for Linux
# Write app config
cp configs/robot_config.json "$DEVICE_MOUNT/oasis-config.json"
# Write a first-boot systemd service that runs setup
cat > "$DEVICE_MOUNT/oasis-firstboot.service" << 'EOF'
[Unit]
Description=Oasis First-Boot Setup
After=network.target
ConditionPathExists=/boot/oasis-config.json
[Service]
Type=oneshot
ExecStart=/opt/oasis-apps/my-robot/setup.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
echo "Bootstrap complete. Eject and insert SD card."setup.sh (runs once on first boot, then the service disables itself):
#!/bin/bash
apt-get install -y python3-pip libopencv-dev
pip3 install -r /opt/oasis-apps/my-robot/requirements.txt
systemctl disable oasis-firstboot
rm /boot/oasis-config.jsonThis pattern ensures the runtime environment is fully configured before the main app starts, without requiring a network connection at flash time.
The oasis-manager desktop app (oasis-manager/) automates the above workflow:
- Select your target board (RPi SD card or Arduino port)
- Choose apps from the repository browser
- Click Flash — manager handles SD imaging, app installation, and bootstrap config in one step
See SIMPLIFIED_ARCHITECTURE.md for the full manager UI design.
The original Python-based RPi toolkit (legacy/rpi/) is preserved for reference and backward compatibility with existing deployments. It is not recommended for new projects. See legacy/rpi/README.md for its documentation.
| Project | Platform | Complexity |
|---|---|---|
| Greenhouse monitor | ESP32 | Simple — use YAML |
| Time-lapse camera | RPi | Simple — use YAML |
| Mushroom chamber | RPi + Arduino | Simple — use YAML |
| Drone flight controller | ESP32 / custom MCU | Advanced — custom sketch |
| Robot arm (6-DOF) | RPi + I2C servo driver | Advanced — custom app |
| Outdoor weather station | ESP32 | Simple — use YAML |
| Automated irrigation grid | RPi + relay bank | Moderate — YAML + control loop |