Chapter 3. Sourcery G++ Lite for ARM uClinux

Abstract

This chapter contains information about using Sourcery G++ Lite on your target system. This chapter also contains information about changes in this release of Sourcery G++ Lite. You should read this chapter to learn how to best use Sourcery G++ Lite on your target system.

Table of Contents

Debugging ARM uClinux
GDB Server
ARM Halting Debug Mode
Sourcery G++ Lite Release Notes
Changes in Sourcery G++ Lite 2007q3-51
Changes in Sourcery G++ Lite 2007q3-33
Changes in Sourcery G++ Lite 2007q1-21
Changes in Sourcery G++ Lite 2007q1-10
Changes in Sourcery G++ Lite 2007q1-3

Debugging ARM uClinux

Sourcery G++ Lite provides two ways to debug a target board. A gdbserver can be used to debug user applications and a Sourcery G++ Lite Debug Sprite can be used to debug the kernel itself.

GDB Server

Sourcery G++ Lite contains a gdbserver for running on the target. The servers are located in the arm-uclinuxeabi/libc/cpu/usr/bin directories of your installation. Although there are different servers for each CPU variant, the default in arm-uclinuxeabi/libc/usr/bin works across all ARM architectures. You need to copy this to your target system and then invoke it as

# gdbserver :port program

port can be any available TCP port; 5000 is a common choice. gdbserver waits for a connection from gdb and then commences serving requests for it. To connect to gdbserver from your host system, start gdb, but specify the special .gdb version of your program.

arm-uclinuxeabi-gdb program.gdb

Then connect to the target system,

(gdb) target remote host:port

At this point you are able to debug as usual.

ARM Halting Debug Mode

Sourcery G++ Lite contains the Sourcery G++ Debug Sprite. This sprite uses Halting Debug Mode, and is provided for remote debugging of a bare board. You can use this to debug a program when there is no operating system on the board, or for debugging the operating system itself. If the board is running an operating system, and you wish to debug a program running on that OS, you should use the facilities provided by the OS itself (for instance, using gdbserver).

This section demonstrates execution and debugging of a simple application. Create a file named hello.c:

#include <stdio.h>

int
main (void)
{
  printf("Hello World!\n");
  return 0;
}

Compile and link the program for the target board. If it is a stand-alone program for a Stellaris LM3S800-series board use:

> arm-uclinuxeabi-gcc -mcpu=cortex-m3 -mthumb -Tlm3s8xx-rom.ld \
  hello.c -o hello -g

For other boards you must make appropriate substitutions in the preceding command. If your program is an operating system kernel such as uClinux or Linux, your usual build method should be adequate, as the kernel contains the necessary initialization code for interrupt handlers.

Verify that the Sourcery G++ Debug Sprite supports your debug hardware:

arm-uclinuxeabi-sprite -i

This prints out a list of supported device types. All ICE units supported by the Sourcery G++ Debug Sprite auto-detect the device connected to them, so nothing needs to be done to identify it explicitly. The command should output:

CodeSourcery ARM Debug Sprite
rdi: (rdi-library=<file>&rdi-config=<file>) RDI Device
  rdi:/// - RDI Device
armusb: [speed=<n:0-7>] ARMUSB device
  armusb:/// - ARMUSB Device

This shows that RDI and ARMUSB devices are supported.

Start the debugger on your host system:

> arm-uclinuxeabi-gdb hello

Connecting GDB to the board depends on the debug device you are using. If you are using an ARMUSB debug device, use:

(gdb) target remote | arm-uclinuxeabi-sprite \
armusb:///?speed=2 lm3s8xx
Remote debugging using | arm-uclinuxeabi-sprite \
armusb:///?speed=2 lm3s8xx
arm-uclinuxeabi-sprite:Target reset
start () at /buildpath/newlib-arm/libgloss/arm/crt0.S:50
50              ldr     r0, =__data_load
Current language:  auto; currently asm

If you are connecting via RDI, you must specify the full path to the RDI library file and configuration file for that library:

(gdb) target remote | \
arm-uclinuxeabi-sprite \
"rdi:///?rdi-library=library&rdi-config=config"
Remote debugging using | arm-uclinuxeabi-sprite \
"rdi:///?rdi-library=library&rdi-config=config"
ARMulator RVARMulatorISS1.4 [Build 297]
For support please contact support-sw@arm.com
Software supplied by: ARM Limited
ARM1136JF-S
ARM11 Instruction Set Simulator, May 24 2006
ARM Instruction Set Simulator for  [Build number 297]
, CP15, 8KB ICache, 8KB DCache 32KB DTCRam0 -Supports SmartCaching
32KB ITCRam0 -Supports SmartCaching , VFP11 (no support code), \
4GB, Pagetables, Mapfile, VIC - PL192
VIC: this is a RELEASE build
, Profiler, SIMRDI MemCallback, Tube, Millisecond [6666.67
cycles_per_millisecond], Tracer
Tracing: Instructions, Memory accesses, Events, Disassemble, \
Trace bus, Trace registers, Opcode Fetch Mask \
0x00000000-0x00000000, RDI Codesequences, Semihosting, \
CP14 Debug(6,2,2)
Little endian
arm-uclinuxeabi-sprite:Missing config file; this may not work
arm-uclinuxeabi-sprite:Target reset
0x00000000 in ?? ()

