Skip to main content

sim-bridge

Run AVR and STM32 firmware in simulation — with UART, GDB debugging and VCD waveform recording exposed through one small CLI toolkit.

sim-bridge wraps two mature open-source MCU simulators — simavr (AVR) and Renode (STM32) — and turns "start a simulator and wire up its debug interfaces" into a small set of repeatable commands. It adds the plumbing the raw simulators leave to you:

  • UART I/O — the firmware console is published as a PTY (AVR) or TCP socket (STM32), auto-allocated and written to a port file, so any terminal, socket client or test script can talk to the firmware as if it were a serial port.
  • GDB server — every host exposes a GDB stub, so you can set breakpoints and step through firmware from your editor instead of printf-debugging.
  • VCD recording — signal transitions (AVR modules and STM32 GPIO pins, discovered at runtime) are recorded into VCD (Value Change Dump) files that GTKWave can open: a scope for timing questions that are hard to answer on real hardware.

The value is not in the simulators themselves (both are excellent and used unmodified) but in the harness around them: one consistent state machine, one control protocol, and one set of commands across two MCU families.

This is useful for embedded firmware developers who want to verify stepper and timer timing, PWM duty cycles, interrupt latency, or UART protocol behaviour without physical hardware. It works for any AVR or STM32 firmware — CNC G-code firmware is simply the case sim-bridge was extracted from, which is why G-code shows up in the examples.

How it works

sim-bridge runs two cooperating processes:

 ┌─────────────┐         TCP (JSON control)        ┌─────────────┐
 │  *-vcd CLI  │  ◄──────────────────────────►  │  *-host CLI  │
 │  (client)   │                                  │  (server)   │
 └─────────────┘                                  └──────┬──────┘
                                                        │
                                          ┌─────────────┼─────────────┐
                                          ▼             ▼             ▼
                                    ┌──────────┐ ┌──────────┐ ┌──────────┐
                                    │ UART     │ │ GDB      │ │ VCD      │
                                    │ socket/  │ │ server   │ │ hooks    │
                                    │ PTY      │ │          │ │          │
                                    └──────────┘ └──────────┘ └──────────┘
  • *-host launches the simulator (simavr or Renode), loads the firmware ELF, exposes the firmware UART, opens a GDB server, and registers the signal hooks used for VCD recording.
  • *-vcd is the control client. It discovers the host via a port file in /tmp/, then issues start / stop / status / list commands to drive VCD recording.

Per-platform differences are handled for you rather than exposed:

AVR (simavr) STM32 (Renode)
UART PTY at /tmp/simavr-uart-pty TCP socket on --uartport
Signal discovery simavr-vcd list — module based (timer1.compa) renode-vcd list — GPIO based (PA0, gpioPortA)
Hook mechanism bundled C++ bridge, compiled on first run and cached IronPython injected through Renode's Robot XML-RPC server
VCD writing streamed to file while recording buffered in memory, written on stop -f
Discovery file /tmp/simavr-bridge.port /tmp/renode-bridge.port

CLI commands

Command Platform Role Description
simavr-host AVR Host Runs an AVR firmware ELF on simavr: UART PTY + GDB server + VCD control port
simavr-vcd AVR VCD control Discovers signals and records VCD on a running simavr-host
renode-host STM32 Host Runs an STM32 firmware ELF on Renode: UART socket + GDB server + Robot server
renode-vcd STM32 VCD control Discovers GPIO pins and records VCD on a running renode-host
sim-bridge-skill — Skill installer Installs the bundled AI-agent skill into an agent skills directory

Note: simavr-host / simavr-vcd only support Linux (POSIX PTY + socket APIs). renode-host / renode-vcd work on Linux and macOS.

Installation

From PyPI

pip install sim-bridge

For STM32 (Renode) support, also install renode-run (not on PyPI):

uv tool install git+https://github.com/antmicro/renode-run.git

From source

git clone <repo-url> && cd sim-bridge
uv tool install .          # recommended
# or
pip install .

System dependencies

For simavr-host (AVR simulation):

