OpenOCD

OpenOCD is software we use on our PC to program microcontrollers using a cmsis-dap tool. In more advanced cases, we can also use it for realtime debugging of our embedded code with breakpoints, variable inspection, etc.

Credit to Erik Strand, master CBA programmer and thusly knighted compiler wizard, who was either there when they wrote the deep magic, or at least read all of the change logs since. He was the original author of this guide, and to Nathan Melenbrink, who drafted the next version.

  1. OpenOCD
    1. Installing with Package Managers
    2. Installing From Source
    3. Additional Setup
  2. Basic Use
    1. Config files
    2. Loading Bootloaders with OpenOCD
    3. Common Errors

Installing with Package Managers

On Linux, TODO.

On Mac, using Homebrew: brew install openocd. As of Dec. 5, 2019, this gives you version 0.10.0, which supports ATSAMD11, but not SAMD51. So you if you want to use the latter chip, you might need to build from source.

On Windows, there is no package manager. But you can grab binaries here. Once you’ve downloaded the latest release, unpack it and put it wherever you want it to live. The important file is bin/openocd. You can either type out the full path whenever you want to run it (e.g. something like C:\\Program Files\openocd\bin\openocd, instead of just openocd), or you can add the bin dir to your path. (See here or Google elsewhere for instructions on adding directories to your path.)

Installing From Source

This section is for Linux and Mac only

If you want to know exactly which version you’re using, or you’re going for maximum bare metal cred, you can build from source. This can be helpful if you’ll be developing between different operating systems - one less thing that could be different - or if the package available on your system is out of date.

The official git repo is on SourceForge.

git clone https://git.code.sf.net/p/openocd/code openocd-code

To build it, you’ll need gcc, as well as make, libtool, pkg-config version 0.23 or greater, and possibly others detailed here. Once you have the prereqs, building is a standard process. Just note that you need to enable cmsis-dap, which is the protocol your computer will use to communicate with an ATMEL ICE debugger.

./bootstrap
./configure --enable-cmsis-dap
make
make install

Compiler note: you should be able to use clang, but it doesn’t seem to work (at least on Mac). I get the following error:

src/flash/nor/nrf5.c:613:5: error: format specifies type 'unsigned short' but the argument has type 'uint32_t' (aka 'unsigned int') [-Werror,-Wformat]

To fix it, tell the configuration script to use gcc: /configure --enable-cmsis-dap CC=gcc-8 (or whatever gcc you have installed). Note that the default gcc command on Mac is not actually gcc; it’s clang. So you’ll have to install it if you haven’t already.

Additional Setup

You’ll almost certainly end up needing a handful of other helpful tools. Depending on your other work you may already have many of these on your machine.

This command assumes Linux

sudo apt install autoconf build-essential cmake libtool libtool-bin libhidapi-dev libusb-dev libusb-1.0-0-dev pkg-config

Another essential one is gdb (if you want to do any debugging). Most documents on the web say to install gdb-arm-none-eabi, but unless you’re using an older version of gdb these days you’re going to want gdb-multiarch.

sudo apt install gdb-multiarch

Basic Use

Config files

When OpenOCD starts, it first processes some configuration commands. You can specify a specific config file with openocd -f path/to/your/config.cfg, or by default it looks for openocd.cfg. At a minimum, OpenOCD needs to know how to communicate with the programming/debug tool you’re using (e.g. ATMEL ICE), and what microcontroller you’re using. For ATMEL ICE, we want cmsis-dap. (You can read more about what this means here.)

Loading Bootloaders with OpenOCD

To make this simple, you can download this folder from Erik’s atsamd11 hello-world when flashing a bootloader for the ATSAMD11C. If you’re using a different chip, use that folder (and .cfg file) as a template, and see if you can modify it for your microcontroller.

Then, navigate to that folder in the terminal, and simply do

openocd

It should find the openocd.cfg file, read that, and use it to program the .bin file onto your microcontroller.

Here’s what success might look like:

nathan@dhcp-10-250-26-247 bootloader % openocd
Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter driver' not 'interface'
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: FW Version = v0.1
Info : CMSIS-DAP: Serial# = 88B075D3
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 400 kHz
Info : SWD DPIDR 0x0bc11477
Info : at91samd11c14a.cpu: hardware has 4 breakpoints, 2 watchpoints
Error: at91samd11c14a.cpu -- clearing lockup after double fault
Polling target at91samd11c14a.cpu failed, trying to reexamine
Info : at91samd11c14a.cpu: hardware has 4 breakpoints, 2 watchpoints
Info : starting gdb server for at91samd11c14a.cpu on 3333
Info : Listening on port 3333 for gdb connections
target halted due to debug-request, current mode: Thread 
xPSR: 0x71000000 pc: 0xfffffffe msp: 0xfffffffc
target halted due to debug-request, current mode: Thread 
xPSR: 0x71000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
Info : SAMD MCU: SAMD11C14A (16KB Flash, 4KB RAM)
** Programming Finished **
** Verify Started **
** Verified OK **
shutdown command invoked
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

Common Errors

With backwards / disconnected connectors, you might see something like this:

Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter driver' not 'interface'
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: FW Version = v0.1
Info : CMSIS-DAP: Serial# = 88B075D3
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 400 kHz
Error: Error connecting DP: cannot read IDR


Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

Another error gets a bit further, where the 5th from last line is different:

Info : SWD DPIDR 0x0bc11477


Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

The line Info : SWD DPIDR 0x0bc11477 indicates that the DPIDR (Debug Port ID Register) has been identified.