Skip to main content

esp-target-debug

Use when debugging firmware on Espressif ESP32-S3/P4 boards over the built-in USB-Serial-JTAG (attach, backtrace, breakpoints, FreeRTOS tasks, console), or openocd says "could not find or open device", the 303a:1001 port vanishes, or the S3 debug port becomes the firmware's USB device.

소스 정보

저장소
hathach/agentrc
최근 소스 활동
2026년 10월 13일 08:44
감지된 SKILL.md 언어
영어
스타
1
포크
2

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
esp-target-debug
description
Use when debugging firmware on Espressif ESP32-S3/P4 boards over the built-in USB-Serial-JTAG (attach, backtrace, breakpoints, FreeRTOS tasks, console), or openocd says "could not find or open device", the 303a:1001 port vanishes, or the S3 debug port becomes the firmware's USB device.
# esp-target-debug — Espressif built-in USB-JTAG backend Methodology — intrusiveness ladder, board locks, dual-side capture, diagnosis standards — lives in `target-debug`; this skill is the Espressif backend: a different gdb, a different openocd (fork), no probe serial (the debugger IS a USB device), and a PHY story that decides whether JTAG exists at all. Built-in USB-Serial-JTAG only; external JTAG is a TODO (no rig adapter). ## The PHY map — decides everything (verified on the rig, 2026-09-16) Observed on these two rig boards (names are TinyUSB BSP aliases) running USB device firmware on the OTG controller; other S3/P4 boards share the chip-level facts, not the wiring. Project specifics (symbols, which uid is which): `target-debug`'s `projects/`. | Board | USB-SJ vs OTG | JTAG while USB device runs? | |--------------------------|------------------------------------------------------|-----------------------------| | espressif_p4_function_ev | separate pins: USB-SJ GPIO24/25 (FS), OTG own HS PHY | **yes — coexist** (verified: 303a:1001 + cafe:4008 simultaneously; attach remains available but resets the app, below) | | espressif_s3_devkitm | ONE shared PHY/port | **no** — the same hub port flips 303a:1001 → cafe:4008 as the app boots; openocd fails `esp_usb_jtag: could not find or open device!` | Flashing works in ANY PHY state: the rig flashes via the boards' CP2102N UART bridges. The UART side is also the remote reset: `esptool.py --after hard_reset read_mac`. ### P4 (Function-EV) notes - The board has **no USB-SJ connector** — GPIO24 (D−, white) / GPIO25 (D+, green) / GND are broken out from header J1 to a rig hub port. Swapped D+/D− enumerates as `new low-speed USB device` + error -71; correct shows `new full-speed`. ### S3 (DevKitM) notes - Debugging windows: firmware that never starts the OTG controller (verified: attach/halt/symbol resolution), the ROM or ESP-IDF's second-stage bootloader (always stable), or external JTAG (TODO). - **Keep-alive quirk (verified)**: with app firmware running and nothing attached, USB-SJ drops ~4 s after boot (device-side disconnect, then half-dead `-71` setup failures until reset). Attach a client inside the window — once it survives the window it stays up. Recover via the UART reset above. - With [0x0, 0x1000) erased (the bootloader's first sector), the ROM loops printing "invalid header: 0xffffffff" on the UART bridge, and USB-Serial-JTAG (303a:1001) enumerates on the native port. verified 2026-10-13 espressif_esp32s3_devkitc_1: an esptool erase of that range. - PHY mux reference: `RTC_CNTL_RTC_USB_CONF_REG` (0x60008120) bits `SW_HW_USB_PHY_SEL`/`SW_USB_PHY_SEL` (TRM 10.56); 0 = eFuse/hardware control (default). `esptool.py read_mem/write_mem` peeks and pokes registers over plain UART with the chip in download mode. ## Attach ```bash . "$IDF_PATH/export.sh" # openocd-esp32, riscv32-/xtensa-esp32s3-elf-gdb, esptool openocd -c 'set ESP_RTOS FreeRTOS' -f board/esp32p4-builtin.cfg \ -c 'adapter serial <MAC-with-colons>' & # S3: board/esp32s3-builtin.cfg riscv32-esp-elf-gdb -batch -ex 'target extended-remote :3333' \ -ex 'tbreak <app symbol>' -ex continue -ex bt -ex 'info threads' -ex detach <elf> # S3 is Xtensa: use xtensa-esp32s3-elf-gdb with the same arguments ``` - `adapter serial` = the chip MAC **with colons** — the USB-SJ device's iSerial exactly as `lsusb -v -d 303a:1001` or `/dev/serial/by-id/usb-Espressif_USB_JTAG_serial_debug_unit_<MAC>-if00` prints it. Read it from the device: a rig config's flasher uid may name a different port (the project's notes say which). - `set ESP_RTOS FreeRTOS` must precede the board cfg: with it, `info threads` lists every task with name/state/CPU (verified: usbd Running @CPU0, IDLE1 @CPU1, ...); without it, one bare "Remote target". - `export.sh` may leave the RISC-V GDB off PATH: look under `~/.espressif/tools/riscv32-esp-elf-gdb/<version>/riscv32-esp-elf-gdb/bin/` (verified on ci.lan 2026-09-18, version `17.1_20260402`). - The ELF: the firmware's own build output (an `idf.py` build directory) — symbolized app backtraces verified. - **P4 attach resets the target** in the measured rig configuration: openocd reports memory protection enabled, resets to disable it, then reports a JTAG CPU reset. The initial `tud_task_ext` breakpoint therefore observed a fresh boot (`xTickCount = 2`, `cfg_num = 0`), not the pre-attach enumerated state; observing steady state reached after that reset was not established. Other built-in-JTAG targets may reset too; do not use this route to preserve a wedged board's pre-attach state (`target-debug`'s attach-and-halt-only rule). - Halting still stops USB service: the host may drop the DUT during long halts. On P4 the DUT did not return to the bus after detach; use the UART hard reset above before expecting it to re-enumerate. ## Scripted-session gotchas (verified) - xtensa-gdb batch `continue`/`interrupt` is async-flaky — for scripted state reads, halt via openocd telnet :4444 first, then attach gdb to the stopped target. Interactive sessions are unaffected. - cpu1 debug-logic examination can fail (`OCD_ID = 00000000`) — `-c 'set ESP_ONLYCPU 1'` degrades to cpu0-only debugging, but a breakpoint in a task scheduled on the other hart then stays silently unreachable. - openocd-esp32 v0.12.0-esp32-20251215 asserted at `riscv.c:2150` when a second breakpoint was armed after the first hit in the two-hart P4 setup. Budget one breakpoint per session on that version. - ROM-frame backtraces (`0x4004xxxx` on S3, `0x4fc0xxxx` on P4, all `??`) mean the core idles in ROM — break in app code (`tbreak <app symbol>`) for symbolized frames. ## Technique mapping (vs the `target-debug` arsenal) | target-debug technique | Espressif backend | |------------------------|-------------------| | GDB autopsy, bp/wp | same flow via openocd-esp32 :3333; RISC-V triggers (P4) / Xtensa 2 bp + 2 wp (S3) | | Vector catch | none — breakpoint the panic handler; `mcause`/`mepc`/`mtval` on P4 | | SWO / DWT data trace | none — apptrace over JTAG is the analog (untested: needs CONFIG_APPTRACE + app init) | | RTT / log lines | console on **UART0 = the CP2102 flasher tty** by default (verified); USB-SJ console needs sdkconfig `ESP_CONSOLE_USB_SERIAL_JTAG` (untested) | | FreeRTOS threads | native — `set ESP_RTOS FreeRTOS` (see Attach) | | verifybin | `esptool.py verify_flash` (untested) | ## Rig deltas - Shared rig boards: hold the project's board lock first (its `HIL contract:` names the skill that owns it); reflash-pristine before release applies unchanged. - One client per USB-SJ: openocd and a terminal on the USB-SJ CDC side conflict the same way J-Link clients do. ## TODO — external JTAG (needs hardware) S3 JTAG pins GPIO39–42 (MTCK/MTDO/MTDI/MTMS) + any adapter openocd-esp32 supports (ESP-Prog/FT2232-class); would give S3 debugging under live USB traffic. Mind `EFUSE_DIS_PAD_JTAG` / JTAG-source strapping. Unverified.
GitHub에서 보기