Boot your firmware. Break it. Prove it survives.
Macrohill boots your real firmware on a live, deterministic emulation of your board. Inject hardware faults, author test cases with AI or by hand and run them against the running system, profile where every instruction and byte goes, and replay recorded sensor data to catch regressions. No lab. No bench. Just software.
Hardware behavior shows up in the field, not the lab.
Firmware teams test on a handful of boards under ideal conditions. The behavior that takes products down, a marginal power rail, a flipped bit, an I²C peripheral that stalls when it heats up, a sensor that drifts, only shows up at scale, after ship. Bench testing is slow, destructive, and impossible to run on every commit.
From board file to graded firmware in three steps.
Point Macrohill at your project. It builds an emulation, boots your binary, and runs your tests automatically.
Import your board definition. Macrohill maps CPUs, peripherals, buses, and power domains into a deterministic model of your hardware. No manual register plumbing.
Your unmodified firmware binary boots on the emulation exactly as it would on silicon. Deterministic, inspectable, and fully reproducible.
Drive the running system with test cases, inject faults, profile it, and replay recorded data. Macrohill grades whether your firmware detected, recovered, or silently failed.
A catalog of what actually goes wrong in silicon.
Rail sag, droop, and dropout across supply domains, including partial brownouts that half-boot peripherals.
Single-event upsets in RAM, flash, and registers. Model radiation, aging, and marginal cells deterministically.
I²C stalls, SPI CRC errors, bus contention, and clock-stretch timeouts injected mid-transaction.
Stuck-at, drift, glitch, and total loss of ADC and sensor inputs to test degraded-mode logic.
Jitter, drift, and PLL loss. Surface race conditions and watchdog interactions that only appear off-nominal.
Temperature-driven throttling and electromagnetic bursts modeled as timed disturbances on any peripheral.
Write test cases. Or let the AI write them.
Describe what your firmware should do and Macrohill drafts test cases from your source. Or write them by hand. Every test runs against the live emulation: drive stimuli, assert on decoded signals and log output, and catch numeric drift or boot failures automatically.
# test_bed: nav-degraded-mode.yaml on: brownout 3.3V -> 2.6V @ t=1.2s expect: log: "entering safe mode" # within 50ms signal: nav.state == SAFE drift: heading.mean within 0.5 of golden ──────────────────────────────── ✓ generated 6 cases from nav.c (ai) ✓ log oracle matched +38ms ✓ heading drift 0.21 within tolerance verdict PASS 2 stimuli, 3 assertions
See where every instruction and byte goes.
Capture a profile over any window of a run. Every profile is deterministic, so two runs of the same firmware profile the same way.
Where each processor spends its time, per function. Rank the hottest call stacks by their share of instructions executed.
Heap and fixed-size memory pools in use, plus peak stack per thread. Catch leaks and overflows before they reach silicon.
Instruction rate over the window, busiest peripherals, and interrupt counts, as a live picture of what the system is doing.
Replay recorded sensor data. Catch regressions.
Record real sensor readings as CSV and replay them into the emulated sensor during a live run. Pin the known-good output, then re-run on every change so drift and regressions fail the build instead of shipping.
# imu0-drive.csv · replayed into accel/gyro t_ms,ax,ay,az 0, 0.01, -0.02, 9.81 10, 0.04, -0.01, 9.79 20, 0.02, 0.03, 9.82 ──────────────────────────────── ✓ fed 4,096 samples into imu0 (accel + gyro) ✓ output matched golden run no drift regression PASS replay 1 dataset
Runs on every commit, like a test suite should.
Drop one job into your existing pipeline. Macrohill gates merges on a resilience score, comments the escaped faults on the pull request, and gives you a deterministic seed to replay any failure locally.
# .github/workflows/macrohill.yml jobs: firmware-test: uses: macrohill/run@v1 with: board: ./boards/nav.yaml firmware: ./build/nav.elf suite: full gate: resilience >= 0.95 ──────────────────────────────── ✓ booted nav.elf on emulation (0.8s) ✓ ran test suite all pass → injecting fault campaign ... caught 11,904 detected + recovered escaped 514 silent failures resilience 0.9586 gate: PASS
Get the Macrohill CLI.
Install in one line with the standalone script, or through Homebrew. The same CLI drives local runs and the CI job that gates your merges.
# macOS / Linux · curl | sh curl -fsSL https://raw.githubusercontent.com/pUrGe12/homebrew-tap/main/install.sh | sh
# macOS / Linux brew install pUrGe12/tap/macrohill
Every injection point, graded.
Macrohill maps the full injection surface of your run. Each cell is a fault site. Dark cells were caught and recovered. Red cells escaped and need attention. Replay any of them with a single deterministic seed.