TITLE: Building OpenOCD on a Fresh Ubuntu
AUTHOR: Chuck McManis
LAST UPDATE: 31-Mar-2019


OpenOCD is an open source tool that connects with the ARM “On Chip Debugger” (the OCD part of OpenOCD). This debug engine is documented at the ARM website in some detail.

As process improvements have continued in semiconductors, the number of transistors you can fit on a very small die has gone up exponentially (Moore’s law in a nutshell). For an embedded microprocessor like the Cortex-M series this means it is economical to “spend” some transistors on what is essentially a “front panel” inside the chip. From the debug engine you can stop and start the CPU, inspect all of the registers and memory, set breakpoints or watch points, and trace the execution of your program in real time. OpenOCD uses this facility to control the chip via an interface that is provided by a third party.

The tricky bit however is that OpenOCD evolves faster than the package maintainers can update their packages. Thus installing it from packages, the typical thing you might do, gets you an out of date version that might not support the shiny toy you are trying to program. I’ve found myself in this situation many times and as a result have rebuilt it from source many times. And every time I do this on a “new” install of Linux I realize there are a lot of dependencies that you need to build all the bells and whistles. That lead me to writing it all down this time so that I (and you if you want) can refer back to this when we’re rebuilding it yet again to incorporate a new eval board or chip.

Getting the Source

This is the easy part, for me it consists entirely of the following:

git clone --recursive https://github.com/ntfreak/openocd

This will get you not only the OpenOCD source, but some submodules that it uses as well, these are:

But even with the submodules that is not enough so we’re going to grab some packages as well that are pre-built. I’m using Ubuntu (18.04 in this example) so I’ll be using apt. We get the -dev versions because we want the include files that are needed to build source code that calls into the libraries.

At this point ./bootstrap will work and you are on to satisfying dependencies for configure.

This will get you this configuration report:

OpenOCD configuration summary
MPSSE mode of FTDI based devices        yes (auto)
ST-Link JTAG Programmer                 yes (auto)
TI ICDI JTAG Programmer                 yes (auto)
Keil ULINK JTAG Programmer              yes (auto)
Altera USB-Blaster II Compatible        yes (auto)
Bitbang mode of FT232R based devices    yes (auto)
Versaloon-Link JTAG Programmer          yes (auto)
TI XDS110 Debug Probe                   yes (auto)
OSBDM (JTAG only) Programmer            yes (auto)
eStick/opendous JTAG Programmer         yes (auto)
Andes JTAG Programmer                   yes (auto)
USBProg JTAG Programmer                 no
Raisonance RLink JTAG Programmer        no
Olimex ARM-JTAG-EW Programmer           no
CMSIS-DAP Compliant Debugger            yes (auto)
Cypress KitProg Programmer              yes (auto)
Altera USB-Blaster Compatible           no
ASIX Presto Adapter                     no
OpenJTAG Adapter                        no

So pretty much everything except some JTAG adapters. As it turns out there are a lot of useful JTAG adapters so to pick them up we need to add libftdi which is a library to talk to the FTDI MPSSE chip in a slightly different way than the generic version. It is also a place where you can get hung up if you’re not careful. libftdi-dev brings in the old version of the USB library, whereas libftdi1 uses the newer USB library. This will get you the OpenJTAG adapter, the Altera USB-Blaster compatible, and the ASIX Presto adapter.

Building and installing

Once you’ve got configure working the way you want it, building and installing is pretty straight forward. From the top level directory type make and the system will proceed to building the code into the final tool. It should run long error free (although I get a warning from ar which is harmless).

To install it you will need to be root, so use the sudo command and type:

sudo make install

This will install it in /usr/local/bin with its configuration files in /usr/local/share/openocd. You should then be able to type:

openocd --version

To verify that it has been installed correctly and can run. While doing this build for this writeup this prints out the following:

$ openocd --version
Open On-Chip Debugger 0.10.0+dev-00755-ga7479fa8 (2019-03-31-13:05)
Licensed under GNU GPL v2
For bug reports, read

Now there are a couple of more steps that you need to do before you are done, the first is to copy the file contrib/60-openocd.rules into the directory /etc/udev/rules.d. What this will do will tell the udev service to assign pretty much every USB attached debugger that OpenOCD can talk to, to the plugdev group. Then, if you add your own userid to the plugdev group then you will be able to use OpenOCD without running at root.

I discourage any activity that requires you run as root simply because it is very dangerous. Many people have typed commands (like rm -rf *) when they forgot they were root and given themselves a huge mess to clean up. Fortunately if that mess involves rebuilding OpenOCD from source you’re covered.

Basic OpenOCD operation

Ok, so you’ve built it, you have installed it. Now a very short discussion of how you run it.

Since I use the Nucleo boards, which have an ST-Link built into them generally, in a lot of my articles I’ll use that as an example.

When I plugged a Nucleo-F446RE into my system, the following shows up in the kernel message log (you can dump this with the command dmesg).

[138930.731430] usb 1-4: new full-speed USB device number 8 using xhci_hcd
[138930.881843] usb 1-4: New USB device found, idVendor=0483, idProduct=374b, bcdDevice= 1.00
[138930.881847] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[138930.881850] usb 1-4: Product: STM32 STLink
[138930.881853] usb 1-4: Manufacturer: STMicroelectronics
[138930.881855] usb 1-4: SerialNumber: 0670FF515350836767133625
[138930.938503] usb-storage 1-4:1.1: USB Mass Storage device detected
[138930.938874] scsi host1: usb-storage 1-4:1.1
[138930.939106] cdc_acm 1-4:1.2: ttyACM0: USB ACM device
[138930.947420] usbcore: registered new interface driver uas
[138931.964424] scsi 1:0:0:0: Direct-Access     MBED     microcontroller  1.0 PQ: 0 ANSI: 2
[138931.965067] sd 1:0:0:0: Attached scsi generic sg0 type 0
[138931.965590] sd 1:0:0:0: [sda] 1056 512-byte logical blocks: (541 kB/528 KiB)
[138931.965796] sd 1:0:0:0: [sda] Write Protect is off
[138931.965799] sd 1:0:0:0: [sda] Mode Sense: 03 00 00 00
[138931.966016] sd 1:0:0:0: [sda] No Caching mode page found
[138931.966023] sd 1:0:0:0: [sda] Assuming drive cache: write through
[138931.973129]  sda:
[138931.973888] sd 1:0:0:0: [sda] Attached SCSI removable disk

This tells you that it showed up as a composite device with three “ports”. One appears as the STLink device, one appears as a serial port, and one appears as a USB disk drive. This configuration was designed to support Mbed programming. Which is a great way to go, especially if you’re programming these things from Windows machines.

We will use the OpenOCD board configuration st_nucleo_f4.cfg as this Nucleo has an Cortex-M F4 type processor on board.

I usually create a separate terminal window for running OpenOCD as it will run continuously. So in that separate window I start it with:

$ openocd -f board/st_nucleo_f4.cfg
Open On-Chip Debugger 0.10.0+dev-00755-ga7479fa8 (2019-03-31-13:05)
Licensed under GNU GPL v2
For bug reports, read
Info : The selected transport took over low-level target control. The results
might differ compared to plain JTAG/SWD
adapter speed: 2000 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 2000 kHz
Info : STLINK V2J24M10 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.249836
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections

And there it is, up and running listening for arm-none-eabi-gdb to connect to it on port 3333. As you can see from the information messages it has found the ST-Link device, it sees the target CPU running at 3.25 volts, the chip has six breakpoints and four watchpoints.