Skip to content

esp32sim 0.1.0

Choose a tag to compare

@joakimeriksson joakimeriksson released this 02 Sep 10:38
· 1459 commits to main since this release

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-c3

or 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.