Skip to content

Debugging with CMSIS-DAP

This tutorial covers setting up hardware debugging for NanoVNA-H firmware development using a CMSIS-DAP debug probe and OpenOCD.

  • Connecting a CMSIS-DAP debug probe
  • Configuring OpenOCD for NanoVNA-H
  • Using GDB for firmware debugging
  • Setting breakpoints and inspecting variables

CMSIS-DAP is a standard debug interface. Compatible probes include:

ProbeNotes
DAP-LinkCommon, inexpensive
DAPLink (official)Open-source reference design
J-LinkProfessional, also supports CMSIS-DAP mode
ST-Link v2Can be converted to CMSIS-DAP with firmware
Black Magic ProbeBuilt-in GDB server, no OpenOCD needed

The NanoVNA-H has SWD (Serial Wire Debug) pads on the PCB:

PinFunctionConnect To
SWDIODataProbe SWDIO
SWCLKClockProbe SWCLK
GNDGroundProbe GND
3V3Power (optional)Probe VRef
NanoVNA-H Debug Probe
---------- -----------
SWDIO <-------------> SWDIO
SWCLK <-------------> SWCLK
GND <-------------> GND
3V3 <--- optional -> VRef
  1. Locate the debug pads

    Look for small test points or pads labeled SWD, SWDIO, SWCLK on the NanoVNA PCB.

  2. Solder connection wires

    Use thin wire (30 AWG recommended) to connect the debug pads to your probe.

  3. Connect grounds first

    Always connect GND before other signals.

  4. Verify connections

    Use a multimeter to check for shorts between SWDIO, SWCLK, and GND.

Terminal window
sudo apt install openocd

Verify installation:

Terminal window
openocd --version

The NanoVNA-H repository includes a configuration file: NanoVNA_DAP.cfg

If not present, create it with this content:

# NanoVNA-H (STM32F072) OpenOCD configuration
source [find interface/cmsis-dap.cfg]
transport select swd
source [find target/stm32f0x.cfg]
adapter speed 4000
# Reset configuration
reset_config srst_nogate
init
targets
  1. Connect the debug probe

    Connect the probe to your computer via USB and to the NanoVNA via SWD.

  2. Power the NanoVNA

    Connect the NanoVNA via USB or battery.

  3. Start OpenOCD

    Terminal window
    openocd -f NanoVNA_DAP.cfg
  4. Verify connection

    Successful output:

    Open On-Chip Debugger 0.11.0
    Info : CMSIS-DAP: SWD supported
    Info : CMSIS-DAP: Atomic commands supported
    Info : CMSIS-DAP: FW Version = 1.0
    Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nRSET = 1
    Info : CMSIS-DAP: Interface ready
    Info : clock speed 4000 kHz
    Info : SWD DPIDR 0x0bb11477
    Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints
    Info : starting gdb server for stm32f0x.cpu on 3333

OpenOCD now runs a GDB server on port 3333.

  1. Open a new terminal

  2. Navigate to build directory

    Terminal window
    cd /path/to/NanoVNA-H
  3. Start GDB with the ELF file

    Terminal window
    arm-none-eabi-gdb build/H.elf
  4. Connect to OpenOCD

    In GDB:

    (gdb) target extended-remote localhost:3333
  5. Reset and halt the target

    (gdb) monitor reset halt
CommandDescription
target extended-remote localhost:3333Connect to OpenOCD
monitor reset haltReset and stop at beginning
monitor reset runReset and run
loadFlash the firmware (alternative to dfu-util)
continue or cContinue execution
break mainSet breakpoint at main()
break ui.c:100Set breakpoint at line 100 of ui.c
step or sStep into function
next or nStep over function
print variablePrint variable value
info registersShow CPU registers
backtrace or btShow call stack
quit or qExit GDB
(gdb) target extended-remote localhost:3333
Remote debugging using localhost:3333
0x08001234 in main () at main.c:150
(gdb) monitor reset halt
target halted due to debug-request, current mode: Thread
(gdb) break sweep
Breakpoint 1 at 0x8002468: file main.c, line 256.
(gdb) continue
Continuing.
Breakpoint 1, sweep () at main.c:256
256 static bool sweep(bool break_on_operation, uint16_t ch_mask) {
(gdb) print sweep_points
$1 = 101
(gdb) backtrace
#0 sweep () at main.c:256
#1 0x08001a34 in Thread1 () at main.c:243
#2 0x08000f90 in _port_thread_start ()
(gdb) continue

You can flash firmware without entering DFU mode:

(gdb) monitor reset halt
(gdb) load
Loading section .text, size 0x1c234 lma 0x8000000
Loading section .data, size 0x2e4 lma 0x801c234
Start address 0x8000000, load size 115992
Transfer rate: 42 KB/sec, 9666 bytes/write.
(gdb) monitor reset run

This is faster for iterative development than DFU mode.

  1. Install Cortex-Debug extension

    Search for “Cortex-Debug” in VS Code extensions.

  2. Create launch.json

    Create .vscode/launch.json:

    {
    "version": "0.2.0",
    "configurations": [
    {
    "name": "NanoVNA-H Debug",
    "type": "cortex-debug",
    "request": "launch",
    "servertype": "openocd",
    "cwd": "${workspaceFolder}",
    "executable": "${workspaceFolder}/build/H.elf",
    "configFiles": [
    "${workspaceFolder}/NanoVNA_DAP.cfg"
    ],
    "svdFile": "${workspaceFolder}/STM32F0x2.svd",
    "runToEntryPoint": "main",
    "showDevDebugOutput": "raw"
    }
    ]
    }
  3. Download SVD file (optional)

    SVD files provide register definitions for the Peripherals view. Download from STM32 SVD files.

  4. Start debugging

    Press F5 or click the Debug icon.

Similar configuration is possible with Eclipse CDT and the GNU MCU Eclipse plugins.

”Error: unable to find a matching CMSIS-DAP device”

Section titled “”Error: unable to find a matching CMSIS-DAP device””
  • Check USB connection
  • Verify probe appears in lsusb (Linux) or Device Manager (Windows)
  • Try different USB port
  • Check probe firmware
  • Verify SWD connections (especially GND)
  • Check for shorts
  • Ensure NanoVNA is powered
  • Try reducing adapter speed in config file
  • The MCU may be running and ignoring halt request
  • Try monitor reset halt before other commands
  • Check reset line connection if available
  • The F072 has only 4 hardware breakpoints
  • Software breakpoints require writable flash (not always possible)
  • Remove unused breakpoints
  • The default build uses -O2 optimization

  • For debugging, edit Makefile to use -O0:

    USE_OPT = -O0 -ggdb ...
  • Rebuild and reflash

Enable printf output via the debug probe:

(gdb) monitor arm semihosting enable

Requires semihosting support in firmware (not enabled by default).

The F303 (NanoVNA-H4) supports ITM/SWO tracing for non-intrusive debugging. This requires additional hardware setup.

Monitor memory access:

(gdb) watch measured[0][0][0]
Hardware watchpoint 2: measured[0][0][0]
(gdb) continue
Hardware watchpoint 2: measured[0][0][0]
Old value = 0.5
New value = 0.75

The F072 has 2 watchpoints, F303 has 4.