What this is · how it works

About

A cycle-driven emulator for the Arduino UNO R4 Minima that runs real Arduino firmware — the actual Blink.ino, the real ArduinoCore libraries — in the browser via Rust compiled to WebAssembly.

On this page: The product · The chip · How it is proven · Limits

The product

This page exists for one reader: someone deciding whether to trust the Demo tab next to it. The emulator models the RA4M1 microcontroller at the register level — every peripheral is a Rust model behind the real memory-mapped address — and runs unmodified firmware images built with arduino-cli against ArduinoCore-renesas 1.6.0. The Arduino core wraps Renesas FSP, and FSP runs on the emulated core, so register-accurate models are enough: no firmware is rewritten or stubbed for the emulator.

The browser build is small on purpose: the R4-only core links just wasm-bindgen plus a panic hook — no STM32 leftovers, no ESP32 radio. The WiFi board's second chip stays parked until its code is ready.

The chip

The board is the Minima: Renesas RA4M1 R7FA4M1AB3CFM, a Cortex-M4F at 48 MHz with 256 KB of flash at 0x00000000, 32 KB of SRAM at 0x20000000, and 8 KB of data flash. The on-board bootloader occupies 0x0000–0x3FFF, so apps link at 0x4000 and the emulator boots from that table. The same silicon ships on the EK-RA4M1 kit in a bigger package — the Demo page has a tab that boots a bare-metal image at zero and lights its P106 LED1 to prove it.

How it is proven

Every peripheral carries a proof, and every proof runs the same shape: build a fresh emulated system, write real MMIO, tick, assert state. Register-level proofs pin down single peripherals; firmware proofs boot vendored r4*.bin images — the real Arduino libraries driving the real FSP drivers — and assert the observable outcome: a toggled LED, a DAC sample, a round-tripped byte, an enumerated USB device.

Two Rust suites hold the line: the snapshot core (127 tests: 37 legacy CPU/system + 90 R4 proofs) and the small R4-only core (90 R4 proofs), always run single-threaded because the cores share process globals. When a firmware stall traced back to the CPU — predicated Thumb flags, the flagless MOV-register alias, the DTC repeat-length counter — the fix went into both cores with a GAS-assembled encoding probe as ground truth, and the upstream bug tracker got the entry. Nothing is worked around in board code.

The Demo page replays 25 of those proofs live: each tab boots its firmware image in the WASM core and polls live registers for the verdict. Flag traces read status registers only — data registers are never touched, because reading one would eat the firmware's byte.

Limits

Back to demo Read the docs