Skip to content

Latest commit

Β 

History

82 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SynapticOS

AI-Native Operating System for Microcontrollers

Inference-first runtime for resource-constrained edge devices.
Built on Zephyr RTOS. Designed for the NXP FRDM-MCXN947.

Version License Phase Tests


The Problem

Most RTOS platforms treat AI inference as an afterthought β€” a library bolted onto a scheduler that was designed for control loops and sensor polling. On microcontrollers with dedicated NPUs, this mismatch wastes silicon: the NPU sits idle while the CPU copies buffers, the memory allocator fragments the heap, and there is no clean way to manage model lifecycles or pipeline data from sensor to prediction.

The Solution

SynapticOS treats inference as the primary workload, not an add-on. Every subsystem β€” memory, scheduling, hardware abstraction, model management β€” is designed around the data flow of a neural network inference pipeline.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        SynapticOS Runtime                       β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Sensor  │─▢│  Pre-    │─▢│   NPU    │─▢│    Post-      β”‚   β”‚
β”‚  β”‚  Input   β”‚  β”‚ process  β”‚  β”‚ Invoke   β”‚  β”‚   process     β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚       β”‚              β”‚             β”‚               β”‚            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚              Tensor-Aware Memory Arena                    β”‚  β”‚
β”‚  β”‚         (16-byte aligned, persistent + ephemeral)        β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚              Hardware Abstraction Layer                  β”‚   β”‚
β”‚  β”‚    NPU (eIQ Neutron)  Β·  DSP (PowerQuad)  Β·  DMA       β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Model   β”‚  β”‚Profiling β”‚  β”‚  Shell   β”‚  β”‚   IPC        β”‚   β”‚
β”‚  β”‚Store+OTA β”‚  β”‚  Engine  β”‚  β”‚ Commands β”‚  β”‚ (Dual-Core)  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   Zephyr RTOS     β”‚
                    β”‚   v3.7.0          β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Features

Feature Description
Tensor-Aware Memory Bump allocator with 16-byte DMA alignment. Persistent region for weights, ephemeral region for activations, dedicated scratch pool. Zero fragmentation.
NPU/DSP Abstraction Clean HAL with full state machine (idle/busy/suspended). Swap between QEMU stubs and real Neutron NPU without changing application code.
Model Lifecycle Register, load, invoke, unload, unregister. Duplicate detection, state guards, metadata tracking.
Persistent Model Store Flash-backed A/B model slots with a ping-pong committed registry (generation counter + CRC32, newest-valid-wins), per-copy wear tracking, and a CRC32 gate on every load. Registry commit 1.9–2.6 ms, boot scan 23–189 us, measured on the board.
A/B OTA Model Updates Power-loss-safe staged updates: stream in chunks, verify from flash, then commit. Activate and rollback (including activating a staged update after a reboot), hot-swap with inference quiescence, and CPU1 park/resume around bank-1 flash writes. Ships with a UART shell transport and host-side sender.
Model Packaging .synm container tooling: syn_model_pack.py (stdlib-only packer with a built-in TFLite flatbuffer reader), syn_flash_layout.py (dual-core-safe partition map generator), syn_ota_send.py (UART OTA sender).
Deadline Dispatch & Layer Preemption Jobs order by priority, then earliest deadline, then FIFO; deadline misses are counted. Preemptible layered jobs yield at layer boundaries to higher-priority work and resume bit-exactly (10 us context save, measured on the board, stub NPU).
Memory-Optimal Activation Planning DAG models with skip connections share one plan area laid out by a lifetime-based first-fit planner: 43% below the all-live peak on the 8-layer demo DAG, planned in 18 us on the board.
Health Monitoring & Fault Recovery Hardware watchdog (WWDT) fed only while every busy source is fresh β€” an induced CPU0 hang reboots clean in under 2 s. CPU1 heartbeat supervision parks and re-releases a hung second core (600 ms detect + 1.3 ms re-release, measured) without disturbing CPU0.
Zero-Copy DMA Ingest Double-buffered frame pump over the MCXN947 eDMA (software stub on QEMU): the CPU processes frame N in place while DMA lands frame N+1. +251% frame rate over CPU copy at 8 KB frames, 1000 frames with zero corruption, measured on the board.
PowerQuad DSP Offload Self-calibrating FFT and Q15 matmul on the MCXN947 PowerQuad with transparent per-operation software fallback. Measured on the board: 3.03Γ— on 256-pt float FFT (132 us/op vs 403 us software), 1.72Γ— on 16Γ—16 Q15 matmul β€” honest numbers against the hard-FPU software kernels; the small-matrix path is overhead-bound by design.
Inference Profiling Cycle-accurate timing of each pipeline stage (preprocess, NPU, postprocess). Memory peak tracking and NPU utilization metrics.
Interactive Shell Inspect and drive the runtime over serial: syn version, syn mem stats/dump, syn model list/info/load/unload, syn npu caps/plan, syn infer run/stats, syn prof last, syn ipc status/stats, syn health, syn dma bench, syn store status, syn ota begin/data/rawdata/done/activate/rollback β€” with model-name tab completion.
Dual-Core Offload The AI runtime runs on CPU0; CPU1 requests inference as an OS service over lock-free shared-memory rings (15 us typical round-trip, measured on the board). Includes CPU1 boot orchestration with blank-bank fallback and an out-of-tree CPU1 board port for Zephyr 3.7.
Cross-Core Protection CPU0's MPU guards CPU1's RAM read-only, with fault containment (offending thread aborted, both cores continue). One-directional by silicon: the MCXN947's CPU1 has no MPU.
Dual-Target Support Same codebase builds and runs on real hardware (FRDM-MCXN947) and emulated targets (QEMU Cortex-M3) for CI-friendly development.

