Skip to content
SimanticDashboard

Meet your virtual hardware.

Simantic runs your firmware on simulated MCUs, so you can observe and debug your system without a physical board.

Introduction

The Simantic CLI ships as a single binary named sim. It authenticates against the Simantic backend, resolves your MCU's configuration on demand (--mcu), and drives a simulation of your firmware.

Simulator access is by approval

You need an approved account to run firmware. Before spending time on installation or account setup, email us to request access and tell us which hardware you want to simulate.

Installation

Run the installer, which downloads the zip for your platform, verifies its checksum, extracts the sim binary to ~/.local/bin, and hands off to sim login if the shell is interactive. An existing install can also update itself with sim update (see Updating).

curl -fsSL https://simantic.com/install | sh

Published platforms are linux-x64 and osx-arm64. Pass --check to print the latest version without installing, or -h for the full option list.

Install via Homebrew

brew tap simantic-dev/simantic
brew install simantic

Installs the same sim binary as the script above. Sign in with sim login after installing, and use brew upgrade simantic to update.

Authentication

Create an API key

  1. Sign in and open Account → API Settings.
  2. Enter a name for the token, then select Create token.
  3. Copy the token immediately. The full key is shown only once.

An API key identifies your account. Creating one does not grant simulator access; running firmware still requires approval.

Sign in from the CLI

Use the browser sign-in flow for an interactive terminal:

sim login

For manual setup with an API key, use sim auth.

The auth command prompts for your email and personal access token and writes them to ~/.sim_id (mode 0600 on Unix).

sim auth
# Email: you@example.com
# API key: smtc_xxxxxxxxxxxxxxxx
# Credentials saved for you@example.com

The API key prompt hides input on a TTY (echoes nothing while you type). If stdin is redirected, it falls back to a normal line read.

The token must start with smtc_. The file format is:

EMAIL=you@example.com
API_KEY=smtc_xxxxxxxxxxxxxxxx

Replace or revoke a key

Open API Settings and select Revoke for the key, then confirm. If you lose a key, create a replacement and run sim auth again with it.

Keep keys out of source control and shared logs. If authentication fails, check that the key starts with smtc_, has not been revoked, and belongs to the email you entered.

Listing MCUs

The models command calls the backend and prints the supported MCU model names. The list is fetched fresh every time — nothing is cached on disk.

sim models
# Supported models:
#   stm32f401re
#   stm32f401ce
#   stm32f401ve

Running a simulation

The root command runs a simulation. Provide an ELF binary and a backend MCU model (--mcu).

sim --mcu stm32f401re --elf ./firmware.elf
OptionRequiredDefaultNotes
--mcuyes—MCU model returned by models.
--elfyes—Path to the ELF firmware to load.
--timeoutno15Simulation timeout in seconds (≥ 0).
--outputno./output.txtPath to write simulation output.
--configurationno—STM32CubeMX .ioc configuration file used to render the replx template before simulation.
--asciinooffRender UART output as ASCII strings (one line per record) instead of wrapped hex bytes.
--only-messagesnooffStrip the [timestamp] (peripheral) prefix from each output row and emit just the payload.
--groupno—Hierarchical group path. Accepts one or more space-separated values; the first is the top-level group and each subsequent value is a subgroup of the previous (e.g. --group team-a board-x rev2).
--use-cachednooffReuse a cached copy of the MCU's replx from ~/.sim_cache instead of fetching from the backend. On a cache miss the replx is fetched and cached for next time. --mcu flows only.
--real-timenooffPin the sim to ~1× wall-clock. By default the sim free-runs as fast as the host allows; pass this only when something needs real-world pacing.

If the token is missing or invalid, or the MCU is unknown, the command exits with status 1 and a descriptive error on stderr.

Output format

By default, each UART record is rendered as one or more rows of hex bytes wrapped at 16 bytes per row, prefixed with the record's virtual timestamp and source peripheral label:

[0.001234s] (usart2) 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 0D 0A

With --ascii, each record becomes a single line of printable ASCII (bytes outside 0x20–0x7E, including CR/LF, collapse to .):

[0.001234s] (usart2) Hello, world!..

With --only-messages, the [timestamp] (label) prefix is dropped and only the payload is written — useful when piping into another tool that expects a clean stream. --ascii and --only-messages compose:

Hello, world!..

Updating

The update command updates the installed sim binary in place to the latest released version. It reads the published latest.json manifest, compares it against the running binary's version, and — if newer — downloads the build for your platform, verifies its SHA-256, and atomically swaps the running executable.

sim update          # install the latest release if one is available
sim update --check  # report whether a newer version exists, without installing
  • Replaces the file at the running executable's path.
  • Supported on the published platforms only (linux-x64, osx-arm64); other platforms print a message and exit non-zero.
  • Never downgrades — a release will not replace a newer or equal local version.
  • Makes no backend or credential calls; it only reads the public release bucket. If sim lives in a system location, run with sufficient permissions to overwrite it.

Network behavior

Backend calls happen on --mcu flows (and on auth / models). The backend calls are:

  • validate-token — called before fetching MCU details.
  • list-supported-mcus — called by models.
  • get-mcu-details — called by the root command when --mcu is set.

All three require an Authorization: Bearer <smtc_…> header. By default nothing is cached on disk; if the backend is unreachable, those flows fail.

Passing --use-cached opts into a per-MCU on-disk cache under ~/.sim_cache. The first run for a given --mcu still fetches get-mcu-details and writes the result to ~/.sim_cache/<key>.json. Subsequent --use-cached runs read that file and skip both validate-token and get-mcu-details, so a cached MCU simulates with no network calls. Set SIM_CACHE_DIR to use a different directory, and delete the file (or the whole directory) to force a refresh.