Hardware Setup
This guide covers the physical and configuration setup needed before mcjtag can talk to your target. It assumes you already have a debug probe and a target board — if you are looking for a recommendation, the DAP-Link + Blue Pill kit is what mcjtag is developed against.
SWD vs JTAG
Section titled “SWD vs JTAG”Both are debug transport protocols supported by ARM cores. The choice depends on your hardware and what you need to do.
| Feature | SWD | JTAG |
|---|---|---|
| Signal count | 2 (SWDIO + SWCLK) | 4+ (TDI, TDO, TMS, TCK) |
| Pin budget | Lower — fits on small boards | Higher — needs a header or adapter |
| Chain scanning | Single target only | Multiple devices on one chain |
| Speed | Generally equal | Generally equal |
| Chip support | ARM Cortex-M/A/R only | ARM, RISC-V, FPGA, any JTAG device |
| Recommendation | Use for most Cortex-M work | Use when you need chain scanning or non-ARM targets |
If your target is an ARM Cortex-M and you only have one chip to debug, SWD is simpler. If you have multiple devices on a chain, or your target is RISC-V or an FPGA, use JTAG.
Wiring
Section titled “Wiring”SWD (minimum connections)
Section titled “SWD (minimum connections)”| Probe Pin | Target Pin | Notes |
|---|---|---|
| SWDIO | SWDIO | Bidirectional data line |
| SWCLK | SWCLK | Clock, driven by the probe |
| GND | GND | Required — the most common wiring mistake is a missing ground |
| 3.3V | VCC | Only if the target needs power from the probe. Many boards have their own supply. |
JTAG (minimum connections)
Section titled “JTAG (minimum connections)”| Probe Pin | Target Pin | Notes |
|---|---|---|
| TDI | TDI | Test Data In — serial data from probe to target |
| TDO | TDO | Test Data Out — serial data from target to probe |
| TMS | TMS | Test Mode Select — controls the TAP state machine |
| TCK | TCK | Test Clock — driven by the probe |
| GND | GND | Required |
| nRST | RESET | Optional but recommended. Allows the probe to reset the target. |
Common wiring mistakes
Section titled “Common wiring mistakes”- Missing GND — The debug interface will not work without a shared ground reference. If you see “no JTAG TAPs found” or “target not examined yet”, check ground first.
- Swapped TDI/TDO — These are named from the perspective of the target. TDI goes into the target, TDO comes out. Some probe boards label them from their own perspective, which reverses the sense.
- nRST floating — If the target has a reset pin that is not connected to the probe,
reset_haltandreset_runmay not work reliably. Use a pull-up if you cannot wire it.
Common debug probes
Section titled “Common debug probes”DAP-Link (CMSIS-DAP)
Section titled “DAP-Link (CMSIS-DAP)”Budget-friendly open-source probe. Many USB dongles and dev boards include a DAP-Link interface. mcjtag ships with example configs for this probe.
source [find interface/cmsis-dap.cfg]transport select swdadapter speed 1000source [find target/stm32f1x.cfg]Supports both SWD and JTAG depending on the firmware variant.
ST-Link
Section titled “ST-Link”Built into STMicroelectronics Nucleo and Discovery boards. Also available as a standalone USB dongle (ST-Link/V2, ST-Link/V3).
source [find interface/stlink.cfg]transport select hla_swdadapter speed 1000source [find target/stm32f4x.cfg]Note: ST-Link uses a proprietary protocol (hla_swd or hla_jtag), which has
some limitations compared to CMSIS-DAP. For example, you cannot do raw JTAG
shift operations through jtag_shift().
J-Link
Section titled “J-Link”Professional probe from Segger. Fast, reliable, and well-supported. Requires the J-Link software package to be installed alongside OpenOCD.
source [find interface/jlink.cfg]transport select swdadapter speed 4000source [find target/nrf52.cfg]FTDI-based adapters
Section titled “FTDI-based adapters”Various low-cost adapters based on FTDI chips (FT2232H, FT232H). Configuration depends on the specific board layout.
source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg]transport select jtagadapter speed 2000source [find target/stm32f1x.cfg]OpenOCD configuration
Section titled “OpenOCD configuration”An OpenOCD config file has four logical sections. The order matters.
# 1. Interface — what debug probe are you using?source [find interface/cmsis-dap.cfg]
# 2. Transport — SWD or JTAG?transport select swd
# 3. Speed — adapter clock in kHz. Start low and increase if stable.adapter speed 1000
# 4. Target — what chip is being debugged?source [find target/stm32f1x.cfg]Finding the right target config
Section titled “Finding the right target config”OpenOCD ships with configs for hundreds of chips. Common ones:
| Chip Family | Config File |
|---|---|
| STM32F1 (Blue Pill, etc.) | target/stm32f1x.cfg |
| STM32F4 (Nucleo-F4, etc.) | target/stm32f4x.cfg |
| STM32H7 | target/stm32h7x.cfg |
| nRF52 (Nordic) | target/nrf52.cfg |
| RP2040 (Raspberry Pi Pico) | target/rp2040.cfg |
| ESP32 | target/esp32.cfg |
| GD32F1 (GigaDevice) | target/stm32f1x.cfg (compatible) |
| Generic Cortex-M | target/cortex_m.cfg |
If you are unsure which config to use, target/cortex_m.cfg works for any
ARM Cortex-M device. You lose chip-specific flash programming support, but
all register and memory operations work.
To find configs on your system:
find /usr/share/openocd/scripts/target -name "*.cfg" | sortAdapter speed
Section titled “Adapter speed”Start at 1000 kHz (1 MHz). If you get reliable connections, you can increase to
4000 or higher. If you see errors or intermittent failures, drop to 100.
Long wires, breadboard connections, and noisy environments all degrade signal integrity and may require lower speeds.
Using mcjtag’s auto-spawn
Section titled “Using mcjtag’s auto-spawn”Instead of starting OpenOCD manually, set OPENOCD_CONFIG and mcjtag handles it:
# Pass the config file pathOPENOCD_CONFIG=/path/to/my-board.cfg uvx mcjtagmcjtag will start OpenOCD as a subprocess, connect to it, and stop it when the session ends. The config file should be a complete OpenOCD config (interface + transport + speed + target).
You can also pass host and port for an existing OpenOCD instance:
OPENOCD_HOST=192.168.1.100 OPENOCD_PORT=6666 uvx mcjtagVerifying the setup manually
Section titled “Verifying the setup manually”Before involving mcjtag, confirm OpenOCD works on its own:
openocd -f /path/to/your/config.cfgHealthy output looks like:
Info : CMSIS-DAP: SWD supportedInfo : CMSIS-DAP: FW Version = 0254Info : clock speed 1000 kHzInfo : SWD DPIDR 0x1ba01477Info : stm32f1x.cpu: Cortex-M3 r1p1 processor detectedInfo : stm32f1x.cpu: target has 6 breakpoints, 4 watchpointsIf OpenOCD fails here, mcjtag will also fail. Fix the OpenOCD setup first.