GDB

From NXTGCC

Jump to: navigation, search

Contents

GDB

The first thing we have to agree on is that debuggging is an illusion, but a nice one. We think (initially) that we have stopped the processor and now we can just inspect it as we like. But the processor keeps running, and we are inspecting a snapshot of how (parts of) the processor looked when it hit a breakpoint.

GDB is the debugging system that is connected to GCC. In terms of Lego Mindstorms NXT, the GDB system offers a remote debugging system. This system allows us to use a most PC running GDB and inspect the inner workings of NXT while it is running. To be more specific, we think about the firmware executing on NXT as a remote program. Abiding by a few interfaces that GDB asks for, we are able to look inside NXT and see what the current values are in the registers etc.

Registers

The ARM processor in NXT have a number of registers. These registers are places to keep information for the processor while it is executing instructions. The ARM processor is executing instructions in a normal mode, but in embedded systems it will often switch to alternative modes. This is done in response to information delivered to the ARM processor via a peripheral such as I2C. For debugging purposes, we can use a mode in the processor called undefined instruction mode. What happens is that when the processor changes mode from normal mode to a different mode (such as undefined mode) the registers are saved (some are saved automatically, and some we have to save), and then it is possible to inspect them from the new mode.

USB

To debug NXT there has to be a connection to the GDB host running on the PC. The easiest USB driver to use is the Fantom SDK. It is already on the PC. The NXTGCC GDB uses this DLL to communicate with NXT. Inside the Fantom C++ files, there is a section with "extern C" that lists the C methods that can be called. The methods that are really crucial for NXTGCC GDB is the read and write methods for arbitrary bytes. This allows for an implementation of the GDB remote debugging protocol.

arm-elf-gdb

The toolchain is arm-elf-gcc and the debugger is arm-elf-gdb. On the host PC, this program loads the firmware image (in ELF format) and then controls the communication to NXT. It also features a simulator.

USB 2.0

The communication between NXT and the host PC is done via USB. This involves so-called endpoints and is quite involved. To make a long story short, the host PC needs to know what kind of USB is connected and this is done with descriptors that are sent to the host. An useful tool at this point is USBlyzer, because we can see what the PC sends to NXT, and vise versa. When we are debugging/developing/extending the NXTGCC GDB debugger this is needed.

Eclipse

Eclipse is used as the IDE for the firmware development toolkit. The debugger is contained in the NXTGCCFANTOM project. There are lots of documentation around for using Insight) or [http://wiki.eclipse.org/DSDP/DD/GDB Eclipse.

Packet format

The packet format of the GDB serial protocol is convenient for the NXTGCC GDB debugger. It includes a checksum, which comes after the # in the packet (see the packet description). The problem is the the Fantom DLL does not like if we try to read from the USB if there is not something to read, but the GDB packet format comes in handy, because we know just to read two characters (the checksum) after the #. That is the reason why the NXTGCC Fantom GDB wrapper (discussed later) writes and especially reads one character at a time to/from NXT.

Debugging Ping/Pong

The GDB talk between GDB, the GDB/Fantom DLL wrapper, and NXT is a little complicated. The following table summarizes it. Please see the main.c file in the Eclipse NXTGCCFANTOM project for details on the wrapper part. For how NXT works, please refer to the nxtdebug.c file in the Eclipse NXTGCC project.

GDB Host (tcp->) (<-tcp) FANTOMGDB (usb->) (<-usb) NXT
Placed in firmware download mode
Compile and download firmware
NXT boots into normal mode and starts to execute the downloaded firmware code
Listen to NXT who is the "master"
(FANTOM in parallel sends out USB descripter requested to NXT, which have to answered to)
Program counter reaches a breakpoint and sends GDB trap message
Fantom is listening and relay the initial GDB trap message
GDB gets the trap message
GDB sends a qSupported message
Listen to GDB who is now "master"
NXT replies
GDB sends out messages to query the registers
Acts as relay via TCP/USB
NXT faithfully replies

One thing to note: It may be noted that I have chosen to use TCP for the interface between GDB and Fantom... It will be possible to have geographically remote NXT debugging sessions....

Screendumps from a debugging session

After (or before) reading this section, you can download and install the latest NXTGCC package.

Eclipse

Start by right-clicking on the NXTGCCFANTTOM project and choose run as local C/C++ application. When you change code in the project, the just rebuild the project (or select Build Automatically) in the Project menu. Before this point it is assumed that you have compiled a firmware (run "NXTGCC Make" from the Eclipse external tools menu) and (for example) enabled the breakpoint-generating method on line 291 in c_comm.c). Regardless, you have to have a breakpoint in the code. Note that the NXTGCC release does not have this line enabled, so you have to enable it and re-compile the firmware, which automatically copies the firmware the NXTGCCFANTOM project.


File:NXTGCC-GDB-INITIALSCREEN.png


NXT is placed in SAMBA mode, and the above command downloads the new firmware image. Then it waits for GDB to be fired up. You may be presented with the choice of choosing between Cygwin and Mingw. The NXTGCC release is currently using Mingw, so:


File:NXTGCC GDB-MINGW.png


File:NXTGCC-GDB-WAIT-FOR-GDB.png


Let's fire up GDB. A little utility program called "Open Command Window Here" may be useful (see Microsoft Powertoys). A command window with the current directory of the Eclipse NXTGCC FANTOM directory is opened:


File:NXTGCC-GDB-START-ARM-ELF-GDB.png


File:NXTGCC-GDB-START-REMOTE-TARGET.png


Now we can get information about the current contents of the registers (pls. refer to nxtbebug.c for details):


File:NXTGCC-GDB-INFO-REGISTERS.png


For validation, there is placed a 4 in register 0:

/*---- Save r0 and SPSR on the Undef stack */
    mrs     r14, SPSR
    mov     r0, #4 /* See if we can see this in the code */
    stmfd   sp!, {r0, r14}

Please see Cstartup.S aroung line 476. That is also what we see when invoking the info registers command.

Links

  • N(e)XT Steps
    • The above was done from the ground up with the old sparc stub
    • Stepping in the code: [3] + ecos. The ecos code is comprehensive.
    • OPENOCD: The OPENOCD debugger is popular and it yield hardware debugging support. For example, the (software) GDB debugger described above will only work when NXT is booted and the USB is configured.
    • Over the air debugging (using Bluetooth on NXT) similar to what can be done to the Sun Spots that I have played around with.
Personal tools
navigations