Debug sketch on Arduino Zero Pro with GDB and OpenOCD

Arduino is simple platform but empowers it’s users to do fantastic projects. People with experience in writing software for bigger computers can get strange feeling when they have no access to debugger. Debugger is tool for tracing program execution – You can examine/modify variables, going through code step by step and many more. In other words it let’s You know why program does not behave as expected. It is very useful tool, especially when You have to deal with more complex programs. But Arduino does not have such tool, only debugging method is to write messages via Serial class.

Arduino Zero Pro for rescue

We have Arduino Zero Pro in our offer. This board has 32-bit ARM Cortex-M0 processor. New feature is interface for debugging sketches on board. You can do it with JTAG/SWD adapter, or just connecting board to PROGRAMMING USB port. This article will show You how to access debugger feature with free and open tools.

Debug in progress
Debug in progress


How to start?

Test were done with computer running Linux, but all required software is bundled with Arduino IDE, so this tutorial should work also on Windows and MacOS without any significant changes.

Arduino ORG

It is important to note, that we will need Arduino IDE from not from At this moment (Apr/May 2015) only IDE on has support for Arduino Zero Pro.

We need to download and install Arduino IDE 1.7.3 or newer. Next step is to increase number of messages given by IDE during sketch compilation. Open preferences (Ctrl+,) and near  Show verbose option during mark compilation.

For our first debug target we will use Blink. Open it  (menu Files/Examples/01. Basic/Blink), connect Arduino Zero to computer using PROGRAMMING port, in IDE select also Arduino Zero Pro (Programming) and upload sketch to board (Ctrl+U).


ARM consortium has agreed on communication standard for Cortex-M0 processors. It is called CMSIS (more details about – link) and there is open software supporting this standard.

Let me introduce You – OpenOCD. OpenOCD binary files are bundled with Arduino IDE and You don’t have to install anything more.

Starting OpenOCD

Having our Blink sketch on board, we go to directory where is Arduino IDE and we start OpenOCD using this command:

./hardware/tools/OpenOCD-0.9.0-dev-arduino/bin/openocd -s hardware/tools/OpenOCD-0.9.0-dev-arduino/share/openocd/scripts/ -f hardware/arduino/samd/variants/arduino_zero/openocd_scripts/arduino_zero.cfg

Argument after -s defines folder where are configuration files for OpenOCD, and after -f switch there is configuration file defining Arduino Zero Pro capabilities.Result for running this command should be similar to this:

Open On-Chip Debugger 0.9.0-dev-g1deebff (2015-02-06-13:06)
Licensed under GNU GPL v2
For bug reports, read
Info : only one transport option; autoselect 'cmsis-dap'
adapter speed: 500 kHz
adapter_nsrst_delay: 100
cortex_m reset_config sysresetreq
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: JTAG Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : CMSIS-DAP: FW Version = 01.1F.0118
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)
Info : CMSIS-DAP: Interface ready
Info : clock speed 500 kHz
Info : IDCODE 0x0bc11477
Info : at91samd21g18.cpu: hardware has 4 breakpoints, 2 watchpoints


OpenOCD is ready to work. It listens on ports  4444 and 3333. On first port there is telnet server and second one hosts GDB server.

GDB is open source software for debugging programs. It is also bundled with Arduino IDE. It is important to have GDB with support for ARM architecture, so use binaries attached to Arduino IDE.

To proceed we need file with compiled program in  ELF format and with included informations required to properly debug code. Such file is prepared by Arduino IDE during compilation and is stored in temporary directory. To know where this file is we compile Blink again, this time without uploading to board. Just press Ctrl+R and examine output in IDE console window. In one of last lines You will see path and filename with .elf extension. See by Yourself, but note that console window is scrolled to the right, to see this file path:

Where to find ELF file location in Arduino IDE
Where to find ELF file location in Arduino IDE


We are ready to run GDB. In folder with Arduino IDE issue command:

./hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb -d examples/01.Basics/Blink/

Folder given after -d switch is place where GDB can find source files for our program. This is required by GDB to display it later to You when You will step through Your program. After issuing this command You should see GDB command line:

GNU gdb (GNU Tools for ARM Embedded Processors (Arduino build))
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
For bug reporting instructions, please see:

In this article I show You only basic steps to get debugger features, for more detailed info about how to use GDB dig by Yourself. In future we may prepare more detailed info about GBD.

First we have tell GDB where to find file with program and debug information:

(gdb) file /tmp/build4557814640826011475.tmp/Blink.cpp.elf
Reading symbols from /tmp/build4557814640826011475.tmp/Blink.cpp.elf...done.

Command file is used to supply path and filename to program, just insert here path copied from Arduino IDE few steps earlier.

Now we need to inform GDB where it can find our live program:

(gdb) target remote localhost:3333
Remote debugging using localhost:3333
0x00000000 in ?? ()

Now we can take control over program execution, examine this GDB session output:

(gdb) monitor reset halt
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x21000000 pc: 0x000028b8 msp: 0x20002c08
(gdb) monitor reset init
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x21000000 pc: 0x000028b8 msp: 0x20002c08
(gdb) l loop
19    // initialize digital pin 13 as an output.
20    pinMode(13, OUTPUT);
21  }
23  // the loop function runs over and over again forever
24  void loop() {
25    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
26    delay(1000);              // wait for a second
27    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
28    delay(1000);              // wait for a second
(gdb) b 25
Breakpoint 1 at 0x4120: file Blink.ino, line 25.
(gdb) cont
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, loop () at Blink.ino:25
25    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
(gdb) c

Breakpoint 1, loop () at Blink.ino:25
25    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)

Command monitor reset halt sends to our board processor instruction to stop sketch execution, now LED on Arduino stops blinking. monitor reset init resets Arduino CPU to empty state, and it becomes ready to start over.

l loop display loop function code (that is reason why we need tell GDB where are source files). Command b 25 sets breakpoint in line 25 of current source file. cont resumes program execution (well, actually it starts from beginning since we have issued  monitor reset init ). This is reason why after cont, program gets to line 25 and before LED is lit execution is halted. Next c commands allow to run code until it returns to line 25 .

What’s next?

This is simple example to illustrate new possibilities Arduino Zero Pro opens before You. People familiar with GDB are ready now to order Arduino Zero Pro  and start exploring new ways to debug sketches. Others can see on this short video, debugging on Zero Pro is quite easy.

But, since GDB is working nothing does stop us from using some graphical interface for GDB, list of such tools is quite long. We have used DDD (this time You have to install it by Yourself)

DDD during debug session with Arduino Zero Pro
DDD during debug session with Arduino Zero Pro

To use it with Arduino You have to tell DDD where is proper GDB:

ddd --debugger "hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb -d examples/01.Basics/Blink/"