Using GDB with T-Engine
Written by: Huang Bo and Fauzi Abbas (Centre for High Performance Embedded Systems [CHiPES], NTU Singapore)
This article points out how to use GDB with the T-Engine development environment. For this article, we used the SH7727 T-Engine on a Windows PC. Since GDB uses T-Monitor functions as target, the target transfers control to T-Monitor when control is passed to GDB. Ordinarily, T-Kernel-based programs have a reloadable format with addresses determined at the time of loading. However, for this procedure to work, addresses in the program to be debugged must be set at the time of linking. Therefore, the program must be linked using fixed logical address format for debugging. (Details are given below.)
Setting up the Target Hardware
Not much to do here – just connect the T-Engine to the host PC using the RS-232 port. Check that the DIP-SW2 is set to ON so that the baud rate is set at 115200bps.
Preparing the Host
We used the drawsamp sample from the T-Engine kit for this work. So, we worked in the usr/local/te/kappl/drawsamp directory.
1. Set up the debugging environment.
User@Local :/usr/local/te/kappl/drawsamp/$ ls
sh7727 src
User@Local :/usr/local/te/kappl/drawsamp/$ mkdir sh7727.debug
User@Local :/usr/local/te/kappl/drawsamp/$ ls
sh7727 sh7727.debug src
User@Local :/usr/local/te/kappl/drawsamp/$ cd sh7727.debug/
User@Local :/usr/local/te/kappl/drawsamp/sh7727.debug/$ ln –s ../src/Makefile .
2. Create a file called (.gdbinit) that contains the following:
set remotebaud 115200 (DIP-SW2 ON sets the serial communication rate to 115200 bps)
target tmon /dev/ttyS0 (which communication port the T-Engine is attached to)
3. Save the file in directory where you are going to run the debugger (preferably the “sh7727.debug” directory)
User@Local :/usr/local/te/kappl/drawsamp/sh7727.debug/$ ls
Makefile (Note: “.gdbinit” is in this folder but hidden from view)
User@Local :/usr/local/te/kappl/drawsamp/sh7727.debug/$
4. Modify the “Makefile” so that it looks as follows. You may have to adjust it slightly for your situation.
DEPS = Dependencies
DEPENDENCIES_OUTPUT := $(DEPS)
include ../../etc/makerules
# ----------------------------------------------------------------------------
TARGET = sample
S = ../src
VPATH = $S
SRC = main.c drawsamp.c mem.c graphic.c
OBJ= $(addsuffix .o, $(basename $(SRC)))
SRC.C= $(strip $(patsubst %.C, %.c, $(filter %.C, $(SRC))))
CFLAGS += $(CFLAGS_WARNING)
#This will be included if you specify the mode as ‘debug’
ifeq ($(mode), debug)
LDLIBS += -ltm
endif
#Note the absolute address below
ifeq ($(MACHINE), sh7727)
$(TARGET).abs: START_ADR = -Wl,-Ttext,0xc0000074
endif
# ----------------------------------------------------------------------------
.PHONY: all clean install
ALL = $(TARGET) $(TARGET).abs $(TARGET).map $(TARGET).mot $(TARGET).trg
%.map: %
all: $(ALL)
$(TARGET): $(OBJ)
$(LINK.o) $(LDOBJS) $^ $(LOADLIBES) $(LDLIBS) $(OUTPUT_OPTION)
$(TARGET).abs: $(OBJ)
$(LINK_TK.o) $(LDOBJS) $^ $(LOADLIBES) $(LDLIBS) $(OUTPUT_OPTION)
$(TARGET).trg: $(TARGET).abs
cp $< $@
$(STRIP) $@
$(TARGET).mot: $(TARGET).abs
$(OBJCOPY) $(OUTPUT_SREC) $< $@
clean:
$(RM) $(OBJ) $(SRC.C) $(ALL) $(DEPS)
install:
$(addprefix $(EXE_INSTALLDIR)/, $(ALL))
$(addprefix $(EXE_INSTALLDIR)/, $(TARGET)): $(EXE_INSTALLDIR)/%: %
$(EXE_INSTALL_STRIP)
ifdef DEPENDENCIES_OUTPUT
$(DEPS): ; touch $(DEPS)
else
$(DEPS): $(SRC) ; $(MAKEDEPS) $@ $?
endif
include $(DEPS)
$(SRC.C):
Note that the address is specified explicitly as 0xC0000074 since dynamic addresses are not supported.
Preparing the Application
1. We need to make small changes to the source. Add the following lines (in blue) at the first line where the code executes.
#include "drawsamp.h"
#ifdef DEBUG
#include <util\tmonitor.h>
#endif
EXPORT ER main( INT ac, UB *av[] )
{
#ifdef DEBUG
tm_monitor();
#endif
T_CTSK ctsk;
T_RTSK rtsk;
static ID tskid = -1;
if ( ac < 0 ) {
if (tskid >= 0) {
exitproc();
while (tk_ref_tsk(tskid, &rtsk) >= E_OK) tk_dly_tsk(1);
}
goto ext;
}
...
...
Note that DEBUG will be defined when we do the make.
2. Build the application
User@Local :/usr/local/te/kappl/drawsamp/sh7727.debug/$ make mode=debug
Makefile:83: Dependencies: No such file or directory
touch Dependencies
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/gccsh -g -ffreestanding -Wall -Wno-format -Wno-main
-I/usr/local/te/include -D_SH7727_ -DDEBUG -c ../src/main.c -o main.o
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/gccsh -g -ffreestanding -Wall -Wno-format -Wno-main
-I/usr/local/te/include -D_SH7727_ -DDEBUG -c ../src /drawsamp.c -o drawsamp.o
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/gccsh -g -ffreestanding -Wall -Wno-format -Wno-main
-I/usr/local/te/include -D_SH7727_ -DDEBUG -c ../src/mem.c -o mem.o
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/gccsh -g -ffreestanding -Wall -Wno-format -Wno-main
-I/usr/local/te/include -D_SH7727_ -DDEBUG -c ../src/graphic.c -o graphic.o
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/gccsh -L/usr/local/te/lib
/sh3l -r -T /usr/local/te/lib/sh3l/reloc.lnk main.o drawsamp.o mem.o graphic.o -lg -ltk -lg -lsvc -ltm
-o sample
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/gccsh -specs=specs-tk –L
/usr/local/te/lib/sh3l -static -T /usr/local/te/lib/sh3l/static.lnk -Wl,-Ttext,0xc0000074 main.o drawsamp.o
mem.o graphic.o -lg -ltk -lg -lsvc -ltm -o sample.abs
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/nm -n sample.abs > sample.map
/usr/local/te/tool/Cygwin-i686/bin/sh-unknown-tkernel-objcopy -O srec --srec-forceS3 --srec-len 32 sample.abs sample.mot
cp sample.abs sample.trg
/usr/local/te/tool/Cygwin-i686/sh-unknown-tkernel/bin/strip --strip-unneeded sample.trg
User@Local :/usr/local/te/kappl/drawsamp/sh7727.debug/$ ls
Dependencies drawsamp.o main.o sample sample.map sample.trg Makefile graphic.o mem.o sample.abs sample.mot
User@Local :/usr/local/te/kappl/drawsamp/sh7727.debug/$
Starting to use GDB
1. First, download the application to the T-Engine. At the T-Engine console, do the following.
[/SYS]% recv –c –d sample.trg
Target: sample.trg
sample.trg
[/SYS]% lodspg sample.trg
TM>(Disconnect from your serial terminal)
2. Startup the debugger with the ‘abs’ version of the application
User@Local :/usr/local/te/kappl/drawsamp/$/usr/local/te/tool/Cygwin-i686/bin/sh-unknown-tmonitor-gdb.exe sample.absGNU gdb 5.2
Copyright 2002 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=i686-pc-cygwin --target=sh-unknown-tmonitor".
..
0xc0002800 in tm_monitor ()
(gdb) l (line where the code is)
16 EXPORT ER main( INT ac, UB *av[] )
17 {
18 T_CTSK ctsk;
19 T_RTSK rtsk;
20 static ID tskid = -1;
21
22 #ifdef DEBUG
23 tm_monitor();
(gdb) s (step: jump into function)
Single stepping until exit from function tm_monitor, which has no line number information.
main (ac=1, av=0x401d9130) at ../src/main.c:26
26 if ( ac < 0 ) {
(gdb) n (next: jump over function)
36 ctsk.exinf = NULL;
(gdb) b 38 (set breakpoint)
Breakpoint 1 at 0xc000028c: file ../src/main.c, line 38.
(gdb) c (continue till end or breakpoint)
Continuing.
Breakpoint 1, main (ac=1, av=0x401d9130) at ../src/main.c:38
38 ctsk.task = task;
(gdb) q
The program is running. Exit anyway? (y or n) y
In red, we have shown the meanings of the GDB commands. For more details, please refer to the GDB manual.
Note: If the ‘(gdb)’ prompt does not appear, then pres “CTRL+C” two times.