Skip to main content

esp32-debug

ESP32 debugging via serial log and USB-JTAG (OpenOCD + GDB). Invoke when user encounters bugs, crashes, or unexpected behavior on ESP32 and needs systematic root cause analysis.

ソース情報

リポジトリ
kukucaiCndy/embedded_ai_skills
ソースの最終更新活動
2026年6月9日 13:44
検出された SKILL.md の言語
複数言語
スター
60
フォーク
12

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
esp32-debug
description
ESP32 debugging via serial log and USB-JTAG (OpenOCD + GDB). Invoke when user encounters bugs, crashes, or unexpected behavior on ESP32 and needs systematic root cause analysis.
# ESP32 Debug — Systematic Troubleshooting ## Overview This skill covers the complete debug workflow for ESP32 projects: - **Serial log debugging** (ESP_LOGI/ESP_LOGE) — lightweight, non-intrusive, preferred first approach - **USB-JTAG debugging** (OpenOCD + GDB) — deep hardware-level debugging - **Combined approach** (serial + JTAG) for complex issues ## Platforms | Debug Method | ESP32 | ESP32-S3/C3/C6/C2/H2 | Hardware Required | |--------------|:-----:|:---------------------:|-------------------| | Serial log | ✅ | ✅ | USB cable only | | USB-JTAG (built-in) | ❌ | ✅ | USB cable only | | External JTAG | ✅ | ✅ | ESP-Prog / J-Link | ## Execution Flow ``` User reports a bug/crash/unexpected behavior ↓ [Step 1] 🔍 环境准备 — Verify dev environment, tools, connections ↓ [Step 2] ❓ 问题理解 — Ask clarifying questions to scope the problem ↓ [Step 3] 📖 代码研读 — Read ALL relevant code BEFORE making changes ↓ [Step 4] 🔧 调试方案选择 — Choose method A (serial), B (JTAG), or C (combined) ↓ [Step 5] ⚡ 方案执行 — Add diagnostics, build, flash, capture data ↓ [Step 6] 🧠 根因分析 — Identify direct + root cause with evidence ↓ [Step 7] 📋 报告输出 — Structured report with analysis + fix options ↓ [Step 8] ⏳ 等待用户决策 — Wait for user to choose action ``` --- ## Step 1: Environment Preparation ### 1.1 Verify esp32-dev Skill > **AI 首次执行本 Skill 时,必须先确认 `esp32-dev` skill 已加载。** ``` AI 自行判断 esp32-dev skill 是否可用: 1. 检查 esp32_env.json 是否存在(位于当前 skill 的 scripts/ 目录) 2. 检查脚本 idf_export.ps1、idf_build.ps1 等是否可用 3. 如缺少关键脚本或环境文件 → 引导用户先执行 esp32-dev skill 完成环境初始化 ``` > esp32-dev skill 提供完整的 ESP-IDF 工具链路径、工程编译、烧录流程。本 Skill 的编译/烧录步骤均复用 esp32-dev 的能力。 ### 1.2 检查 USB-JTAG 连接(方案 B / C 必需) > **AI 在使用 JTAG 调试前,必须先探测设备并验证连接。** **Step A — 检查 USB 设备是否被系统识别:** ```bash # Windows — 用脚本检查 USB 设备列表和驱动状态 powershell -NoProfile -ExecutionPolicy Bypass -File "check_jtag_driver.ps1" ``` 查看输出中是否有 `USB JTAG/serial debug unit` (VID 303A, PID 1001),且 MI_02 接口的驱动为 `libusb0`。 | 结果 | 动作 | |------|------| | 设备存在 + 驱动为 `libusb0` | ✅ 继续 | | 设备存在 + 驱动为 `WINUSB` | ❌ 引导用户使用 Zadig 替换驱动(见 `esp32-dev` skill) | | 设备不存在 | ❌ 检查 USB 线、芯片型号是否支持 USB-JTAG(ESP32 经典版不支持) | **Step B — 启动 OpenOCD 并验证 JTAG 连接:** ```bash # Windows — 使用脚本启动 OpenOCD powershell -NoProfile -ExecutionPolicy Bypass -File "idf_openocd.ps1" -project_path <project_dir> # Linux/macOS idf.py openocd ``` **预期输出:** ``` Info : esp_usb_jtag: Device found. Info : JTAG tap: esp32s3.tap0 tap/device found: 0x120034e5 Info : [esp32s3.cpu0] Examination succeed Info : [esp32s3.cpu1] Examination succeed Info : Listening on port 3333 for gdb connections ``` | 结果 | 动作 | |------|------| | CPU0/CPU1 Examination succeed | ✅ JTAG 调试通道正常 | | `LIBUSB_ERROR_NOT_FOUND` | ❌ 驱动问题,回到 Step A 替换驱动 | | `JTAG tap: esp32s3.tap0 found` | ✅ 芯片识别正确 | | Only CPU0 found | 正常(部分芯片为单核) | **Step C — 验证 OpenOCD 可读写芯片内存:** ```bash # 通过 OpenOCD telnet 快速验证 echo -e "mdw 0x3FC9C000 4\nexit" | telnet localhost 4444 ``` > 如能正常输出内存地址和对应的 hex 值,说明 JTAG 读写通道正常。 ### 1.3 安装并配置串口监听工具 **指定工具 — EmberInterDebugTool(首选):** > **本工具为安装包形式,需安装后才能使用。** 工具配套 **GUI** 和 **CLI** 两种模式,**使用前需先启动 GUI**。 **下载地址:** `https://github.com/kukucaiCndy/EmberinterTool/releases` | 步骤 | 操作 | |------|------| | 1. 下载安装包 | 从 Releases 页面下载最新安装包(`.exe` / `.dmg` / `.deb`) | | 2. 运行安装程序 | 按安装向导完成安装,记录安装目录 | | 3. 启动 GUI | 安装完成后先启动 GUI,确认工具正常运行 | | 4. CLI 可用 | GUI 启动后,CLI 命令行接口才可用于脚本/自动化场景 | **安装后默认路径:** `C/D/E/F:\Program Files (x86)\EmberInterDebugTool` **GUI 架构:** GUI 负责串口连接管理,CLI 通过 IPC 与 GUI 联动。CLI 可随时启停,不影响串口数据采集。CLI 断连不影响串口数据持续采集。 #### 加载工具 Skill 并学习 CLI 命令 > **AI 在使用串口工具前,必须先加载工具对应的 skill,掌握其命令行参数。** **Skill 获取来源(按优先级):** ``` 1. 本地优先:从工具安装目录获取 常见路径: Windows: C/D/E/F:\Program Files (x86)\EmberInterDebugTool\skill\ 2. 线上备用:从 GitHub 仓库获取 https://github.com/kukucaiCndy/embedded_ai_skills/tree/master/tools/emberinter ``` > **⚠️ 不要假设参数名。** 必须通过 skill 中的说明确认后再使用。 #### CLI 关键命令速查 **连接管理:** ```bash # 列出可用串口 serial-monitor-cli --list # 连接并清空日志 serial-monitor-cli --connect COM10 --baudrate 115200 --clear # 交互模式(持续运行,可收发) serial-monitor-cli -p COM10 --cli ``` **数据发送:** ```bash # 发送文本(自动追加 CRLF) serial-monitor-cli --send "help" -p COM10 # 发送 HEX 字节(不加换行符) serial-monitor-cli --send-hex "FF AB 03 1A" -p COM10 ``` **日志监听与诊断:** ```bash # 持续监听并保存到文件 serial-monitor-cli -p COM10 -o esp32_log.txt # 只显示含 ERROR 的日志 serial-monitor-cli -p COM10 -f ERROR # 获取最近日志(JSON 格式,适合脚本解析) serial-monitor-cli --get-logs 50 --json # 查看连接状态 serial-monitor-cli --get-status --json ``` **交互模式命令(`--cli` 进入后):** | 命令 | 说明 | |------|------| | `connect <port> [baud]` | 连接指定串口,默认 115200 | | `disconnect` / `disc` | 断开当前串口 | | `send <text>` | 发送文本(自动加 CRLF) | | `sendhex <hex>` | 发送 HEX 字节 | | `filter <keyword>` | 过滤关键词,空字符串取消过滤 | | `hex` / `text` | 切换 HEX 显示模式 | | `status` / `s` | 查看当前连接状态 | | `clear` / `c` | 清空日志缓冲区 | | `quit` / `q` | 退出 CLI(GUI 继续运行) | #### 固件烧录后验证工作流 ```bash # Step 1: 确保 GUI 已运行,启动 CLI 持续监听 serial-monitor-cli -p COM10 -o esp32_log.txt # Step 2: 烧录固件(需先断开 EmberInterDebugTool 连接以释放端口) taskkill /F /IM serial-monitor.exe # 关闭 GUI,释放 COM 口 idf.py -p COM10 flash # 烧录 # Step 3: 重启 GUI + 连接 + 发送命令验证 start "" "D:/Program Files (x86)/EmberInterDebugTool/serial-monitor.exe" serial-monitor-cli --connect COM10 --baudrate 115200 --clear serial-monitor-cli --send "help" -p COM10 sleep 2 serial-monitor-cli --get-logs 50 --json ``` > **注意:** GUI 占用串口时 `idf.py flash` 会失败。烧录前需先关闭 GUI 释放端口。烧录完成后重启 GUI 进行交互测试。 #### 备选工具 — idf.py monitor ESP-IDF 自带串口监听也可作为备选: ```bash idf.py -p COM10 monitor ``` 但优先使用 EmberInterDebugTool 以获得统一的调试体验。 ### 1.4 准备调试工具链 **AI 在执行调试前必须确认以下工具可用:** | 工具 | 用途 | 验证命令 | 来源 | |------|------|---------|------| | `esptool` | 芯片检测、Flash 读写 | `esptool --version` | ESP-IDF 工具链 | | `idf.py monitor` | 串口监听 | `idf.py monitor --help` | ESP-IDF | | `openocd` | JTAG 调试服务器 | 通过 `idf_openocd.ps1` 脚本启动 | ESP-IDF 工具链 | | `xtensa-esp32s3-elf-gdb` | GDB 调试客户端 | `xtensa-esp32s3-elf-gdb --version` | ESP-IDF 工具链 | | `xtensa-esp32s3-elf-objdump` | 反汇编 | `xtensa-esp32s3-elf-objdump --version` | ESP-IDF 工具链 | | `xtensa-esp32s3-elf-nm` | 符号表 | `xtensa-esp32s3-elf-nm --version` | ESP-IDF 工具链 | | `xtensa-esp32s3-elf-addr2line` | 地址到源码行 | `xtensa-esp32s3-elf-addr2line --help` | ESP-IDF 工具链 | > **⚠️ 所有工具路径通过 `esp32_env.json` 自动获取,AI 使用脚本封装后调用。** 不要硬编码工具路径,始终通过脚本或 `esp32_env.json` 中的路径。 **芯片前缀速查表:** | 芯片 | GDB 前缀 | objdump/nm/addr2line 前缀 | |------|---------|--------------------------| | ESP32 | `xtensa-esp32-elf-` | `xtensa-esp32-elf-` | | ESP32-S2 | `xtensa-esp32s2-elf-` | `xtensa-esp32s2-elf-` | | ESP32-S3 | `xtensa-esp32s3-elf-` | `xtensa-esp32s3-elf-` | | ESP32-C3/C6/H2 | `riscv32-esp-elf-` | `riscv32-esp-elf-` | --- ## Step 2: Problem Understanding **AI MUST ask the user these 4 questions before proceeding:** ### Q1: Problem symptoms > "请详细描述问题现象。例如:程序卡死在某处、重启循环、输出异常值、外设不工作、Wi-Fi/BLE连接失败等。" ### Q2: Reproducibility > "问题是稳定复现还是偶发?如果是稳定复现,触发条件是什么?" ### Q3: Recent changes > "最近修改了哪些代码?有没有新增功能、修改配置、更换硬件?" ### Q4: Device state > "设备当前状态是什么?串口有什么输出?有没有 panic 信息、backtrace 或错误日志?" **After gathering answers, AI should classify the problem type:** - **Crash/Panic** → Priority: JTAG + backtrace analysis - **Logic error** (wrong behavior) → Priority: Serial log + code review - **Performance** (slow, timing issue) → Priority: Serial log with timestamps - **Connectivity** (Wi-Fi/BLE) → Priority: ESP_LOG + protocol analysis --- ## Step 3: Code Reading **AI MUST read all relevant code BEFORE suggesting any changes.** ### Reading scope: 1. `main.c` — app_main() and main logic 2. All ISRs (interrupt service routines) in the project 3. FreeRTOS task creation and callback functions 4. Initialization code (GPIO, peripherals, Wi-Fi, BLE) 5. `sdkconfig` — check relevant Kconfig settings 6. Custom components in `components/` 7. IDF framework configs if relevant (e.g., `CONFIG_FREERTOS_*`, `CONFIG_ESP_WIFI_*`) ### Analysis checklist: - [ ] Variable initialization — are all variables properly initialized? - [ ] Function call chain — trace the execution path - [ ] Timing/delay — are `vTaskDelay()` values sensible? - [ ] Buffer sizes — are buffers large enough? No overflows? - [ ] Stack sizes — are FreeRTOS task stacks sufficient? - [ ] ISR timing — are ISRs short enough? No blocking calls? - [ ] Interrupt priority — are priorities correct? (higher number = lower priority on ESP32) - [ ] Shared data — are critical sections/mutexes used for shared resources? - [ ] Error handling — are `ESP_ERROR_CHECK()` return values checked? - [ ] Memory — any null pointer dereferences? Memory leaks? --- ## Step 4: Debug Method Selection ### Method A: Serial Log (首选 — Preferred) - **When**: Stable repro, device responsive, logic/peripheral issues - **Pros**: No extra hardware, real-time, low intrusion, keeps CPU running - **Cons**: Limited to what you log, can miss transient states - **Tools**: `ESP_LOGI()` / `ESP_LOGE()` macros + `idf.py monitor` ### Method B: USB-JTAG (备选 — Backup) - **When**: Crash/panic, device unresponsive, need CPU register/stack dump - **Pros**: Full CPU control, breakpoints, watchpoints, register dump - **Cons**: Halts CPU, needs driver setup (Zadig on Windows) - **Tools**: OpenOCD + GDB (`idf.py openocd` + `idf.py gdb`) ### Method C: Serial + JTAG Combined (联用) - **When**: Complex issue — serial shows anomaly, JTAG provides context - **Pros**: Best of both worlds, cross-validation - **Workflow**: Serial log triggers → JTAG breakpoint to confirm - **Example**: ESP_LOGI reports bad value → GDB `watch` to find writer ### Decision Flow ``` Can the device output serial logs? ├── YES → Method A (add ESP_LOGI diagnostics) └── NO → Does the device have USB-JTAG? ├── YES → Method B (OpenOCD + GDB) └── NO → Method A with minimalist logging (UART0 always works) ``` --- ## Step 5: Method A — Serial Log Debugging ### 5.1 Add diagnostic logs **AI should insert ESP_LOG calls at key points:** ```c // Function entry/exit ESP_LOGI(TAG, "function_name: entry, param=%d", param); // Variable state ESP_LOGI(TAG, "state: var1=%d, var2=0x%08x, ptr=%p", var1, var2, ptr); // Error paths ESP_LOGE(TAG, "error: esp_err=%s (0x%x)", esp_err_to_name(err), err); // FreeRTOS task info ESP_LOGI(TAG, "task: %s, stack_free=%lu", pcTaskGetName(NULL), uxTaskGetStackHighWaterMark(NULL)); // Heap info ESP_LOGI(TAG, "heap: free=%lu, min_free=%lu", esp_get_free_heap_size(), esp_get_minimum_free_heap_size()); // Wi-Fi state
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る