mcpField
O
openocd-jtag

openocd-jtag

github.com/mohitmishra786Development269550 installsUpdated 18w ago
Repository

About openocd-jtag

openocd-jtag is a skill for agents working with embedded debugging. It covers OpenOCD setup, GDB connections, firmware flashing, hardware watchpoints, and common connection errors.

Key features

  1. 01Configure OpenOCD for JTAG and SWD
  2. 02Connect GDB to a target
  3. 03Flash firmware with OpenOCD
  4. 04Set hardware breakpoints and watchpoints
  5. 05Diagnose common target connection errors

Use cases

  1. 01Choose JTAG or SWD for a microcontroller
  2. 02Set up GDB for bare-metal debugging
  3. 03Flash firmware and verify the write
  4. 04Troubleshoot OpenOCD target detection

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill openocd-jtag

After installing, type/openocd-jtagin Claude Code to confirm it loaded.

Details

From the project README

OpenOCD / JTAG Debugging

Purpose

Guide agents through configuring OpenOCD for JTAG and SWD targets, flashing firmware to microcontrollers, attaching GDB for bare-metal debugging, setting hardware watchpoints, and configuring J-Link and CMSIS-DAP adapters.

Triggers

  • "How do I connect GDB to my MCU with OpenOCD?"
  • "How do I flash firmware using OpenOCD?"
  • "How do I set up J-Link with OpenOCD?"
  • "What's the difference between JTAG and SWD?"
  • "How do I set a hardware watchpoint in GDB?"
  • "OpenOCD says 'Error: unable to find JTAG device' — how do I fix it?"

Workflow

1. JTAG vs SWD
FeatureJTAGSWD (Serial Wire Debug)
Pins4+ (TCK, TMS, TDI, TDO, TRST)2 (SWCLK, SWDIO)
Multi-targetYes (daisy chain)No (one target)
SpeedUp to 30 MHzUp to 10 MHz
AvailabilityFull JTAG: Cortex-A/R, RISC-VSWD: Cortex-M only
Cable costMore complexSimpler 2-wire

Most Cortex-M microcontrollers support both. Use SWD when pin count is limited.

2. OpenOCD configuration
# openocd.cfg — CMSIS-DAP (ST-Link v2, DAPLink)
source [find interface/cmsis-dap.cfg]
source [find target/stm32f4x.cfg]
adapter speed 4000              # kHz

# For SWD explicitly
transport select swd

# J-Link adapter
source [find interface/jlink.cfg]
jlink serial 123456789          # optional: select by serial
source [find target/nrf52.cfg]
adapter speed 8000
# Run OpenOCD (keeps running, serves GDB on port 3333)
openocd -f openocd.cfg

# Common interface config files
ls $(openocd --help 2>&1 | grep "scripts" | head -1)/interface/
# cmsis-dap.cfg, jlink.cfg, ftdi/olimex-arm-usb-ocd.cfg, stlink.cfg ...

# Common target config files
ls $(openocd --help 2>&1 | grep "scripts" | head -1)/target/
# stm32f4x.cfg, nrf52.cfg, esp32.cfg, rp2040.cfg, at91sam4s.cfg ...
3. Connecting GDB
# In terminal 1: start OpenOCD
openocd -f openocd.cfg

# In terminal 2: start GDB
arm-none-eabi-gdb firmware.elf

# GDB commands
(gdb) target extended-remote :3333   # connect to OpenOCD
(gdb) monitor reset halt              # reset and halt target
(gdb) load                            # flash ELF to target
(gdb) monitor reset init             # re-initialize after flash
(gdb) break main                      # set software breakpoint
(gdb) continue

# One-liner for quick debugging
arm-none-eabi-gdb -ex "target extended-remote :3333" \
                  -ex "monitor reset halt" \
                  -ex "load" \
                  -ex "break main" \
                  -ex "continue" \
                  firmware.elf
4. Flashing firmware
# Flash via OpenOCD telnet interface
telnet localhost 4444

# OpenOCD telnet commands
> reset halt
> program firmware.elf verify reset
> exit

# Or via GDB
(gdb) monitor flash write_image erase firmware.bin 0x08000000
(gdb) monitor reset run

# Flash only (no debug) — script mode
openocd -f openocd.cfg \
        -c "program firmware.elf verify reset exit"

# For raw binary
openocd -f openocd.cfg \
        -c "program firmware.bin 0x08000000 verify reset exit"
5. Hardware breakpoints and watchpoints

Software breakpoints (break) patch instruction memory with trap instructions — they don't work in flash-execute-in-place without debug registers. Use hardware breakpoints instead:

# Hardware breakpoint (uses debug register, limited count: 4-8 on Cortex-M)
(gdb) hbreak function_name
(gdb) hbreak *0x08001234

# Hardware watchpoint — triggers on memory read/write
(gdb) watch global_variable         # write watchpoint
(gdb) rwatch some_buffer            # read watchpoint
(gdb) awatch sensor_value           # read OR write watchpoint

# List breakpoints/watchpoints
(gdb) info breakpoints

# Cortex-M typically has: 4–8 hardware breakpoints, 2–4 watchpoints
6. OpenOCD commands reference
# Via telnet (port 4444) or GDB monitor
monitor reset halt          # reset and hold at reset vector
monitor reset init          # reset and run init scripts
monitor reset run           # reset and run freely
monitor halt                # halt running target
monitor resume              # resume execution
monitor mdw 0x20000000      # memory display word at address
monitor mww 0x40021000 0x1  # memory write word
monitor reg r0              # read register
monitor arm disassemble 0x08000000 16  # disassemble 16 instructions

# Flash operations
monitor flash list
monitor flash erase_sector 0 0 0   # erase sector 0
monitor flash write_bank 0 firmware.bin 0
7. Common errors
ErrorCauseFix
unable to find JTAG deviceWrong interface, cable, or powerCheck USB connection; power target; verify interface config
JTAG scan chain interrogation failedWrong target config or bad SWD modeMatch config to exact MCU; try transport select swd
flash 'stm32f4x' is not supportedWrong targetCheck MCU part number; use correct .cfg
Error: timed out while waiting for target haltedTarget running, not haltedmonitor halt; check BOOT pins
Cannot access memory at addressMMU, memory protection, or wrong addressCheck MPU config; use correct flash/RAM address
Warn: target not examined yetOpenOCD not connected to targetCheck power and connections
8. J-Link configuration
# openocd.cfg for J-Link
source [find interface/jlink.cfg]
jlink usb 0          # use first J-Link found
transport select swd  # or jtag
adapter speed 4000

source [find target/stm32l4x.cfg]

J-Link GDB Server (alternative to OpenOCD):

# Segger's own GDB server
JLinkGDBServer -if SWD -device STM32L476RG -port 3333 &
arm-none-eabi-gdb -ex "target remote :3333" firmware.elf

Related skills

  • Use skills/embedded/freertos for FreeRTOS-aware debugging with OpenOCD
  • Use skills/embedded/zephyr for Zephyr's west debug integration
  • Use skills/debuggers/gdb for GDB session management
  • Use skills/embedded/linker-scripts for understanding memory map for flash addresses

Comments

Markdown supported