This appendix presents information specific to GNAT for LynxOS-178 2.2.4.
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
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
gprbuild. For the LynxOS-178 2.2.4 X86 target this would look
$ 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
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.
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.
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
demo1.adb, which can be found in the
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
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
Note that once execution has completed, the server on the board must be restarted before a new debugging session may begin.
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)