关于 ESP32 Simulator
ESP32 Simulator 让编码 Agent 在本地 ESP32 指令级模拟器中启动并测试固件,适用于没有开发板时的嵌入式开发反馈循环。它通过 MCP 返回串口日志、崩溃信息和屏幕截图,并可脚本化操作虚拟硬件。
主要功能
- 01在本地模拟器中启动 ESP32 固件
- 02检查串口输出并断言日志内容
- 03捕获崩溃信息和显示屏截图
- 04脚本控制按钮、GPIO、UART 和触摸
- 05支持虚拟 WiFi 与多种芯片型号
适用场景
- 01无实体开发板时验证 ESP32 固件
- 02检查启动日志是否符合预期
- 03模拟按钮输入并测试固件响应
- 04在 CI 中运行固件模拟断言
MCP 相关
MCP 服务向编码 Agent 提供运行、断言、脚本控制和截图工具,返回控制台日志、停止原因、崩溃信息或 PNG。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
6收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| chip | enum | 否 | 目标芯片系列。默认值为 s3(ESP32-S3)。esp32 | s3 | c3 | c6 |
| wifi | string | 否 | 附加一个带 DHCP/DNS/NAT 的虚拟接入点。规格格式如 'ssid=demo,psk=secret'(键:ssid、psk、chan、bssid),也可直接填写开放网络的 SSID。站点将获得 10.0.2.15。 |
| board | string | 否 | 开发板型号:S3:'atech14'(默认)、'waveshare-lcd4b'、'waveshare-amoled18-v2'、'waveshare-cam';C6:'waveshare-c6-lcd147';ESP32:'ttgo-tdisplay'、'esp32dev-loopback';裸模块使用 'none'。C3 没有开发板,此参数请省略。参见 sim_list_boards。 |
| appBin | string | 否 | 应用程序二进制文件(.bin)的直接路径。 |
| console | enum | 否 | 要捕获的控制台源(默认:both = UART0 + USB-Serial/JTAG)。ESP-IDF 在两个控制台上镜像输出的行只显示一次。uart0 | usb | both | all | none |
| ptableBin | string | 否 | 分区表文件 partition-table.bin 的直接路径(使用 appBin 进行真实 ROM 启动时需要)。 |
| maxSeconds | number | 否 | 模拟运行的最长时间(秒)(默认值:10s)。模拟通常比实时运行更快。 |
| projectDir | string | 否 | ESP-IDF 项目根目录或构建目录的路径。省略时使用当前工作目录。 |
| bootloaderBin | string | 否 | bootloader.bin 的直接路径(使用 appBin 进行真实 ROM 启动时需要)。 |
| stopAfterExceptions | number | 否 | 在发生 N 次 CPU 异常后停止(默认未设置)。会统计每次异常,包括 Xtensa 固件频繁发生的窗口溢出/下溢异常,因此这是调试辅助功能,而非崩溃检测器。无论如何,都会根据日志检测 panic。 |
详细介绍
esp32sim-mcp
你的 Agent 编写 ESP32 固件、启动并测试它。不需要开发板,也不需要账号。
一次真实的 Claude Code 会话,实时录制(仅裁剪了末尾的等待片段):它修改 ESP-IDF 的 hello_world,由于未安装 ESP-IDF 而在 Docker 中构建,并在模拟器中检查控制台。
编码 Agent 擅长编写嵌入式 C 代码,但运行代码时却无能为力:桌上没有开发板时,“能编译”就是反馈循环的终点。
esp32sim-mcp 补上了这一环。它为 Claude Code、Codex、Cursor 或任何 MCP 客户端提供一组工具,可在本地指令级 ESP32 模拟器 esp32sim 中启动 Agent 刚刚构建的固件,并返回芯片输出的内容、是否发生崩溃,以及显示屏上显示的内容。Agent 读取结果、修复代码并再次尝试,就像你在工作台上接着开发板调试一样。
- 🔌 无需硬件,无需云端。 一切都在你的计算机上运行。不需要账号、令牌或开发板。
- 🧬 真实的启动链。 在 ESP32-S3、C3、C6 和经典 ESP32 上运行 Espressif 的掩膜 ROM、ESP-IDF 引导加载程序以及未经修改的应用。
- 📡 不止于控制台。 虚拟 WiFi 接入点,支持 DHCP、DNS 和 NAT,还支持按钮、旋转编码器、GPIO、UART 输入、触摸和显示屏截图。
- 🧪 断言,而非凭感觉。
sim_expect返回通过/失败结果和缺失的确切行,让 Agent 知道要修复什么。 - ⚡ 速度快。 仿真通常快于实时运行:在 Apple 芯片上,WiFi 站点接入网络的 8 秒仿真时间约需 0.6 秒。
- 🤖 附带技能。
init会安装一项 Agent 技能,指导 Agent 完成编写 → 构建 → 仿真 → 修复的循环;即使未安装 ESP-IDF,也会指导如何在 Docker 中构建。
快速开始
npx -y esp32sim-mcp setup # emulator + mask ROMs, pinned and SHA-256 verified
cd your-esp-idf-project
npx -y esp32sim-mcp init # registers the MCP server and the skill for your agents
然后让你的 Agent 执行一项能在串行控制台上看到效果的任务:
添加一个每秒打印一次的计数器,构建它,并在模拟器中检查它是否计数到 5。
要求:Node.js 22+,以及 ESP-IDF 或 Docker(用于构建固件)。预构建的模拟器二进制文件支持 macOS(Apple 芯片)和 Linux(x64、arm64);请参阅其他平台。
Agent 看到的内容
在一次真实会话中,Agent 调用:
{
"tool": "sim_expect",
"projectDir": ".",
"chip": "s3",
"board": "none",
"maxSeconds": 10,
"patterns": ["Hello world!", "Counter: 1", "Counter: 2", "Counter: 3", "Counter: 4", "Counter: 5"]
}
并得到:
### Expect Test: ✅ PASSED
Matched 6 / 6 patterns.
- ✅ Matched (line 54): `Hello world!`
- ✅ Matched (line 55): `Counter: 1`
...
- ✅ Matched (line 65): `Counter: 5`
#### Full UART Logs:
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0xf (SPI_FAST_FLASH_BOOT)
...
如果发生问题,它会收到崩溃信息(Guru Meditation Error、栈溢出、断言失败、堆损坏)以及此前的日志,并明确指出缺失的模式。
工具
| 工具 | 功能 |
|---|---|
sim_run | 启动固件并返回控制台日志、停止原因、模拟时间和任何 panic。 |
sim_expect | 运行固件并断言控制台中出现字符串或正则表达式,默认按顺序匹配。 |
sim_script | 在模拟时间戳驱动硬件:按下/释放按钮、设置 gpio 电平、转动 knob、输入 uart/serial 数据、touch、stop。 |
sim_screenshot | 返回指定模拟时间下开发板显示屏的 PNG 图像。 |
sim_list_boards | 列出芯片、开发板、显示屏和输入设备。 |
sim_doctor | 检查模拟器和 ROM,并说明如何修复缺失项。 |
所有工具都接受 projectDir(通过 build/flasher_args.json 查找 ESP-IDF 构建),或显式指定的 appBin/bootloaderBin/ptableBin 路径,以及 chip、board 和 wifi(例如 ssid=demo,psk=secret)。系统会捕获 UART0 和 USB-Serial/JTAG 控制台,因此无论项目将日志输出到哪个控制台,输出都会显示。
工作原理
flowchart LR
A["Coding agent<br/>(Claude Code, Codex, Cursor)"] -- "edits code,<br/>runs idf.py build<br/>(local or Docker)" --> B["ESP-IDF build/"]
A -- "MCP: sim_expect, sim_run, ..." --> C["esp32sim-mcp"]
C -- "flasher_args.json" --> B
C -- "spawns" --> D["esp32sim emulator<br/>mask ROM → bootloader → app"]
D -- "UART / USB-JTAG, panics,<br/>display, virtual WiFi" --> C
C -- "pass/fail, logs, PNG" --> A
esp32sim-mcp 是一层精简且经过测试的封装:它查找构建,将工具调用转换为 esp32sim 命令行调用,分离并去重两个控制台的输出,检测 panic,并整理结果以供 Agent 使用。模拟本身由 esp32sim 完成。
在 CI 中使用
无需 Agent 也能运行相同的检查,通过时退出代码为 0,失败时为 1。以下是一个构建固件并断言启动日志的 GitHub Actions 任务:
jobs:
firmware:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22
- name: Build
run: docker run --rm -v "$PWD:/project" -w /project espressif/idf:v5.5.4 idf.py set-target esp32s3 build
- name: Install the emulator
run: npx -y esp32sim-mcp setup
- name: Boot and check the console
run: npx -y esp32sim-mcp expect --max-seconds 10 --pattern "app_main" "Counter: 5"
本仓库自己的 CI 也会使用 examples/hello-esp32 执行这些操作,其中包括通过脚本按下按钮。
所有 CLI 命令
esp32sim-mcp setup # install emulator + ROMs (or: install-emulator, fetch-roms)
esp32sim-mcp init [--global] [--agent claude-code|codex|cursor|claude-desktop] [--dry-run]
esp32sim-mcp run [-p dir] [--chip s3] [--board none] [--max-seconds 5] [--wifi ssid=x,psk=y]
esp32sim-mcp expect --pattern "a" "b" [--unordered] [--script actions.txt] [...run options]
esp32sim-mcp list [--chip c6]
esp32sim-mcp doctor
esp32sim-mcp serve # the MCP server (what agents launch)
支持的芯片和开发板
| 芯片 | 开发板(board) |
|---|---|
| ESP32-S3 | atech14(默认:ST7735 TFT、按钮、旋转编码器、LED 灯环、音频)、waveshare-lcd4b(480×480 触摸屏)、waveshare-amoled18-v2(368×448 AMOLED 触摸屏)、waveshare-cam(OV5640 摄像头)、none |
| ESP32-C3 | 仅控制台(无开发板模型) |
| ESP32-C6 | waveshare-c6-lcd147(172×320 LCD)、none |
| ESP32(经典款) | ttgo-tdisplay(135×240 TFT)、esp32dev-loopback、none |
标准 ESP-IDF 项目请使用 none。虚拟 WiFi 接入点支持全部四种芯片。
Agent 设置
init 会检测你使用的 Agent,并为每个 Agent 配置相应设置。默认在固件项目中运行;--global 则会写入用户级设置。
| Agent | MCP 服务(项目 / --global) | 技能(项目 / --global) |
|---|---|---|
| Claude Code | .mcp.json / claude mcp add --scope user | .claude/skills/ / ~/.claude/skills/ |
| Codex | ~/.codex/config.toml(仅用户级) | .agents/skills/ / ~/.codex/skills/ |
| Cursor | .cursor/mcp.json / ~/.cursor/mcp.json | .cursor/skills/ / ~/.cursor/skills/ |
| Claude Desktop | 仅限 --global | — |
现有条目会保留,重复运行不会产生任何更改,无法解析的配置文件也不会被修改。
Claude Code 插件。 你也可以不使用 init,而是将服务和技能一起安装为插件,供所有项目使用:
/plugin install esp32sim --marketplace stramanu/esp32sim-mcp
MCP 注册表。 该服务已发布到 官方 MCP 注册表,名称为 io.github.stramanu/esp32sim-mcp。对于其他 MCP 客户端:
{
"mcpServers": {
"esp32sim": { "command": "npx", "args": ["-y", "esp32sim-mcp", "serve"] }
}
}
其他平台
setup 会在 macOS arm64 和 Linux x64/arm64 上安装预构建二进制文件。这些二进制文件由本仓库的模拟器工作流从源代码构建,并附带签名的构建来源证明(gh attestation verify <archive> -R stramanu/esp32sim-mcp)。在其他平台上,请使用 Cargo 构建 esp32sim(rustup),并固定到此版本经过测试的提交:
cargo install --locked --git https://github.com/mikroverk/esp32sim --rev f535f3b42293a76ab64c231a0425f35857ab6cf1 esp32sim
npx esp32sim-mcp fetch-roms
ESP32SIM_PATH 指向其他位置的模拟器二进制文件,ESP32SIM_ROM_DIR 指向另一个 ROM 目录;ESP-IDF 安装目录中的 ROM 会自动查找。
对比
| 无需开发板即可运行 | 需要账户或令牌 | 专为 Agent 打造 | |
|---|---|---|---|
| esp32sim-mcp | ✅ 本地模拟器 | 否 | ✅ MCP 服务 + 技能 |
| Wokwi CLI MCP | ✅ | 是(WOKWI_CLI_TOKEN) | ⚠️ 实验性 |
| esparagus(Espressif) | ❌ 刷写真实硬件 | 否 | ✅ |
| 单独使用 esp32sim | ✅ | 否 | ❌ 命令行和 Web 界面 |
esparagus 是顺理成章的下一步:先用 esp32sim-mcp 进行模拟,再在真实开发板上确认。
限制
- 模拟器并非硅芯片。esp32sim 未建模的外设、RF 时序和 Bluetooth 在此都无法模拟;发布前请在硬件上确认。
- Agent 自行构建固件(使用
idf.py,在本地或 Docker 中);MCP 服务不会进行编译。 - Windows 尚未经过测试。
贡献
欢迎提交问题和拉取请求。开发环境设置以及端到端测试如何针对真实模拟器运行,请参阅 CONTRIBUTING.md;变更内容请参阅 CHANGELOG.md。
致谢
- esp32sim,由 Joakim Eriksson、Alice 和 Mattia Fiumara 开发:实际执行模拟工作的模拟器(MIT)。
- Espressif:ESP-IDF 和 mask ROM ELF 文件(Apache-2.0)。
- Model Context Protocol。
许可证
MIT © Emanuele Strazzullo
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。