world leader in high performance signal processing
Trace: » debugging

GDB based debugging

This page is preliminary…

Bare metal ELF Image compiled from GCC toolchain can debugged via standard GDB commands. GNU debugger will not be re-explained for Bare Metal applications. Refer to the generic pages for explanations on using the same. Even if the GDB is traditionally used with serial or ethernet based debugging, Gdbproxy enables debugging via JTAG also. A quick overview of this approach is given below. Refer to this presentation for more information: gdbproxy

Running gdproxy - sample output:

C:\Program Files\Analog Devices\GNU Toolchain\2010R1\elf\bin>bfin-gdbproxy.exe

Remote proxy for GDB, v0.7.2, Copyright (C) 1999 Quality Quorum Inc. MSP430 adaption Copyright (C) 2002 Chris Liechti and Steve Underwood Blackfin adaption Copyright (C) 2008 Analog Devices, Inc.

GDBproxy comes with ABSOLUTELY NO WARRANTY; for details use `--warranty' option. This is Open Source software. You are welcome to redistribute it under certain conditions. Use the '--copying' option for details.

Found USB cable: ICE-100B
ICE-100B Firmware Version is 2.0.0
IR length: 5
Chain length: 1
Device Id: 00110010011111001000000011001011 (0x327C80CB)
  Manufacturer: Analog Devices, Inc. (0x0CB)
  Part(0):      BF537 (0x27C8)
  Stepping:     3
  Filename:     c:\program files\analog devices\gnu toolchain\svn-20101128\elf\b
in\../share/urjtag/analog/bf537/bf537
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/urjtag/src/bfin/bfin-part-bfin
.c:154 bfin_wait_ready() Warning: untested cable or frequency, set wait_clocks t
o 21
warning:   bfin: no board selected, BF537 is detected
notice:    bfin: jc: waiting on TCP port 2001
notice:    bfin: jc:  (you must connect GDB before using jtag console)
notice:    bfin-gdbproxy.exe: waiting on TCP port 2000

Eclipse

Eclipsed provides a front end for GDB based debugging. This is useful for those who are more comfortable with a GUI or IDDE based environment. Refer to Eclipse pages for more info: Eclipse.

Sample Project options for Eclipse (similar to VDSP Project Options):

The MMR viewer for Bare metal applications:

Bootloaders in Bare metal development

Developing and debugging Bare metal applications generally requires JTAG tools. Using a JTAG interface, users can accurately debug the application running on the target. However, it is also possible to run / debug the ELF Image with the boot-loader concept. Since most of the boot loaders are expected to support debugging through serial and ethernet (which enables them to load and debug Linux images), the same concept may be utilized to debug a bare metal ELF image, though with limited support.

Boot loaders may vary in their support for bare metal debugging, but in general they should have these common functionalities:

  • Command and data transfer through serial.
  • Command and/or data transfer through ethernet.
  • Support for running and/or debugging ELF Image.
  • Support for gdb server.

u-boot

Users may find the following features particularly useful for bare metal applications (especially without JTAG):

kgdb method

u-boot also supports kgdb to debug the Linux Kernel. This method maybe employed for debugging bare metal ELF Image also.

/* TO DO: list the commands here*/

uMon

uMon or micromonitor bootloader has some capabilities that can be utilized for ELF image running and debugging. This software can either work standalone or it can also co-exist with u-boot such that the u-boot can load the ELF image of this bootloader. The following output was taken from uMon running on BF537 EZ-KIT Lite.

Only the relevant commands are listed here. Refer to uMon pages for building and using the bootloader.

To create the uMon ELF image (bram.elf), refer to uMon documentation at uMon. Then, with the target running u-boot, the image is transferred to the target's memory…

bfin> tftp 0x1000000 bram.elf
Using bfin_mac device
TFTP from server 192.168.10.20; our IP address is 192.168.10.10
Filename 'bram.elf'.
Load address: 0x1000000
Loading: ######################################################
done
Bytes transferred = 786456 (c0018 hex)

Then u-boot loads bram.elf and turns over control to its entrypoint; which in turn gives control of the board to uMon command prompt.

bfin> bootelf 0x1000000
Loading phdr 0 to 0x02f00000 (289976 bytes)
## Starting application at 0x02f00000 ...tTFS altdevtbl[0] appears corrupt
TFS altdevtbl[1] appears corrupt
Misformed ethernet addr at: 0x20000010


                             MICRO MONITOR 1.18.17
                           Platform: ADDS-BF537-EVAL
                              CPU: BlackFin BF537
                         Built: Jun 22 2011 @ 18:37:39
                       Monitor RAM: 0x2f46cb8-0x2f61ea0
                        Application RAM Base: 0x100000
                                  IP: 0.0.0.0
                                 CPU Version 3
uMON>help -i
MICRO MONITOR 1.18.17
Platform: ADDS-BF537-EVAL
CPU: BlackFin BF537
Built: Jun 27 2011 @ 18:11:56
Monitor RAM: 0x2f46d8c-0x2f61fc4
Application RAM Base: 0x100000
IP: 0.0.0.0
CPU Version 3
Stack: bottom=0x2f5f4e4, size=8192
Moncomptr:    0x02f00004
Etheradd_ptr: 0x20000010
AltTFSdevtbl: 0x20000030

Change parameters for network.

uMON>set IPADD 192.168.10.10
uMON>set ETHERADD 00:11:22:33:44:55
uMON>set
       PROMPT = uMON>
   APPRAMBASE = 0x100000
  BOOTROMBASE = 0x20000000
     PLATFORM = ADDS-BF537-EVAL
 MONITORBUILT = Jun 22 2011 @ 18:37:39
    MONCOMPTR = 0x2f00004
  TARGETTIMER = 0x2f000a2
 TICKSPERMSEC = 0x7a120
  VERSION_MAJ = 1
  VERSION_MIN = 18
  VERSION_TGT = 17
  CONSOLEBAUD = 57600
        IPADD = 192.168.10.10
     ETHERADD = 00:11:22:33:44:55
uMON>ether on

Build the application ELF image. Note that the startup code of the bare metal application should not mess up with the Stack allocation done by uMon. It should also make sure to return back to uMon safely with mon_appexit(). An example that was compiled with '-nostartfiles' option is given below:

#include <cdefBF537.h>
#include <monlib.h>
extern unsigned char _bss_start, _bss_end;
int main(void);
void _start(void)
{
	register unsigned char *ramstart;
	ramstart = &_bss_start;
	while(ramstart < &_bss_end)
		*ramstart++ = 0;

/* Connect the application to the monitor. This must be done prior to the application making any other attempts to use the "mon_" functions provided by the monitor. */
	 
	monConnect((int(*)())(*(unsigned long *)0x02f00004),(void *)0,(void *)0);

	int r = main();

	mon_appexit(0);

}
int main(void)
{
	*pPORTF_FER 		= 0x0000;		// Setup for LEDs
	*pPORTFIO_DIR		= 0x0FC0;		// Setup port for output
	*pPORTFIO_SET		= 0x0FC0;		// Turn all LEDs on

	return 0;
}

Load and run the application image.

uMON>tftp -F bare -fE 192.168.10.20 get bare_test_bf537
Retrieving bare_test_bf537 from 192.168.10.20...
TFTP transfer complete.
Rcvd 177937 bytes
Adding bare (size=177937) to TFS...
uMON>bare

Application Exit Status: 0 (0x0)
uMON>

ELF Image can also be stored as a function that can be accessed via call command.

uMON>tfs -v ld bare
 .text     : copy    6704 bytes from 0x20102c1c to 0xffa00000
 .bss      : set      304 bytes  at  0xff800000 to 0x00
 .comment  :           72 bytes not processed (tot=72)
 .debug_aranges:           64 bytes not processed (tot=136)
 .debug_pubnames:         1305 bytes not processed (tot=1441)
 .debug_info:         9381 bytes not processed (tot=10822)
 .debug_abbrev:          628 bytes not processed (tot=11450)
 .debug_line:         1296 bytes not processed (tot=12746)
 .debug_frame:         1904 bytes not processed (tot=14650)
 .debug_str:         1636 bytes not processed (tot=16286)
 .debug_loc:         2418 bytes not processed (tot=18704)
 .debug_macinfo:       142844 bytes not processed (tot=161548)
 .shstrtab :          166 bytes not processed (tot=161714)
 .symtab   :         2832 bytes not processed (tot=164546)
 .strtab   :         1949 bytes not processed (tot=166495)
 entrypoint: 0xffa00000
uMON>call $ENTRYPOINT
Application Exit Status: 0 (0x0)
uMON>

gdbserver on uMon

uMon can be configured with a gdb server running on Ethernet - to provide basic download and then post-mortem analysis. If there was a crash or exit, the “application code, data and their symbols” would still be in memory and gdb could be connected to uMon to symbolically look at state. Note that currently there is no support for using gdb as a runtime debugger.

At host, set up the gdb and debug symbolically (note: no breakpoint / step / run / continue). Some examples are given below.

C:\Program Files\Analog Devices\GNU Toolchain\2010R1\elf\bin>bfin-elf-gdb.exe bare_test_bf537
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=i386-mingw32msvc --target=bfin-elf"...
(gdb) target remote udp:192.168.10.10:1234
warning: The remote protocol may be unreliable over UDP.
Some events may be lost, rendering further debugging impossible.
Remote debugging using udp:192.168.10.10:1234
warning: unrecognized item "OK" in "qSupported" response
0x00000000 in ?? ()
(gdb) print global_data
$3 = 5678
(gdb) print 0xff800000
$6 = 4286578688

Note that the debugging context is within the executed application. By forcing a return via exception, gdb can look inside the registers also.

#define EXCEPTION()     asm("excpt 5");     /* Force exception */

(gdb) info registers
r0             0x0      0
r1             0x40     64
r2             0xf870   63600
r3             0x2f4acfc        49589500
r4             0x2f5f0f4        49672436
...

Application can make use of the uMon in-built heap manager for dynamic allocations, instead of using the standard APIs. It gives a descriptive analysis of the allocation functions and usage. Note that the monitor itself uses malloc / free, so one would see additional numbers in the output. Application needs to call mon_malloc() & mon_free(p) to connect to the heap manager in the uMon. One example is given below.

uMON>heap
Heap summary:
  Malloc/realloc/free calls:  99/0/47
  Malloc/free totals: 1604/812
  High-water level:   792
  Malloc failures:    0
  Bytes overhead:     1060
  Bytes currently allocated:   792
  Bytes free on current heap:  63684
  Bytes left in allocation pool:  0