- Notifications
You must be signed in to change notification settings - Fork0
CMSIS-DAP programmer using TCP/IP rather than USB connection to the host. Runs on ESP32 and connects over WiFi to OpenOCD using the cmsis-dap-tcp backend. Supports JTAG and SWD.
License
bkuschak/cmsis_dap_tcp_esp32
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
OpenOCD supports the CMSIS-DAP protocol to communicate with a JTAG / SWDprogrammer. Typically this is a local programmer with a USB connection. Withthe addition of the OpenOCD cmsis_dap_tcp backend, the CMSIS-DAP protocol cannow run over TCP/IP instead of USB. This allows OpenOCD to connect to a remoteprogrammer over the network.
This project provides the remote-side implementation of the cmsis_dap_tcpprotocol, using an ESP32 as the remote programmer. It allows a cheap ESP32board to program and debug an ARM microcontroller target. Both JTAG and thetwo-wire SWD interface are supported. OpenOCD connects to the ESP32 usingTCP/IP over WiFi, allowing remote flashing and debugging of the ARM targetboard.
- Tested with the XIAO ESP32C6 and ESP32-S3-DevKitC-1 development boards as theprogrammer, and STM32F103 Blue Pill and Nucleo STM32F401RE as the targets.
- Either JTAG mode or SWD mode can be used to program the target. 2 GPIO areneeded for SWD, or a minimum of 4 GPIO for JTAG.
- An optional GPIO pin can be used to drive the NRST# (SRST) signal, but thisis typically not required.
- In JTAG mode, an optional GPIO pin can be used to drive the TRST signal, butthis is typically not required.
- A separate GPIO may be used to control an activity LED.
- UART to TCP/IP bridge can be enabled to provide access to the target board'sserial console remotely, using an ESP32 UART.
- Typical performance:
- Reading / writing SRAM: up to 200 KB/sec
- Flashing a 512 KB firmware image to the STM32F401REcompletes in about 13.4 seconds, including erase, program, and verify (with 4to 8 seconds of that time used for flash erasure). The Blue Pill takes about6 seconds for a 64KB image.
- Performance depends on the quality of your WiFi network.
The CMSIS-DAP code came from the Firmware directory of theCMSIS-DAPrepo.DAP_config.h was thenmodified to support the ESP32 GPIO.
commit 1fd47bed772ea40923472c90dfe11516e76033ee (HEAD -> main, tag: v2.1.2, origin/main, origin/HEAD)The software has some limitations:
- SWO is currently unsupported.
- Maximum clock rate is about 1000 KHz (ESP32C6 configured for 160 MHz / 80 MHz).
- The WiFi credentials are hardcoded. The software must be rebuilt if you wantto change them.
This code requires the ESP-IDF build tools. Refer to the officialinstallation guideand install them first.
Activate your ESP-IDF virtual environment:
. $HOME/esp/esp-idf/export.shThe code supports multiple different boards, and each one has its ownsdkconfig file.
Choose the correctsdkconfig.<board_name> file for your board and copy ittosdkconfig. Then configure, build and flash the firmware. For example,for the Xiao ESP32-C6 board:
cp sdkconfig.xiao_esp32c6 sdkconfigidf.py fullclean menuconfigidf.py build flashIn menuconfig, goto to the "CMSIS-DAP configuration" page.
Your WiFi SSID and password can be configured on the "WiFi configuration"subpage. (If you are not using WPA2, you might need to adjust the WiFi Scanauth mode threshold).


If needed, you can change the GPIO port pins for JTAG, SWD, reset, and LED onthe "GPIO number assignments" subpage. The signals can be disabled if they arenot needed.

