1. esp32sim 简介
esp32sim是一个指令级 ESP32 模拟器,可以直接跑未修改的原版 ESP-IDF 固件。
https://github.com/mikroverk/esp32sim
很多模拟器只运行重新编译过的业务代码,esp32sim 不一样,它从芯片的 mask ROM 开始执行,经过真实的二级 bootloader 和 ESP-IDF 启动代码,进入 FreeRTOS 后再运行应用。
这意味着启动日志、复位原因、分区表读取和外设初始化顺序,都可以模拟运行。

2. 零安装入口
零安装入口在项目主页,打开后能直接看到芯片支持范围、演示和文档。
https://mikroverk.github.io/esp32sim/

进入 Touch-LCD-4B 演示页,点右上角的 Configure。
这里能看到实际要喂给仿真器的东西:板卡型号、Flash 大小、PSRAM 大小,以及 ROM、bootloader、分区表和应用文件。
配置如:
board: waveshare-lcd4b
flash: 16 MB
PSRAM: 8 MB
2.1 运行demo
从 Demos 里选 Touch-LCD-4B energy panel,按下 Boot。状态离开加载阶段后,界面会切换到一块 480×480 的触屏设备,UART 控制台开始滚动。

3. 换成自己的固件
ESP-IDF、PlatformIO 或 Arduino 的构建目录如:
build/bootloader/bootloader.bin
build/partition_table/partition-table.bin
build/<应用名>.bin
PlatformIO 通常在 .pio/build/<env>/ 下;Arduino 导出的文件名带有 .ino 前缀。
三个文件分别填到 bootloader.bin、partition-table.bin 和 app.bin。
如果板卡不是内置型号,先把 board 换成 none,让固件只走串口控制台。这样能先把启动问题与显示、触摸、音频等板级模型分开。
Flash 和 PSRAM 必须与固件编译时的配置一致。
ELF 文件是可选项。不填也能启动。
4. 用 CLI 固定一次结果
这里使用发布包,进入 WSL 后解包,先确认版本:
tar xzf esp32sim-0.3.0-linux-x86_64.tar.gz
cd esp32sim-0.3.0
./esp32sim --version
4.1 准备 ROM
ROM 要单独获取。发布包里带了下载脚本,文件会按 SHA-256 校验:
tools/fetch-rom-elfs.sh roms
export ESP32SIM_ROM_DIR=$PWD/roms
下面运行仓库里的 Touch-LCD-4B 演示固件:
FW=/path/to/esp32sim/web/wasm/fw/public
./esp32sim --board waveshare-lcd4b \
--flash-mb 16 --psram-mb 8 \
--boot rom --rom roms/esp32s3_rev0_rom.elf --console uart0 \
--bootloader "$FW/panel-bootloader.bin" \
--ptable "$FW/panel-ptable.bin" \
--app "$FW/panel-demo.bin" \
--flash-at "0x610000=$FW/energydata.json" \
--tft-png panel.png --max-seconds 8
其中,参数--max-seconds 不能省略。没有设置运行时间,运行不会自己停。

--tft-png panel.png 保存的是固件实际画到屏幕上的结果:

4.2 找不到 ROM?
发布包不附带 Espressif 的 mask ROM。没有设置路径,直接运行会提示ELF找不到:
no esp32s3 mask ROM ELF found
这时先运行 tools/fetch-rom-elfs.sh roms,再通过 --rom 或 ESP32SIM_ROM_DIR 指向 ROM 目录。

6. 总结
esp32sim最合适的是启动链和软件联调。板子没到,先让 ROM、bootloader、分区表和应用完整跑一遍;改完启动配置,用固定时间上限跑回归;做 LVGL、触摸、音频或网络协议时,先把业务逻辑推进到能观察的阶段。
------------ END ------------