Services - tools - models - for embedded software development
Embecosm divider strip
Prev  Next

4.5.1.  An Example Debugging Session.

The directory sw/test-progs contains a number of simple test programs. Use the Makefile to build these. The programs include a simple "Hello World" program in hello.c, which compiles to the file hello.

First build the GDB server. Use the command make from the top level directory.

$ make

<makefile output>

time -p ./Vorpsoc_fpga_top

             SystemC 2.2.0 --- May 16 2008 10:30:46
        Copyright (c) 1996-2006 by all Contributors
                    ALL RIGHTS RESERVED
Loading flash image from sim/src/flash.in
(orpsoc.v.uart_top) UART INFO: Data bus width is 32. Debug Interface present.

(orpsoc.v.uart_top) UART INFO: Doesn't have baudrate output

Listening for RSP on port 51000
	  

In a separate window, change to the sw/test-progs sub-directory and build the example programs using make. Then start the OpenRISC 1000 implementation of GDB (see Embecosm Application Note 2: The OpenCores OpenRISC 1000 Simulator and Tool Chain: Installation Guide [6] for details of how to install the tool chain).

$ or32-uclinux-gdb
Building automata... done, num uncovered: 0/216.
Parsing operands data... done.
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
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=i686-pc-linux-gnu --target=or32-uclinux".
(gdb) 
	  

First load the program symbol table using the file command. Then connect to the GDB server using the target remote command. Since no port number was specified, the default 51000 will be used:

(gdb) file hello
Reading symbols from .../sw/test-progs/hello...done.
(gdb) target remote :51000
Remote debugging using :51000
0x040001f0 in ?? ()
(gdb) 
	  

At start up the processor is stalled, so it looks to the GDB client as though the target has just hit a breakpoint at the address of the Previous Program Counter (PPC). Since the processor stalled just as it finished executing in Flash memory, the address of the PPC is an address in Flash. That has nothing to do with the "Hello World" program which will be loaded, and for which the symbol table has already been loaded. So the GDB client cannot identify which source code this location corresponds to and just reports it as ??.

The window with the GDB server acknowledges the connection:

Listening for RSP on port 51000
Remote debugging from host 0.0.0.0
	  

Since this is a local connection the remote host is reported as 0.0.0.0.

The client can now load the hello world program. This will take a few seconds, even for a program as small as this, since each word has to be loaded over the model of JTAG, taking round 750 clock cycles. Even with a model running at nearly 100kHz this takes some time.

(gdb) load hello
Loading section .text, size 0x1350 lma 0x0
Loading section .rodata, size 0x1f lma 0x1350
Start address 0x100, load size 4975
Transfer rate: 323 bytes/sec, 236 bytes/write.
(gdb) 
	  

A breakpoint can be set on the main program and execution continued:

(gdb) break main
Breakpoint 1 at 0x12f4: file hello.c, line 26.
(gdb) continue
Continuing.

Breakpoint 1, main () at hello.c:26
26        simputs ("Hello World!\n");
(gdb) list
21      #include "utils.h"
22
23
24      main()
25      {
26        simputs ("Hello World!\n");
27        simputs ("The answer is ");
28        simputn (6 * 7);
29        simputs ("\n");
30        simexit (42);
(gdb) 
	  

Placing a breakpoint on simputs allows the output generation to be followed:

(gdb) break simputs
Breakpoint 2 at 0x1234: file utils.c, line 105.
(gdb) c
Continuing.

Breakpoint 2, simputs (str=0x1350 "Hello World!\n") at utils.c:105
105       for( i = 0; str[i] != '\0' ; i++ ) {
(gdb) list
100      */
101     void  simputs( char *str )
102     {
103       int  i;
104
105       for( i = 0; str[i] != '\0' ; i++ ) {
106         simputc( (int)(str[i]) );
107       }
108
109     }       /* simputs() */
(gdb)
	  

At this stage no characters have been output, but continuing again will cause the function to execute once:

(gdb) continue
Continuing.

Breakpoint 2, simputs (str=0x1350 "Hello World!\n") at utils.c:105
105       for( i = 0; str[i] != '\0' ; i++ ) {
(gdb)
	  

Switching back to the server window, the first line of output can be seen:

Listening for RSP on port 51000
Remote debugging from host 0.0.0.0
Hello World!
	  

The GDB extensions for OpenRISC 1000 are supported, so the info spr and spr commands are both available:

(gdb) info spr cpucfgr
SYS.CPUCFGR = SPR0_2 = 32 (0x20)
(gdb) 
	  

The CPU configuration register is showing that only the ORBIS32 instruction set is currently supported.

Deleting all breakpoints the program will run to completion:

(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) continue
Continuing.
Remote connection closed
(gdb)
	  

The server window shows the program running to completion. In this example hello.c calls simexit which uses the OpenRISC 1000 l.nop 1 instruction to cause the simulation to terminate.

Listening for RSP on port 51000
Remote debugging from host 0.0.0.0
Hello World!
The answer is 42
546960700.00 ns: Exiting (42)
SystemC: simulation stopped by user.
Closing connection
real 2708.49
user 87.82
sys 0.53
$
	  

On completion the RSP connection is dropped.

Embecosm divider strip