If you want to use the UART to TCP/IP bridge, it can be configured on thethe "UART to TCP/IP bridge" subpage. (Currently, the baud rate and othersettings cannot be changed at runtime). A script
host/uart_bridge.shis provided that usessocatto present the remote UART as a pseudo-ttythat can be opened using any serial terminal program on the host.
Get the latest source code from git. Configure and build it as usual:
git clone git://git.code.sf.net/p/openocd/code openocdcd openocd./bootstrap./configuremakeAn OpenOCD configuration file has been provided for convenience.Edit yourtcl/interface/cmsis_dap_tcp.cfg configuration file to point toyour ESP32's IP address:
adapter driver cmsis-dapcmsis-dap backend tcpcmsis-dap tcp host 192.168.1.107cmsis-dap tcp port 4441transport select swdreset_config noneIf you are on a slow WiFi network, you might need to add this line to avoidshort timeouts that can lead to command mismatch errors in some cases. If so,specify a longer timeout in milliseconds:
cmsis-dap tcp min_timeout 300To flash an STM32 target, for example, run the following command from yourOpenOCD build directory. Replacefirmware.elf with the name of yourELF file, andstm32f1x.cfg with the appropriate file for yourmicrocontroller.
./src/openocd --search tcl \ -f tcl/interface/cmsis-dap-tcp.cfg \ -f tcl/target/stm32f1x.cfg \ -c "program firmware.elf verify reset exit"After power-on, the ESP32 will attempt to connect to the WiFi that wasconfigured using menuconfig. It will then begin listening for an incomingconnection from OpenOCD. The ESP32 will print status and error messages to theconsole, including the WiFi connection status and IP address. A message isprinted whenever the OpenOCD client connects or disconnects. (Only one activeclient is allowed).
You can run the serial monitor to view the console output. To exit the serialmonitor useCtrl+].
idf.py monitorOnce the ESP32 has connected to WiFi and obtained an IP address by DHCP, youcan then run OpenOCD. You should see something like this from the ESP32:
CMSIS-DAP TCP running on ESP32ESP-IDF version: v6.0-dev-1489-g4e036983a7Hardware version: esp32s3 with 2 CPU core(s), WiFi/BLE, silicon revision v0.2, 2MB external flashMinimum free heap size: 337312 bytesMAC address: E4B323B60EB4Attempting to connect to WiFi SSID: 'SomeWifiRouter'Connected to WiFi SSID: 'SomeWifiRouter'. RSSI: -75 dBmIP address: 192.168.1.107Disabling WiFi power savings to improve performance.cmsis_dap_tcp: listening on port 4441.UART bridge: remapping UART_TX = GPIO_NUM_16, UART_RX = GPIO_NUM_15.UART bridge: listening on port 4442 for UART1.IPv6 address (link-local): fe80:0000:0000:0000:9aa3:16ff:feec:6640IPv6 address (global): 2406:3400:031f:ba10:9aa3:16ff:feec:6640Additional debugging messages may be enabled by editingmain/cmsis_dap_tcp.h and uncommenting the following line. This willimpact performance.
#define DEBUG_PRINTINGA single SWD 32-bit transfer completes in about 45 microseconds, with anSWCLK clock rate of approximately 1 MHz. Yellow is SWCLK. Green is SWDIO.
(TODO: the scope available at the time to make these measurements was verylimited. Redo these measurements with a better scope).
Actual performance will depend on your WiFi network. For slow networks,you might need to increase thecmsis-dap tcp min_timeout parameter ifyou see error messages related to command mismatch.
Starting the OpenOCD server like this:
./src/openocd \ --search tcl \ -c "debug_level 2" \ -c "adapter driver cmsis-dap" \ -c "transport select swd" \ -c "cmsis-dap backend tcp" \ -c "cmsis-dap tcp host 192.168.1.107" \ -c "cmsis-dap tcp port 4441" \ -c "cmsis-dap tcp min_timeout 150" \ -f "tcl/target/stm32f4x.cfg" \ -c "reset_config none"Open On-Chip Debugger 0.12.0+dev-01114-gbf01f1089 (2025-08-07-11:52)Licensed under GNU GPL v2For bug reports, readhttp://openocd.org/doc/doxygen/bugs.htmlInfo : CMSIS-DAP: using minimum timeout of 100 ms for TCP packets.none separateInfo : Listening on port 6666 for tcl connectionsInfo : Listening on port 4444 for telnet connectionsInfo : CMSIS-DAP: Connecting to 192.168.1.107:4441 using TCP backendInfo : CMSIS-DAP: SWD supportedInfo : CMSIS-DAP: JTAG supportedInfo : CMSIS-DAP: Atomic commands supportedInfo : CMSIS-DAP: Test domain timer supportedInfo : CMSIS-DAP: FW Version = 2.1.2Info : CMSIS-DAP: Serial# = E4B323B60EB4Info : CMSIS-DAP: Interface Initialised (SWD)Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1Info : CMSIS-DAP: Interface readyInfo : clock speed 2000 kHzInfo : SWD DPIDR 0x2ba01477Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detectedInfo : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpointsInfo : [stm32f4x.cpu] Examination succeedInfo : [stm32f4x.cpu] starting gdb server on 3333Info : Listening on port 3333 for gdb connectionsInfo : accepting 'telnet' connection on tcp/4444Xiao ESP32C6 running at 160 MHz is the programmer board. Connecting to anSTM32F401RE target and reading and writing SRAM:
% telnet localhost 4444> poll off> load_image ./random_96kb.bin 0x2000000098304 bytes written at address 0x20000000downloaded 98304 bytes in 1.092678s (87.858 KiB/s)> dump_image /dev/null 0x20000000 0x18000dumped 98304 bytes in 1.469766s (65.317 KiB/s)Programming and verifying a 512 KB flash image takes about 20 seconds:
time ./src/openocd \ --search tcl \ -c "debug_level 2" \ -c "adapter driver cmsis-dap" \ -c "transport select swd" \ -c "cmsis-dap backend tcp" \ -c "cmsis-dap tcp host 192.168.1.107" \ -c "cmsis-dap tcp port 4441" \ -f "tcl/target/stm32f4x.cfg" \ -c "reset_config none" \ -c "program ${ELF} verify reset exit"Open On-Chip Debugger 0.12.0+dev-01114-gbf01f1089 (2025-08-07-11:52)Licensed under GNU GPL v2For bug reports, readhttp://openocd.org/doc/doxygen/bugs.htmlnone separateInfo : CMSIS-DAP: Connecting to 192.168.1.107:4441 using TCP backendInfo : CMSIS-DAP: SWD supportedInfo : CMSIS-DAP: JTAG supportedInfo : CMSIS-DAP: Atomic commands supportedInfo : CMSIS-DAP: Test domain timer supportedInfo : CMSIS-DAP: FW Version = 2.1.2Info : CMSIS-DAP: Serial# = E4B323B60EB4Info : CMSIS-DAP: Interface Initialised (SWD)Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1Info : CMSIS-DAP: Interface readyInfo : clock speed 2000 kHzInfo : SWD DPIDR 0x2ba01477Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detectedInfo : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpointsInfo : [stm32f4x.cpu] Examination succeedInfo : [stm32f4x.cpu] starting gdb server on 3333Info : Listening on port 3333 for gdb connections[stm32f4x.cpu] halted due to debug-request, current mode: ThreadxPSR: 0x01000000 pc: 0x08000734 msp: 0x20018000** Programming Started **Info : device id = 0x10016433Info : flash size = 512 KiB** Programming Finished **** Verify Started **** Verified OK **** Resetting Target **shutdown command invokedreal0m19.242suser0m0.052ssys0m0.155sPerformance is higher on ESP32-S3. The throughput seems more variableon each run, but here are some representative numbers for writing andreading SRAM:
% telnet localhost 4444> poll off> load_image ./random_96kb.bin 0x2000000098304 bytes written at address 0x20000000downloaded 98304 bytes in 0.489488s (196.123 KiB/s)> dump_image /dev/null 0x20000000 0x18000dumped 98304 bytes in 0.832846s (115.267 KiB/s)About
CMSIS-DAP programmer using TCP/IP rather than USB connection to the host. Runs on ESP32 and connects over WiFi to OpenOCD using the cmsis-dap-tcp backend. Supports JTAG and SWD.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.


