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에서 보기