Measured honestly. Real eIQ Neutron inference is live (optional neutron module, Phase 6): a 32Γ—32Γ—3 INT8 classifier runs in 6.6 ms when resident and 17.1 ms including the on-demand model swap the single-residency NPU needs in a mixed pipeline (prepare ~10.5 ms, CRC-gated), sustained at 10 FPS alongside two stub-model workloads and live dual-core serving with zero errors β€” worst observed tail 21.5 ms, which misses the 20 ms REALTIME target when a swap lands behind an in-flight job (keep the REALTIME model resident to hold 6.6 ms). Figures for the stub-model workloads (and all dual-core serving latencies) remain stub-NPU-labeled until a real 96Γ—96 model is converted. The OTA transport streams raw binary over the 115200-baud shell: a 432 KB slot-max update lands in 38.88 s (11.1 KB/s β€” 2.06x the old hex transport and 98.7% of the line rate, so the original 10 s target needs a faster link, not better software).

Target Hardware

Spec Value
Board NXP FRDM-MCXN947
CPU Dual Arm Cortex-M33 @ 150 MHz
NPU eIQ Neutron (4.8 GOPS INT8)
SRAM 512 KB
Flash 2 MB
Price ~$15 USD

Getting Started

Prerequisites

  • Ubuntu 24.04 (or compatible Linux)
  • Python 3.10+ with west, pyocd
  • Zephyr SDK 0.17.0+

See docs/01-ubuntu-setup.md for detailed environment setup.

Build & Run

# Clone and initialize workspace
mkdir ~/workspace && cd ~/workspace
git clone https://github.com/Dimitrios-Kafetzis/SynapticOS.git synaptic-os
cd synaptic-os && west init -l . && cd .. && west update
pip install -r zephyr/scripts/requirements.txt

# Run on QEMU (no hardware needed)
west build -b qemu_cortex_m3 synaptic-os/samples/hello_inference --pristine
west build -t run

# Or build for real hardware
west build -b frdm_mcxn947/mcxn947/cpu0 synaptic-os/samples/hello_inference --pristine
west flash

Expected Output

[00:00:00.000,000] <inf> hello_inference: === SynapticOS 0.5.0 β€” Hello Inference ===
[00:00:00.000,000] <inf> hello_inference: Registered model 'test_classify' (handle=1)
[00:00:00.000,000] <inf> hello_inference: Model loaded to NPU
[00:00:00.000,000] <inf> hello_inference: Input tensor: 1x16x16x3 (768 bytes)
[00:00:00.000,000] <inf> syn_infer: Pipeline 'run_sync' built: 1 stages, est. 4106 bytes
[00:00:00.000,000] <inf> hello_inference: Inference completed in 1361 us
[00:00:00.000,000] <inf> hello_inference: Prediction: class 0 (confidence 127)
[00:00:00.000,000] <inf> syn_prof: === Inference Profile ===
[00:00:00.000,000] <inf> hello_inference: === Hello Inference complete ===

