Now that we can compile stuff for ARM, we need a way to see what our code is doing.
Most (all?) of ARM processors have JTAG. JTAG is used to access the debug port on the CPU, allowing to change state, registers, memory, peripheral registers, etc. OpenOCD knows how to talk to CPU through JTAG.
We are going to show you how to setup OpenOCD with GDB and make them behave together.

In Part 2 we assume that you are coming with all the environment variables set as in Part 1.

Go get the sources of GDB and OpenOCD from:

We used OpenOCD version 0.3.0-rc0, and GDB version 7.0.1. Go build the GDB, and install it with the rest of the toolchain.

cd gdb-7.0.1/
mkdir build
cd build
../configure --target=$ARMTARGET --prefix=$TOOLPATH
sudo make install

OpenOCD is pretty straight forward as well. Except you need to specify which JTAG adapters you want to use. You should check the “configure help” to see all available. We own Wiggler and Usbprog, so we are enabling those.

cd openocd
mkdir build
cd build
../configure --enable-parport --enable-usbprog --prefix=$TOOLPATH
sudo make install

Now that we have complete toolchain, we need to create OpenOCD configuration file. The idea with OpenOCD is, that you have separate configuration file for every project/every board configuration.

The setup we are going show uses Olimex STM32-103STK board with Wiggler clone adapter.

Everytime you start OpenOCD it looks for openocd.cfg file. This file should contain information on what interface you are using, speed, port, etc, and target(s) specification.
Default settings for many interfaces come with OpenOCD. If you are using some standard setup, you should be able to find your config here:


You also need to be sure to include target file. Target files specify TAP(s) that are provided, some constrains like RAM size, Flash size. Also if you have some good known evaluation board.
If you cannot find the right target file, look in similarly named files, Most of these targets are same (in JTAG sense).

Our configuration looks like this:

interface parport
parport_port 0
parport_cable wiggler
jtag_speed 0
source [find board/olimex_stm32_h103.cfg]

This configures the wiggler to use /dev/parport0 in maximal speed mode. And adds the olimex board configuration.
In this file you can also define procedures that could save you a lot of time. For example to flash and restart STM32 cpu you need to issue 3-4 commands. These procedures are written in lightweight TCL language. TCL Crash course will give you overview of this language.

proc flash_load {file} {
poll off
stm32x mass_erase 0
sleep 500
flash write_image $file elf
poll on

Disabling the poll mode will save you some bandwidth while flashing, thus saving some time. The difference is not noticeable on high-speed interfaces, so you can omit these commands.

Now that we have everything setup, we can fire up the OpenOCD. If you have entered everything correctly you should see that OpenOCD has identified the TAPs correctly. If not check your JTAG connection and retry.

Update: I have found out that for some ARM processors (namely Cortex-M3) I had to issue “reset halt” command, otherwise I got many errors.
Using this command line helps:
openocd -f openocd.cfg -c "init" -c "halt" -c "reset halt"

Once it’s up and running OpenOCD listens on 2 ports by default:
– 3333 for GDB connection.
– 4444 for telnet connection.

Connecting with telnet to localhost:4444 will give you command line where you can control OpenOCD directly. Help command will print all the known commands.

For the GDB to be able to use the OpenOCD, you need to tell it, where to find the remote target. Easiest way to do so, is to create file named “.gdbinit” in the directory of your project.
In this file you want to specify following:

file stm32.elf
target remote localhost:3333
monitor soft_reset_halt

First line tells GDB where to find the elf for symbols. Second line specifies that the target is remote and sitting on port 3333. The third line executes “soft_reset_halt” command on the monitor.
The monitor in this case is OpenOCD. Using the monitor command you can execute any command of the OpenOCD and the output will appear in the GDB. For complete list of commands see the help command.

I won’t go much deeper into using GDB, as there are many other nice tutorials out there :).