Refer to the section called “Invoking Sourcery G++ Debug Sprite” for a full description of the armusb:, rdi: and lm3s8xx arguments, or if you are using a different device to access your target board.

At this point you can use GDB to load your program onto the target board and control its execution as required:

(gdb) load
Loading section .text, size 0xaa0 lma 0x0
Loading section .ARM.exidx, size 0x8 lma 0xaa0
Loading section .data, size 0xfc lma 0xaa8
Start address 0x11, load size 2980
Transfer rate: 6231 bits/sec, 596 bytes/write.

Set a breakpoint so that the debugger stops when your program reaches main:

(gdb) break main
Breakpoint 1 at 0xf4: file hello.c, line 5.

If you continue (begin) execution of your program and you are using an ARMUSB device, GDB will initially stop at the start symbol of your program:

(gdb) continue
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
start () at /buildpath/newlib-stable/libgloss/arm/crt0.S:50
50      in /buildpath/newlib-stable/libgloss/arm/crt0.S

Then, allow the program to execute until it reaches main:

(gdb) continue
Continuing.

Breakpoint 1, main () at hello.c:5
5         printf ("Hello world\n");
Current language:  auto; currently c
(gdb) next
Hello world
6         return 0;

Permit the program to finish executing with:

(gdb) continue
Continuing.

Program exited normally.

Invoking Sourcery G++ Debug Sprite

The debug sprite is invoked as follows:

arm-uclinuxeabi-sprite [options] device-url config-file

The device-url specifies the debug device to use to communicate with the board. It follows the standard

scheme:scheme-specific-part[?options]

format. Most device URL schemes also follow the regular

scheme:[//hostname:[port]]/path[?options]

format. The meanings of hostname, port, path and options parts depend on the scheme and are described below. The following schemes are supported:

armusb

Use an ARMUSB debugging device. Refer to the section called “ARMUSB Devices”.

rdi

Use an RDI debugging device. Refer to the section called “Remote Debug Interface Devices”.

The optional ?options portion is allowed in all schemes. This allows additional device-specific options of the form name=value. Multiple options are concatenated using &. Some options are required for proper operation of some devices, e.g. the RDI scheme must be given the rdi-library and rdi-config options.

The config-file specifies an XML configuration file that describes the memory map and features of the target board. If config-file refers to a file (via a relative or absolute pathname), it is read. Otherwise, config-file can be a board name, and the toolchain's board config directory is searched for a matching file. The -b option lists config files in the board config directory. See the section called “Config File Syntax” for the syntax of the configuration files.

Sourcery G++ Debug Sprite Options

The following options are supported by the Sourcery G++ Debug Sprite:

-b

Print a list of config files in the board config directory.

-h

Print a list of options and their meanings. A list of device-url syntaxes is also shown.

-i

Print a list of the accessible devices. If a device-url is also specified, only devices for that device type are scanned. Each supported device type is listed along with the options that can be appended to the device-url. For each discovered device, the device-url is printed along with a description of that device. Note that no currently-implemented device types report scanned devices, as each may only connect to a single auto-detected device.

-l [host]:port

Specify the host address and port number to listen for a GDB connection. If this option is not given, the debug sprite communicates with GDB using stdin and stdout. If you start the sprite from within GDB using the target remote | arm-uclinuxeabi-sprite ... command, you do not need this option.

-m

Listen for multiple sequential connections. Normally the debug sprite terminates after the first connection from GDB terminates. This option instead makes it listen for a subsequent connection. To terminate the sprite, open a connection and send the string END\n.

-q

Do not print any messages.

-v

Print additional messages.

If any of -b, -i or -h are given, the Debug Sprite terminates after providing the information rather than waiting for a debugger connection.

ARMUSB Devices

ARMUSB debug devices are supported. There are no valid hostname, port or path settings for the device-url, so it is simply specified as:

armusb:[///][?options]

The following options are permitted:

speed=speed

Specify the speed of the connection, from 0 (fastest, default) to 7 (slowest). Depending on the CPU speed of the target board, lower values may lead to unreliable communication with the target. It is recommended to use slower speeds in that case.

Remote Debug Interface Devices

Remote Debug Interface (RDI) devices are supported. The RDI device URL accepts no hostname, port or path components, so the device-url is specified as follows:

rdi:[///][?options]

The following options are required:

rdi-library=library

Specify the library (DLL or shared object) implementing the RDI target you wish to use.

rdi-config=configfile

Specify a file containing configuration information for library. The format of this file is specific to the RDI library you are using, but tends to constitute a list of key=value pairs. Consult the documentation of your RDI library for details.

Debugging a Remote Board

You can run the Sourcery G++ Debug Sprite on a different machine from the one on which GDB is running. For example, if your board is connected to a machine in your lab, you can run the debugger on your laptop and connect to the remote board. The Sourcery G++ Debug Sprite must run on the machine that is connected to the ARM board.

To use this mode, you must start the sprite with the -l option and specify the port on which you want it to listen. For example:

arm-uclinuxeabi-sprite -l :10000

starts the sprite listening on port 10000. Use the following command to connect GDB to the remote sprite:

(gdb) target remote host:10000

where host is the name of the remote machine.

Semihosting

Semihosting is implemented in a way which depends on the device type. ARMUSB and RDI both provide semihosting support, with slightly different sets of provided functions. For RDI, semihosting is implemented using RDI vector entries. The supported functions are:

  • dbgprint

  • dbgpause

  • writec

  • readc

  • write

  • gets

  • reset

  • message

For ARMUSB and other device types, semihosting is implemented using the Angel interface. The following functions are present:

  • open

  • close

  • writec

  • write0

  • write

  • read

  • istty

  • seek

  • flen

  • remove

  • rename

  • system

  • errno

  • exit

If appropriate, the C library uses semihosting to provide the low-level operations required for file access and other system facilities.

Config File Syntax

The config-file can be a user-written XML file to describe a non-standard board. The Sourcery G++ Debug Sprite searches for config files in the arm-uclinuxeabi/lib/boards directory in the installation. Refer to the files in that directory for examples.

The file's DTD is:

<!-- Target description files for ARM.  -->
<!ELEMENT target-description
    (target-init|target-memory|target-features)*>
<!ELEMENT target-init
    (write-control-register|write-memory|delay)*>
<!ELEMENT write-control-register EMPTY>
<!ATTLIST write-control-register
    address CDATA   #REQUIRED
    value   CDATA   #REQUIRED
    bits    CDATA   #IMPLIED>
<!ELEMENT write-memory EMPTY>			
<!ATTLIST write-memory
    address CDATA   #REQUIRED
    value   CDATA   #REQUIRED
    bits    CDATA   #IMPLIED>
<!ELEMENT delay EMPTY>			
<!ATTLIST delay
    time CDATA   #REQUIRED>
<!ELEMENT target-memory (memory-device)*>
<!ELEMENT memory-device (description?)>
<!ATTLIST memory-device
    address CDATA   #REQUIRED
    size    CDATA   #REQUIRED
    type    CDATA   #REQUIRED
    device  CDATA   #IMPLIED>
<!ELEMENT description (#PCDATA)>			

<!ELEMENT target-features
  (banked-regs|has-vfp|system-v6-m|system-v7-m)*>
<!ELEMENT banked-regs EMPTY>
<!ELEMENT has-vfp EMPTY>
<!ELEMENT system-v6-m EMPTY>
<!ELEMENT system-v7-m EMPTY>

All values can be provided in decimal, hex (with a 0x prefix) or octal (with a 0 prefix). Addresses and memory sizes can use a K, KB, M, MB, G or GB suffix to denote a unit of memory. Times must use a ms or us suffix.

The following elements are available:

<target-description>

This top-level element encapsulates the entire description of the target. It can contain <target-init>, <target-features>, and <target-memory> elements.

<target-init>

The <target-init> element must be present, but is currently unused. Future versions of the Sourcery G++ Debug Sprite may use this element to record a board-specific initialization sequence.

<target-features>

The <target-features> element specifies features of the target system. This element can occur at most once. It can contain <banked-regs>, <has-vfp>, <system-v6-m> and <system-v7-m> elements.

<target-memory>

This element describes the memory map of the target board. It is used by GDB to determine where software breakpoints may be used and when flash programming sequences must be used. This element can occur at most once. It can contain <memory-device> elements.

<banked-regs>

The <banked-regs> element specifies that the CPU of the target board has banked registers for different processor modes (supervisor, IRQ, etc.).

<has-vfp>

The <has-vfp> element specifies that the CPU of the target board has VFP registers.

<system-v6-m>

The <system-v6-m> element specifies that the CPU of the target board has ARMv6-M architecture system registers.

<system-v7-m>

The <system-v7-m> element specifies that the CPU of the target board has ARMv7-M architecture system registers.

<memory-device>

This element specifies a region of memory. It has four attributes: address, size, type and device. The address and size attributes specify the location of the memory device. The type attribute specifies that device as ram, rom or flash. The device attribute is required for flash regions; it specifies the flash device type.

<description>

This element encapsulates a human-readable description of its enclosing element.