Repository navigation
The second release of esp32sim, the instruction-level emulator that runs unmodified ESP-IDF, Arduino and Contiki-NG firmware from the real mask ROM through the bootloader into the application. 0.2.0 adds a third chip, the ESP32-C6, boots Linux 6.11 on the ESP32-S3, and gives the S3 a WebAssembly JIT in the browser.
Try it without installing: https://joakimeriksson.github.io/esp32sim/
New chip: ESP32-C6
- One RV32IMAC core, run with
esp32sim-c6. hello_world matches a real Waveshare ESP32-C6-LCD-1.47 in 203 of 204 console lines. - The Waveshare ESP32-C6-LCD-1.47 board: an ST7789 over SPI and DMA, and a WS2812.
- An 802.15.4 MAC with hardware ACKs in both directions, address filtering and CCA. Several motes share one radio medium, in one process or in one browser tab.
- Contiki-NG runs as an unmodified IDF app, up to an RPL/IPv6 root and client.
--coojaruns the C6 as a lock-stepped external mote of Cooja-NG.
Linux on the ESP32-S3
- svermigo/Linux-on-esp32-S3 boots to a shell natively and in the browser, with the esp-hosted network adapter on core 0 and Linux on core 1.
- UART0 has a receive FIFO, so you can type into the console. The page adds an xterm.js terminal tab.
Faster in the browser and on PIE
-
The browser build compiles hot Xtensa blocks and bounded regions to WebAssembly. That covers function entry, variable shifts, scalar floating point, integer operations, and PIE SIMD on WASM SIMD. Differential tests compare the generated blocks with the interpreter.
-
The PIE inference kernels pack their operands at decode and load 128 bits in one read. The dot product and division are compiled in the wasm JIT, and the native JIT calls PIE directly.
-
On pocket-tank, a 4-bit transformer running on PIE, the speed rose as follows:
0.1.0 code 0.2.0 Native (Apple silicon) 0.47× real time 0.72× Node 0.31× 0.63× Headless Chrome 0.32× 0.62×
Boards and peripherals
- The Waveshare ESP32-S3-Touch-AMOLED-1.8 V2: a CO5300 over QSPI and CST820 touch.
- The Atech board gains two NeoPixel Light Grids as a per-voice SID VU meter. Its firmware moved to its own project, atech-firmware.
- S3 boards now use shared device models, one file per board.
- GDMA memory-to-memory channel pairs, board-backed GP-SPI DMA transfers, output-enable toggles seen as GPIO edges, and one RNG model shared by the C3 and C6.
- A shared-time
CostModelhook, with a measured SRAM cost model and priced MMIO reads and LX7 opcodes for the S3.
The demo page
- Fifteen demos: Linux (plain, logged in, and in a terminal), hello_world, the Touch-LCD-4B panel and its SID player, pocket-tank, the C3 and C6 hello_world, the C6 energy scanner, three Contiki-NG setups, and the Atech synth and SID jukebox.
- Each demo has its own page text, and panels that draw rotated are shown upright.
tools/fetch-demo-assets.shfetches the mask ROMs, xterm.js and the Linux image, so the page runs from a checkout exactly as on the live site.
Benchmarks
tools/bench.pyruns interleaved A/B benchmarks. The pace report includes a real-time ratio.- A browser benchmark harness runs pinned workloads, TinyDraw and pocket-tank, and rejects invalid captures.
Fixes
- An S3 image built for 16 MB flash no longer reboot-loops after a software or panic reset. The reboot kept the wrong flash size.
- The
--webserver accepts WebSocket upgrades whatever the header's letter case. - Function stubs read their arguments from the frame the pending windowed call set up. Also fixed: the NTP transmit timestamp fraction, a duplicate AES mapping, C3 read bounds, CO5300 window coordinates split across SPI transfers, and a wasm abort when reading the environment.
Project
- A LICENSE file: MIT, copyright Joakim Eriksson and Alice.
- CI runs Clippy with warnings as errors, the wasm module under Node through the page's manifests, worker pacing tests, and differential tests for generated WebAssembly.
Regression bar
cargo test --release --workspace -- --include-ignored runs the committed demo firmware and pins console text, audio and instruction counts. CI runs it on every push, along with the wasm checks above.
Install
cargo build --release # target/release/esp32sim, esp32sim-c3, esp32sim-c6or use the macOS arm64 binaries attached below. The mask ROM ELFs come with ESP-IDF (~/.espressif/tools/esp-rom-elfs/), or pass --rom.
Thanks to Alice (@aliceisjustplaying) for the browser WebAssembly JIT, the benchmark harness, the cost model, the AMOLED board and the Clippy clean-up.
Not in this release
- Cycle-accurate timing. One instruction is one cycle by default; the cost model is a hook.
- Bluetooth on any chip. The Linux demo stubs out BLE provisioning.
- WiFi on the C3 and C6.
- A block cache or JIT for the RISC-V chips.
- pocket-tank at real time.