Run Tests

west twister -T synaptic-os/tests -p qemu_cortex_m3
# 158 tests, 21 suites, 100% pass rate (two apps: tests/unit + tests/unit_store)

Build Footprint

Build Target Flash RAM
dual_model (CPU0: runtime, shell, serving, OTA) FRDM-MCXN947 130.5 KB 250.5 KB of 256 KB
dual_model (CPU1: remote client) FRDM-MCXN947 33.1 KB 42.7 KB of 64 KB
ota_update (CPU0: runtime, shell, OTA demo) FRDM-MCXN947 115.0 KB 244.1 KB
ota_update QEMU Cortex-M3 87.2 KB 63.6 KB of 64 KB
hello_inference QEMU Cortex-M3 47.2 KB 39.4 KB

Project Structure

synaptic-os/
β”œβ”€β”€ include/synaptic/       Public API headers (frozen)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ core/               Runtime: memory, model registry + store, OTA engine,
β”‚   β”‚                       flash map/port, IPC, boot, health/watchdog, DMA ingest,
β”‚   β”‚                       profiling, init, shell
β”‚   β”œβ”€β”€ hal/
β”‚   β”‚   β”œβ”€β”€ mcxn947/        Neutron NPU + PowerQuad DSP drivers
β”‚   β”‚   └── stub/           Software fallbacks for QEMU / CI
β”‚   β”œβ”€β”€ preprocess/         Image, audio, quantization pipelines
β”‚   └── postprocess/        Classification, detection output processing
β”œβ”€β”€ samples/
β”‚   β”œβ”€β”€ hello_inference/    End-to-end inference demo
β”‚   β”œβ”€β”€ face_detection/     Continuous vision-pipeline demo
β”‚   β”œβ”€β”€ keyword_spotting/   Audio pipeline demo
β”‚   β”œβ”€β”€ dual_model/         Cross-core inference demo (CPU0 runtime + CPU1 remote client)
β”‚   └── ota_update/         End-to-end OTA-over-UART demo (factory -> update -> rollback)
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ unit/               133 unit tests across 18 suites
β”‚   └── unit_store/         25 store/OTA/hot-swap tests across 3 suites (RAM-emulated flash)
β”œβ”€β”€ tools/                  syn_model_pack.py, syn_flash_layout.py, syn_ota_send.py,
β”‚                           syn_coverage.sh, profiler viz
β”œβ”€β”€ boards/nxp/
β”‚   β”œβ”€β”€ frdm_mcxn947/       Device tree overlays, board configs, flash partition map (CPU0)
β”‚   └── frdm_mcxn947_cpu1/  Out-of-tree CPU1 board port (missing from mainline Zephyr 3.7)
β”œβ”€β”€ scripts/                Environment setup and validation
└── docs/                   Guides and specifications

Lessons from Real Hardware

