Skip to content
This repository has been archived by the owner on Jul 6, 2019. It is now read-only.

Debugging Zinc Code with GDB and Eclipse

Paul Osborne edited this page Jun 2, 2015 · 3 revisions

Overview

This page describes steps to setup your development environment so that you can debug your Zinc application on target hardware. The steps here are verified to work with the MBED NXP LPC1768 board, but the steps should apply very directly to any board with a bootloader supporting CMSIS-DAP. Many steps will also apply to other debug probes, but changes should be expected.

The following shows the various elements in the debug toolchain described here:

Chip <-> JTAG/SWD <-> Bootloader Chip <-> CMSIS-DAP/USB <-> PyOCD <-> GDB Server <-> GDB Client <-> Eclipse

The key elements in the chain worth noting are:

  • Debug Probe: Many boards (especially MBED compatible) now include an on-board discrete bootloader chip that can be used as a debug probe via CMSIS-DAP. The MBED LPC1768, for instance, includes an LPC11u35. See mbed HDK. If your chip does not have a bootloader chip like this, a standard debug probe like a Segger J-Link, LPCLINK2, or the Bus Blaster can fill the same role.
  • CMSIS-DAP: This is a standardized protocol over USB that provides access over USB to SWD/JTAG/CoreSight commands in a standardized way.
  • PyOCD: Implements the CMSIS-DAP protocol on the host side and exposes a GDB server. GDB monitor commands can be sent to perform out-of-band operations like resetting the chip.

Basic GDB Setup

Build the code with debug symbols

This builds the code with extra debug symbols and disables optimizations that make the code difficult for the debugger to trace (functions are inlined, etc.).

$ make DEBUG=true EXAMPLE_NAME=blink

Using GDB with PyOCD

First, you will need to install pyOCD:

$ sudo pip install --pre -U https://github.com/mbedmicro/pyOCD/archive/master.zip

You can start a GDB Server instance by doing

$ sudo pyocd-gdbserver

With the server running and attached to the target, you can perform remote debugging with a GDB Client:

$ arm-none-eabi-gdb target/thumbv7m-none-eabi/debug/examples/blink
(gdb) target remote localhost:3333
(gdb) load
Loading section .vector, size 0xcc lma 0x0
Loading section .debug_gdb_scripts, size 0x22 lma 0xcc
Loading section .text, size 0x176c lma 0xf0
Start address 0x33c, load size 6234
Transfer rate: 3 KB/sec, 1246 bytes/write.
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x0000030a in wait_us<zinc::hal::lpc17xx::timer::Timer> (self=0x10001eb0, us=10000) at src/hal/../util/wait_for.rs:36
(gdb) bt
#0  0x0000030a in wait_us<zinc::hal::lpc17xx::timer::Timer> (self=0x10001eb0, us=10000) at src/hal/../util/wait_for.rs:36
#1  wait_ms<zinc::hal::lpc17xx::timer::Timer> (self=0x10001eb0, ms=10) at src/hal/timer.rs:42
#2  blink::main () at examples/app_blink.rs:35
#3  0x00000106 in blink::start () at examples/app_blink.rs:15
#4  0x00000434 in main ()
...

Eclipse Setup

Install Plugins

Eclipse with the CDT (C/C++ Development Tools) has good support for debuggers based on GDB. Install Eclipse with the CDT and add the following update sites and install the plugins:

Create a new C/C++ Project

Although there is a rust mode, I found the easiest way to set things up was to create a new "C/C++ Project with Existing Makefile". Creating a Project makes it easier to navigate the code in order to set breakpoints and select the ELF File for Debugging.

Select the root of the Zinc project (or your own project root) instead of the default source directory.

Create new Debug Configuration

  1. Select Run -> Debug Configurations.
  2. Hit New with "GDB OpenOCD Debugging" selected
  3. Setup Main Tab similar to this

Main Tab

  1. Setup Debugger Tab Similar to This

Debugger Tab

You can go ahead and tweak other tabs to your hearts content but no other changes should be required out of the box to get something working.

Debug It

With the configuration created, there are a few things you should do each time you want to debug:

  1. Make sure you have an up-to-date build with debug symbols
  2. Start up pyOCD again (each time you end a session it will close)
  3. Start the Debugging Session

When you start debugging, the debugger should stop at main(). You can do normal debugger stuff from there. Note that in many cases the early breakpoints may not resolve to a real line of code. You can change the settings to not break on main and set your own breakpoints.

Viewing Peripheral Registers

One final piece of functionality provided by the EmbSysRegView plugin that can be extremely helpful is the ability to view peripheral registers for the particular chip you are debugging. In order to see the peripheral registers for your chip, there are a couple steps.

  1. Go to Window -> Preferences -> C/C++ -> Debug -> EmbSys Register View and configuration your chip/board. If your board is not supported, it may be possible to add it if you can find its CMSIS-SVD definition.
  2. When in the Debug view, go to Window -> Show View -> Other... and add Debug -> EmbSys Registers. This will add a new tab that will have all of the Peripheral registers for the chip. You can read and modify peripheral registers from this view.

Pretty Picture

If all works out, the end result should look something like this:

Debugging