jumpstation

JumpStation Studio

What It Is

JumpStation Studio is the JumpStation integrated development environment — a Linux application that provides a single, consistent interface for writing, running, and deploying projects that span a Linux host and one or more attached physical devices.

It runs on any JumpStation-class Linux host:

Platform Physical device interface
JumpStation (CM5 / RK3588S2) GPIO breakout adapter → direct GPIO, I2C, SPI, UART
JumpStation Turbo (CM5 / RK3588S2 + DX-M1) Same as base + accelerated profiling
Arduino UNO Q STM32U585 MCU → USB-CDC serial bridge
Any Linux host with a serial-attached device Serial bridge transport

The key design principle: app code does not know which transport is underneath. A project written on a CM5 with a GPIO breakout adapter runs unchanged on a UNO Q with an STM32 MCU — the DeviceBus abstraction handles the difference.


The App Lab Problem

Arduino App Lab (preloaded on the UNO Q) provides a similar unified interface for Arduino sketch + Python development. JumpStation Studio replaces it with:

  Arduino App Lab JumpStation Studio
Platform UNO Q only Any JumpStation Linux host
Hardware abstraction Platform-specific Unified DeviceBus API
AI integration Pre-loaded models Full targeting + distillation pipeline
Deployment target UNO Q local only Any device in the spectrum via JumpBundle
Model source Arduino App Lab catalog Bring your own + JumpStation targeting
Sketch language Arduino C/C++ Arduino C/C++ + Python (MCU firmware optional)

Project Model

A Studio Project is the unit of development. It contains up to three layers:

my_project/
├── studio.json           # Project manifest
├── app.py                # Python application (Linux / MPU side)
├── sketch/               # Optional: Arduino sketch (MCU / real-time side)
│   └── sketch.ino
└── model/                # Optional: AI model (JumpBundle model layer)
    └── weights.tflite

studio.json declares:

When a project is ready to deploy, Studio hands it off to the JumpBundle builder, which packages it as a .jbundle targeting the appropriate device class.


The Device Bus

The DeviceBus is the unified hardware abstraction layer. Application code imports one API regardless of the physical transport underneath.

from core.studio.device_bus import DeviceBus

bus = DeviceBus.detect()          # Auto-detects transport from host platform
bus.digital_write(pin=13, value=1)
reading = bus.analog_read(pin=0)
bus.i2c_write(addr=0x48, data=bytes([0x01, 0x00]))
bus.on_interrupt(pin=2, edge="rising", callback=my_handler)

Transports

Transport Used when Backend
GpioTransport CM5 / RK3588S2 with breakout adapter libgpiod (Linux GPIO character device)
SerialBridgeTransport UNO Q (STM32U585) or any serial-attached MCU USB-CDC / UART serial protocol
SimulatedTransport No hardware attached (CI, unit testing) In-process state machine

The transport is selected automatically by DeviceBus.detect() based on the host platform. It can also be specified explicitly:

from core.studio.transports import SerialBridgeTransport

bus = DeviceBus(transport=SerialBridgeTransport(port="/dev/ttyACM0", baud=115200))

DeviceBus API Surface

Method Description
digital_read(pin) Read digital high/low from a pin
digital_write(pin, value) Set a digital pin high or low
analog_read(pin) Read ADC value (0–1023 normalized to 0.0–1.0)
pwm_write(pin, duty, freq) Write PWM signal to a pin
i2c_read(addr, n_bytes) Read N bytes from an I2C device
i2c_write(addr, data) Write bytes to an I2C device
spi_transfer(data) Full-duplex SPI byte exchange
uart_read(n_bytes) Read from UART
uart_write(data) Write to UART
on_interrupt(pin, edge, callback) Register a pin-change interrupt handler
close() Release the transport cleanly

Sketch Bridge Protocol

When the SerialBridgeTransport is active (UNO Q or serial-attached MCU), Studio communicates with the MCU using a lightweight protocol over USB-CDC:

Host → MCU:   [CMD][PIN][DATA...]
MCU  → Host:  [STATUS][DATA...]

Command bytes map directly to the DeviceBus API surface. The MCU-side firmware (a minimal Arduino sketch flashed once at first boot) decodes these commands and executes them against the real-time environment, returning results synchronously.

This means: the MCU does not run application logic. It is a hardware bridge. Application logic lives entirely on the Linux side. This is the opposite of the Arduino App Lab model, where the sketch and Python share application responsibility.

For applications that genuinely require real-time MCU execution (tight timing loops, hardware PWM precision, interrupt-driven protocols), Studio supports a sketch component in the project — a full Arduino sketch that runs on the MCU alongside the bridge firmware. The host communicates with both layers.


The Two Jump Paths

From within Studio, once the project is working on the development host, the targeting workflow determines where it ultimately lives:

Path A — Retarget to a smaller device

The application logic is suitable for a Pico, ESP32, or UNO Q. The targeting suite compresses the model, rewrites the entry point for the target runtime, and packages a JumpBundle.

jumpstation target --project my_project/ --calibration data/
# → TargetDeclaration: device_class=pico, backend=tflite_micro
jumpstation bundle --project my_project/ --target pico
# → dist/my_project_pico.jbundle

Path B — The host IS the product

The JumpStation, JumpStation Turbo, or UNO Q is the deployed device. The JumpBundle packages the full Linux application for installation on a target host.

jumpstation bundle --project my_project/ --target uno_q
# → dist/my_project_uno_q.jbundle (deploys as Linux package + optional sketch)

Both paths produce a JumpBundle. The targeting suite determines which path is appropriate.


Module Layout

core/studio/
├── __init__.py
├── device_bus.py      # DeviceBus class + Transport ABC
├── transports.py      # GpioTransport, SerialBridgeTransport, SimulatedTransport
├── project.py         # StudioProject dataclass + studio.json loader/validator
└── runner.py          # run(), deploy(), flash_sketch(), attach_device()

Further Reading