Every phase is verified on the physical board, not just QEMU β€” and the board keeps teaching lessons the emulator can't. All of these were found on hardware, fixed, and re-verified:

  • Never release CPU1 into erased flash (Phase 3). Releasing the second core into a blank bank wedges the whole chip, including the debug port; recovery is ISP-only. SynapticOS blank-checks the bank via the ROM API before releasing CPU1.
  • Never issue one long multi-sector flash erase (Phase 4). A single ROM-API FLASH_Erase call spanning 55 sectors (the 440 KB OTA staging slot) wedged the chip the same way, while every 1-sector erase before and after was fine. OTA and store erases are now sector-wise with 1 ms breathers; the identical 432 KB transfer then passed.
  • Placeholder limits become field bugs (Phase 4). The stub NPU HAL's arbitrary 256 KB cap refused to load a valid, stored, activated 432 KB model β€” and syn ota rollback restored service in one command, an involuntary demo of why rollback exists. The cap now tracks flash slot capacity.
  • Size the shell RX ring for the transport (Phase 4). The default 64-byte UART ring drops bytes of 2 KB hex lines when scheduling jitter delays mid-line reads; OTA over the shell needs a 1 KB ring, and the sender disables echo during transfers.
  • The DMA driver may not know your transfer mode (Phase 5). Zephyr 3.7's eDMA driver never issues the software START that mem-to-mem transfers need on eDMA v4 (and arms the hardware request on mux source 0 instead). The HAL programs the transfer itself β€” including clearing the latched DONE flag, which is write-1-to-clear and silently gates the next START.
  • DMA reachability is a bus-security property, not an address-map one (Phase 5). TrustZone secure-alias pointers bus-error inside the eDMA, and the tensor arena turned out not to be eDMA-reachable at all under the current bus attributes. Worst of it: with the SoC's shared no-error-IRQ setup, a faulted transfer is a silent timeout. Ingest benchmarks moved to DMA-reachable statics; arena DMA visibility is a Phase 6 item.
  • Don't abort between back-to-back one-shot DMA transfers (Phase 5). An abort issued between transfers wedges the next completion; the ingest pump keeps the channel armed across frames instead.
  • A preempting submitter must outrank the scheduler thread (Phase 5). The on-hardware preemption demo failed on first run because the submitting thread could never inject mid-job from a lower priority β€” QEMU's cooperative test threads had masked the requirement entirely.

Roadmap

SynapticOS is developed in six phases, each building on the previous:

  Phase 1        Phase 2         Phase 3        Phase 4       Phase 5        Phase 6
  Foundation     Inference       Dual-Core      Model         Production     Ecosystem
                 Pipeline        & IPC          Lifecycle     Hardening      & Tooling
  ─────●─────────────●────────────●──────────────●─────────────●──────────────○───▢
  v0.1.0         v0.2.0         v0.3.0         v0.4.0        v0.5.0         v1.0.0
  βœ“ Complete    βœ“ Complete    βœ“ Complete    βœ“ Complete   βœ“ Complete
Phase Focus Version
1. Foundation Memory, HAL, model registry, profiling, shell, tests v0.1.0 βœ“
2. Inference Pipeline Pipeline engine, priority job scheduler, PowerQuad DSP, pre/post-processors, live profiling v0.2.0 βœ“
3. Dual-Core & IPC Asymmetric multiprocessing, lock-free shared-memory IPC, cross-core inference offload, MPU protection, CPU1 board port v0.3.0 βœ“
4. Model Lifecycle Flash-backed model store, power-loss-safe A/B OTA updates, hot-swap, dual-core-safe flash map, packaging tools v0.4.0 βœ“
5. Production Hardening Deadline dispatch + layer preemption, activation planning, watchdog + fault recovery, zero-copy DMA ingest, binary OTA transport, coverage, 11k-inference soak v0.5.0 βœ“
6. Ecosystem & Tooling Real eIQ Neutron NPU inference, NPU residency contract, multi-model store with staging eviction, metrics re-measure, out-of-tree SDK template, community docs, v1.0 release v1.0.0 (in progress)

Documentation

Document Description
Ubuntu Environment Setup Full setup guide for development on Ubuntu 24.04
Project Setup & First Build West workspace initialization and first build
Architecture Specification System design, data flow, and component overview
Application Template Build your own app against SynapticOS out-of-tree, from a fresh workspace to a running QEMU/FRDM build

Contributing

Contributions are welcome β€” see CONTRIBUTING.md for the ground rules (Apache-2.0, -Werror, conventional commits, tests with every change, honest measured results). Issues and pull requests use the repository templates; PRs target the dev branch.

Ways in:

  • Build something on top: start from the application template β€” no fork needed
  • Open an issue for bugs, questions, or feature ideas (bug reports ask for the target, commit, and a serial log)
  • Star the repo and watch releases for milestone announcements

License

Licensed under the Apache License 2.0.

About

AI-native RTOS for Cortex-M33 + eIQ Neutron NPU, built on Zephyr. Target: NXP FRDM-MCXN947.

Topics

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages