LynxOS-178 Topics

This appendix presents information specific to GNAT for LynxOS-178 2.2.4.

Getting Started

This section is a starting point for using GNAT to develop and execute Ada programs for Lynx Software Technologies’ LynxOS-178 target environment. We assume that you know how to use GNAT in a native environment and how to start a telnet or other login session to connect to your board running LynxOS-178.

To compile code for a LynxOS-178 system running on a X86 board, the basic compiler command is i586-elf-lynxos178e-gcc.

In order to find the target libraries, GNAT requires the ENV_PREFIX variable to be defined. Please consult the LynxOS-178 documentation for more information about this environment variable.

With GNAT, the easiest way to build the basic Hello World program is with gprbuild. For the LynxOS-178 2.2.4 X86 target this would look like:

$ gprbuild --target=i586-elf-lynxos178e hello
using project file .../_default.gpr
Compile
   [Ada]          hello.adb
Bind
   [gprbind]      hello.bexch
   [Ada]          hello.ali
 Link
   [link]         hello.adb

(The first line is the command entered by the user – the subsequent three are the programs run by gprbuild.)

This creates the executable hello, which you then need to load on the board (using ftp or an NFS directory for example) to run it. You can also include the binary in your KDI.

Kernel Configuration

The appropriate configuration for your LynxOS-178 kernel depends on the target system and the requirements of your application. GNAT itself adds no additional demands; however in some situations it may be appropriate to increase the conservative resource assumptions made by the default configuration.

Resource limits may be set as needed. See the documentation provided by LynuxWorks for more information.

Debugging

GNAT’s debugger is based on the same GNU gdb technology as the debugger provided by LynxOS-178, though with a great number of extensions and enhancements to support the Ada language and GNAT. The LynxOS-178 documentation is relevant to understanding how to get the debugger started if you run into difficulties.

The procedure for cross debugging on LynxOS-178 requires that the executable is first launched on the target under the utility gdbserver, and then the cross debugger is started on the host and attached to it. It is recommended that you include the i586-elf-lynxos178e-gdbserver binary in your KDI so it’s always available for debugging.

To demonstrate a debugging session, we will use a slightly more complex program called demo1.adb, which can be found in the examples directory of the GNAT distribution. This program is compiled with debugging information as follows:

$ gprbuild --target=x86-lynx178elf -g demo1
using project file .../_default.gpr
Compile
   [Ada]          demo1.adb
   [Ada]          gen_list.adb
   [Ada]          instr.adb
Bind
   [gprbind]      demo1.bexch
   [Ada]          demo1.ali
Link
   [link]         demo1.adb

Once the executable is created, copy it to your working directory on the board. In this directory, you will have to launch the gdb server and choose a free port number on your TCP/IP socket. Presuming the Internet hostname of the board is myboard and the port chosen is 2345, issue the following command:

myboard> i586-elf-lynxos178e-gdbserver :2345 demo1

Then return to your host environment and run the debugger. To run the cross debugger from the command line without the visual interface use the command i586-elf-lynxos178e-gdb.

The first thing to do at the (gdb) prompt from within gdb is to load the symbol table from the executable:

(gdb) file demo1
Reading symbols from demo1...done.
(gdb)

You then have to attach to the server running on the board. Issue the command:

(gdb) target remote myboard:2345

After the server has been started and attached from the host, the program is running on the target but has halted execution at the very beginning. The following commands set a breakpoint and continue execution:

(gdb) break demo1.adb:37
Breakpoint 1 at 0x100064d0: file demo1.adb, line 37.
(gdb) cont
Continuing.

Breakpoint 1, demo1 () at demo1.adb:37
37         Set_Name (Fuel, "Fuel");
(gdb)

Here the execution has stopped at the breakpoint set above. Now you can use the standard gdb commands to examine the stack and program variables.

Note that once execution has completed, the server on the board must be restarted before a new debugging session may begin.

Debugging Example

Carrying on a little further with the debugging session, the following example illustrates some of the usual debugging commands for moving around and seeing where you are:

(gdb) next
38         Set_Name (Water, "Water");
(gdb) bt
#0  demo1 () at demo1.adb:38
#1  0x10001218 in main (argc=1, argv=2147483640, envp=2147483520) at
b~demo1.adb:118
#2  0x10017538 in runmainthread ()
#3  0x10001048 in __start ()
(gdb) up
#1  0x10001218 in main (argc=1, argv=2147483640, envp=2147483520) at
b~demo1.adb:118
118       Ada_Main_Program;
(gdb) down
#0  demo1 () at demo1.adb:38
38         Set_Name (Water, "Water");
(gdb)

To examine and modify variables (of a tagged type here):

(gdb) print speed
$1 = (name => "Speed         ", value => -286331154)
(gdb) ptype speed
type = new instr.instrument with record
    value: instr.speed;
end record
(gdb) speed.value := 3
$2 = 3
(gdb) print speed
$3 = (name => "Speed         ", value => 3)
(gdb) info local
speed = (name => "Speed         ", value => 3)
fuel = (name => "Fuel          ", value => -286331154)
oil = (name => ' ' <repeats 14 times>, value => -286331154, size => 20,
  fill => 42 '*', empty => 46 '.')
water = (name => ' ' <repeats 14 times>, value => -286331154, size => 20,
  fill => 42 '*', empty => 46 '.')
time = (name => ' ' <repeats 14 times>, seconds => 0, minutes => 0, hours =>
0)
chrono = (name => ' ' <repeats 14 times>, seconds => 0, minutes => 0,
  hours => 0)
db = (access demo1.dash_board.internal) 0x0
(gdb)

And finally letting the program it run to completion:

(gdb) c
Continuing.

Program exited normally.
(gdb)