# Debian/Ubuntu
sudo apt install build-essential libsimavr-dev rapidjson-dev
  • g++ — compiles the bundled C++ bridge on first run (cached in /tmp/sim_bridge/)
  • libsimavr-dev — provides libsimavr, libsimavrparts, and headers (compatible with simavr 1.6 and 1.8)
  • rapidjson-dev — C++ JSON parser for the control protocol

For renode-host (STM32 simulation):

uv tool install git+https://github.com/antmicro/renode-run.git

renode-run manages the Renode binary; sim-bridge calls it automatically.

Quickstart

AVR (simavr)

You need an AVR firmware ELF file (e.g. built with cmake -B build -DMCU=atmega328p . && cmake --build build).

# Terminal 1: launch simulation host
simavr-host build/atmega328p_GRBL_Debug.elf --gdbport 1234
# → UART PTY:   /tmp/simavr-uart-pty
# → GDB server: localhost:1234
# → VCD control port: auto (written to /tmp/simavr-bridge.port)

# Terminal 2: record waveforms
simavr-vcd list                        # discover available signals
simavr-vcd start -s timer1 -f out.vcd  # start recording (atomic)
# ... drive the firmware through /tmp/simavr-uart-pty ...
simavr-vcd stop                        # stop → out.vcd written

# View waveform
gtkwave out.vcd

Signal names follow simavr's module convention: <module>.<signal> (e.g. timer1.compa, uart0.rxd, portb.pb3).

Signal groups (shorthand): use the module name as a group. Common groups on ATmega328P: portb, portc, portd, timer0, timer1, timer2, uart0, adc, spi, twi, all.

STM32 (Renode)

You need a firmware ELF file and a Renode .resc platform script. the .resc Must followresc-template.md

# Terminal 1: launch simulation host
renode-host \
    --resc platform.resc \
    --firmware build/stm32f103_GRBL_Debug.elf \
    --gdbport 3333
# → UART socket:  localhost:12345 (talk to the firmware here)
# → GDB server:   localhost:3333
# → Robot server: auto (written to /tmp/renode-bridge.port)

# Terminal 2: record waveforms
renode-vcd list                         # discover GPIO pins
renode-vcd start -s PA0 -s PA1 -s PA3   # start recording specific pins
# ... drive the firmware at localhost:12345 ...
renode-vcd stop -f out.vcd              # stop → out.vcd written

# View waveform
gtkwave out.vcd

Signal names use STM32 convention: PA0, PB5, PC15, or entire ports gpioPortA, gpioPortB, etc. Use all (default) for all pins.

Talking to the firmware over UART

The UART is a plain byte channel, so it accepts whatever protocol your firmware speaks — text commands, binary framing, or G-code as in this example. On STM32 it is a TCP socket; on AVR it is a PTY.

Interactive (PuTTY / gtkterm): connect to 127.0.0.1:12345 (Raw mode).

Command line:

echo -e '$X\nG1 X100 Y100 F1000\n' | nc -q10 127.0.0.1 12345

Python script:

import socket, time

s = socket.create_connection(('127.0.0.1', 12345))
time.sleep(2); s.recv(4096)              # wait for boot

s.sendall(b'$X\n'); time.sleep(1); s.recv(4096)    # unlock
s.sendall(b'G1 X100 Y100 F1000\n')                  # move
time.sleep(10); s.recv(4096)

s.close()

VCD recording details

State machine (host-authoritative):

idle ──start──► recording ──stop──► idle
  • start is atomic: registers hooks + begins simulation in one step. Returns error if already recording.
  • stop requires --file: pauses simulation, drains transitions, writes VCD, returns to idle.
  • status: query current state and transition count.
  • list: enumerate recordable signals on the running firmware, so you never guess a signal name.

Command reference

simavr-host

simavr-host FIRMWARE [--gdbport PORT] [--uart INDEX] [--freq HZ] [--mcu NAME]

Runs the given AVR firmware ELF on simavr. The bundled C++ bridge (simavr_uart_bridge.cpp) is compiled on first run and cached by source hash; it provides the UART PTY and the VCD signal hooks.

