Repository navigation
esp32sim 0.1.0
The first tagged release of esp32sim: an instruction-level emulator that runs unmodified ESP-IDF and Arduino firmware for the ESP32-S3 (two Xtensa LX7 cores) and the ESP32-C3 (RISC-V), from the real mask ROM through the second-stage bootloader into the application, with the SoC peripherals modelled at the register level and boards modelled as devices on the pins.
What runs today
- ESP32-S3: mask ROM → bootloader → FreeRTOS apps; SPI flash and octal PSRAM through the cache MMU; systimer, timer groups, interrupt matrix per core, GPIO, USB-Serial/JTAG, UARTs, I2C, GDMA with I2S/LCD_CAM/RMT, SHA/AES/RSA accelerators, WiFi MAC driven by Espressif's closed blobs against a virtual AP with WPA2 and a user-mode NAT to the real network.
- ESP32-C3: unmodified IDF firmware from the mask ROM to
app_main, verified line by line against a real module. - Boards: Atech 14-port Pocket Synth (ST7735, WS2812 ring, encoder, buttons, I2S audio), Waveshare ESP32-S3-CAM-OV5640, Waveshare ESP32-S3-Touch-LCD-4B; a bare module for stock projects.
- A basic-block interpreter and an AArch64 JIT (2× real time on the SID player), the interpreter being the bit-exact oracle (
--no-jit). - The same emulator in the browser (WebAssembly): https://joakimeriksson.github.io/esp32sim/
- Live board UI, action scripts, WAV/PNG capture, hardware differential testing over JTAG.
Architecture (this release)
One machine for every chip (esp-soc), the shared peripheral IP in esp-periph behind a Device trait and one device_set! table per chip, the CPU contract in emu-core. Adding a peripheral is one implementation and one table line; a board is one impl BoardModel; a chip plugs its cores, bus and interrupt routing into the machine. See docs/adding.md.
Analysis
--profile-blocks, --coverage, --irq-latency and --vcd run at full speed on the block path; --trace, --break, --watch, --regtrace, --profile, --regstat and --debug are there too.
Regression bar
cargo test --release --workspace -- --include-ignored runs the committed demo firmware and pins console text, audio (SHA-256) and instruction counts; CI runs it on every push. Every change in the refactor that produced this release was held to byte-identical output and a benchmark within noise.
Install
cargo build --release # target/release/esp32sim, esp32sim-c3or the macOS arm64 binaries attached below. The mask ROM ELFs come with ESP-IDF (~/.espressif/tools/esp-rom-elfs/), or pass --rom.
Not in this release: cycle-accurate timing (1 instruction = 1 cycle by design; a CostModel hook exists), C3 WiFi/BLE, --boot app on the C3.