simavr-vcd

simavr-vcd list                          # list available signals
simavr-vcd start [-s SIGNAL]... [-f FILE] [--period US]
simavr-vcd status
simavr-vcd stop

renode-host

renode-host --resc FILE --firmware FILE [--gdbport PORT] [--uartport PORT] [--robot-port PORT]

Runs the given STM32 firmware ELF on Renode (through renode-run), using the supplied .resc platform script for the MCU and board description.

renode-vcd

renode-vcd list [-g PORT_LETTER]
renode-vcd start [-s SIGNAL]...
renode-vcd status
renode-vcd stop -f FILE

Injects GPIO state-change hooks into the running Renode instance over its Robot XML-RPC server, so recording works for any STM32 part whose GPIO ports Renode models.

AI agent skill (Claude Code, CodeArts, Cline, ...)

sim-bridge ships with an AI agent skill so a coding agent can drive the whole build → simulate → record → inspect loop for you. The skill is bundled inside the Python package (sim_bridge/skills/sim-bridge-firmware/) and installs into your agent's skills directory with one command — no repository clone needed:

sim-bridge-skill list        # show the bundled skill, its files, and source path
sim-bridge-skill install     # auto-detect the agent skills directory

Explicit targets:

sim-bridge-skill install claude          # ~/.claude/skills
sim-bridge-skill install codeartsdoer    # ~/.codeartsdoer/skills
sim-bridge-skill install cline           # ~/.cline/skills
sim-bridge-skill install copilot         # ~/.copilot/skills
sim-bridge-skill install dsh             # ~/.dsh/skills
sim-bridge-skill install --dest ./.claude/skills   # any other directory

Options: --force replaces an existing copy, --dry-run previews without writing, and --symlink links to the bundled copy instead of copying (handy in a source checkout). Reload or restart your agent session afterwards so the skill is picked up.

Once installed, the agent knows:

  • how to build Debug firmware for AVR (simavr) and STM32 (Renode) and launch the host;
  • how to record GPIO / timer / UART signals to VCD and analyse them in GTKWave;
  • how to set up VS Code tasks.json / launch.json for breakpoint debugging over GDB;
  • the platform pitfalls: -DUSE_USB=OFF, -DHAL_SERIAL_DMA=OFF, renode-run only, flash overflow in Debug builds, renode-vcd stop -f, and the one-shot state machine.

Skill contents (also readable directly in the repository):

File Contents
src/sim_bridge/skills/sim-bridge-firmware/SKILL.md Entry point: workflow, platform choice, hard constraints
references/avr-simavr.md AVR build, simavr-host, signal groups, UART PTY
references/stm32-renode.md STM32 build, renode-host, GPIO recording, UART socket
references/resc-template.md Renode .resc rules and a full template
references/vscode-config.md VS Code debug configuration templates
references/adapting-to-your-project.md Adopting sim-bridge in any firmware project
references/troubleshooting.md Build, port, state-machine, and empty-VCD errors

License

MIT

Release files for sim-bridge 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sim-bridge 0.1.1
File Size Uploaded
sim_bridge-0.1.1.tar.gz 38.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sim-bridge 0.1.1
File Interpreter ABI Platform
sim_bridge-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 93.6 kB

Release files / sim_bridge-0.1.1.tar.gz

Download URL sim_bridge-0.1.1.tar.gz
Size 38.5 kB
Tags Source
SHA-256 checksum
How to use checksums
606e2404de780ab77d467a0e40bbd81025dd9e78124899722ab7d9576d286c43
BLAKE2b-256 checksum
How to use checksums
78fb62fe729fd5d39b571f1b2dd07908d9e02e3347d1cbdb6a1b32924690fc14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / sim_bridge-0.1.1-py3-none-any.whl

Download URL sim_bridge-0.1.1-py3-none-any.whl
Size 55.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd5ae330713060924c98683b191a05b26310ef91ad7888263db252bb1cb6ed91
BLAKE2b-256 checksum
How to use checksums
f0274edf1621b986b1535d334da6bfb4acda412e17e54796568902ac4541177b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page