\input texinfo   @c -*-texinfo-*-
@input texiplus
@c %**start of header

@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
@c                                                                            o
@c                            GNAT DOCUMENTATION                              o
@c                                                                            o
@c                              G N A T _ U G X                               o
@c                                                                            o
@c                     Copyright (C) 1992-2009, AdaCore                       o
@c                                                                            o
@c  GNAT is free software;  you can  redistribute it  and/or modify it under  o
@c  terms of the  GNU General Public License as published  by the Free Soft-  o
@c  ware  Foundation;  either version 2,  or (at your option) any later ver-  o
@c  sion.  GNAT is distributed in the hope that it will be useful, but WITH-  o
@c  OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY  o
@c  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License  o
@c  for  more details.  You should have  received  a copy of the GNU General  o
@c  Public License  distributed with GNAT;  see file COPYING.  If not, write  o
@c  to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston,  o
@c  MA 02111-1307, USA.                                                       o
@c                                                                            o
@c  GNAT is maintained by Ada Core Technologies Inc (http://www.gnat.com).    o
@c                                                                            o
@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
@c
@c                           GNAT_UG Style Guide
@c
@c  1. Always put a @noindent on the line before the first paragraph
@c     after any of these commands:
@c
@c          @chapter
@c          @section
@c          @subsection
@c          @subsubsection
@c          @subsubsubsection
@c
@c          @end smallexample
@c          @end itemize
@c          @end enumerate
@c
@c  2. DO NOT use @example. Use @smallexample instead.
@c
@c  3. Each @chapter, @section, @subsection, @subsubsection, etc.
@c     command must be preceded by two empty lines
@c
@c  4. The @item command should be on a line of its own if it is in an
@c     @itemize or @enumerate command.
@c
@c  5. When talking about ALI files use "ALI" (all uppercase), not "Ali"
@c     or "ali".
@c
@c  6. DO NOT put trailing spaces at the end of a line.  Such spaces will
@c     cause the document build to fail.
@c
@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

@setfilename gnat_ugx.info
@include version.texi
@c version.texi contains a command that sets the gnat_version flag

@set NOW January 2008
@c This flag is used where the text refers to conditions that exist when the
@c text was entered into the document but which may change over time.
@c Update the setting for the flag, and (if necessary) the text surrounding,
@c the references to the flag, on future doc revisions:
@c search for @value{NOW}.

@include edition.texi
@c edition.texi contains commands that set exactly one of the flags
@c FSFEDITION, PROEDITION, GPLEDITION
@c and that clear the other two

@ifset FSFEDITION
@set GNATEDITION GNAT
@set DEFAULTLANGUAGEVERSION Ada 2005
@settitle GNAT User's Guide Supplement for Cross Platforms
@end ifset

@ifset PROEDITION
@set GNATEDITION GNAT Pro
@set DEFAULTLANGUAGEVERSION Ada 95
@settitle GNAT Pro User's Guide Supplement for Cross Platforms
@end ifset

@ifset GPLEDITION
@set GNATEDITION GNAT
@set DEFAULTLANGUAGEVERSION Ada 2005
@settitle GNAT User's Guide Supplement for Cross Platforms
@end ifset

@setchapternewpage odd
@c %**end of header

@titlepage

@ifset FSFEDITION
@title GNAT User's Guide
@sp 1

@flushright
@titlefont{@i{Supplement for Cross Platforms}}
@end flushright
@sp 2

@subtitle GNAT, The GNU Ada Compiler
@subtitle GNAT Version @value{gnat_version}
@end ifset
@c --------
@ifset PROEDITION
@title GNAT Pro User's Guide
@sp 1

@flushright
@titlefont{@i{Supplement for Cross Platforms}}
@end flushright
@sp 2

@subtitle The GNAT Pro Ada Compiler
@subtitle GNAT Pro Version @value{gnat_version}
@end ifset
@c --------
@ifset GPLEDITION

@title GNAT User's Guide
@sp 1

@flushright
@titlefont{@i{Supplement for Cross Platforms}}
@end flushright
@sp 2

@subtitle GNAT, The GNU Ada Compiler
@subtitle GNAT GPL Edition, Version @value{gnat_version}
@end ifset
@c --------
@subtitle Document revision level $Revision: 163874 $
@subtitle Date:  $Date: 2010-05-12 13:22:37 -0400 (Wed, 12 May 2010) $

@author AdaCore

@page
@vskip 0pt plus 1filll

Copyright @copyright{} 1995-2008, Free Software Foundation

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with the Invariant Sections being ``GNU Free Documentation License'', with the
Front-Cover Texts being
``GNAT User's Guide Supplement for Cross Platforms'',
and with no Back-Cover Texts.
A copy of the license is included in the section entitled ``GNU
Free Documentation License''.

@end titlepage

@ifnottex
@ifset FSFEDITION
@node Top
@top GNAT User's Guide Supplement for Cross Platforms

GNAT User's Guide Supplement for Cross Platforms

@noindent
GNAT, The GNU Ada Compiler@*
GNAT Version @value{gnat_version}@*
@end ifset
@c -------------
@ifset PROEDITION
@node Top
@top GNAT Pro User's Guide Supplement for Cross Platforms

GNAT Pro User's Guide Supplement for Cross Platforms

@noindent
The GNAT Pro Ada Compiler@*
GNAT Pro Version @value{gnat_version}@*
@end ifset
@c -------------
@ifset GPLEDITION
@node Top
@top GNAT User's Guide Supplement for Cross Platforms

GNAT User's Guide Supplement for Cross Platforms

@noindent
GNAT, The GNU Ada Compiler@*
GNAT GPL Edition, Version @value{gnat_version}@*
@end ifset
@c -------------

@noindent
Document revision level $Revision: 163874 $@*
Date: $Date: 2010-05-12 13:22:37 -0400 (Wed, 12 May 2010) $

@noindent
AdaCore

@noindent
Copyright @copyright{} 1995-2005, Free Software Foundation

@noindent
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with the Invariant Sections being ``GNU Free Documentation License'', with the
Front-Cover Texts being
``GNAT User's Guide Supplement for Cross Platforms'',
and with no Back-Cover Texts.
A copy of the license is included in the section entitled ``GNU
Free Documentation License''.

@menu

* About This Guide::
* Preliminary Note for Cross Platform Users::
* Bareboard and Custom Kernel Topics::
* Common VxWorks Topics::
* Tornado 2.x / VxWorks 5.x Topics::
* Workbench / VxWorks 6.x Topics::
* VxWorks 653 Topics::
* VxWorks MILS Topics::
* LynxOS Topics::
* AAMP Topics::
* PowerPC 55xx ELF Topics::
* AVR Topics::
* LEON / ERC32 Topics::
* ELinOS Topics::
* PikeOS Topics::
* GNU Free Documentation License::
* Index::

 --- The Detailed Node Listing ---

@detailmenu
About This Guide

* What This Guide Contains::
* What You Should Know before Reading This Guide::
* Related Information::
* Conventions::

Preliminary Note for Cross Platform Users

Bareboard and Custom Kernel Topics

* Bareboard and Custom Kernel Introduction::
* Bareboard and Custom Kernel Examples::

Common VxWorks Topics

* Executing a Program on VxWorks::
* Mixed-Language Programming::
* Kernel Configuration for VxWorks::
* Handling Relocation Issues for PowerPC Targets::
* Zero Cost Exceptions on PowerPC Targets::
* Calling exported Ada procedures from the VxWorks shell::
* Simulating Command Line Arguments for VxWorks::
* Using addr2line on VxWorks::
* Removal of Unused Code and Data::

Tornado 2.x / VxWorks 5.x Topics

* Kernel Compilation Issues for VxWorks::
* Support for Software Floating Point on PowerPC Processors::
* Stack Overflow Checking on VxWorks 5.x::
* Interrupt Handling for VxWorks::
* Debugging Issues for VxWorks 5.x::
* Using GNAT from the Tornado 2 Project Facility::
* Using GNAT Pro with the RTI ScopeTools::
* Frequently Asked Questions for VxWorks::

Workbench / VxWorks 6.x Topics

* GNAT Pro for VxWorks 6 Installation::
* Using GNAT Pro for VxWorks 6::
* Building a VxWorks 6 Application::
* SMP Support::
* Using the VxWorks 6 Simulator::
* Debugging an Application on VxWorks 6::

VxWorks 653 Topics

* VxWorks 653-Introduction::
* Setting Up a VxWorks 653 System::
* Running and Debugging Applications::
* Application Design Considerations::

VxWorks MILS Topics

* VxWorks MILS Overview::
* Common Considerations for VxWorks MILS Applications::
* Applications in the Guest OS Environment::
* Applications in the High Assurance Environment::

LynxOS Topics

* Getting Started with GNAT on LynxOS::
* Kernel Configuration for LynxOS::
* Debugging Issues for LynxOS::
* An Example Cross Debugging Session for LynxOS::
* Issues Linking on LynxOS::

AAMP Topics

* Getting Started with GNAT for AAMP (GNAAMP)::
* GNAAMP-Specific Switches::
* Clock Support::
* Debugging for GNAAMP::

PowerPC 55xx ELF Topics

* PowerPC 55xx ELF Topics Introduction::
* PowerPC 55xx ELF Topics Floating Point::
* PowerPC 55xx ELF Topics EABI::
* PowerPC 55xx ELF Topics Debugging::

LEON / ERC32 Topics

* Getting Started with GNAT Pro for LEON / ERC32::
* Executing and Debugging on Simulators::
* Executing and Debugging on Hardware Platforms::
* Adapting the Run-Time System::
* Run-Time Restrictions::
* Console Output::
* Stack Overflow Checking::
* Interrupt Handling::
* Non-Symbolic Traceback::

ELinOS Topics

* GNAT Pro for ELinOS Installation::
* Kernel Configuration for ELinOS::
* Building a ELinOS Application::
* Debugging an Application on ELinOS::

PikeOS Topics

* Kernel Configuration for PikeOS::
* Building an Ada application on PikeOS::
* Building an Ada application on PikeOS using GNATbench::
* Running an Ada application on PikeOS::
* Debugging an Ada application on PikeOS::
* Debugging an Ada application on PikeOS using GNATbench::
* Using the APEX Run-Time Library on PikeOS::

GNU Free Documentation License

Index

@end detailmenu
@end menu
@end ifnottex

@node About This Guide
@unnumbered About This Guide

@noindent
This guide describes the use of @value{GNATEDITION}, a compiler and software
development
toolset for the full Ada programming language, in a cross compilation
environment.
It supplements the information presented in the
@cite{@value{GNATEDITION} User's Guide}.
It describes the features of the compiler and tools, and details
how to use them to build Ada applications that run on a
target processor.

@value{GNATEDITION} implements Ada 95 and Ada 2005, and it may also be invoked
in Ada 83 compatibility mode.
By default, @value{GNATEDITION} assumes @value{DEFAULTLANGUAGEVERSION},
but you can override with a compiler switch
to explicitly specify the language version.
(Please refer to the section ``Compiling Different Versions of Ada'', in
@cite{@value{GNATEDITION} User's Guide}, for details on these switches.)
Throughout this manual, references to ``Ada'' without a year suffix
apply to both the Ada 95 and Ada 2005 versions of the language.

This guide contains some basic information about using @value{GNATEDITION} in
any cross environment, but the main body of the document is a set
of Appendices on topics specific to the various target platforms.

@ifset PROEDITION
For ease of exposition, ``GNAT Pro'' will generally be referred to simply as
``GNAT'' in the remainder of this document.
@end ifset

@menu
* What This Guide Contains::
* What You Should Know before Reading This Guide::
* Related Information::
* Conventions::
@end menu

@node What This Guide Contains
@unnumberedsec What This Guide Contains

@noindent
This guide contains the following chapters:
@itemize @bullet

@item
About This Guide

@item
@ref{Preliminary Note for Cross Platform Users}, describes the basic
differences between the cross and native versions of GNAT.

@item
@ref{Bareboard and Custom Kernel Topics}, describes how to build,
load and run programs on a target without requiring the services
of an underlying kernel.

@item
@ref{Common VxWorks Topics}, presents information relevant to all VxWorks
targets for cross-compilation.

@item
@ref{ Tornado 2.x / VxWorks 5.x Topics}, presents information relevant to
Tornado 2.x and VxWorks 5.x targets.

@item
@ref{Workbench / VxWorks 6.x Topics}, presents information relevant to
Workbench and VxWorks 6.x targets.

@item
@ref{VxWorks 653 Topics}, presents information relevant to
VxWorks 653 targets.

@item
@ref{VxWorks MILS Topics}, presents information relevant to
VxWorks MILS targets.

@item
@ref{LynxOS Topics}, presents information relevant to the LynxOS
target for cross-compilation configurations.

@item
@ref{AAMP Topics}, presents information relevant to the AAMP
target for cross-compilation configurations.

@item
@ref{PowerPC 55xx ELF Topics}, presents information relevant to the
PowerPC 55xx ELF targets for cross-compilation configurations.

@item
@ref{AVR Topics}, presents information relevant to the AVR microcontroller
targets for cross-compilation configurations.

@item
@ref{LEON / ERC32 Topics}, presents information relevant to the
LEON / ERC32 targets for cross-compilation configurations.

@item
@ref{ELinOS Topics}, presents information relevant to the
ELinOS targets for cross-compilation configurations.

@item
@ref{PikeOS Topics}, presents information relevant to the
PikeOS targets for cross-compilation configurations.
@end itemize

@node What You Should Know before Reading This Guide
@unnumberedsec What You Should Know before Reading This Guide

@noindent
This user's guide assumes a basic familiarity with the Ada 95 language, as
described in the International Standard ISO/IEC-8652:1995,
January 1995.
It does not require knowledge of the new features introduced by Ada 2005,
(officially known as ISO/IEC 8652:1995 with Technical Corrigendum 1
and Amendment 1).
Both Ada reference manuals are included in the GNAT documentation
package.

This user's guide also assumes that you are familiar with
the @cite{@value{GNATEDITION} User's Guide}, and that
you know how to use @value{GNATEDITION} on a native
platform.

@node Related Information
@unnumberedsec Related Information

@noindent
For further information, refer to the following
documents:

@itemize @bullet
@item
@cite{@value{GNATEDITION} User's Guide}, either the
generic or VMS version; these describe the GNAT compilation
model, software development environment, and toolset.

@item
@cite{@value{GNATEDITION} Reference Manual}, which contains all reference
material for the GNAT implementation of Ada.

@item
@cite{ASIS-for-GNAT User's Guide}, which describes how to use ASIS with the
GNAT environment.

@item
@cite{ASIS-for-GNAT Reference Manual}, which contains reference material
supplementing the @cite{ASIS-for-GNAT User's Guide}

@item
@cite{Ada 95 Reference Manual}, which defines the Ada 95 language standard.

@item
@cite{Ada 2005 Reference Manual}, which defines the Ada 2005 language standard.

@item
@cite{Debugging with GDB}, which
contains all details on the use of the GNU source-level debugger.

@item
@cite{GNU Emacs Manual}, which
contains full information on the extensible editor and programming
environment Emacs.
@end itemize

@node Conventions
@unnumberedsec Conventions
@cindex Conventions
@cindex Typographical conventions

@noindent
Following are examples of the typographical and graphic conventions used
in this guide:

@itemize @bullet
@item
@code{Functions}, @code{utility program names}, @code{standard names},
and @code{classes}.

@item
@option{Option flags}

@item
@file{File Names}, @file{button names}, and @file{field names}.

@item
@var{Variables}.

@item
@emph{Emphasis}.

@item
[optional information or parameters]

@item
Examples are described by text
@smallexample
and then shown this way.
@end smallexample
@end itemize

@noindent
Commands that are entered by the user are preceded in this manual by the
characters @w{``@code{$ }''} (dollar sign followed by space). If your system
uses this sequence as a prompt, then the commands will appear exactly as
you see them in the manual. If your system uses some other prompt, then
the command will appear with the @code{$} replaced by whatever prompt
character you are using.

@node Preliminary Note for Cross Platform Users
@chapter Preliminary Note for Cross Platform Users

@noindent
The use of GNAT in a cross environment is very similar to its use in a
native environment. Most of the tools described in the
@cite{@value{GNATEDITION} User's Guide},
including the ASIS-based tools (@command{gnatelim}, @command{gnatstub},
@command{gnatpp}),
have similar functions and options in both modes. The major
difference is that the name of the cross tools includes the target for
which the cross compiler is configured. For instance, the cross
@command{gnatmake} tool is invoked as @command{@i{target}-gnatmake}
where @code{@i{target}} stands for the name of
the cross target. Thus, in an environment configured for the
target @code{powerpc-wrs-vxworks}, the @command{gnatmake} command is
@code{powerpc-wrs-vxworks-gnatmake}. This convention allows the
installation of a native and one or several cross development
environments on the same machine.

An exception to the naming rule
exists for the AAMP target (@pxref{AAMP Topics} for information
on AAMP tool name conventions).

In the rest of this manual, we generally refer to the tools with their
simple native names (e.g., @command{gcc}) when we are describing
their generic functionality, and with their full cross names
(e.g., @command{@i{target}-gcc}) when we are describing their invocation.

The tools that are most relevant in a cross environment are
@command{gcc}, @command{gnatmake},
@command{gnatbind}, and @command{gnatlink} to build cross
applications; and @command{gnatls} for cross library
browsing.

@command{gdb} is usually available for cross
debugging in text mode. The graphical debugger interface in
@command{GPS} is always a native tool but it can be configured to drive
a cross debugger, thus allowing graphical cross debugging
sessions.
Some other tools such as @command{gnatchop},
@command{gnatkr}, @command{gnatprep},
@command{gnatxref},
@command{gnatfind} and @command{gnatname} are also provided
for completeness even though they do not differ greatly from their native
counterparts.

The GNAT Project facility is integrated into the cross environment.
@cindex Project facility (in a cross environment)
GPS uses the @code{gnatlist} attribute in the @code{Ide} package,
whose value is @code{@i{target}-gnatls}, to compute the
cross-prefix.  From this information the correct location for the
GNAT run-time library, and thus also the correct cross-references,
can be determined.
See the GPS documentation for more details, in particular
the section @cite{Working in a Cross Environment}.

@c   **************************************
@c   * Bareboard and Custom Kernel Topics *
@c   **************************************
@node Bareboard and Custom Kernel Topics
@appendix Bareboard and Custom Kernel Topics

@noindent
This chapter describes how to use the @value{GNATEDITION} cross tools to build
programs that do not require support
from any kernel running on the target hardware.
It uses the PowerPC with ELF object module format as the target
platform to illustrate these issues.

@menu
* Bareboard and Custom Kernel Introduction::
* Bareboard and Custom Kernel Examples::
@end menu

@node Bareboard and Custom Kernel Introduction
@section Introduction

@noindent
Throughout this chapter we will use one approach to linking. There
are many ways that @command{gnatlink} (or @command{powerpc-elf-gnatlink}
as it would be invoked on this platform), or @command{gnatmake}
can be used; but we will adopt a lower level approach that is
a bit clearer and more flexible.

The program @command{gnatlink} normally performs 2 steps:
@enumerate
@item
it calls @command{gcc} to compile the file generated by @command{gnatbind};
@item
it calls @command{gcc} to link all
the relocatable object files into an executable.
@end enumerate

@noindent
We will break out those steps.
We will use @command{powerpc-elf-gcc} to compile the binder-generated
file, and @command{powerpc-elf-ld} to do the linking.

Other configurations of GNAT, native or targeting an embedded OS,
use tools for manipulating binary files that are
provided with the target system (whether native or cross).  In the
platform illustrated in this chapter, because there is no target OS
and no development
tools that would be provided with an OS, @value{GNATEDITION} provides the tools
that are necessary or useful.
@value{GNATEDITION} Cross comes with with the GNU @code{binutils}
package properly configured and built. The linker, @command{powerpc-elf-ld},
is one of those tools.  .

@command{gcc} (or @command{powerpc-elf-gcc}) is really a driver program that
runs other programs for compiling, assembling, linking and performing
other needed steps.
When used for linking, @command{gcc} knows which object files and libraries
are needed for the target environment, and it adds these to the
linker command line.

@node Bareboard and Custom Kernel Examples
@section Examples

@noindent
Given the many variations on the host and target environment that you
may be using, it is not possible to
formulate a universally applicable sequence of commands for
building, loading, and running a program.
Instead, this section presents a series of scenarios reflecting
various levels of sophistication in the target tools,
with enough detail to allow you to prepare the necessary setup.
For illustration purposes the examples will
assume a PowerPC / ELF target, and
occasionally may reflect a Unix host.

There are two main issues that you need to consider:

@itemize @bullet
@item
how an executable program is loaded onto the target hardware, and

@item
the state of the hardware / software environment after the program
has been loaded.
@end itemize

@noindent
One of the simpler configurations is as follows:

@itemize @bullet
@item
the target hardware has a monitor program
in ROM that runs at powerup

@item
a command line interface controls the target through
a serial port connected to the host

@item
a load command in the monitor program uses @command{tftp}
to load a specified ELF file from the host
(there is an ethernet interface, and the monitor handles
TCP/IP protocols)
@end itemize

@noindent
In other words, the monitor on the target board is relatively ``smart''.
To run a program that you've built with @value{GNATEDITION} Cross
(an executable ELF file) you just need to load the program and ``go''
-- the monitor program keeps track of the start address recorded in the
ELF file.

The following simple example will illustrate the issues with building,
loading and running a program;
it merely sets a word in RAM to a particular value.
With the ROM monitor program you can see the program's effect by
looking at the memory location
before and after execution.

@smallexample @c ada
@group
with System.Storage_Elements; use System.Storage_Elements;

procedure nu is
   J : Integer;
   for J'Address use To_Address (16#200_000#);
begin
   J := 5;
end nu;
@end group
@end smallexample

@noindent
Based on your experience with the GNAT tools for a native environment,
you might try to build this program with the command:

@smallexample
  powerpc-elf-gnatmake nu
@end smallexample

@noindent
While there is a small chance that you could get the resulting
executable to run, this is unlikely.  In the relatively easy-to-use
setup that we've described so far, the load command
will likely read the entry point from the ELF file @file{nu}.
Since there is
no symbol named @code{_start}, the linker has chosen the first address in
the .text section as the entry point.
However, that is not where the program should start execution.
Moreover, the linker has chosen some builtin default
addresses for placing the various sections of the program.  It is highly
unlikely that they will be appropriate for your target hardware.

Assuming that @code{16#100_000#} is a good starting location in RAM for
your program, the following steps will build a more useful executable.

@smallexample
  powerpc-elf-gnatmake -g -b -c nu
  powerpc-elf-gcc -c b~nu.adb
  powerpc-elf-ld -e main -Ttext 0x100000 b~nu.o nu.o -o nu
@end smallexample

@noindent
Note that the @option{-b -c} options to @command{gnatmake}
combine compiling and binding, and omit the linking step.

As with the native tools, the
binder creates a file named @file{b~@i{XXX}.adb} where @i{XXX}
is the name
of the main subprogram.  The second command above compiles the
binder output file.
The @command{ld} command works as follows:

@itemize @bullet
@item
the @option{-e main} option tells @command{ld} that the symbol
@code{main} is the entry point

@item
the @option{-Ttext 0x100000} option tells @command{ld} to start
the @code{.text} section at the address @code{16#100_000#}.
We are using the
knowledge that @code{.text} is the first segment in memory,
and @command{ld} places
other segments following it.
@end itemize

@noindent
In this case, it is also possible to combine these steps into a single
command:

@smallexample
  powerpc-elf-gnatmake -g nu -largs -Wl,-e,main,-Ttext,0x100000
@end smallexample

@noindent
When the resulting @code{nu} is loaded, the image will start at
@code{16#100_000#}, and the entry point will be wherever
the procedure @code{main} is placed.

Although this is more likely to run than the earlier example, there
still may be some problems.
To get more detail you can use the @option{-save-temps} option
for @command{gcc} (or @option{-cargs -save-temps} to
@command{gnatmake}), which
will save the intermediate assembly language file using the
@file{.s} file extension.  The symbol name for the outer level procedure
has @code{_ada_} prepended and is thus @code{_ada_nu}.
In @file{b~nu.adb} you will find the
main procedure (notice the export in @file{b~nu.ads}).
It sets default
values for command line variables (which do not apply in this
environment), calls @code{adainit} (which would run the elaboration
code if there was any), calls @code{Break_Start} (which is there to provide
a convenient place to set a breakpoint when debugging), and, finally,
calls your @code{nu} code.

If your target environment is not so fortunately set up, you
will not be able to use the ELF file @code{nu} produced above.  Such a
simple scheme also breaks down in numerous ways as soon as you
write any code with any more complexity.

To cope with such issues,
you will need to create and use a startup routine in assembly
language. Define the symbol @code{_start} at the desired code entry
point; the linker will find that symbol, and you no
longer need
the @option{-e} option to @command{ld}.
Several additional items will also be useful to
include in the startup code: zeroing @code{.bss},
and setting the stack pointer and perhaps other registers.

Uninitialized global data are reserved in the @code{.bss} section in the
executable file.  During linking, all uninitialized variables are
assigned an address in @code{.bss}, and all references to these variables
are relocated properly, but no actual data are contained in the ELF
executable (it is allocatable but not loadable).  It is expected
that the locations within @code{.bss} are set to zero before execution begins.

We will no longer assume that some smart loader is taking care of so
much; the startup code is responsible for zeroing the @code{.bss} data,
before it branches to your application's Ada entry.
Since @code{nu} contained no declarations of uninitialized variables (the
address clause causes @code{J} to be treated differently), this
was not an issue for that simple program.  Also, it is
conceivable that the ROM monitor will set the stack to a usable value
before branching to the entry point.
However, it is more likely that you will want to set
the stack pointer early in your startup code, and there may be other
registers that must be set.  For example, if the relevant Application
Binary Interface (ABI) specifies an addressing mode that is relative
to a designated register, the linker will output a symbol containing
the value that the register must be set to.
For example, on MIPS, @code{_gp} must be
loaded into register 28.
On PowerPC you could set @code{r13} to point to
the small data area (although this is not necessary unless you take advantage
of this feature, and is not relevant here).

Here is the ``bare bones'' startup assembly code, @file{start.s}:

@smallexample
@group
        top_of_stack = 0x200000

        .section ".text"
        .global  _start
_start:
        lis 1, __bss_start@@ha
        la  1, __bss_start@@l (1)
        lis 2, __end@@ha
        la  2, __end@@l (2)
        li  3, 0
@end group
@group
bssloop:
        cmp  0,0,1,2
        bge  bssdone
        stw  3, 0(1)
        addi 1, 1, 4
        b    bssloop
@end group
@group
bssdone:
        addis 1, 0, top_of_stack@@h
        ori   1, 1, top_of_stack@@l

        bl    main
forever:
        b     forever
@end group
@end smallexample

@noindent
And here is the link command:

@smallexample
powerpc-elf-ld -Ttext 0x100000 -o nu start.o nu.o b~nu.o
@end smallexample

@noindent
A single command that would build the application is:

@smallexample
powerpc-elf-gnatmake -g nu -largs -Wl,-Ttext,0x100000,start.o
@end smallexample

@noindent
It is very likely that your setup may work with S-record files.
If so, the following @command{objcopy} command converts the executable ELF
file @file{nu} to an S-record file @file{nu.sre} (details are in the
binutils documentation):

@smallexample
powerpc-elf-objcopy -S -O srec nu nu.sre
@end smallexample

@noindent
A script written in @command{ld}'s script language controls
how @command{ld} composes the pieces of a
relocatable (@file{.o}) file when creating an executable.
Up to now, the default builtin script has been assumed.
You can see this default script by running
@command{powerpc-elf-ld -verbose}, which writes the contents
to your terminal.
Note that this script is large and complicated, containing data
specific to different debugging formats, programming languages (C++
in particular), and dynamic libraries (not applicable).
However, you will also find the definitions of @code{__bss_start}
and @code{__end}, which reflect the.
bounds of the @code{.bss} section of the
executable.
Complete information about the linker and its scripting language
may be found in the @cite{Using ld} document.

An extremely simple linker script might be a better starting
point for building what you need.  Here is one that will work
in our still relatively amenable working environment:

@smallexample
  OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
                "elf32-powerpc")
  OUTPUT_ARCH(powerpc)
  ENTRY(_start)
  PROVIDE (top_of_stack = 0x200000);
  SECTIONS
  @{
    . = 0x100000;
    .text :
    @{
      *(.text)
      *(.rodata)
    @}

    .data :
    @{
      *(.data .sdata .sdata2)
    @}

    __bss_start = .;
    .bss :
    @{
     *(.bss .sbss)
     *(COMMON)
    @}
    __end = .;
  @}
@end smallexample

@noindent
Briefly, this script defines three output segments:

@itemize @bullet
@item
.text, which
contains all of the @code{.text} and @code{.rodata} sections from the input
files;

@item
.data

@item
.bss
@end itemize

@noindent
``.'' is referred to as the location counter.
It is set to @code{0x100000} before the first segment, and all of the
code follows after that (since ``.'' is never explicitly set to
a new value).
The location counter is used to set the values
of the @code{__bss_start} and @code{__end} symbols.
The script defines the symbol @code{top_of_stack}, so you may remove
it from the startup code if you prefer to use the linker script
to set its value.
@code{PROVIDE} defines the value if it isn't defined elsewhere.

Unless you explicitly discard input sections, they will be
copied to the output executable with the same name.  E.g., if you
compiled your code with debug information, linking with the
script above will copy it into the executable -- you will then be
able to debug.

A note on debugging: the version of @command{gdb} provided
@cindex @command{gdb}
with @value{GNATEDITION} Cross is ``Ada aware''.
But you need to determine how @command{gdb} running on your host will
interact with code on your target.
Most likely, it will use @command{gdb}'s serial protocol
to interact with some agent that can control execution of your code.
One example is the use of a hardware probe that controls the processor
through a JTAG (BDM, COPS) port.  @value{GNATEDITION} Cross supports the
Abatron BDI 2000, which is a hardware device that connects to the target
through JTAG, implements the @command{gdb} serial protocol in firmware,
and communicates using
that protocol over its ethernet port.  For example, a BDI could be known
on your local network by the hostname @code{bdi},
and when running @command{powerpc-elf-gdb}
you would use the @command{gdb} command @code{target remote bdi:2001}.
This tells @command{gdb}
that it will control the execution of your program by using the serial
protocol running on port @code{2001} of the host @code{bdi}.
Another possibility is that
there is a kernel running on your target hardware that controls program
execution (your application) and which implements the @command{gdb}
serial protocol over some connection -- often a serial port.

We will highlight one other feature of @command{ld} scripting which is often
used, particularly in later stages of development.  Early on, you
might have a way of loading your program into RAM and running
it from there.  Eventually, you might want to burn some parts into ROM
and (particularly) if your code runs from hardware bootup you will
have an issue with the @code{.data} segment.  At bootup, the initial data
in @code{.data} is in ROM at one range of addresses, but it has to be
in RAM during execution, at a different range of addresses. (You
might well want @code{.text} moved to RAM also for performance reasons,
but we'll illustrate with @code{.data}.)
@command{ld} assumes that every
section has two addresses: the VMA, or ``virtual memory address'', and
the LMA, or ``load module address''.  The VMA is the run-time address
of the beginning of the section in RAM; the LMA is the address in
ROM.  In the @command{ld} script example, there was nothing specified between
the name of the output section @code{.data} and the following @code{:}
character. The syntax
allows you to specify the starting address (VMA) there.  It defaults
to the location counter if not specified.  By default, LMA is set
to the VMA.  An @code{AT} clause is used to set the LMA separately.
For example:

@smallexample
  data_image_begin = 0xdc000000;
  data_begin       = 0xE0000000;

  .data data_begin : AT (data_image_begin) @{
    *(.data .sdata .sdata2)
  @}
  data_end = .;
@end smallexample

@noindent
In this description of @code{.data}, the section is loaded at
@code{data_image_begin},
but is expected to be at @code{data_begin} at run time.  I.e., all references
to objects in @code{.data} are resolved to addresses in the section starting
at the VMA, @code{data_begin}.  Code can be added to @file{start.s} to use the
three symbols defined to copy the @code{.data} segment from ROM to RAM before
the application starts up.

Some examples are supplied in the @file{examples} directory of the GNAT Pro
installation containing multi-language applications with project files. A
@file{Makefile} is provided to build the source code for the desired target
and run time. For example:

@smallexample
make TARGET=powerpc-elf RUNTIME=zfp
@end smallexample

@c **************************
@c *  Common VxWorks Topics *
@c **************************
@node Common VxWorks Topics
@appendix Common VxWorks Topics

@noindent
This chapter describes topics that are relevant to all GNAT for VxWorks
configurations. Note that the GNAT tool prefix for Tornado 2.x / VxWorks 5.x
or Workbench / VxWorks 6.x is @code{powerpc-wrs-vxworks-},
@code{e500v2-wrs-vxworks-} or @code{i586-wrs-vxworks-}; for Workbench / VxWorks
653, it is @code{powerpc-wrs-vxworksae-}; for VxWorks MILS, it is
@code{powerpc-wrs-vxworksmils}.

@menu
* Executing a Program on VxWorks::
* Mixed-Language Programming::
* Kernel Configuration for VxWorks::
* Handling Relocation Issues for PowerPC Targets::
* Zero Cost Exceptions on PowerPC Targets::
* Calling exported Ada procedures from the VxWorks shell::
* Interrupt Handling for VxWorks::
* Simulating Command Line Arguments for VxWorks::
* Using addr2line on VxWorks::
* Removal of Unused Code and Data::
@end menu

@node Executing a Program on VxWorks
@section Executing a Program on VxWorks

@noindent
Getting a program to execute involves loading it onto the target,
running it, and then (if re-execution is needed) unloading it. These
instructions apply mainly to Tornado 2.x / VxWorks 5.x, but can also
apply to Workbench / VxWorks 653 when building an application for the
Core OS, or Workbench / VxWorks 6.x when building an application for
the kernel space.
(Note that this is not the usual way of executing applications on VxWorks 653 -
see the sections on VxWorks 653 for details).

@menu
* Loading and Running the Program::
* Unloading the Program::
@end menu

@node Loading and Running the Program
@subsection Loading and Running the Program

@noindent
An Ada program is loaded and run in the same way as a C program.
Details may be found in the @cite{Tornado User's Guide}.

In order to load and run our sample program, we assume that
the target has access to the disk of the host containing the required object
and that its working directory has been set to the directory containing this
object.
The commands are typed in Tornado's Windshell. The @code{windsh} prompt
is the @code{->} sequence.
In this example, the object is named @code{hello}, and when its execution
results in the display of the @code{Hello World} string.

For VxWorks 5.x and VxWorks 6.x:

@smallexample
-> vf0=open("/vio/0",2,0)
new symbol "vf0" added to symbol table.
vf0 = 0x2cab48: value = 12 = 0xc
-> ioGlobalStdSet(1,vf0)
value = 1 = 0x1
-> ld < hello
value = 665408 = 0xa2740
-> hello
Hello World
value = 0 = 0x0
->
@end smallexample

For VxWorks 653, in the Core OS, the load command is different:

@smallexample
[vxKernel] -> vf0=open("/vio/0",2,0)
new symbol "vf0" added to symbol table.
vf0 = 0x2cab48: value = 12 = 0xc
[vxKernel] -> ioGlobalStdSet(1,vf0)
value = 1 = 0x1
[vxKernel] -> ml < hello
value = 665408 = 0xa2740
[vxKernel] -> hello
Hello World
value = 0 = 0x0
[vxKernel] ->
@end smallexample

@noindent
The first two commands redirect output to the shell window.
They are only needed if the target server was started without the
@code{-C} option.  The third command loads the module, which is the file
@file{hello} created previously by the @code{gnatmake} command.
Note that for Tornado 653, the @command{ml} command replaces @command{ld}."

The @code{Hello World} program comprises a procedure named @code{hello},
and this
is the name entered for the procedure in the target server's symbol table
when the module is loaded.  To execute the procedure, type the symbol name
@code{hello} into @code{windsh} as shown in the last command above.

Note that by default the entry point of an Ada program is the name of the main
Ada subprogram in a VxWorks environment. It is possible to use an alternative
name; see the description of @code{gnatbind} options for details.

@node Unloading the Program
@subsection Unloading the Program

@noindent
It is important to remember that
you must unload a program once you have run it. You
cannot load it once and run it several times. If you don't follow
this rule, your program's behavior can be unpredictable, and will most
probably crash.

This effect is due to the implementation of Ada's @emph{elaboration}
semantics.  The unit elaboration phase comprises a @emph{static} elaboration
and a @emph{dynamic} elaboration. On a native platform they both take place
when the program is run. Thus rerunning the program will repeat the complete
elaboration phase, and the program will run correctly.

On VxWorks, the process is a bit different.
The static elaboration phase is handled by
the loader (typically when you type @code{ld < program_name} in
@code{windsh}). The dynamic phase takes place when the program is run. If the
program is run twice and has not been unloaded and then reloaded, the
second time it is run, the static elaboration phase is skipped.
Variables initialized during the static elaboration phase
may have been modified during the first execution of the program. Thus the
second execution isn't performed on a completely initialized environment.

Note that in C programs, elaboration isn't systematic. Multiple runs without
reload might work, but, even with C programs, if there is an elaboration
phase, you will have to unload your program before re-running it.

@node Mixed-Language Programming
@section Mixed-Language Programming

@noindent
The @cite{@value{GNATEDITION} User's Guide}, in the section
@cite{Building Mixed Ada & C++ Programs},
subsection ``A Simple Example'',
presents the compilation commands needed to build one of the
GNAT examples.
The relevant commands for the GNAT VxWorks/PowerPC target are
as follows:
@cindex Mixed-language programming (for VxWorks)

@smallexample
$ powerpc-wrs-vxworks-gnatmake -c simple_cpp_interface
$ powerpc-wrs-vxworks-gnatbind -n simple_cpp_interface
$ powerpc-wrs-vxworks-gnatlink simple_cpp_interface -o ada_part
$ c++ppc -c -DCPU=PPC604  -I/usr/windppc/target/h  cpp_main.C
$ c++ppc -c -DCPU=PPC604  -I/usr/windppc/target/h  ex7.C
$ ldppc -r -o my_main my_main.o ex7.o ada_part
@end smallexample

@noindent
Note that the tool prefix for VxWorks 653 is @code{powerpc-wrs-vxworksae-}
rather than @code{powerpc-wrs-vxworks-}.

@node Kernel Configuration for VxWorks
@section Kernel Configuration for VxWorks

@noindent
When configuring your VxWorks kernel we recommend including the target
shell. If you omit it from the configuration, you may get undefined
symbols at load time, e.g.

@smallexample
-> ld < hello.exe
Loading hello.exe
Undefined symbols:
mkdir
@end smallexample

@noindent
Generally, such undefined symbols are harmless since these are used by
optional parts of the GNAT run time. However if running your application
generates a VxWorks exception or illegal instruction, you should reconfigure
your kernel to resolve these symbols.


@node Handling Relocation Issues for PowerPC Targets
@section Handling Relocation Issues for PowerPc Targets
@cindex Relocation issues for PowerPc VxWorks targets
@cindex PowerPc VxWorks, relocation issues
@cindex VxWorks PowerPc, relocation issues

@noindent
Under certain circumstances, loading a program onto a PowerPC
board will fail with the message
@emph{Relocation value does not fit in 24 bits}.
This section summarizes why and when such a problem will arise, and
explains how it can be solved.

@menu
* Background and Summary::
* Technical Details::
@end menu

@node Background and Summary
@subsection Background and Summary

@noindent
Prior to release 3.15 of GNAT Pro, the compiler's default behavior
was to use relative addressing mode for all subprogram calls, including
those in the GNAT run-time library.
This led to the ``24 bits'' problem for
many user applications.  Starting with 3.15, the run-time library
accompanying the compiler has been compiled with the @option{-mlongcall}
command line argument, which directs the compiler to generate
absolute addresses for subprogram calls. Furthermore, users who
were encountering the problem started compiling their code with
an explicit @option{-mlongcall} option, and the problem largely disappeared.

Starting with release 6.0.2 of GNAT Pro, the effects of @option{-mlongcall}
are turned on by default for all compilations, including the compilation
of binder-generated files.  Thus users no longer have to supply the
@option{-mlongcall} option themselves.

In light of this change in the default behavior, a user requiring the
relative addressing mode (for example for performance tuning) will now need
to explicitly specify the @option{-mno-longcall} option.

@node Technical Details
@subsection Technical Details

@noindent
VxWorks on the PowerPC follows the variation of the SVR4 ABI known
as the Embedded ABI (@emph{EABI}).
@cindex Embedded ABI (for VxWorks on PowerPc)
@cindex EABI (for VxWorks on PowerPc)
In order to save space and time in
embedded applications, the EABI specifies that the default for
subprogram calls should be the branch instruction with relative
addressing using an immediate operand.  The immediate operand
to this instruction (relative address) is 24 bits wide.  It
is sign extended and @code{2#00#} is appended for the last 2 bits (all
instructions must be on a 4 byte boundary).

The resulting
26 bit offset means that the target of the branch must be within
+/- 32 Mbytes of the PC-relative branch instruction.  When
loading a program, VxWorks completes the linking phase by
resolving all of the unresolved references in the object being
loaded.  When one of those references is a relative address in
a branch instruction, and the linker determines that the target
is more than 32 Mbytes away from the branch, the error occurs.

This only happens when the BSP is configured to use
more than 32 MBytes of memory.  The VxWorks kernel is loaded into
low memory addresses, and the error usually occurs when the target
loader is used (because it loads objects into high memory, and thus
calls from the program to the VxWorks kernel can be too far).
@cindex VxWorks kernel (relocation issues on PowerPc)

One way to solve this problem is to use the Tornado
host loader; this will place programs in low memory, close to the kernel.

For versions of GNAT Pro which precede 6.0.2, the @option{-mlongcall} option
for gcc causes the compiler to construct the absolute address
of a subprogram in a register and use a branch instruction with absolute
addressing mode. Starting with 6.0.2, absolute addresses are the
default, and @option{-mno-longcall} is needed to use relative addresses for
subprogram calls.

For GNAT Pro versions 3.15 through 6.0.1, the GNAT run-time libraries
are compiled with @option{-mlongcall}. In many
cases the use of these libraries is sufficient to avoid the
relocation problem, since it is the run-time library that contains
calls to the VxWorks kernel that need to span the address space gap.
The run-time libraries for version 6.0.2 and later also contain only
the absolute addressing mode.

When using the GNAT Pro 3.15 through 6.0.1, you may need to compile
your application code using @option{-mlongcall} if there
are calls directly to the kernel, if the application is very large,
or in some specialized linking/loading scenarios.

You can compile individual files with @code{-mlongcall} by placing this
option on the @code{gcc} command line (for brevity we are omitting the
@code{powerpc-wrs-vxworks-} prefix on the commands shown in this
paragraph).
If you provide @code{-mlongcall} as an option for @code{gnatmake}, it will be
passed to all invocations of @code{gcc} that @code{gnatmake} directly performs.
Note that one other compilation is made by @code{gnatlink}, on the file created
by @code{gnatbind} for the elaboration package body
(see @cite{Binding Using @command{gnatbind}} in the
@cite{@value{GNATEDITION} User's Guide}).
Passing @code{-mlongcall} to @code{gnatlink}, either directly
on the @code{gnatlink} command line or by including @code{-mlongcall} in the
@code{-largs} list of @code{gnatmake}, will direct @code{gnatlink} to compile
the binder file with the @code{-mlongcall} option.

To see the effect of @code{-mlongcall}, consider the following small example:

@smallexample @c ada
procedure Proc is
   procedure Imported_Proc;
   pragma Import (Ada, Imported_Proc);
begin
   Imported_Proc;
end;
@end smallexample

@noindent
If you compile @code{Proc} with the default options (no @code{-mlongcall})
with a GNAT Pro release prior to 6.0.2, the following code is generated:

@smallexample
_ada_proc:
        ...
        bl imported_proc
        ...
@end smallexample

@noindent
In contrast, here is the result with the defaults for GNAT Pro 6.0.2 and
later, or with the @option{-mlongcall} option passed to earlier releases

@smallexample
_ada_proc:
        ...
        addis 9,0,imported_proc@@ha
        addi 0,9,imported_proc@@l
        mtlr 0
        blrl
        ...
@end smallexample

@noindent
For additional information on this issue, please refer to WRS' SPRs
6040, 20257, and 22767.


@node Zero Cost Exceptions on PowerPC Targets
@section Zero Cost Exceptions on PowerPC Targets

@noindent
The Zero Cost eXceptions handling (ZCX) model is available for kernel
mode on PowerPC processors.

On VxWorks 6, ZCX is activated by default.
@c
In this mode, proper transformation of signal deliveries into Ada
exceptions requires increasing the kernel exception stack to at least
10*1024 bytes, which may be achieved by modifying the
@code{taskKerExcStackSize} global variable before tasks are spawned.
@c
This affects all the tasks spawned after the change, and is typically
needed for user stack-checking purposes.
@c
The setjmp/longjmp (SJLJ) exception model is still available, by
switching to an alternative runtime library with @option{--RTS=kernel-sjlj}.

On VxWorks 5, the SJLJ model is activated by default.
@c
ZCX is available by switching to an alternative runtime library with
@option{--RTS=zcx}.

@node Calling exported Ada procedures from the VxWorks shell
@section Calling exported Ada procedures from the VxWorks shell

@noindent
If you need to call Ada subprograms from outside your Ada application (for
example, from the Windshell), you will in general need to make the executing
task known to the Ada run-time library. A typical situation is the need to
enable or disable traces in your Ada application from the shell by calling an
Ada procedure that sets the value of a Boolean controlling the traces.

The problem is the following: when you call the Ada procedure, it may raise an
exception on the target. This could be through normal execution, or it could be
caused solely by the fact that the thread executing the procedure has not been
made known to the Ada run-time library. There are a number of situations in
full Ada applications where the run-time library must be able to determine what
task is running, and must be able to access some Ada-specific data structures
in order to do its job. If a VxWorks task has not been registered, the ``id''
that is accessed by the run-time library will be invalid, and will reference
invalid data (or invalid memory).

The solution is to use the @code{GNAT.Threads.Register_Thread} and
@code{GNAT.Threads.Unregister_Thread} routines, so that the task
in which the called subprogram is executing (typically the shell task) is
known by the Ada run-time. This way, when the Ada task id is requested at some
point in the procedure's execution, a valid value will be fetched, and the
necessary data structures will have been allocated and properly initialized.

The following small example shows how to use this feature:

@smallexample @c ada
package Traces is

   procedure Put_Trace (Info : String);
   --  Print Info on the standard output if the traces are on

   procedure Trace_On;
   pragma Export (C, Trace_On, "trace_on");
   --  Activate the traces

   procedure Trace_Off;
   pragma Export (C, Trace_Off, "trace_off");
   --  Deactivate the traces
end Traces;

with System;       use System;
with Ada.Text_IO;  use Ada.Text_IO;
with GNAT.Threads; use GNAT.Threads;
package body Traces is
   Trace : Boolean := False;

   ---------------
   -- Put_Trace --
   ---------------

   procedure Put_Trace (Info : String) is
   begin
      if Trace then
         Put_Line (Info);
      end if;
   end Put_Trace;

   --------------
   -- Trace_On --
   --------------

   procedure Trace_On is
      Id : System.Address;
   begin
      Id := Register_Thread;
      Trace := True;
      Unregister_Thread;
   end Trace_On;

   ---------------
   -- Trace_Off --
   ---------------

   procedure Trace_Off is
      Id : System.Address;
   begin
      Id := Register_Thread;
      Trace := False;
      Unregister_Thread;
   end Trace_Off;

end Traces;

with Traces; use Traces;
procedure Increment is
   Value : Integer := 1;
begin
   for J in 1 .. 60 loop
      Value := Value + 1;
      Put_Trace (Integer'Image (Value));
      delay 1.0;
   end loop;
end Increment;
@end smallexample

@noindent
After having compiled and loaded the application on your target, spawn it and
control the traces by calling @code{trace_on} and @code{trace_off} from the
shell. You should see numbers displayed in the VxWorks console when the traces
are on.

@smallexample
-> sp increment
task spawned: id = 3b0dcd0, name = s1u0
value = 61922512 = 0x3b0dcd0
-> trace_on
value = 0 = 0x0
-> trace_off
value = 0 = 0x0
@end smallexample

@node Interrupt Handling for VxWorks
@section Interrupt Handling for VxWorks

@noindent
GNAT offers a range of options for hardware interrupt handling on VxWorks 5,
for VxWorks 6 downloadable kernel modules (DKM) and for the VxWorks MILS Guest
OS.

Directly vectored interrupt procedure handlers can also be used in the CoreOS
of VxWorks 653; otherwise interrupt handling is unsupported for
VxWorks 653 and for VxWorks 6 real-time processes. These are operating system
restrictions.

See @cite{VxWorks MILS Topics} for configuration requirements for handling
interrupts in a virtual board.

In rough order of latency and lack of restrictions:

@itemize @bullet
@item Directly vectored interrupt procedure handlers
@item Directly vectored interrupt procedures that signal a task using
a suspension object
@item Ada 95 / Ada 2005 protected procedure handlers for interrupts
@item Ada 83 style interrupt entry handlers for interrupts
@end itemize

@noindent
In general, the range of possible solutions trades off latency versus
restrictions in the handler code.  Restrictions in direct vectored
interrupt handlers are documented in the @cite{VxWorks Programmer's Guide}.
Protected procedure handlers have only the
restriction that no potentially blocking operations are performed within
the handler.  Interrupt entries have no restrictions.  We recommend the
use of the protected procedure mechanism as providing the best balance
of these considerations for most applications.

All handler types must explicitly perform any required hardware cleanups,
such as issuing an end-of-interrupt if necessary.

For VxWorks 653, applications that handle interrupts must be loaded into
the kernel protection domain (CoreOS).

@itemize @bullet
@item Direct Vectored Interrupt Routines

@noindent
This approach provides the lowest interrupt latency, but has the most
restrictions on what VxWorks and Ada run-time calls can be made, as well
as on what Ada entities are accessible to the handler code.  Such handlers
are most useful when there are stringent latency requirements, and very
little processing is to be performed in the handler.  Access to the
necessary VxWorks routines for setting up such handlers is provided in
the package @code{Interfaces.VxWorks}.

VxWorks restrictions are described in the @cite{VxWorks Programmer's Manual}.
Note in particular that floating point context is not automatically saved and
restored when interrupts are vectored to the handler.  If the handler is
to execute floating point instructions, the statements involved must be
bracketed by a pair of calls to @code{fppSave} and @code{fppRestore} defined
in @code{Interfaces.VxWorks}.  As the compiler may use floating point
registers for non floating point operation (such as memory block copy) it is
highly recommended to either save and restore floating point registers or
to inspect code generated for the interrupt handler.

As stack checking doesn't work within an interrupt handler, be sure
that units containing interrupt handlers are not compiled with
@option{-fstack-check}.

As there is no task identity when executing an interrupt handler, any
Ada run time library code that depends on knowing the current task's
identity must not be used.  This includes tasking constructs (except
for most subprograms of @code{Ada.Synchronous_Task_Control}), concatenation
and other functions with unconstrained results and exceptions
propagation.

In general, it is a good idea to save and restore the handler that was
installed prior to application startup.  The routines @code{intVecGet}
and @code{intVecSet} are used for this purpose.  The Ada handler code
is installed into the vector table using routine @code{intConnect},
which generates wrapper code to save and restore registers.

Example:

@smallexample @c ada
with Interfaces.VxWorks; use Interfaces.VxWorks;
with System;

package P is

   Count : Natural := 0;
   pragma Atomic (Count);

   --  Interrupt level used by this example
   Level : constant := 1;

   --  Be sure to use a reasonable interrupt number for the target
   --  board!  Refer to the BSP for details.
   Interrupt : constant := 16#14#;

   procedure Handler (Parameter : System.Address);

end P;

package body P is

   procedure Handler (parameter : System.Address) is
      S : Status;
   begin
      Count := Count + 1;
      --  Acknowledge interrupt.  Not necessary for all interrupts.
      S := sysBusIntAck (intLevel => Level);
   end Handler;
end P;

with Interfaces.VxWorks; use Interfaces.VxWorks;
with Ada.Text_IO; use Ada.Text_IO;

with P; use P;
procedure Useint is
   task T;

   S : Status;

   task body T is
   begin
      for I in 1 .. 10 loop
         Put_Line ("Generating an interrupt...");
         delay 1.0;

         --  Generate interrupt, using interrupt number
         S := sysBusIntGen (Level, Interrupt);
      end loop;
   end T;

   --  Save old handler
   Old_Handler : VOIDFUNCPTR := intVecGet (INUM_TO_IVEC (Interrupt));
begin
   S := intConnect (INUM_TO_IVEC (Interrupt), Handler'Access);
   S := sysIntEnable (intLevel => Level);

   for I in 1 .. 10 loop
      delay 2.0;
      Put_Line ("value of count:" & P.Count'Img);
   end loop;

   --  Restore previous handler
   S := sysIntDisable (intLevel => Level);
   intVecSet (INUM_TO_IVEC (Interrupt), Old_Handler);
end Useint;
@end smallexample

@item Direct Vectored Interrupt Routines

@noindent
A variation on the direct vectored routine that allows for less restrictive
handler code is to separate the interrupt processing into two levels.

The first level is the same as in the previous section.  Here we perform
simple hardware actions and signal a task pending on a Suspension_Object
(defined in @code{Ada.Synchronous_Task_Control}) to perform the more complex
and time-consuming operations.  The routine @code{Set_True} signals a task
whose body loops and pends on the suspension object using
@code{Suspend_Until_True}.
The suspension object is declared in a scope global to both the handler and
the task. This approach can be thought of as a slightly higher-level
application of the @code{C} example using a binary semaphore given in the
VxWorks Programmer's Manual.  In fact, the implementation of
@code{Ada.Synchronous_Task_Control} is a very thin wrapper around a VxWorks
binary semaphore.

This approach has a latency between the direct vectored approach and the
protected procedure approach.  There are no restrictions in the Ada task
code, while the handler code has the same restrictions as any other
direct interrupt handler.

Example:

@smallexample @c ada
with System;
package Sem_Handler is

   Count : Natural := 0;
   pragma Atomic (Count);

   --  Interrupt level used by this example
   Level : constant := 1;
   Interrupt : constant := 16#14#;

   --  Interrupt handler providing "immediate" handling
   procedure Handler (Param : System.Address);

   --  Task whose body provides "deferred" handling
   task Receiver is
       pragma Interrupt_Priority
          (System.Interrupt_Priority'First + Level + 1);
    end Receiver;

end Sem_Handler;

with Ada.Synchronous_Task_Control; use Ada.Synchronous_Task_Control;
with Interfaces.VxWorks; use Interfaces.VxWorks;
package body Sem_Handler is

   SO : Suspension_Object;

   task body Receiver is
   begin
      loop
         --  Wait for notification from immediate handler
         Suspend_Until_True (SO);

         --  Interrupt processing
         Count := Count + 1;
      end loop;
   end Receiver;

   procedure Handler (Param : System.Address) is
      S : STATUS;
   begin
      --  Hardware cleanup, if necessary
      S := sysBusIntAck (Level);

      --  Signal the task
      Set_True (SO);
   end Handler;

end Sem_Handler;

with Interfaces.VxWorks; use Interfaces.VxWorks;
with Ada.Text_IO; use Ada.Text_IO;
with Sem_Handler; use Sem_Handler;
procedure Useint is

   S : STATUS;

   task T;

   task body T is
   begin
      for I in 1 .. 10 loop
         Put_Line ("Generating an interrupt...");
         delay 1.0;

         --  Generate interrupt, using interrupt number
         S := sysBusIntGen (Level, Interrupt);
      end loop;
   end T;

   --  Save old handler
   Old_Handler : VOIDFUNCPTR := intVecGet (INUM_TO_IVEC (Interrupt));
begin
   S := intConnect (INUM_TO_IVEC (Interrupt), Handler'Access);
   S := sysIntEnable (intLevel => Level);

   for I in 1 .. 10 loop
      delay 2.0;
      Put_Line ("value of Count:" & Sem_Handler.Count'Img);
   end loop;

   --  Restore handler
   S := sysIntDisable (intLevel => Level);
   intVecSet (INUM_TO_IVEC (Interrupt), Old_Handler);
   abort Receiver;
end Useint;
@end smallexample

@item Protected Procedure Handlers for Interrupts

@noindent
This is the recommended default mechanism for interrupt handling.
It essentially wraps the hybrid handler / task mechanism in a higher-level
abstraction, and provides a good balance between latency and capability.

Vectored interrupts are designated by their interrupt number, starting from
0 and ranging to the number of entries in the interrupt vector table - 1.

In the GNAT VxWorks implementation, the following priority mappings are used:
@itemize @bullet
@item Normal task priorities are in the range 0 .. 245.
@item Interrupt priority 246 is used by the GNAT @code{Interrupt_Manager}
task.
@item Interrupt priority 247 is used for vectored interrupts
that do not correspond to those generated via an interrupt controller.
@item Interrupt priorities 248 .. 255 correspond to PIC interrupt levels
0 .. 7.
@item Priority 256 is reserved to the VxWorks kernel.
@end itemize

Except for reserved priorities, the above are recommendations for setting the
ceiling priority of a protected object that handles interrupts, or the
priority of a task with interrupt entries.  It's a very good idea to follow
these recommendations for vectored interrupts that come in through the PIC
as it will determine the priority of execution of the code in the protected
procedure or interrupt entry.

No vectored interrupt numbers are reserved in this implementation, because
dedicated interrupts are determined by the board support package. Obviously,
careful consideration of the hardware is necessary when handling interrupts.
The VxWorks BSP for the board is the definitive reference for interrupt
assignments.

Example:

@smallexample @c ada
package PO_Handler is

   --  Interrupt level used by this example
   Level : constant := 1;

   Interrupt : constant := 16#14#;

   protected Protected_Handler is
      procedure Handler;
      pragma Attach_Handler (Handler, Interrupt);

      function Count return Natural;

      pragma Interrupt_Priority (248);
   private
      The_Count : Natural := 0;
   end Protected_Handler;

end PO_Handler;

with Interfaces.VxWorks; use Interfaces.VxWorks;
package body PO_Handler is

   protected body Protected_Handler is

      procedure Handler is
         S : Status;
      begin
         --  Hardware cleanup if necessary
         S := sysBusIntAck (Level);

         --  Interrupt processing
         The_Count := The_Count + 1;
      end Handler;

      function Count return Natural is
      begin
         return The_Count;
      end Count;
   end Protected_Handler;

end PO_Handler;

with Interfaces.VxWorks; use Interfaces.VxWorks;
with Ada.Text_IO; use Ada.Text_IO;

with PO_Handler; use PO_Handler;
procedure Useint is

   task T;

   S : STATUS;

   task body T is
   begin
      for I in 1 .. 10 loop
         Put_Line ("Generating an interrupt...");
         delay 1.0;

         --  Generate interrupt, using interrupt number
         S := sysBusIntGen (Level, Interrupt);
      end loop;
   end T;

begin
   S := sysIntEnable (intLevel => Level);

   for I in 1 .. 10 loop
      delay 2.0;
      Put_Line ("value of count:" & Protected_Handler.Count'Img);
   end loop;

   S := sysIntDisable (intLevel => Level);
end Useint;
@end smallexample

@noindent
This is obviously significantly higher-level and easier to write than the
previous examples.

@item Ada 83 Style Interrupt Entries

GNAT provides a full implementation of the Ada 83 interrupt entry mechanism
for vectored interrupts.  However, due to latency issues,
we only recommend using these for backward compatibility.  The comments in
the previous section regarding interrupt priorities and reserved interrupts
apply here.

In order to associate an interrupt with an entry, GNAT provides the
standard Ada convenience routine @code{Ada.Interrupts.Reference}.  It is used
as follows:

@smallexample @c ada
Interrupt_Address : constant System.Address :=
   Ada.Interrupts.Reference (Int_Num);

task Handler_Task is
   pragma Interrupt_Priority (248);  -- For instance
   entry Handler;
   for Handler'Address use Interrupt_Address;
end Handler_Task;
@end smallexample

@noindent
Since there is no restriction within an interrupt entry on blocking operations,
be sure to perform any hardware interrupt controller related operations before
executing a call that could block within the entry's accept statements.  It
is assumed that interrupt entries are always open alternatives when they
appear within a selective wait statement.  The presence of a guard gives
undefined behavior.

Example:

@smallexample @c ada
with Ada.Interrupts;
with System;
package Task_Handler is

   --  Interrupt level used by this example
   Level : constant := 1;

   Interrupt : constant := 16#14#;

   Interrupt_Address : constant System.Address :=
      Ada.Interrupts.Reference (Interrupt);

   task Handler_Task is
      pragma Interrupt_Priority (248);  -- For instance
      entry Handler;
      for Handler'Address use Interrupt_Address;

      entry Count (Value : out Natural);
   end Handler_Task;
end Task_Handler;

with Interfaces.VxWorks; use Interfaces.VxWorks;
package body Task_Handler is

   task body Handler_Task is
      The_Count : Natural := 0;
      S : STATUS;
   begin
      loop
         select
            accept Handler do
               --  Hardware cleanup if necessary
               S := sysBusIntAck (Level);

               --  Interrupt processing
               The_Count := The_Count + 1;
            end Handler;
         or
            accept Count (Value : out Natural) do
               Value := The_Count;
            end Count;
         end select;
      end loop;
   end Handler_Task;

end Task_Handler;

with Interfaces.VxWorks; use Interfaces.VxWorks;
with Ada.Text_IO; use Ada.Text_IO;

with Task_Handler; use Task_Handler;
procedure Useint is

   task T;

   S : STATUS;
   Current_Count : Natural := 0;

   task body T is
   begin
      for I in 1 .. 10 loop
         Put_Line ("Generating an interrupt...");
         delay 1.0;

         --  Generate interrupt, using interrupt number
         S := sysBusIntGen (Level, Interrupt);
      end loop;
   end T;

begin
   S := sysIntEnable (intLevel => Level);

   for I in 1 .. 10 loop
      delay 2.0;
      Handler_Task.Count (Current_Count);
      Put_Line ("value of count:" & Current_Count'Img);
   end loop;

   S := sysIntDisable (intLevel => Level);
   abort Handler_Task;
end Useint;
@end smallexample
@end itemize

@node Simulating Command Line Arguments for VxWorks
@section Simulating Command Line Arguments for VxWorks

@noindent
The GNAT implementation of @code{Ada.Command_Line} relies on the standard C
symbols @code{argv} and @code{argc}.  The model for invoking ``programs'' under
VxWorks does not provide these symbols.  The typical method for invoking a
program under VxWorks is to call the @code{sp} function in order to spawn a
thread in which to execute a designated function (in GNAT, this is the implicit
main generated by gnatbind. @code{sp} provides the capability to push
a variable number of arguments onto the stack when the function is invoked.
But this does not work for the implicit Ada main, because it has no way of
knowing how many arguments might be required.
This eliminates the possibility of using @code{Ada.Command_Line}.

(Note that this section is only marginally relevant to VxWorks 653 and not
applicable to VxWorks MILS, since applications on these platforms are usually
invoked as part of system startup.
The situation described here is only relevant there if the application is being
downloaded to the Core OS / vxKernel partition, and is being directly spawned).

One way to solve this problem is to define symbols in the VxWorks environment,
then import them into the Ada application.  For example, we could define the
following package that imports two symbols, one an int and the other a string:

@smallexample @c ada
with Interfaces.C.Strings;
use Interfaces.C.Strings;
package Args is
   --  Define and import a variable for each argument
   Int_Arg : Interfaces.C.Int;
   String_Arg : Chars_Ptr;
private
   pragma Import (C, Int_Arg, "intarg");
   pragma Import (C, String_Arg, "stringarg");
end Args;
@end smallexample

@noindent
An Ada unit could then use the two imported variables @code{Int_Arg} and
@code{String_Arg} as follows:

@smallexample @c ada
with Args; use Args;
with Interfaces.C.Strings;
use Interfaces.C, Interfaces.C.Strings;
with Ada.Text_IO; use Ada.Text_IO;
procedure Argtest is
begin
   Put_Line (Int'Image (Int_Arg));
   Put_Line (Value (String_Arg));
end Argtest;
@end smallexample

@noindent
When invoking the application from the shell, one will then set the values
to be imported, and spawn the application, as follows:

@smallexample
-> intarg=10
-> stringarg="Hello"
-> sp (argtest)
@end smallexample

@node Using addr2line on VxWorks
@section  Using addr2line on VxWorks
@cindex addr2line
@cindex vxaddr2line

@menu
* Differences between VxWorks and native platforms::
* Using <target>-vxaddr2line::
* An example::
@end menu

@noindent
For general information about addr2line, see
@cite{Getting Internal Debugging Information}
in the @cite{@value{GNATEDITION} User's Guide}.

@node Differences between VxWorks and native platforms
@subsection Differences between VxWorks and native platforms

@noindent
Using addr2line on the VxWorks, where modules are often dynamically loaded,
is a bit different than on native platforms. When dealing with
dynamically loaded modules, one needs to determine the offset at which
the module has been loaded.  This allows addr2line to correlate the target
addresses of the stack trace with the addresses in the load module.

On VxWorks, there are two ways a module can be located into target memory:
@itemize @bullet
@item
it is dynamically linked and loaded
@item
it is statically linked with the kernel
@end itemize

In both cases, the addresses used in the module are different from the ones
used within the target memory address space under VxWorks.

In contrast, on a native system, the executable has the same addresses in
the object file and in memory, as virtual addresses are used. There is no
need to collate the addresses on target with those in the object module.

As addr2line uses the addresses in the module, we
need to adjust the addresses returned as a traceback at run-time so that they
can be correctly interpreted by addr2line. To do this manually, we would follow
a procedure like this:

A symbol that is always present in
the module is determined in order to compute the offset between the addresses
at run-time and the addresses in the module.  Its address in the module is
subtracted from its address in memory, and the computed delta is added to each
address in the traceback.

@node Using <target>-vxaddr2line
@subsection Using <target>-vxaddr2line

Manually performing the computation just described is tedious, so a tool has
been introduced to automate the process: <target>-vxaddr2line, where <target>
is the name of target (e.g. powerpc-wrs-vxworks for VxWorks 5.x and 6.x;
powerpc-wrs-vxworksae for VxWorks 653). All that needs to be done is to give
the name of the module, the address of the symbol @code{adainit} in memory and
the traceback values as parameters. The computation is then done automatically,
and the result is transmitted to addr2line, which returns the symbolic
traceback in the usual manner.

@node An example
@subsection An example

The example session of this section is for powerpc-wrs-vxworks. Replace this
target name by the target you are using. Consider the following simple source
code :

@smallexample @c ada
      1
      2 procedure CE is
      3
      4    procedure Raise_Constraint_Error is
      5    begin
      6      raise Constraint_Error;
      7    end;
      8
      9    procedure Sub_2 (Should_Raise_CE : Boolean) is
     10    begin
     11      if Should_Raise_CE then
     12        Raise_Constraint_Error;
     13      end if;
     14    end;
     15
     16    procedure Sub_1 is
     17    begin
     18      Sub_2 (Should_Raise_CE => True);
     19    end;
     20 begin
     21    Sub_1;
     22 end;
@end smallexample

@itemize @bullet
@item
Build the example with gnatmake, providing the -E binder argument in this
case so that a raw backtrace is returned for the unhandled exception. -g is
required in any case because addr2line uses debug information to perform the
symbolic transcription.
@smallexample
$ powerpc-wrs-vxworks-gnatmake -g ce -bargs -E
@end smallexample

@item
Load and run the resulting module on the target board. It raises the
expected unhandled exception and generates the associated raw backtrace:
@smallexample
-> ld < ce
Loading /ce |
value = 591824 = 0x907d0
-> sp ce
task spawned: id = 1b8aae0, name = s2u0
value = 28879584 = 0x1b8aae0
->
Execution terminated by unhandled exception
Exception name: CONSTRAINT_ERROR
Message: ce.adb:6
Call stack traceback locations:
0x3b8394 0x3b83e0 0x3b8420 0x3b8458 0x3b82f0 0x19a184
@end smallexample

Now convert the backtrace into symbolic references...

@item
Determine the address of a reference symbol of the module (we use the address
of @code{adainit}), which we obtain by calling the VxWorks @code{lkup}
function:
@smallexample
-> lkup "adainit"
adainit                   0x003b81d0 text     (ce.exe)
value = 0 = 0x0
@end smallexample

@item
We now have the information needed to run @code{vxaddr2line}:
@smallexample
powerpc-wrs-vxworks-vxaddr2line ce 0x003b81d0 0x3b8394 ... 0x19a184
                                -- ---------- ---------------------
                         exec file  Ref.addr.  Run-Time backtrace
@end smallexample

This gives the following:

@smallexample
000001C0 at .../ce.adb:6
0000020C at .../ce.adb:12
0000024C at .../ce.adb:18
00000284 at .../ce.adb:21
0000011C at .../b~ce.adb:88
@end smallexample
[meaningless output for the last address]

The last line is not shown here because it designates stub code within VxWorks
and is not part of the user's application.

Note that on VxWorks 653 and VxWorks MILS, the program name argument to
vxaddr2line is the ``.sm'' file for the partition in which the application is
executing.
@end itemize

@node Removal of Unused Code and Data
@section Removal of Unused Code and Data

@noindent
As for all elf platforms using 2.16.1 GNU binutils, GNAT for VxWorks now
supports unused code and data elimination. For a complete description of this
functionality, please refer to the @value{GNATEDITION} User's Guide.

However, the use of this functionality need some extra care for VxWorks. In
fact, GNAT for VxWorks performs by default partial linking on all VxWorks
versions, except VxWorks 6 in RTP mode.

Because of this partial linking, the unused code and data elimination requires
the use of @code{-e} / @code{--entry} ld option to correctly work. The usage
of these options is also described in the @value{GNATEDITION} User's Guide.

For example, in order to compile my_program.adb, you can use the following
 command line:

@smallexample
powerpc-wrs-vxworks-gnatmake my_program.adb -cargs -ffunction-sections \
  -fdata-sections -largs -Wl,--gc-sections -Wl,--entry=my_program
@end smallexample

@c *************************************
@c *  Tornado 2.x / VxWorks 5.x Topics *
@c *************************************
@node Tornado 2.x / VxWorks 5.x Topics
@appendix Tornado 2.x / VxWorks 5.x Topics

@noindent
This chapter describes topics that are specific to GNAT for Tornado 2.x /
VxWorks 5.x configurations.

@menu
* Kernel Compilation Issues for VxWorks::
* Support for Software Floating Point on PowerPC Processors::
* Stack Overflow Checking on VxWorks 5.x::
* Debugging Issues for VxWorks 5.x::
* Using GNAT from the Tornado 2 Project Facility::
* Using GNAT Pro with the RTI ScopeTools::
* Frequently Asked Questions for VxWorks::
@end menu

@node Kernel Compilation Issues for VxWorks
@section Kernel Compilation Issues for VxWorks 5.x and VxWorks 6.x

@noindent
This section describes the different ways to statically link an Ada module
(built using the @value{GNATEDITION} toolchain) with a VxWorks kernel.
The main issue is that two distinct toolchains are used:

@itemize @bullet
@item
The Wind River toolchain (diab or gnu)

@item
The @value{GNATEDITION} toolchain
@end itemize

@noindent
Both toolchains compile Ada or C modules using either of two libraries:
GCC Library or Wind River Library. These two libraries share
common symbols and are mostly compatible.  However, there is a potential
issue with the exception handling functions. If you tried to directly link
your Ada module with the VxWorks kernel you would get ``duplicate
symbols'' errors for the linker, as two versions of the exceptions
management library are
included. In order to resolve this issue you will need, depending on the
context, to select only one of these libraries or else find a way to include
both of them. This section covers two topics:

@itemize @bullet
@item Which library to use

@item How to achieve the link
@end itemize

@noindent
The library to select depends on the following issues:

@itemize @bullet
@item Whether C++ is used

@item Whether the ZCX run-time is used for the Ada module
@end itemize

@noindent
If you are using C++ in your project, then you will need the
exception handling functions. As the GCC Library from the @value{GNATEDITION}
toolchain implements the exception mechanisms differently from the Wind River
Library, you need in this case to use the Wind River Library.

@noindent
The ZCX run-time library packaged in the PowerPC @value{GNATEDITION}
toolchains uses the exception mechanism implemented in the GCC Library
distributed with @value{GNATEDITION}.  If you are using this run-time
library you must select the GCC Library and not the one from the Wind
River toolchain.

@noindent
The sjlj Ada run-time library in the @value{GNATEDITION} toolchain does not
rely on the mechanism present in the GCC Library, so if you are using that
run-time in your Ada module, it's better to use the Wind River Library as
it allows you to use C++.

@noindent
If you are using both C++ and the ZCX runtime, then the situation is more
complex as you need the two libraries. A possible approach is described at the
end of this section.

@noindent
There are several different ways to perform the link:

@itemize @bullet
@item Using the Wind River Library

@noindent
You need to compile your Ada module with the
@option{-nostdlib} option, which excludes the @value{GNATEDITION} GCC Library:

@smallexample
gnatmake foo.adb -largs -nostdlib
@end smallexample

and then add the resulting executable file (@file{foo} or
@file{foo.exe}) to your kernel. On
VxWorks 5.x this can be achieved by adding the object in the
 @code{EXTRA_MODULES} macro of your kernel project.

@item Using the @value{GNATEDITION} GCC Library

You need to do the following:

@itemize @bullet
@item Compile your Ada module:

@smallexample
gnatmake foo.adb -largs -nostdlib
@end smallexample


@item Add the resulting executable file to the kernel as described above.

@item Remove the Wind River Library from the kernel and then put in the
@value{GNATEDITION} version instead. On VxWorks 5.x, this step is achieved by
modifying the @code{LIBS} macro.
 In order to obtain the location of the @value{GNATEDITION} GCC Library do
the following:

@smallexample
powerpc-wrs-vxworks-gcc -print-libgcc-file-name <options>
@end smallexample

@noindent
Even if this command does not perform any compilation it is important to
specify to GCC the options used when the Ada module was compiled. Indeed, the
@value{GNATEDITION} toolchain provides several versions of the GCC Library;
by specifying the
GCC options in the previous command you will obtain the correct
version.

@item In your kernel configuration, be sure to remove ``Compiler Support
Routines'' components. Indeed this component adds a C file to your
kernel that will create a dependence on all @file{.o} files present in the
Wind River Library, and you will receive error messages from the linker
about missing symbols.  An inconvenient consequence is that if you plan
to dynamically download modules to your kernel, then some symbols from
the GCC Library might not be present.
@end itemize

@item Including both GCC and Wind River Libraries

@itemize @bullet
@item Compile your Ada module

@smallexample
powerpc-wrs-vxworks-gnatmake foo.adb
@end smallexample

@item Make all the symbols of your Ada module local except the main
entry point

@smallexample
objcopyppc -G foo foo new-foo
@end smallexample

@item Add the resulting executable file to your kernel.
@end itemize
@end itemize

@noindent
If you need a bootable application, then refer to the section @cite{Creating
Bootable Application} in the @cite{Projects} chapter of the @cite{Tornado
User's Guide}. There is a detailed discussion on adding user initialization
routines.

@node Support for Software Floating Point on PowerPC Processors
@section Support for Software Floating Point on PowerPC Processors

@noindent
The PowerPC 860 processor does not have hardware floating-point support.
In order to build and run GNAT modules properly, you need to install and
invoke software-emulated floating-point support as follows:

@itemize @bullet
@item
Under the subdirectory @file{lib\gcc\powerpc-wrs-vxworks\4.1.2} of the
GNAT installation:
@itemize @bullet
@item
Create a file @file{ada_object_path} containing the following
line:
@smallexample
rts-soft-float\adalib
@end smallexample

@item
Create a file @file{ada_source_path} containing the following
line:
@smallexample
rts-soft-float\adainclude
@end smallexample
@end itemize

@item
When using the compiler, specify @option{-msoft-float}
as a compiler and a linker option, e.g.:
@smallexample
$powerpc-wrs-vxworks-gnatmake -msoft-float module -largs -msoft-float
@end smallexample
@end itemize

@node Stack Overflow Checking on VxWorks 5.x
@section Stack Overflow Checking on VxWorks 5.x

@noindent
GNAT does not perform stack overflow checking by default. This means that if
the main environment task or some other task exceeds the available stack space,
then unpredictable behavior will occur.

To activate stack checking, compile all units with the gcc option
@option{-fstack-check}. For example:

@smallexample
$ @i{target}-gcc -c -fstack-check package1.adb
@end smallexample

@noindent
Units compiled with this option will generate extra instructions to check
that any use of the stack (for procedure calls or for declaring local
variables in declare blocks) do not exceed the available stack space.
If the space is exceeded, then a @code{Storage_Error} exception is raised.

For declared tasks, the stack size is always controlled by the size
given in an applicable @code{Storage_Size} pragma (or is set to
the default size if no pragma is used).

For the environment task, the stack size is defined by the @code{stackSize}
argument when spawning the Ada program via the @code{taskSpawn} routine. If no
stack size is specified, the stack size is set to the VxWorks default value.

The GNAT run time retrieves stack boundaries information from the VxWorks
kernel using the @code{taskInfoGet} routine provided by the @code{taskShow}
library. Therefore, in order to have stack overflow checking working the
@code{taskShow} library must be linked into the VxWorks kernel. This can be
done using one of the following methods:

@itemize @bullet
@item Defining @code{INCLUDE_SHOW_ROUTINES} in @code{config.h} when using
configuration header files
@item Selecting @code{INCLUDE_TASK_SHOW} when using the Tornado project
facility
@end itemize

@node Debugging Issues for VxWorks 5.x
@section Debugging Issues for VxWorks 5.x

@menu
* Using the Debugger in Monotask Mode::
* Using the Debugger in Multitask Mode::
* Debugging an Ada Application Spawned from a C Program::
@end menu

@noindent
The debugger can be launched directly from the Tornado environment
or from @code{GPS}.
It can also be used directly in text mode as shown below:

@noindent
The command to run @code{GDB} in text mode is

@smallexample
$ @i{target}-gdb
@end smallexample

@noindent
where @i{target} is the name of target of the cross GNAT
compiler. In contrast with native @code{gdb}, it is not useful to give
the name of the program to debug on the command line. Before starting
a debugging session, one needs to connect to the VxWorks-configured board
and load the relocatable object produced by @code{gnatlink}.
This can be achieved by the following commands:

@smallexample
(vxgdb) target wtx myboard
(vxgdb) load program
@end smallexample

@noindent
where @code{myboard} is the host name or IP number of the target board, and
@code{wtx} is the name of debugging protocol used to communicate
with the VxWorks board. Early versions of VxWorks, up to 5.2, only
supported the @code{<vxworks>} protocol, whereas starting with VxWorks 5.3
and Tornado, another protocol called  @code{<wtx>} was introduced. The
choice of the protocol can be made when configuring the VxWorks
kernel itself. When available, the @code{<wtx>} is greatly preferable:
it is the only protocol supported by the GNAT version of gdb. When the debugger
is launched directly from Tornado, the proper @code{target} command
is automatically generated by the environment.  Note that a target server
for @code{myboard} is expected to be running before launching the debugger.

The GNAT debugger can be used for debugging multitasking programs in two
different modes. A minimal understanding of these modes is
necessary  to use the debugger effectively. The two modes are:

@itemize @bullet
@item Monotask mode: attach to and debug a single task.
This mode is equivalent to the capabilities offered by CrossWind. The
debugger interacts with a single task, while not affecting other tasks
(insofar as possible). This is the default mode.

@item Multitask mode:
The debugger has control over all Ada tasks in an application. It is
possible to gather information about these tasks, and to
switch from one to another within a single debugging session.
@end itemize

@noindent
It is not advisable to switch between the two modes within a debugging
session. A third mode called System mode is also available and can be
used in place of the Multitask mode. Refer to the Tornado documentation
for this.

Among the criteria for selecting the appropriate mode is the effect of
task synchronization on the application's behavior. Debugging a
tasking application affects the timing of the application; minimizing
such effects may be critical in certain situations. The two modes have
different effects: monotask mode only affects the attached task:
others will run normally (if possible). Multitask mode stops all tasks
at each breakpoint and restarts them on single-step, next, finish or
continue; this may help avoid deadlocks in the presence of task
synchronization, regardless of the inherent latency of stopping and
restarting the tasks.

@node Using the Debugger in Monotask Mode
@subsection Using the Debugger in Monotask Mode

@noindent
There are two ways to begin your debugging session:

@itemize @bullet
@item The program is already running on the board.

@noindent
The sequence of commands to use this mode is:
@itemize @bullet
@item Launch GPS (possibly from the Tornado menu)

@noindent
If launching from the command line:

@smallexample
gps --debug=myapp --debugger powerpc-wrs-vxworks-gdb \
    --target=myboard:wtx
@end smallexample

@noindent
Once GPS has opened, connect to the target using the menu selection:

@smallexample
       Debug @result{} Initialize @result{} <no main file>
@end smallexample

Verify that the debugger has access to the debug information of both
your program and the kernel. The Console window should have a message
@code{"Looking for all loaded modules:"} followed by the names of the modules
on the board and @code{"ok"}. If you have some error messages here instead of
@code{"ok"}, the debugging session may not work as expected.

@item Attach to the desired task using
@smallexample
        Debug @result{} Attach...
@end smallexample
@noindent
This task is stopped by the debugger. Other tasks continue to operate
normally (unless they are blocked by synchronization with the stopped
task). The source window should display the source code location at which the
task has been stopped. If the call stack display is enabled, it should reflect
the stack of the attached task.
@end itemize

@item The program hasn't been loaded to the board
@itemize @bullet
@item Launch GPS (possibly from the Tornado menu)
@item Load your program to the board:

If launching from the command line:

@smallexample
gps --debug=myapp --debugger powerpc-wrs-vxworks-gdb \
    --target=myboard:wtx
@end smallexample

@noindent
Once GPS has opened, connect to the target using the menu selection:

@smallexample
       Debug @result{} Initialize @result{} myapp
@end smallexample

@noindent
GPS should display:
@smallexample
Downloading your_program ...done.
Reading symbols from your_program...expanding to full symbols...done.
@end smallexample

@item Set breakpoints in your program.

@noindent
WARNING: the initial breakpoints must be set in code executed by the
/ environment main task of the application.

@item Run your program using one of the three methods below:
@itemize @bullet
@item
Click on the <Start/Continue> button in the GPS toolbar

@item Menu
@smallexample
Debug @result{} Run
@end smallexample

@item
Type into the GPS Debugger Console window
@smallexample
(gdb) run your_program
@end smallexample
@end itemize
@end itemize

@item Whichever method you chose to start your debugging session,
you can use the following commands at this point:
@itemize @bullet
@item  Browse sources and set breakpoints
@item  Examine the call stack (Debug @result{} Data @result{} Call Stack)
@item  Go ``up'' and ``down'' in the call stack (``up'' & ``down'' buttons)
@item  Examine data
(Debug @result{} Data @result{} Display local variables, or any of the other
 methods for
viewing data in GPS)
@item Continue/finish
@end itemize

Next/step/finish will only work if the top frame in the call stack has
debug information.  This is almost never the case when first attaching
to the task since the task is usually stopped by the attach operation
in the GNAT run-time. You can verify which frames of the call stack
have debug information by:
@smallexample
Debug @result{} Data @result{} Call Stack
<right Button> (contextual menu inside the call stack window)
 add "file location"
@end smallexample

@noindent
If the current frame does not have a ``file location'', then there is no
debug information for the frame.  We strongly recommended that you set
breakpoints in the source where debug information can be found and
``continue'' until a breakpoint is reached before using
``next/step''. Another convenient possibility is to use the ``continue
until'' capability available from the contextual menu of the Source
window.

You can also examine the state of other tasks using
@smallexample
Debug @result{} Data @result{} Tasks
@end smallexample

@noindent
but you can't ``switch'' to another task by clicking on the
elements of the task list. If you try to, you will get an error
message in the GPS debugger console:
@smallexample
"Task switching is not allowed when multi-tasks mode is not active"
@end smallexample

@noindent
Once you have completed your debugging session on the attached
task, you can detach from the task:
@smallexample
File @result{} detach
@end smallexample

@noindent
The task resumes normal execution at this stage.  WARNING: when you
detach from a task, be sure that you are in a frame where there is
debug information. Otherwise, the task won't resume properly. You can
then start another attach/detach cycle if you wish.

Note that it is possible to launch several GPS sessions and
simultaneously attach each to a distinct task in monotask mode:
@smallexample
Debug @result{} Initialize @result{} <no main file>
Debug @result{} Attach...     (in the new window)
Debug @result{} Detach
@end smallexample
@end itemize

@node Using the Debugger in Multitask Mode
@subsection Using the Debugger in Multitask Mode

@noindent
The steps are as follows

@itemize @bullet
@item
Launch GPS (possibly from the Tornado menu)

@noindent
There are two possibilities:
@itemize @bullet
@item
If the program is already loaded on the target board, you need only verify
that debug information has been found by the debugger as described
above.

@item
Otherwise, load the program on the board using
@smallexample
Debug @result{} Initialize @result{} myprogram
@end smallexample
@end itemize

@item Set breakpoints in the desired parts of the program

@item Start the program

@noindent
The simplest way to start the debugger in multitask mode is to use the
menu
@smallexample
Debug @result{} Run
@end smallexample

@noindent
and check the box @code{"enable vxWorks multi-tasks mode"}.
You can also use the following gdb commands in the console window
@smallexample
        (gdb) set multi-tasks-mode on
        (gdb) run your_program
@end smallexample

@item Debug the stopped program

@noindent
Once stopped at a breakpoint
(or if you interrupted the application), you can use all the standard
commands listed for monotask mode + task switching (using Debug @result{} Data
@result{} Tasks). Using next/step in this mode is possible with the same
restrictions as for monotask mode, but is not recommended because all
tasks are restarted, leading to the possibility that a different task
hits a breakpoint before the stepping operation has completed.  Such
an occurrence can result in a confusing situation for both the user and
the debugger. So we strongly suggest the use of only breakpoints and
``continue'' in this mode.
@end itemize

A final reminder: whatever the mode, whether you are debugging or not,
the program has to be reloaded before each new execution, so that data
initialized by the loader is set correctly. If you wish
to restart the execution of a program, you can use the
following sequence of gdb commands in the debugger console window:
@smallexample
(gdb) detach
(gdb) unload your_program(.exe)
(gdb) load your_program(.exe)
(gdb) run your_program
@end smallexample

@node Debugging an Ada Application Spawned from a C Program
@subsection Debugging an Ada Application Spawned from a C Program

@noindent
The previous sections have shown how to debug an Ada application that is either
run from the debugger (can then be debugged in mono or multitask mode), or that
is already running on the target (can be debugged in monotask mode). Now, you
may be in a situation where the Ada application is spawned from a C program via
@code{taskSpawn}. If you need to debug the application in monotask mode, then
the previous section about a debugging session in monotask mode applies. But if
you wish to debug the Ada application in multitask mode, a special procedure
must be followed.

Let's assume that you are in the following situation: a C application
(here called ``loader'') loads a multitasking Ada application from a disk
or network, and spawns it using
@code{taskSpawn}. An error appears in the Ada part and you need to debug it in
multitask mode. Here are the steps to follow (the example code is
provided at the end of the chapter):

@itemize @bullet
@item
The target server and the VxWorks kernel must be configured to enable
synchronization between the host and target symbol tables (see the
Tornado/VxWorks documentation). This is required as the symbols of the Ada
application are added to the target symbol table, while the debugger uses the
target server (host) symbol table. If there is no synchronization between the
two tables, the debugger will not have access to the symbols of the Ada
application.

@item
In your C code, replace @code{taskSpawn} by @code{taskInit}. Like
@code{taskSpawn}, @code{taskInit} will initialize the task. However, it will
not start it. The initialized task will remain in @cite{SUSPEND} mode.

@item
Once you have recompiled and loaded your C application, start it.

@item
Start the debugger. It should see the loaded Ada module.

@item
In the debugger console, set the debugger to multitask mode:
@smallexample
        (gdb) set multi-tasks-mode on
@end smallexample

@item
Attach the debugger to the Ada task

@item
You can now set breakpoints and start your debugging session using the
@code{continue} command, either from the gdb console or from the GUI.

@end itemize

@noindent
Example of a C application (``loader'') loading and initializing an Ada
application (diners):
@smallexample
/*
 * This is an example on how to load and spawn an application from
 * a C program using two different methods: via taskSpawn, or by
 * using taskInit and taskActivate.
 *
 * With taskSpawn, the task will be initialized and run. A call
 * to taskInit followed by a call to taskActivate gives a similar
 * result.
 *
 * If taskInit is called alone, then the task is only initialized
 * and not started. The advantage of this approach is that you can
 * then attach a debugger to the task and start a debugging session.
 * If the spawned application is a multitasking application written
 * in Ada, then you can debug it in multitask mode.
 *
 * By default, taskSpawn is used. To use taskInit, you should define
 * the symbol DEBUG.
 *
 * Note that VX_FP_TASK is set when spawning the main Ada program.
 * This is required if the program uses any floating-point operations
 * at all, to ensure proper saving and restoring of floating-point
 * registers. The GNAT run-time takes care of setting VX_FP_TASK for
 * tasks other than the environment task, but you need to set this
 * flag explicitly for the environment task.
 */

#include <vxWorks.h>
#include <loadLib.h>
#include <taskLib.h>
#include <symLib.h>
#include <sysSymTbl.h>
#include <ioLib.h>
#include <stdio.h>

#define STACK_SIZE     0x100000

int loader (void) @{
  int fd;
  int STATUS;

  char *module_name = "diners";
  MODULE_ID mod_id;
  FUNCPTR pValue;
  SYM_TYPE pType;

  char *tMonitorStack;

  /* allocate memory for the task stack and task control block */
  tMonitorStack =
    (char *) malloc (STACK_ROUND_UP (STACK_SIZE) + sizeof (WIND_TCB));

  /*
   * load the module to the target and determine its entry point
   */
  printf ("Opening the module...\n");
  fd = open (module_name, O_RDONLY, 0);
  if (fd == ERROR) @{
    printf ("Could not open the module %s\n", module_name);
    return;
  @}

  printf ("Loading module...\n");
  mod_id = loadModule (fd, LOAD_GLOBAL_SYMBOLS);
  if (mod_id == NULL) @{
    printf ("ERROR: could not load the module\n");
    STATUS = close (fd);
    return;
  @}

  STATUS = close (fd);

  printf ("Find the address associated to the symbol '%s'...\n",
          module_name);
  STATUS = symFindByName (sysSymTbl, module_name,
                          (char **)&pValue, &pType);
  if (STATUS == ERROR) @{
    printf ("ERROR: could not find the symbol %s\n", module_name);
    return;
  @}

#ifdef DEBUG
  printf ("Initializing the task...\n");
  STATUS = taskInit
    ((WIND_TCB *) (tMonitorStack),
     module_name,
     100,
     VX_FP_TASK,
#if (_STACK_DIR == _STACK_GROWS_DOWN)
     (char *) (tMonitorStack +
               STACK_ROUND_UP (STACK_SIZE) +
               sizeof (WIND_TCB)),
#else
     (char *) (tMonitorStack + sizeof (WIND_TCB)),
#endif
     STACK_SIZE,
     pValue, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  if (STATUS == ERROR) @{
    printf ("ERROR: could not initialize the module\n");
    return;
  @}

  printf ("done...\n");

  /*
   * Uncomment the following lines if you do not want the Ada application
   *  to remain in SUSPEND mode
   */
  /* printf ("Starting the task...\n");
     taskActivate ((int) tMonitorStack); */

#else
  printf ("Starting the task with taskSpawn...\n");
  STATUS = taskSpawn
    (module_name,
     100,
     VX_FP_TASK,
     STACK_SIZE,
     pValue, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  printf ("done...\n");
#endif
@}
@end smallexample

@node Using GNAT from the Tornado 2 Project Facility
@section Using GNAT from the Tornado 2 Project Facility
@cindex Tornado II Project

@menu
* GNAT as New Toolchain in the Tornado 2 Project Facility::
* Building a Simple Application::
* Mixing C and Ada Code in a Tornado 2 Project::
* Compilation Switches::
* Autoscale and Minimal Kernel Configuration::
* Adapting BSPs to the GNAT toolchain::
* Using GNAT Project Files in a Tornado 2 Project::
@end menu

@noindent
This section describes how to add an Ada module to a Tornado project
using the Tornado 2 Project facility described in
@cite{Tornado User's Guide}, Chapter 4.
All instructions apply to both 'Downloadable Modules' and 'Kernel'
project types.

@node GNAT as New Toolchain in the Tornado 2 Project Facility
@subsection GNAT as New Toolchain in the Tornado 2 Project Facility

@noindent
Tornado 2 allows you to integrate third-party C toolchains.  (@cite{Tornado 2
API Programmer's Guide}, Chapter 7). Thus the GNAT toolchain will be seen as a
new C toolchain when used from the Tornado 2 Project Facility. For each
processor you have chosen during the GNAT/Tornado2 install, you have a
corresponding <proc>gnat toolchain, e.g. PPC604gnat. These toolchains allow you
to include Ada modules into your Tornado projects, and to build them directly
using the Tornado build facilities.

@noindent
The name of the ``C compiler'' in GNAT toolchains is @emph{cc_gnat_<arch>}; the
name of the 'linker' is @emph{ld_gnat_<arch>}, where <arch> is an architecture
(e.g. PPC). Associated build scripts call the appropriate executables during
the build process: the C compiler, the C linker, or the GNAT toolchain,
depending on the context.

@noindent
When using Tornado, you can create two types of projects:
@itemize @bullet
@item A bootable VxWorks image
@item A downloadable application
@end itemize

@noindent
The integration applies to both cases, but it is only needed if you are
building an Ada application. However, the integration (the GNAT toolchain and
the BSPs modified for GNAT) can be used to build C applications as well. In
this situation, you'll get the same behavior as when using corresponding
toolchain (e.g. PPC604gnu).

@node  Building a Simple Application
@subsection  Building a Simple Application

@noindent
First, create a new project, using one of the GNAT toolchains.

@noindent
To add an Ada source file to the current project, click on @code{Project
@result{} Add/Include}, browse to the relevant file, and include it. The
selected Ada source file should contain the application's main subprogram.
Any other required Ada source files will be compiled and linked by the
underlying tools. Note that a Tornado project may contain only one Ada
application, and therefore only one Ada main subprogram.

@noindent
You can now build the project, using @code{Build @result{} Rebuild all}. A log
of the build process will be placed in the file @file{gnatbuild.log} in the
build directory. It contains all calls made by the scripts, and information
associated with each such tool invocation.

@node Mixing C and Ada Code in a Tornado 2 Project
@subsection Mixing C and Ada Code in a Tornado 2 Project

@noindent
When using the GNAT toolchain in the Tornado 2 Project Facility, you can mix C
and Ada code in your project: you can have one main Ada program or no Ada
program, and one or more C source files. For more information on mixed language
programming, see @cite{Mixed Language Programming} and @cite{Interfacing to C}.

@noindent
Please note that the GNAT/Tornado2 integration cannot currently handle mixed C
/ Ada applications, where the C code provides the main entry point. In this
situation, use the manual build procedures given in the sections referenced
above.

@node Compilation Switches
@subsection Compilation Switches
@noindent
Once you have included all your source files, you may modify various build
options. To pass options to the GNAT toolchain, go to the
Project's build settings, on the @code{C/C++ Compiler} tab, and add your
arguments into the input window.

@noindent
Use the following rules to pass arguments to GNAT. The arguments
should be:

@itemize @bullet

@item after any arguments passed to the C toolchain.

@item prefixed with a switch identifying the tool that uses them:

@itemize @bullet
@item @code{-margs @emph{gnatmake-options}} to pass arguments to gnatmake
@item @code{-cargs @emph{gcc-options}} to pass arguments to gcc
@item @code{-bargs @emph{gnatbind-options}} to pass arguments to gnatbind
@item @code{-largs @emph{gnatlink-options}} to pass arguments to gnatlink
@end itemize
@end itemize

@noindent
You can find more information on the compilation process of Ada source files in
the section @cite{The GNAT Compilation Model}. For a list of all available
switches, refer to the sections describing @code{gnatmake}, @code{gnatbind} and
@code{gnatlink}.

@noindent
Here is an example that passes the option @code{-v} to gcc:
@smallexample
-g -mstrict-align -prjtype $(PRJ_TYPE) -ansi -nostdinc -DRW_MULTI_THREAD
-D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -I.
-I/usr/windppc-2.0/target/h -DCPU=PPC604 -cargs -v
@end smallexample

@noindent
Here is an example that passes @code{-a} to gnatmake, @code{-gnatf} and
@code{-gnatD} to gcc and @code{-E} to the binder:
@smallexample
-g -mstrict-align -prjtype $(PRJ_TYPE) -ansi -nostdinc -DRW_MULTI_THREAD
-D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -I.
-I/usr/windppc-2.0/target/h -DCPU=PPC604 -margs -a -cargs -gnatf -gnatD
-bargs -E
@end smallexample

@noindent
In both examples, the switches before @code{-margs}, @code{-cargs},
@code{-bargs} and @code{-largs} are automatically added by the Tornado Project
Facility. They are passed to the C compiler.

@noindent
Note: The @code{-prjtype $(PRJ_TYPE)} option present in a few input
boxes is used by the GNAT toolchain. It is required for the compilation
process. You should not remove it from any input box.

@node Autoscale and Minimal Kernel Configuration
@subsection Autoscale and Minimal Kernel Configuration

@noindent
The Autoscale feature of the Tornado Project Facility can be used to determine
the minimum set of kernel components required by your application when building
a bootable VxWorks image. (Please
refer to the @cite{Tornado II User's Guide} Section 4.4 for more details).
This feature is also available for projects involving Ada code. Just click on
@code{Project@result{}Autoscale} to launch a check to identify the minimal
kernel configuration.

@node Adapting BSPs to the GNAT toolchain
@subsection Adapting BSPs to the GNAT toolchain

@noindent
To use a Board Support Package with the GNAT toolchain, it must be modified.
This can be done manually, or by using the @code{setup} (Solaris) or
@code{gnat-<gnat_version>-t2-integration-windows.exe} (Windows) programs
provided in the GNAT/Tornado2 integration.

@itemize @bullet

@item To automatically create BSPs for the GNAT toolchain from existing ones:

@itemize @bullet

@item Run @code{setup bsps} (on Windows, run the GUI-based integration tool)

@item Enter your Tornado install dir (i.e. the value of @code{WIND_BASE})

@item Choose the BSPs from which new BSPs for the GNAT toolchain should be
created.

@end itemize

@noindent
Note : the BSPs detected are located in the directory
@code{$(WIND_BASE)/target/config/}. The newly-generated BSPs are also placed in
this directory. They have names of the form: @code{<BSP>_GNAT}.

@noindent
This automatic generation and installation operates as described below
to perform the adaptation.

@item To adapt BSPs manually:

The generic procedure is described in the @cite{Tornado API Programmer's
Guide}, Chapter 7 (this chapter is only available in Tornado 2.0.2
documentation).

@itemize @bullet

@item Copy your BSP directory to a new directory

@item Go to this directory

@item Edit the file @file{Makefile},

@itemize @bullet
@item Set TOOL to gnat: @code{TOOL=gnat}

@item Reverse the order of the following lines
@itemize @bullet
@item @code{include $(TGT_DIR)/h/make/make.$(CPU)$(TOOL)}
@item @code{include $(TGT_DIR)/h/make/defs.$(WIND_HOST_TYPE)}
@end itemize

@end itemize

@end itemize

@end itemize

@node Using GNAT Project Files in a Tornado 2 Project
@subsection Using GNAT Project Files in a Tornado 2 Project

@noindent
You can use GNAT Project files to build your Ada applications.  To do so,
use the @option{-Pproject_file} option from @command{gnatmake}.  The path to
the project file can be either absolute or relative to the Tornado build
directory, i.e. where the executable will be placed
(e.g. @file{~/myproject/PPC604gnat}).

@noindent
When used in Tornado, the GNAT project file needs to be modified, as the
module built by GNAT will be generated into the @code{Exec_Dir}
specified by the project file. The @code{Exec_Dir}
needs to be set to the Tornado build directory, so that Tornado can find the
Ada load module. A variable (@code{TARGET_DIR}) is automatically set by the
GNAT/Tornado integration to the Tornado build dir and given to the GNAT
project. One then needs to retrieve this variable in the project to specify the
@code{Exec_Dir}:
@smallexample @c projectfile
project Foo is

   Tornado_Exec_Dir := external ("TARGET_DIR");
   for Exec_Dir use Tornado_Exec_Dir;

end Foo;
@end smallexample

This is the recommended method for using GNAT projects with the GNAT/Tornado
integration.

@noindent
One possible development scenario is to first build and test the Ada
application on the host,and then move it to the target after initial checkout.
The first part is done outside of Tornado with host tools; the second uses the
GNAT/Tornado integration. A single GNAT project file can support both phases.
The mechanism is to use an external variable to indicate whether the
application is being built for host or target execution. The @code{Exec_Dir}
(and other options) are specified to depend on the value of the external
variable.

A typical simple GNAT project file looks like this:

@smallexample @c projectfile
project Foo is

   type Env_Type is ("Default", "Tornado");
   Env : Env_Type := external ("Env", "Default");

   Module_Dir := external ("TARGET_DIR", "./");

   for Main use ("hello.adb");

   case Env is

      when "Default" =>
         for Exec_Dir use "your_dir";

      when "Tornado" =>
         for Exec_Dir use Module_Dir;

   end case;

end Foo;
@end smallexample

When working in the first phase of your project, one just needs to call:
@smallexample
gnatmake -Pfoo
@end smallexample

@noindent
Then in Tornado, the main file @code{hello.adb} needs to be added to the
Tornado project, and the following compilation switches need to be passed to
the GNAT toolchain (see @ref{Compilation Switches}):
@smallexample
-margs -P<dir_to_foo>/foo -XEnv=Tornado
@end smallexample

@noindent
Now, the Ada application can be built, and loaded or linked to the VxWorks
kernel from Tornado, and will use the specifications in the GNAT project file.

@c ******************************************
@node Using GNAT Pro with the RTI ScopeTools
@section Using @value{GNATEDITION} with the RTI ScopeTools

@noindent
This section applies to @value{GNATEDITION} versions 3.16a1 and
5.01a and higher, and to Tornado 2.2 / VxWorks 5.5 with ScopeTools 4.0.

You can use @value{GNATEDITION} with the following RTI ScopeTools:

@table @emph
@item MemScope
The instant memory analyzer
@item ProfileScope
The statistical profiler
@item TraceScope
The execution-flow trace tool
@item StethoScope
The real-time data monitor
@end table

@noindent
The code coverage analysis tool CoverageScope is not designed to be used
with Ada.
This is due to the underlying technology that parses and modifies the
application source file.
The parser is limited to  C and C++.

@menu
* General Information on Using the Tools::
* MemScope::
* ProfileScope::
* TraceScope::
* StethoScope::
@end menu

@node General Information on Using the Tools
@subsection General Information on Using the Tools

@noindent
Since GNAT and Wind River use the same compiler technology (GCC),
the objects generated by both compilers for C and Ada are similar,
and @value{GNATEDITION} integrates smoothly with the RTI tools.

@menu
* Debug Switch::
* Name Demangling::
* Symbol Downloading::
@end menu

@node Debug Switch
@subsubsection Debug Switch

@noindent
The RTI tools are designed to work with modules compiled with DWARF2 support.
By default, the GNAT compiler generates STABS.
To use the ScopeTools with GNAT, you should therefore replace the
@option{-g} switch by @option{-gdwarf-2} that causes DWARF2
debugging information to be generated:

@smallexample
$ powerpc-wrs-vxworks-gnatmake -gdwarf-2 hello.adb
@end smallexample

@noindent
This is especially useful if you want to use the ``goto-source'' feature
available in the RTI ScopeTools.

@node Name Demangling
@subsubsection Name Demangling

@noindent
Ada names, like C++ names, need ``demangling''.
Although Ada name demangling is not directly
supported in the RTI ScopeTools, this is not an issue since, in most
cases, the demangling is straightforward.
Generally ``__'' (two consecutive underscores)
in a variable name corresponds to ``.'' in the mangled Ada name.

@noindent
Consider the following package:

@smallexample @c ada
package Foo is

   procedure My_Proc;

end Foo;

package body Foo is

   procedure My_Proc is
   begin
      null;
   end My_Proc;

end Foo;
@end smallexample

@noindent
If the procedure @code{My_Proc} is referenced somewhere in one of the RTI
tools, it will appear with the name @code{foo__my_proc}, from which the
corresponding Ada name @code{Foo.My_Proc} can be derived.

@noindent
For more complex situations, the comments in the GNAT run-time file
@file{exp_dbug.ads} supplies details.

@node Symbol Downloading
@subsubsection Symbol Downloading

@noindent
Generally, you will download all the symbols (global and local) of your
application when you use the Ada and the RTI tools; e.g.:

@smallexample
-> ld 1,0,"foo"
@end smallexample

@noindent
Otherwise, you may get incomplete information when using ScopeTools.

If you see unexpected symbols like @code{.LMx}, this is a known issue
in ScopeTools 4.0 when used with @value{GNATEDITION}, and you should install
a patch from the RTI web site that addresses this issue.

@node MemScope
@subsection MemScope

@noindent
MemScope works with Ada applications in the same way that it works with
C applications, since dynamic allocation / deallocation in Ada are directly
mapped to the corresponding C functions @code{malloc} and @code{free}.

There is a known issue with the tracing of PPC callbacks (you will get a
MemScopeTracingError message). If you receive such an error message, you can
get a repair patch on the RTI web site.

@node ProfileScope
@subsection ProfileScope

@noindent
ProfileScope works with Ada applications, but see the discussion above
regarding the download of global symbols.

@node TraceScope
@subsection TraceScope

@noindent
TraceScope works with Ada applications. The Ada
functions / procedures are listed in the registration table,
and you can activate the functions as tracepoints.

Return values for functions work for the types @code{Boolean} and
@code{Integer}.

Parameter values work for the predefined types @code{Float}, @code{Integer},
@code{Character}, @code{Long_Float}, and @code{Long_Integer}, but not for
@code{String}.

@node StethoScope
@subsection StethoScope

@noindent
There are two ways to use StethoScope for monitoring
an Ada variable:

@itemize @bullet
@item
Use the Ada binding to the StethoScope API (see the file
@file{filescope.ads} in @file{$WIND_BASE/rti/scopetools.4.0c/src/ada}), or

@item
Export the Ada variable to its C equivalent so that it can be
recognized by StethoScope.
@end itemize

@noindent
For example:

@smallexample @c ada
package Foo is

   My_Var : Integer;
   pragma Export (C, My_Var, "my_var");

end Foo;
@end smallexample

@noindent
Then in the automatic signal installation, you should instruct StethoScope to
monitor the variable @code{my_var}.

At present you have to use a pragma Export. Any attempt to directly
access @code{My_Var} by giving StethoScope the Ada demangled name
(i.e. @code{foo__my_var}) will lead to a ``Signal Installation Error''.

@c ******************************************
@node Frequently Asked Questions for VxWorks
@section Frequently Asked Questions for VxWorks 5.x

@itemize @bullet

@item
When I run my program twice on the board, it does not work. Why not?

@noindent
Ada programs generally require elaboration and finalization, so the
compiler creates a wrapper procedure whose name is the same as the Ada
name of the main subprogram, which invokes the elaboration
and finalization routines before and after your program executes. But the
static part of the elaboration is handled while loading the program
itself, so if you launch it twice this part of the elaboration will
not be performed the second time. This affects the proper elaboration of the
GNAT run-time, and thus it is mandatory to reload your program before
relaunching it.

@item
Can I load a collection of subprograms rather than a standalone program?

@noindent
It is possible to write Ada programs with multiple entry points that
can be called from the VxWorks shell (or from a C or C++ application).
To do this, generate an externally-callable
Ada subsystem (see @cite{Binding with Non-Ada Main Programs}
in the @cite{@value{GNATEDITION} User's Guide}. If you
use this method, you need to call @code{adainit} before calling
any Ada entry point.

@item
When I use the @code{break exception} command, I get the message
@code{"exception" is not a function}, why?

You are not in the proper language mode. Issue the command:
@smallexample
(vxgdb) set language ada
@end smallexample

@item
When I load a large application from the VxWorks shell using the @command{ld}
command, the load hangs and never finishes. How can I load large
executables?

This is a classic VxWorks problem when using the default @code{rsh}
communication
method. Using NFS instead should work. Use the @code{nfsShowMount} command to
verify that your program is in a NFS mounted directory.

@item
When I load a large application from the debugger using the wtx target
connection, the load never finishes, why?

Make sure that the memory cache size parameter of the target server is
large enough. (@code{target -m big_enough_size}, or Memory cache size box
in GUI.) See @cite{Tornado 1.01 API Programming Guide}, Section 3.6.2.

@item
When I spawn my program under the VxWorks shell, interactive input does
not work, why?

Only programs directly launched from the shell can have interactive
input. For a program spawned with the @code{sp} or @code{taskSpawn}
command, you need to have file redirection for input:
@smallexample
->    # here you can have interactive input
-> main
->    # here you cannot
-> sp main
->    # neither here
-> taskSpawn("ess",100,0,8000000,main)
->    # but you can input from a file:
-> taskSpawn("Bae",100,0,8000000,main) < input_file
@end smallexample

@item
The @code{errno} of the task(s) of my Ada application is not null even though
my application is running correctly. Is that normal?

Yes. As explained in the @cite{VxWorks OS Libraries API Reference} in the
@code{errnoLib} section, @cite{most VxWorks functions return ERROR when they
detect an error, or NULL in the case of functions returning pointers. In
general, they set an error status that describes the nature of the error}.

There are a large number of calls to VxWorks functions in the Ada run-time.
Whenever a system call returns a value indicating an error, the error status
is set to a non-zero value. So despite the checking of the return value is
to determine an appropriate action, @code{errno} can still be non-null.

Resetting the error status in the Ada run-time each time a VxWorks function is
called would add unnecessary system call overhead and would not avoid masking
error status information that may appear in user code. So this approach would
not help.

It is a good practice not to rely on the error status value to detect
errors. It should be only used to get more information on errors that have
already been detected by checking the code returned by the VxWorks function. To
be sure to get the error status corresponding to the error detected in the
code, the use of the debugger is recommended.
@end itemize

@c    ********************************
@c    * Workbench / VxWorks 6 Topics *
@c    ********************************
@node Workbench / VxWorks 6.x Topics
@appendix Workbench / VxWorks 6.x Topics
@cindex Workbench / VxWorks 6 Topics

@noindent
This Appendix describes topics that are specific to VxWorks 6. It
introduces the basic features provided by the @value{GNATEDITION} toolchain for
this target, and shows how to use them. It also describes which
functionalities are implemented, and summarizes known issues.

@menu
* GNAT Pro for VxWorks 6 Installation::
* Using GNAT Pro for VxWorks 6::
* Building a VxWorks 6 Application::
* SMP Support::
* Using the VxWorks 6 Simulator::
* Debugging an Application on VxWorks 6::
@end menu

@node GNAT Pro for VxWorks 6 Installation
@section @value{GNATEDITION} for VxWorks 6 Installation

@noindent
The packages shipped with @value{GNATEDITION} for VxWorks 6 have several
installation dependencies that you need to understand in order to build
a user-friendly set@-up:

@itemize @bullet
@item
@i{GNATbench:} this provides build functionalities for both VxSim and PowerPC
targets. All build targets whose name starts with PPC, PENTIUM, SIMPENTIUM,
SIMLINUX or SIMNT are supported.
For debugging features, GNATbench requires Workbench 2.5 (or later).
@end itemize


@noindent
To sum up, a proper installation order is:

@itemize @bullet
@item
Workbench;
@item
VxWorks 6;
@item
the core compilation system package;
@item
GPS;
@item
GNATbench;
@end itemize

@node Using GNAT Pro for VxWorks 6
@section Using @value{GNATEDITION} for VxWorks 6

@noindent
@value{GNATEDITION} for VxWorks 6 comes with a choice of two different
development environments:

@itemize @bullet
@item
GNAT Programming Studio (GPS), which is the standard @value{GNATEDITION} IDE,
@item
GNATbench, the @value{GNATEDITION} plug-in for Workbench (Wind River's IDE
based on Eclipse).
@end itemize

@noindent
Both environments share a common core technology, the GPS engine,
so the choice of environment is mostly a matter of taste. GPS is more
@value{GNATEDITION}-centric and Workbench with the GNATbench plug-in is more
VxWorks-centric.

The debugger technology depends on the environment.
The underlying debugger is gdb in GPS, and DFW in Workbench.
Both debuggers are well integrated into
their respective development environments. The debugging interface in
Workbench has a more VxWorks-centric view, and has practical displays to
interact with the target. GPS has, via gdb, additional knowledge about
Ada-specific data structures and provides additional facilities to display Ada
variables.

The choice between the GPS and the Workbench development environment will
be determined by your development habits and your personal preferences. Note
that, when using Workbench, you can easily switch to
GPS to use some GPS-specific features such as the entity viewer or the
dependency graph, and then switch back to Workbench. GPS is opened with the
same files as Workbench, and file synchronization is assured between GPS and
Workbench at each switch time.


@node Building a VxWorks 6 Application
@section Building a VxWorks 6 Application

@noindent
@value{GNATEDITION} for VxWorks 6 supports two build interfaces:

@itemize @bullet
@item Workbench;
@item GPS;
@end itemize

@noindent
for two types of modules:

@itemize @bullet
@item kernel modules;
@item real time process (RTP) modules.
@end itemize

@menu
* Building from Workbench::
* Building from GPS::
* RTPs and kernel modules::
@end menu

@node Building from Workbench
@subsection Building from Workbench
@cindex Building from Workbench

@noindent
The GNATbench Ada Development User Guide describes how to use GNATbench 
within Workbench. This document, like all Workbench user guides, is 
accessible via the "Help Contents" sub-menu entry under the top-level 
Workbench "Help" menu.

See the "Building" chapter for all the topics related to building Ada 
projects within Workbench. This chapter includes general material, such 
as an overview of the predefined and GNATbench-defined build commands, 
as well as specific information that is essential to building with 
GNATbench.

You should also note that GNATbench provides a number of tutorials that 
provide detailed, step-by-step instructions and screen-shots showing how 
to create and build VxWorks projects. In addition to General Purpose 
Platform (GPP) projects, there are also tutorials on creating and 
building projects not yet directly supported by GNATbench. All these 
tutorials are located under the top-level node of the GNATbench Ada 
Development User Guide. 

@node Building from GPS
@subsection Building from GPS
@cindex Building from GPS

@noindent
Chapter "Working in a Cross Environment" in the @cite{GPS User's Guide}
explains how to adapt the project and configure GPS to work in a cross
environment.

@node RTPs and kernel modules
@subsection RTPs and kernel modules
@cindex RTPs and kernel modules

@noindent
To support both RTPs and kernel modules, two different run-time
libraries are provided. For example, you can build an Ada kernel
module from the @code{demo1} example using the following command:

@smallexample
powerpc-wrs-vxworks-gnatmake -g --RTS=kernel demo1.adb
@end smallexample

@noindent
This will build a relocatable object that you can load in the kernel
context. The @option{-g} switch adds debugging information to the module.

Stack overflow checking using the @option{-fstack-check} switch is
supported for both kernel applications and RTPs. However, if this facility is
to be used for kernel applications, the kernel must be built with
@code{INCLUDE_PROTECT_TASK_STACK} enabled. Note that @option{-fstack-check}
cannot be used on the VxWorks Cert 6.6.x cert kernel.

To build it as an Ada RTP module, you need to use the rtp run-time
library. You will also need to specify the path to the VxWorks 6 RTP
libraries explicitly. The previous example may be built as follows:

@smallexample
powerpc-wrs-vxworks-gnatmake -g --RTS=rtp -mrtp demo1.adb
-largs -Wl,-L$WIND_BASE/target/usr/lib/ppc/PPC32/common
@end smallexample

@noindent
To do so in GPS, you need to update your project properties and add the
options to the corresponding project attributes (e.g., @option{--RTS=rtp},
@option{-mrtp} for Ada make options).

@node SMP Support
@section SMP Support

@noindent
Starting with VxWorks 6.6, the OS supports symmetric multi-processing (SMP) for
specific target boards. GNAT Pro includes run-time libraries supporting DKM
and RTP applications running on a SMP kernel.

To use these libraries, use @option{--RTS=kernel-smp} or
@option{--RTS=rtp-smp}, depending on the application type.

When using these libraries, the VxWorks kernel must be configured with __thread
support.

These libraries can also be used for uniprocessor kernels starting with VxWorks
6.6.

Processor affinity is controlled by using either @code{pragma Task_Info} or by
declaring a discriminant of type @code{System.Task_Info.Task_Info_Type} for a
task type and giving it a value on task creation.

The allowable values range from 0 to n, where n is the number of processors
available. A value of zero sets the processor affinity to ``any processor'',
while other values assign the task to the corresponding processor. Out of range
values, or an attempt to use this mechanism on VxWorks versions prior to 6.6,
will cause creation of the task to fail.

By default, when the above mechanisms are not used, tasks inherit the processor
affinity of the task that creates them (but see the notes on RTPs in the
VxWorks user manuals).

@node Using the VxWorks 6 Simulator
@section Using the VxWorks 6 Simulator

@noindent
If you have access to the build toolchain for the simulator, it should
be invoked using the @code{i586-wrs-vxworks} prefix. This toolchain also
supports both RTP and kernel modules. The toolchain for the simulator
is used in the same way as toolchains for real targets. Please
see @ref{Building a VxWorks 6 Application}.


@node Debugging an Application on VxWorks 6
@section Debugging an Application on VxWorks 6

@noindent
In VxWorks 6, the debugging interface used by the debuggers is a GDB/MI-based
protocol named DFW. The component that offers debug services is called
the DFW server.

Therefore, to be able to connect to the target board, you need first
to have a DFW server running and your target board registered
into this server. You can do that in Workbench using the panels
@code{Remotes Systems} or @code{Target Manager}.

Note also that, to be able to run an RTP, you need access to the file
system where the RTP module is located. This can be done in several
ways, for example via FTP or NFS.

If the kernel has been loaded on the target board using an FTP server,
the target board has access to the file system of the this server.
Then, if your RTP module is accessible in the FTP server's file
system, the target board will be able to load it.

If not, you will have to use one of the other file system clients that
VxWorks provides. Here is an example for NFS. Assuming that you want to
execute @code{/home/workspace/demo1.exe}, located on a machine named
@code{rtphost} whose IP address is 192.168.0.1 and which has a mountable
NFS file system, you can execute it from the target shell with the
following commands:

@smallexample
hostAdd ("rtphost", "192.168.0.1")
nfsMount ("rtphost", "/home/workspace", "/mnt")
@end smallexample

@noindent
In any case, in the target server properties it is important to set
the Pathname Prefix Mapping (corresponding to the previous settings)
when creating the target server (section 19.1.3 of the @cite{Wind River
WorkBench User's Guide}):

@smallexample
  Target Path       Host Path
  rtphost:/mnt   /home/workspace
  /mnt          /home/workspace
@end smallexample

@noindent
After this preliminary setup, you are ready to debug. A debugging
session on VxWorks 6 can be divided into the following steps:

@itemize @bullet
@item
connect to the target board;
@item
load the module on the target memory;
@item
execute and debug your program.
@end itemize

@noindent
The following sections explain how these three steps map into the two
provided debugging solutions: Workbench and GPS.

@menu
* Using Workbench DFW::
* Using GPS and GDB::
@end menu

@node Using Workbench DFW
@subsection Using Workbench DFW

@noindent
Important note: Workbench 2.5 or later should be used for debugging Ada code.

GNATbench is integrated smoothly into Workbench's debugging solution.
It provides Ada support similar to the what is available for C
(breakpoints, control of the debugger execution, etc.). Note that a few Ada
types use a debug encoding that Workbench cannot read yet. In that case, Ada
variables using these types are not displayed by Workbench. A workaround is
to use GPS for debugging.


@node Using GPS and GDB
@subsection Using GPS and GDB

@noindent
As mentioned previously, the Ada debugger in GPS uses the DFW
interface for controlling the execution on the program executing on
the target. To be able to debug an Ada program, the DFW server has to
be launched from Workbench and has to be connected to the target you
are debugging.

Note that this only supports the debugging of kernel applications; to
debug a RTP, you should use the Workbench debugger.

Several DFW servers may have been launched on your host; if so,
you will need to tell the debugger which one it should pick. To do
so:

@itemize @bullet
@item
In Workbench, open @code{Windows -> Preferences}, then expand
@code{Wind River -> Debug Server Setting}. There, you should find the
session name of the DFW server; e.g. @code{dfw-wb3111-$@{user@}}.

@item
Set the environment variable @code{DFW_SERVER_NAME} to this name; e.g.,
on Unix: @code{DFW_SERVER_NAME=dfw-wb3111-me; export DFW_SERVER_NAME}
@end itemize

@noindent
A kernel module generated by the @value{GNATEDITION} toolchain can be loaded
and run in the same way as a VxWorks 5.* kernel module (Ada or C).
An example may be found in @ref{Common VxWorks Topics}.

Before starting a debugging session in GPS, you should ensure that several
fields in your GNAT Project are filled in:

@itemize @bullet
@item
Program host: <name of your connection to the board>
@item
Protocol: @code{dfw} to debug an kernel task
@item
Debugger: @code{powerpc-wrs-vxworks6-gdb}
@end itemize

@noindent
The name of your connection to the board is displayed in Workbench, in
panel @code{Remotes Systems} or @code{Target Manager}, at the root of
your target's connection tree.

As was mentioned previously, the three steps to debugging on VxWorks 6 are
@i{connecting}, @i{loading}, and @i{executing}.

To connect to your target and debug a kernel module, the debugger uses
a target interface named @code{dfw}. To do so in GPS, you can specify the
target protocol in your project properties, and use the menu
@code{Debug -> Initialize -> <no_main_file>}.
Alternatively, if you want to use the command line debugger, you should use
the @code{target} command:

@smallexample
(gdb) target dfw <myboard>
Connecting to DFW server <myhost>:1603...Connecting to <myboard>@@<myhost>...
done.
@end smallexample

@noindent
where @code{<myboard>} is the name of the target board you are attaching to.

You cam load your module either during initialization in GPS,
with one of the choices given by the menu (e.g.,
@code{Debug -> Initialize -> demo1}), or from the console:

@smallexample
(gdb) load demo1
@end smallexample

@noindent
You can then start executing, using the menu @code{Debug -> Run}
or the @code{Start/Continue} button.
As always, there is a corresponding call in the command line debugger,
which is named @code{start} and takes the name of the main procedure
as a parameter:

@smallexample
(gdb) start demo1
Breakpoint 1 at 0xad5768: file demo1.adb, line 4.
Starting program:  demo1
demo1 () at demo1.adb:4
4       procedure Demo1 is
@end smallexample

@noindent
Note that, if your module has already been loaded and executed from an
other tool (e.g. Workbench or the host shell) you can also attach to
the running process in the debugger. To do so, first get the list of kernel
tasks and RTPs with the command @code{info vxworks-tasks}:

@smallexample
(gdb) info vxworks-tasks
0 task 0x604df868       (tShell0)
1 task 0x6037bc70       (tWdbTask)
2 task 0x6036f6d8       (ipnetd)
3 task 0x604159e0       (ipcom_syslogd)
4 task 0x60427af0       (tNet0)
5 task 0x60403a38       (tAioIoTask0)
6 task 0x60403740       (tAioIoTask1)
7 task 0x603e59a8       (tAioWait)
8 task 0x6037e290       (tNbioLog)
9 task 0x60387c38       (tLogTask)
10 task 0x60170774      (tExcTask)
11 task 0x6037a480      (tJobTask)
12 task 0x73acc0        (tMy_p)
@end smallexample

@noindent
This gives you the id of the different tasks. To debug a task, use the
@code{attach} command. For example, to attach @code{tMy_p}:

@smallexample
(gdb) attach 0x73acc0
@end smallexample

@noindent
You can then set breakpoints, start and stop the execution, and display
your variables... For more details, please refer to the
@cite{GDB User's Manual}.

@c    **********************
@c    * VxWorks 653 Topics *
@c    **********************
@node VxWorks 653 Topics
@appendix VxWorks 653 Topics
@cindex VxWorks 653 Topics

@noindent
This Appendix provides information specific to the @value{GNATEDITION}
cross-development system for the Platform VxWorks 653 target.  Supported
versions are Platform for Safety Critical 1.8.x and Platform VxWorks 653 2.2.

@menu
* VxWorks 653-Introduction::
* Setting Up a VxWorks 653 System::
* Running and Debugging Applications::
* Application Design Considerations::
@end menu

@node VxWorks 653-Introduction
@section Introduction

@noindent
VxWorks 653 is a time- and space-partitioned real-time operating system that
conforms to the ARINC-653 standard.
@cindex ARINC-653
Its purpose is to support the
implementation of Integrated Modular Avionics (IMA) system
architectures and similar architectures in other industries. Because an
application running in one partition cannot be affected by those in different
partitions, applications can be developed with greater independence, and their
safety certification can be unlinked from the safety certification of
other subsystems.

The VxWorks 653 architecture and programming model is described in the
@cite{VxWorks 653 Programmer's Guide}.

For programming purposes the operating system (OS) is divided into two
parts:

@itemize @bullet
@item
The @emph{Module or Core OS},
@cindex Module OS (for VxWorks 653)
@cindex Core OS (for VxWorks 653)
which contains drivers and other privileged software.
This part of the system presents an API that is described in the
@cite{VxWorks 653 Module OS API Reference},
@cite{VxWorks 653 Module OS Errno Code List} and
the @cite{VxWorks 653 Programmer's Guide}.

@item
The @emph{Partition OS},
@cindex Partition OS (for VxWorks 653)
which is used within application partitions.
This part of the system presents an API similar to that of VxWorks 5.x, or
the VxWorks 6.x kernel, called vThreads,
@cindex vThreads (for VxWorks 653)
and is also enhanced with optional POSIX and APEX
@cindex APEX (for VxWorks 653)
@cindex POSIX (for VxWorks 653)
(ARINC-653) components.  It is primarily described in the
@cite{VxWorks 653 Partition OS API Reference},
@cite{VxWorks 653 Partition OS Errno Code List} and
the @cite{VxWorks 653 Programmer's Guide}.
@end itemize

@noindent
@value{GNATEDITION} for VxWorks 653 lets you develop applications for the
various VxWorks 653 partition types and operating modes:

@itemize @bullet
@item
Module OS applications can be built with the ``zero footprint'' Ada
run-time library (@code{rts-zfp}).
@cindex Zero Footprint (ZFP) Run-Time Library (for VxWorks 653)

Applications written for the Module OS may only use certain port components
that must be imported by the application, as opposed to the full APEX bindings.

@item
Partition OS applications can be built with the full Ada run-time
library (@code{rts-full}),
@cindex Full Ada Run-Time Library (for VxWorks 653)
the restricted Ravenscar run-time library (@code{rts-ravenscar-cert}),
@cindex Restricted Ravenscar Run-Time Library (for VxWorks 653)
the restricted certifiable run-time library (@code{rts-cert})
@cindex Restricted Run-Time Library (for VxWorks 653)
or the zero footprint run-time library (@code{rts-zfp}).
Application partitions may
include either the full or partial APEX components, or just
the vThreads components. Ada tasking applications must use only the
APEX_MINIMAL subset of APEX.
@end itemize

@noindent
It is expected that nearly all applications developed with @value{GNATEDITION}
will execute in application partitions under the Partition OS.

This Appendix describes the mechanics of building and debugging Ada
applications for VxWorks 653, and also treats other issues relevant to
application development in the various contexts listed above.

@node Setting Up a VxWorks 653 System
@section Setting Up a VxWorks 653 System

@menu
* The GNAT VxWorks 653 Starter Kit::
* Manually Configuring a VxWorks 653 System::
@end menu

@node The GNAT VxWorks 653 Starter Kit
@subsection The GNAT VxWorks 653 Starter Kit
@cindex GNAT VxWorks 653 Starter Kit

@menu
* Configuration and Compilation Issues::
* Running the System::
@end menu

@noindent
A starter kit is available to ease the creation of a first VxWorks 653 system
containing Ada, C or C++ applications. Information about the starter
kit is also available as a @file{README} file in the GNAT VxWorks 653 Starter
Kit package.

The starter kit provides a command line tool @command{vx653_system_install}
@cindex @command{vx653_system_install}
that will create and build a full VxWorks 653 system.

The resulting system contains all the elements needed to start
developing an Ada application on VxWorks 653. The system is configured
with the following characteristics (a non-exhaustive list):

@itemize @bullet
@item
two application partitions

@item
user-defined ports to provide inter-partition communication

@item
two schedules:
@itemize @minus
@item schedule0 (the default) allocates no time to the application partitions,
so that a debugger may be attached.
@item schedule1 provides appropriate time allocations to allow the application
partitions to execute.
@end itemize

@item
a Health Monitor with most entries set to @code{CFG_NO_HANDLER}.
@cindex Health Monitor (for VxWorks 653)
This is
a very basic configuration that prevents any conflict between the
Health Monitor and Ada exceptions.

@cindex Exception handling (for VxWorks 653)
@end itemize

@noindent
Run @command{vx653_system_install} with no arguments to get command line
help. @command{vx653_system_install} requires at least one parameter: the
name of the configuration file to use. Some examples with detailed
documentation are provided with the Starter Kit.

@node Configuration and Compilation Issues
@subsubsection Configuration and Compilation Issues

@noindent
The GNAT VxWorks 653 Starter Kit can be used in one of two possible modes:

@itemize @bullet
@item
one of the default Ada/C systems provided by the starter kit
is linked to the VxWorks kernel, or

@item
an external Ada/C/C++ system can be specified
@end itemize

@noindent

Using @file{Makefile.example} as the configuration file, the Starter Kit will
build the arinc653 example application, which gives a good overview of what
should be done to get started with a VxWorks 653 application.

Using @file{Makefile.testuite} as the configuration file, the Starter Kit will
build a testsuite of the Ada binding to the ARINC653 APEX, and of other
run-time library implementation features.

Both applications use Ada and C APEX processes, and use two
application partitions to run.

In the second case, the user can specify which applications to run in the
first and second partitions. Since the configuration file specifies entry
points for the custom applications (FIRST_APP_MAIN, SECOND_APP_MAIN), the
VxWorks 653 system will be configured so that the custom applications are
started automatically when the partitions containing it are scheduled.

To build a system with only one partition, do not specify a location for
the second partition (SECOND_APP_DIR). The resulting system will
effectively have two partitions, but the second partition will just run a
null program.

To use a custom application, these rules must be followed:

@itemize @bullet

@item
a GNAT Project File must be used for each application partition. These files
can handle, Ada, C and mixed-language applications
@cindex Project files (for VxWorks 653)

@item
this GNAT Project File should be in the root directory of your application's
directory tree

@item
the resulting module should be put in the root directory of your application's
directory tree
@end itemize

@noindent
In a nutshell, the GNAT Project file and the executable should be in the same
directory. See the file @file{Makefile.example} provided with the Starter Kit
for more information on how to create a configuration file to use a custom
application.

For VxWorks 653 2.2, the Starter Kit will generate the Workbench project files
@file{Makefile.wr}, @file{.project} and @file{.wrproject} are generated into
the designated system installation directory (see INSTALL_DIR in
@file{Makefile.example}). That directory and the project it contains can be
imported into Workbench as an existing project when using Workbench 2.6.1 and
GNATbench 2.0.1 or later.  Build targets will be created for various parts of
the system and for the entire system.  See the GNATbench help (in Workbench)
for more information on using Workbench with VxWorks 653 Ada applications.

For VxWorks 653 2.2, you can also clean and rebuild the project or its parts as
created by the starter kit by changing to the system installation directory
and executing a command of the form:

@command{make -f Makefile.wr [target]}

from within the VxWorks 653 2.2 development shell.

@node Running the System
@subsubsection Running the System

@noindent
Once @command{vx653_system_install} has successfully created and compiled the
system, the system can be directly loaded and run on the target. The
compiled system is located in:

@smallexample
INSTALL_DIR/vxWorks
@end smallexample

@noindent
where INSTALL_DIR is the system installation directory specified in the
configuration file.

When the system is started, the application partitions will not execute because
the default schedule (@code{schedule0}) does not allocate any time to them. Use
@code{schedule1} to start the two application partitions.

To specify the schedule to be used, type the following in either the
target shell or the VxWorks shell:

@smallexample
   [vxkernel] -> arincSchedSet (@i{xxx}, 0)
@end smallexample
@cindex @command{arincSchedSet} command (for VxWorks 653)

@noindent
where @i{xxx} is the schedule number: @code{0} for @code{schedule0};
@code{1} for @code{schedule1}; etc.


@node Manually Configuring a VxWorks 653 System
@subsection Manually Configuring a VxWorks 653 System

@noindent
The GNAT VxWorks 653 Starter Kit automates a number of steps that are required
to include an Ada application in a VxWorks 653 system. The operations can be
split into two parts: configuration to define a working VxWorks 653 platform,
followed by configuration to add applications to the system.

Normally, on a real program, the platform will be jointly defined by specialists
such as the platform developer and systems integrator.  Application developers
will then be provided with the platform and a description in XML configuration
files of the resources available to them in the partitions their applications
will execute.  Definition of the platform is outside the scope of this manual,
and is described in the @cite{VxWorks 653 Configuration and Build Guide}.

In this section, we will focus on integration of applications into the platform.
We suggest you first familiarize yourself with the overall process as described
in the above reference.

@menu
* Application Configuration Files ::
* Partition Makefiles ::
@end menu

@node Application Configuration Files
@subsubsection Application Configuration Files

@noindent
For each application, there are two sections of XML configuration info to be
provided.

The first is in the partition description, which will be in either the module
XML file, or in a partition-specific XML file.  Refer to the @cite{VxWorks 653
Configuration and Build Guide} for specific contents.  An example fragment for
a two partition system would be:

@smallexample
    <Applications>
         <Application Name="part1">
         <xi:include href="C:/testbench/first_app/config/application.xml"
/>
          </Application>
         <Application Name="part2">
<xi:include href="C:/testbench/second_app/config/application.xml"
/>
          </Application>
    </Applications>

...

    <Partitions>
          <Partition Name="part1" Id="1">
            <PartitionDescription>
                <Application NameRef="part1"/>
                <SharedLibraryRegion NameRef="ssl"/>
                <Settings
                          RequiredMemorySize="0x500000"
                          PartitionHMTable="part1Hm"
                          watchDogDuration="0"
                          allocDisable="false"
                          numStackGuardPages="0xffffffff"
                          numWorkerTasks="0"
                          isrStackSize="0xffffffff"
                          selSvrQSize="0xffffffff"
                          maxEventQStallDuration="INFINITE_TIME"
                          fpExcEnable="true"
                          syscallPermissions="0xffffffff"
                          numFiles="0xffffffff"
                          maxGlobalFDs="10"
                          numDrivers="0xffffffff"
                          numLogMsgs="0xffffffff"/>
            </PartitionDescription>
        </Partition>
           <Partition Name="part2" Id="2">
            <PartitionDescription>
                <Application NameRef="part2"/>
                <SharedLibraryRegion NameRef="ssl"/>
                <Settings
                          RequiredMemorySize="0x400000"
                          PartitionHMTable="part1Hm"
                          watchDogDuration="0"
                          allocDisable="false"
                          numStackGuardPages="0xffffffff"
                          numWorkerTasks="0"
                          isrStackSize="0xffffffff"
                          selSvrQSize="0xffffffff"
                          maxEventQStallDuration="INFINITE_TIME"
                          fpExcEnable="true"
                          syscallPermissions="0xffffffff"
                          numFiles="0xffffffff"
                          maxGlobalFDs="10"
                          numDrivers="0xffffffff"
                          numLogMsgs="0xffffffff"/>
            </PartitionDescription>
        </Partition>
   </Partitions>
@end smallexample

@noindent
The application part references external XML files used to define the
application characteristics, and the applications defined in that fragment are
then referred to in the partition fragments.

A typical application XML file will look like this:

@smallexample
<ApplicationDescription
	xmlns="http://www.windriver.com/vxWorks653/ConfigRecord"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.windriver.com/vxWorks653/ConfigRecord Application.xsd">
<MemorySize
                        MemorySizeHeap="0x100000"
                        MemorySizeBss="0x80000"
                        MemorySizeText="0x100000"
                        MemorySizeData="0x100000"
                        MemorySizeRoData="0x20000"
                        MemorySizePersistentData="0x10000"
                        MemorySizePersistentBss="0x10000">
                        <AdditionalSection
				Name=".gcc_except_table"
				Size="0x10000"
				Type="DATA"/>
	</MemorySize>
 	<Ports>
 	                  <QueuingPort
                                  Name="queuing_answer_dest"
                                  Direction="DESTINATION"
                                  MessageSize="4"
                                  QueueLength="100"
                                  Protocol="NOT_APPLICABLE"/>
                    <QueuingPort
                                  Name="queuing_sender"
                                  Direction="SOURCE"
                                  MessageSize="4"
                                  QueueLength="100"
                                  Protocol="SENDER_BLOCK"/>
                     <SamplingPort
                                  Name="sampling_sender"
                                  Direction="SOURCE"
                                  MessageSize="4"
                                  RefreshRate="0.001"/>
                    <SamplingPort
                                  Name="sampling_answer_dest"
                                  Direction="DESTINATION"
                                  MessageSize="4"
                                  RefreshRate="0.001"/>
</Ports>
</ApplicationDescription>
@end smallexample

@noindent
Its parts include a standard header that points to the corresponding schema,
definition of the application entry point, the location of the generated
object module and its name, memory area sizes, and an additional section to
support C++ exception handling (if used).  Finally, a section is provided that
defines the APEX ports used by the applications.  These are connected among
partitions in the module XML file.

A final configuration file that you may need to create (it will usually be
provided as part of the platform) defines the interface to the system shared
library that contains the partition operating system.  An example for the
certified vThreads POS would contain something like the following, and would be
used as part of the application partition build as described in the next
section:

@smallexample
<Shared_Library_API
    xmlns="http://www.windriver.com/vxWorks653/SharedLibraryAPI"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    Name="vThreads"
    >

    <Interface>
	<Version Name="Cert"/>
<xi:include
href="$(WIND_BASE)/target/vThreads/config/comps/xml/apex.xml" />
<xi:include
href="$(WIND_BASE)/target/vThreads/config/comps/xml/vthreads_cert.xml" />
    </Interface>
</Shared_Library_API>
@end smallexample

@noindent
Here we again see a standard header, followed by references to the interface
description XML files for the components we need in the partition operating
system.

@node Partition Makefiles
@subsubsection Partition Makefiles

@noindent
Typical partition makefiles for C and C++ are described in the @cite{VxWorks 653
Configuration and Build Guide}.  For Ada and mixed applications, we use the
GPRbuild tool, rather than using .o files as targets as is shown in the guide.
Here is an example makefile for a partition containing an Ada or mixed language
application.  It is invoked from @file{Makefile.wr} in the usual way for
building partitions, from within the VxWorks 653 development shell or Workbench.

@smallexample
# Makefile.part1 - makefile for partition 1

########################
#
# Parameters
#

# INSTALL_DIR: root of build location
# FIRST_APP_DIR, FIRST_APP_PROJ, FIRST_APP_MAIN: location, GPR file, module name
# SYS_CFG_DIR: directory containing ssl interface file ssl.xml
# XML_FILE: module XML file
# POS: cert, full
# RTS: cert, full, ravenscar-cert, zfp
# BINDING: APEX binding to use - apex, apex_zfp, apex_95, apex_minimal
# CPU_TYPE: PPC, SIMNT

########################
#
# Variables
#

include $(WIND_BASE)/target/vThreads/config/make/Makefile.vars

USER_OBJ    = $(INSTALL_DIR)/part1/$(FIRST_APP_MAIN).o
USER_MODULE = $(INSTALL_DIR)/first_app/$(FIRST_APP_MAIN).out

CFLAGS_EXTRA	= "-DUSER_APPL_INIT=$(FIRST_APP_MAIN)()"

ifeq ($(POS), cert)
   CFLAGS_EXTRA	+= -DCERT
endif

ifeq ($(POS),full)
   PART_OBJS    =  vThreadsCplusComponent.o \
	   	   vThreadsCplusLibraryComponent.o \
		   __ctype_tab.o
else
   PART_OBJS    =  vThreadsCplusComponent.o
endif

ifeq ($(CPU_TYPE), PPC)
   BUILD_SPEC = powerpc-wrs-vxworksae
else
   BUILD_SPEC = i586-wrs-vxworksae
endif

########################
#
# Rules
#
########################


include $(WIND_BASE)/target/vThreads/config/make/Makefile.rules

vpath %.gpr $(FIRST_APP_DIR)
vpath %.c   $(WIND_BASE)/target/vThreads/config/comps/src
vpath %.c   $(WIND_BASE)/target/vThreads/config/comps/src/templates

default: part1.sm part1.rpt

# ssl.xml is the interface definition, not the ssl definition:
ssl-stubs.c: $(SYS_CFG_DIR)/ssl.xml

FORCE_EXTERNAL_MAKE:

$(USER_MODULE): FORCE_EXTERNAL_MAKE
        gprconfig --batch --target=$(BUILD_SPEC) \
        --config=ada,,$(RTS) --config=c --config=c++
	gprbuild -P \
        $(INSTALL_DIR)/first_app/$(FIRST_APP_PROJ) \
        -gargs -XRuntime=$(RTS) -XCPU=$(CPU_TYPE) -XBinding=$(BINDING)

$(USER_OBJ): $(USER_MODULE)
	$(CP) $(USER_MODULE) $(USER_OBJ)


LDSFLAGS_EXTRA = -j $*
part1.lds: $(XML_FILE)

LDFLAGS_EXTRA = -T $*.lds

part1.sm: vxMain.o ssl-stubs.o $(USER_OBJ) $(PART_OBJS) part1.lds

clean:
	$(RM) *-stubs.c *.o *.lds *.sm *.rpt
	powerpc-wrs-vxworksae-gnatclean -P \
        $(INSTALL_DIR)/first_app/$(FIRST_APP_PROJ) \
        -XRuntime=$(RTS) -XCPU=$(CPU_TYPE) -XBinding=$(BINDING)
@end smallexample

@node Running and Debugging Applications
@section Running and Debugging Applications
@cindex Debugging (for VxWorks 653)
@cindex @command{gdb} (for VxWorks 653)
@cindex GPS (for VxWorks 653)

@noindent
PSC 1.8.x provides a C-oriented debugger that can be used in a limited way on
Ada applications.  VxWorks 653 2.2 provides a more sophisticated debugger that
can handle C, C++ and Ada. @value{GNATEDITION} provides a VxWorks 653-targeted
version of gdb that has been enhanced to provide Ada-knowledgeable debugging
(as well as supporting C and C++).  This version of gdb is normally invoked
from within the GNAT Programming System (GPS) development environment.  This
section describes the use of the GPS debugger on VxWorks 653.

@menu
* VxWorks 653 System Setup::
* Environment Setup::
* GPS Setup::
* Debugging a Partition::
* Debugging Multiple Partitions::
* System Mode Debugging::
* Debugger Commands Specific to VxWorks 653::
@end menu

@node VxWorks 653 System Setup
@subsection VxWorks 653 System Setup

@noindent
In order to debug on VxWorks 653 you need to attach a debugger at the correct
time during OS initialization. The suggested approach is to define
two schedules in the system in the module XML file.

The first (default)
schedule does not allocate any time to application partitions that we
might wish to debug; the second gives the application partitions their
expected allotments. For example:

@smallexample
    <Schedules>
         <Schedule
                  Id="0"
                  Name="schedule0"
                  MajorFrame="0"
                  MinorFrame="0">
            <PartitionWindow
                             PartitionNameRef="part1"
                             Duration="0.0"
                             ReleasePoint="true"/>
            <PartitionWindow
                             PartitionNameRef="part2"
                             Duration="0.0"
                             ReleasePoint="true"/>
        </Schedule>
         <Schedule
                  Id="1"
                  Name="schedule1"
                  MajorFrame="0"
                  MinorFrame="0">
            <PartitionWindow
                             PartitionNameRef="part1"
                             Duration="0.0001"
                             ReleasePoint="true"/>
            <PartitionWindow
                             PartitionNameRef="part2"
                             Duration="0.0001"
                             ReleasePoint="true"/>
        </Schedule>
  </Schedules>
@end smallexample

@noindent
This approach will ensure that none of the application partitions will
start execution after the system boots.  We can then attach a debugger to
a partition before it starts, so we can debug it from its beginning.

@node Environment Setup
@subsection Environment Setup

@noindent
For PSC 1.8.x, it is necessary to set up the Tornado environment variables for
the debugger before launching GPS. These variables are set by the @code{torVars}
script.
@cindex @code{torVars} script (for VxWorks 653)
On UNIX machines, @command{source} the script that corresponds to
the shell you are using -- @file{torvars.sh} or @file{torvars.csh}.
On a Windows
machine, either make the system call the @file{torVars.bat}
script on startup, or modify your environment variables manually so
that you do not have to execute the script every time. For VxWorks 653 2.2,
execute GPS from within the VxWorks 653 Development Shell (@code{wrenv}) or from
Workbench, as @code{torVars} is no longer used on these versions. Alternatively,
you can debug using the Workbench debugger if you install the GNATbench plugin.

@node GPS Setup
@subsection GPS Setup

@noindent
In GPS, on the general properties page, designate the name of your
target server in the @code{Program Host} field and select @code{wtx} as the
protocol. Leave the @code{Tools host} field blank.

@node Debugging a Partition
@subsection Debugging a Partition

@noindent
The procedure to debug partition 1 is as follows:

@enumerate
@item
Boot the target. It will eventually boot the partition OS and stop
at a target shell prompt (assuming you've included a target shell).  At
this time, the Module OS has performed most of its initializations, and
the partitions have been created, but not yet started.

@item
Start your target server.  This can be done from within Tornado,
or from a command line (preferably using a shell script). It is
recommended that you close the Tornado debugger if you start the target
server from the Tornado GUI.

@item
Within GPS, select
@code{Debug}@result{}@code{Initialize}@result{}@code{<No Main Program>}

@item
Within GPS, select @code{Debug}@result{}@code{Attach}.
A dialog will pop up with a list
of all Module OS tasks.  Select @code{tPartition1} from the list.  The name
given is constructed from the name of the partition as given in
@file{configRecord.c}, prefixed by @code{t}.

@item
At this point, you should be able to set breakpoints within the
application partition, including the one to receive control whenever an
exception occurs. You might also wish to display the call stack at this
time by selecting
@code{Debug}@result{}@code{Data}@result{}@code{Call Stack}.

@item
Once you have set any desired breakpoints, hit the @code{Continue}
button in GPS. The system is running, but since the first schedule is
still being used by the core OS, the application partitions are not
being scheduled.

@item
Change to the schedule that allocates time to the application
partitions by typing the following in the target shell:
@smallexample
            arincSchedSet (1, 0)
@end smallexample
@end enumerate

@noindent
You can now debug the partition as you would any other program.  When your
debugging session is finished we recommend you detach from your target
(@code{Debug}@result{}@code{Detach}) before closing the debugger.

@node Debugging Multiple Partitions
@subsection Debugging Multiple Partitions

@noindent
There are two methods that can be used to debug a multi-partition
VxWorks 653 system. In both methods the Tornado debugger should not
be running.

The first method is to use one GPS instance per partition. Each GPS
instance should be attached to a partition, and no two instances should
be attached to the same partition. Also, when debugging a multi-partition
system you should not do system mode debugging with any of the instances
of GPS.

The second method is to use system-mode debugging. In this mode,
the debugger takes control of the entire system, and allows you
to debug all partitions at the same time. To use that method,
you need to type "system" as the name of the task to attach to.
Only one debugger can be attached to the system.

@node System Mode Debugging
@subsection System Mode Debugging

@noindent
Note that @command{gdb} supports ``system mode'' debugging (see the Tornado
documentation). To debug in system mode follow the steps provided
above to start the debugger. Then open the task list dialog selecting
@code{Debug}@result{}@code{Attach}, type @code{SYSTEM} in the text
entry at the bottom of the dialog, and click @code{OK}.

This will bring the target to system mode and attach the debugger
to it. Breakpoints are preserved when switching between task mode and
system mode.

Alternatively, you can start system mode debugging by typing the
following in the gdb prompt:

@smallexample
    (gdb) attach system
@end smallexample

@noindent
Note then that instead of using the @code{Continue button} to start
your application, you will have to type the following in the gdb
prompt:

@smallexample
    (gdb) continue
@end smallexample

To exit system mode you can use the @code{Debug}@result{}@code{Detach}
menu entry. This will detach the debugger from the target and resume
the execution of your VxWorks 653 system.

@node Debugger Commands Specific to VxWorks 653
@subsection Debugger Commands Specific to VxWorks 653

@noindent
The debugger provides the following two commands related to
the handling of partitions. These features are also available
graphically in GPS, through the
@code{Debug}@result{}@code{Data}@result{}@code{Protection Domain}
menu entry.

@table @code
@kindex info pds
@item info pds

This command prints the list of partitions available on the target.
For each partition, the debugger prints its ID and name.  An asterisk
at the beginning of a partition entry identifies it as the current
partition.

@smallexample
    (gdb) info pds
        PD-ID        Name
    *  0x15f78c      vxKernel
       0x8007a8      vxSysLib
       0x800890      pdsAppDomain
@end smallexample

@kindex pd @var{new-partition}
@item pd @var{new-partition}

This command switches the debugger to the new partition. The partition
ID or the partition name can be used to identify the target partition.

Using the list of partitions from the example above, the two commands
in the following example demonstrate how to switch to the vxSysLib
partition using its partition ID (0x8007a8), and then how to switch
to the pdsAppDomain using its name.

@smallexample
    (gdb) pd 0x8007a8
    [Switching to PD 0x8007a8 (vxSysLib)]
    (gdb) pd pdsAppDomain
    [Switching to PD 0x800890 (pdsAppDomain)]
@end smallexample

@end table

@node Application Design Considerations
@section Application Design Considerations

@menu
* General Application Structure on VxWorks 653::
* The ARINC-653 APEX Binding::
* Selection of a Run-Time Profile::
* Replacement of the Default Last Chance Handler::
* Process-Level Health Monitoring Handler::
@end menu

As a general comment, one should never mix APEX processes, POSIX
threads or Ada tasks in a single application partition. Each of these entities
is part of a distinct high-level model for developing concurrent
applications; mixing them will lead to confusion and unpredictable
application behavior.

Before starting, one should know what ``foreign threads''
are. ``Foreign threads'' refer to threads that are not created by the
Ada run-time environment, and therefore are not known to it without taking
additional bookkeeping steps. In order
to facilitate seamless operation of such ``foreign threads'' when they
execute Ada code, they need to be registered with the Ada run-time. On
some native platforms, GNAT accomplishes this automatically; another
alternative is to use GNAT.Threads (which can be used for raw vThreads
on VxWorks 653).

Since VxWorks 653 applications are expected to comprise mainly APEX processes,
the standard way to perform registration on VxWorks 653 is through the
Apex_Processes.Create_Process routine in the Ada APEX binding provided
with @value{GNATEDITION}.  By using this version of the binding, one can ensure
that exception handling and other operations such as functions with
unconstrained results and the process-level health-monitoring handler are
executed correctly.

@node General Application Structure on VxWorks 653
@subsection General Application Structure on VxWorks 653
@cindex VxWorks 653 application structure

@noindent
For applications that are to execute in application partitions, there is a
typical structure.

There is usually one ``main'' application that will perform initializations:
allocating data, creating and starting various APEX processes, and finally
setting the partition into ``normal'' mode.  Once the partition has entered
normal mode, the vThread executing the main is suspended, no more
dynamic allocation is allowed, and the APEX processes defined within the
partition are scheduled according to the characteristics defined for them
within the main application.

For an Ada application, this means that the main subprogram is expected to
perform initializations as described, and then to suspend until the partition
is restarted.
This suspension occurs when @code{Apex_Processes.Set_Partition_Mode (Normal);}
is called.  All of the work of the application is performed by the subsidiary
processes.  These processes communicate with each other and with processes in
other partitions using the APEX interface.  C, C++ and Ada code can be mixed
within an application, and there are various approaches available to manage the
code. GNAT project files are the best method for combining mixed-language code
within a partition.

Note that more complex organization of applications within a partition (e.g.
multiple initialization threads) are possible, but require more complex setup
and coordination. Refer to @cite{VxWorks 653 Programmer's Guide}.

There are several examples of the basic application structure in the
starter kit.  Both C and Ada applications are provided.

@node The ARINC-653 APEX Binding
@subsection The ARINC-653 APEX Binding
@cindex ARINC-653 Binding (for VxWorks 653)

@noindent
The Ada binding to the ARINC-653 APEX (APplication EXecutive) comes
with the compiler and is available for all run-time libraries.  The bindings
are precompiled for each valid combination of run-time library and binding
variant.  Sources are found under
@file{<gnat-root>/include/apex/apex[_variant]/src/}.

Static libraries that can be linked to are in
@file{<gnat-root>/lib/apex/<PLATFORM>-<RUNTIME>-<BINDING>/libapex.a}. For
example, for VxWorks 653 for the PowerPC architecture, and the use of the cert
run-time and Ada 83 version of the APEX binding, the location of the library to
link is @file{<gnat-root>/lib/apex/powerpc-wrs-vxworkae-cert-apex/libapex.a}.

A GNAT project file to include in a project needing the APEX bindings is
located at @file{<gnat-root>/lib/gnat/apex.gpr}. @file{gprbuild} and
@file{gnatmake} know about this location, so to access this project file, add

@code{with "apex";}

to the top of your project file. This project file eliminates the need to
explicitly include the desired APEX library into the @code{gnatlink} switches.
Note that if you previously used @file{environment.gpr} in your project files
for earlier versions of GNAT Pro, it can still be used.

This project file takes three scenario variables:
@itemize
@item
PLATFORM - the target triplet for your platform, e.g. powerpc-wrs-vxworksae.
The default value is ``powerpc-wrs-vxworksae''.
@item
RUNTIME - the run-time library to use: zfp, cert, ravenscar-cert or full. The
default value is ``full''.
@item
BINDING - the APEX binding to use: apex, apex_95, apex_zfp or apex_minimal. The
default value is ``apex''.
@end itemize
The bindings and valid combinations of RUNTIME and BINDING are described next.


Four bindings are provided:
@itemize
@item The standard Ada 83 APEX binding, designated by @code{BINDING=apex}. This
binding is compatible with the full and cert run-time libraries. Applications
using this binding must not use the Ada tasking facilities.

@item The standard Ada 83 APEX binding, designated by @code{BINDING=apex_zfp}.
This binding is compatible with the zfp and ravenscar-cert run-time libraries.

@item A subset of the standard APEX binding that corresponds to VTHREADS
component APEX_MINIMAL, designated by @code{BINDING=apex_minimal}. This
binding, rooted in unit @code{VxWorks_653.Apex_Minimal}, is suitable for use
full and ravenscar-cert run-time libraries, when only APEX_MINIMAL is included
in the application partition.

@item An implementation of the Ada 95 APEX binding, designated by
@code{BINDING=apex_95}. This binding makes use of the hierarchical library
facility of Ada 95 and Ada 2005.  It also changes some definitions so that
fewer explicit type conversions are needed in application code that uses the
APEX binding. Wrapper packages are provided for backward compatibility with
the Ada 83 binding. This binding is compatible with the cert and full run-time
libraries.  Applications must not use Ada tasking facilities.
@end itemize

The easiest way to set the binding is to add the project file
@file{<gnat-root>/lib/gnat/apex.gpr} into the user project files via a context
clause.  GNAT will search and locate the path to this file if the environment
variable @code{GPR_PROJECT_PATH} is defined to include
@file{<gnat-root>/lib/gnat/} (this should be the case by default).

It is strongly recommended that you use the bindings provided with the
product rather than alternatives, as the provided bindings have been
extensively tested for correctness.

To access and use the apex project in an user project file:
@smallexample
@c projectfile
with ``apex'';
project My_Project is
   ...
   for Source_Dirs use (<list of project source dirs>);
   -- To discriminate on eg variable Runtime:
   case apex.Runtime is
      when "cert" =>
      ...
   end case;
end My_Project;
@end smallexample

@menu
* Using the APEX Binding::
* Using Ada Processes::
@end menu

@node Using the APEX Binding
@subsubsection Using the APEX Binding

@noindent
The full binding can be used if no Ada tasking constructs are used
(note: ravenscar-cert applications should use @code{apex_zfp} or
@code{apex_minimal}).
Alternatively, a subset of the binding can be used if Ada tasking
constructs are used in the application with the full or ravenscar-cert run-time
libraries. This subset corresponds to the APEX routines available when
the APEX_MINIMAL component is used in application partition.

@node Using Ada Processes
@subsubsection Using Ada Processes

@noindent
The standard way to define an APEX process in C is to create an attributes
structure
containing the process information (i.e. its name, entry point, priority,
etc.).  This record is then passed to the APEX @code{CREATE_PROCESS} routine.

It works the same way in Ada. One defines a record of type
@code{Apex_Processes.Process_Attribute_Type} describing the process.
This record is then given as a parameter to
@code{Apex_Processes.Create_Process}.
Examples of how Ada processes are created are available in the starter kit.

The APEX / Ada binding provided with @value{GNATEDITION} for VxWorks 653 adds
the defaulted parameter @code{Secondary_Stack_Size} to the procedure
@code{Apex_Processes.Create_Process}.
In order to support the use of unconstrained function results, a data
structure called the secondary stack
@cindex Secondary Stack
 is allocated to
each APEX process that executes Ada code. (The secondary stack is actually
a mark/release heap). This parameter allows the user to specify the size of
this data structure (in bytes).
If the parameter is defaulted, the APEX binding will allocate a secondary stack
with a size equal to one-fourth of the requested stack size for the process.
This data structure is allocated out of the primary stack, which will have
had its allocation increased by one-fourth, so that the original requested
stack allocation is honored.

Calls to @code{Apex_Processes.Get_Process_Status} will return the size of
the primary stack minus the size of the secondary stack (ie the size
originally requested by the application developer).

Note that an APEX process created via the APEX Ada binding can query its
secondary stack ``high-water mark'' using
@code{GNAT.Secondary_Stack_Info.SS_Get_Max}.
This package is described in @cite{The @value{GNATEDITION} Reference Manual}.

All APEX processes that execute Ada code, regardless of whether their bodies
are largely in C or C++, must use the Ada binding routines to create the
process or query its process status, or to create a process-level health
monitoring handler.
These routines and their parameters (for C) are described in
@file{apex_processes.ads} and @file{apex_health_monitoring.ads}.

@node Selection of a Run-Time Profile
@subsection Selection of a Run-Time Profile

@noindent
As mentioned @value{GNATEDITION} High-Integrity Edition for VxWorks 653
provides several versions of the Ada Run-Time library suitable for differing
certification and application needs.

These include:
@itemize @bullet

@item
A full Ada run-time for application partitions, designated by the keyword
``full''.

@item
A restricted Ada run-time for application partitions, certified to DO-178B,
Level A, designated by the keyword ``cert''.

@item
A minimal Ada run-time that generates no object code (``Zero FootPrint''),
for use in either the Module OS or in application partitions,  designated by
the keyword ``zfp''.

@item
An implementation of the Ravenscar profile based on the cert profile for use in
application partitions, designated by the keyword ``ravenscar-cert''.
@end itemize

@noindent
The desired run-time library is selected at build time by setting the gnatmake
flag @option{--RTS=<run-time keyword>}, using one of the keywords given above.
One can also import @file{apex.gpr}, as described in the section on
the APEX bindings, and define project variable @code{RUNTIME} using the
@option{-X} switch.

The VxWorks 653 certified partition operating system supports the use of the
restricted, Ravenscar and zero footprint profiles.
For more information about profiles, see
@cite{The @value{GNATEDITION} High-Integrity Edition Users Manual}.

@node Replacement of the Default Last Chance Handler
@subsection Replacement of the Default Last Chance Handler

@noindent
All Ada run-time libraries provided with the @value{GNATEDITION} for
VxWorks 653
include the concept of a last chance handler.
This routine is called when an application
terminates due to the occurrence of an unhandled Ada exception.
All of the provided run-time libraries, except ZFP, provide a
default implementation of the last chance handler.
ZFP requires one to be written by the application developer.

The default handler can be overridden by the application developer in all
cases, in order to provide such capabilities as raising an error to the
health monitor.
The following treatments apply:
@itemize @bullet

@item
For the cert, ravenscar-cert and full run-time libraries, the default handler
prints a stack dump and exception message, calls APEX RAISE_APPLICATION_ERROR,
and then terminates the process in which the exception occurred.

@item
For the zfp run-time library, there is no default handler.
@end itemize

@noindent
The profile of the last chance handler for all run-times except ZFP is:

@smallexample
procedure Ada.Exceptions.Last_Chance_Handler
  (Except :  Exception_Occurrence);
pragma Export (C,
               Last_Chance_Handler,
               "__gnat_last_chance_handler");
pragma No_Return (Last_Chance_Handler);
@end smallexample

@noindent
This handler may be replaced by any Ada or C routine that exports the symbol
@code{__gnat_last_chance_handler}
and that matches the given parameter profile.

The profile of the ZFP last chance handler is:

@smallexample @c ada
   procedure Last_Chance_Handler
     (Source_Location : System.Address; Line : Integer);
   pragma Export (C, Last_Chance_Handler,
                  "__gnat_last_chance_handler");
@end smallexample
@findex @code{Last_Chance_Handler}

@noindent
The @code{Source_Location} parameter is a C null-terminated string representing
the source location of the @code{raise} statement, as generated by the
compiler, or a zero-length string if @code{pragma Discard_Names} is used.
@cindex @code{pragma Discard_Names}
The @code{Line} parameter (when nonzero) represents the line number
in the source.
When @code{Line} is zero, the line number information is provided in
@code{Source_Location} itself.

Again, any Ada or C routine that exports @code{__gnat_last_chance_handler} and
matches the designated profile may be used here.

The recommended mechanism for replacing the last chance handler is to execute
@code{powerpc-wrs-vxworksae-gnatmake} or the corresponding C compiler on the
file providing @code{__gnat_last_chance_handler}.  The resulting @code{.o} file
should then be included in the the linker directives for the Ada main
application.

Note that the cert, full and ravenscar-cert run-times support stack overflow
checking using the gcc switch @code{-fstack-check}. It is expected that a
user-written last chance handler will be compiled without this switch (or that
it will be overridden with @code{-fno-stack-check}).  Additionally,
user-written last chance handlers must not require more than 4KB of stack space
so that they can handle a stack overflow Storage_Error.

@node  Process-Level Health Monitoring Handler
@subsection Process-Level Health Monitoring Handler

@noindent
The APEX routine @code{Apex_Health_Monitoring.Create_Handler} allows an
application developer to provide a process-level handler for health monitoring
events.  The vThread that executes this routine will receive the requested
stack size, plus 1/4 of the requested size for a secondary stack.  This allows
such routines to be written in Ada, though they need not be.

In addition to the standard HM events defined in APEX
(@code{Apex_Health_Monitoring}),
VxWorks 653 defines a number of extended HM codes. These are defined in
@file{$WIND_BASE/target/vThreads/h/hmTypes.h}.

@c    ***********************
@c    * VxWorks MILS Topics *
@c    ***********************
@node VxWorks MILS Topics
@appendix VxWorks MILS Topics
@cindex VxWorks MILS Topics

@noindent
This Appendix provides information specific to the @value{GNATEDITION}
cross-development system for the VxWorks MILS operating system.

@menu
* VxWorks MILS Overview::
* Common Considerations for VxWorks MILS Applications::
* Applications in the Guest OS Environment::
* Applications in the High Assurance Environment::
@end menu

@node VxWorks MILS Overview
@section Introduction and Overview

@noindent
VxWorks MILS is a time- and space-partitioned real-time operating system
supporting the development of security-sensitive systems requiring
certification to high levels of assurance (EAL). It is based on a secure
hypervisor / separation kernel that isolates and controls communication between
a number of virtual boards. There are two kinds of virtual boards:

@itemize
@item
Guest OS virtual boards running in a vThreads environment similar to that
provided on VxWorks 653.
@item
The High Assurance Environment (HAE) for the stricter EALs, which
provides a very restricted operating environment similar to a bare board.
@end itemize

@noindent
GNAT Pro for VxWorks MILS provides development tools for both kinds of virtual
boards. Additionally, inclusion of compilation and analysis tools for the SPARK
language supports the use of formal methods as required by higher EALs.

@node Common Considerations for VxWorks MILS Applications
@section Common Considerations for VxWorks MILS Applications

@noindent
These sections discuss system-wide subjects for VxWorks MILS.

@menu
* Configuration ::
* GNATbench for MILS ::
* Run-time Libraries for MILS ::
* APEX Bindings ::
* Multiplexed I/O ::
* Communication between Virtual Boards ::
* Debugging on MILS ::
* Binding to MILS Header Files ::
@end menu

@node Configuration
@subsection Configuration

@noindent
VxWorks MILS is highly configurable, covering such areas as scheduling, system
call permissions for virtual boards, handling of exceptions and interrupts in
virtual boards, communication between them, access to security and safety
critical logs and memory allocation.  The definitive reference to the
configuration items for a VxWorks MILS system is
@cite{VxWorks MILS Configuration and Build Reference}. User guidance and
explanations are provided in the
@cite{VxWorks MILS Configuration and Build Guide}. The Wind River
documentation also includes a very useful tutorial
@cite{VxWorks MILS By Example}. The tutorial goes through configuration and
build of an example system.  Though the system is all written in C, it provides
a very good overview of the process.

This document will not treat the overall configuration and build process, but
will point out issues specific to mixed Ada, SPARK, C and C++ applications in
the Guest OS and High Assurance environments.

@node GNATbench for MILS
@subsection GNATbench for MILS

@noindent
GNATbench is the AdaCore plugin for Workbench. It provides a number of features
supporting application development in Ada and SPARK. GNATbench recognizes
Guest OS and HAE Workbench projects, and provides facilities to use these
project types for Ada or mixed language development.

GNATbench uses the Workbench flexible build facilities for VxWorks MILS. For
this reason, we generally suggest adding C or C++ sources directly to the
virtual board project or one of its subfolders, and allowing the predefined
build infrastructure to compile them. However, one can also have
GNATbench manage their compilation using a GNAT project file. But in
order to do so, the files should either be placed outside of the directories
specified in @code{vpath} directives in the Makefile (including the project
subtree), or have an extension distinct from the Workbench defaults of
@code{.h}, @code{.c} and @code{.cc}. A naming convention is needed in the GNAT
project file for the latter case.

An example mixed language system including both Guest OS and HAE virtual
boards can be found in
@file{<GNAT root>\share\examples\powerpc-wrs-vxworksmils\mils_example}, along with instructions for using GNATbench to
construct the system. The example includes all necessary configuration files.

Using GNATbench to create virtual board projects that contain Ada code is the
most straightforward method of integrating them into a MILS system.

Detailed instructions are given in the GNATbench help item of the Workbench
help menu.

@node Run-time Libraries for MILS
@subsection Run-time Libraries for MILS

@noindent

The following Ada run-time libraries are provided for MILS virtual boards:
@itemize @bullet

@item
Zero Footprint (``zfp'') provides footprint run-time support. At its core level
there is no contribution of object code to the application.  Optional packages
in the library provide useful facilities that will contribute object code.
This run-time library can be used for SPARK applications. It is suitable for
applications requiring certification to high EALs or DO-178B level A. This is
the only run-time library provided for the HAE.

@item
Ravenscar Profile (``ravenscar-cert'') implements the Ravenscar Ada tasking
profile, along with a number of useful facilities for porting applications
from other operating environments. It is based on the VxWorks 653 ``cert''
run-time library which has been certified to DO-178B Level A as part of
aircraft sub-systems.  The profile supports up to EAL 4. It also supports the
Ravenscar SPARK profile.

@item
Full Ada (``full'') implements full Ada semantics and can be useful for porting
existing applications into the Guest OS environment. It is not suitable for
certifications.
@end itemize

For the Guest OS environment, the default run-time library is ``full''. For the
HAE, the only alternative is ``zfp''.

For the Guest OS environment, different run-time libraries can be selected
by withing @file{apex.gpr} in your GNAT project file and specifying the value
of scenario variable @code{RUNTIME}. The possible values are as given above,
one of ``zfp'', ``ravenscar-cert'' or ``full''. If not using a GNAT project
file, the @code{--RTS} switch can be passed to @code{gnatmake} or one can
specify the value for @code{gprbuild} to use with appropriate switches passed
to @code{gprconfig}. See the @cite{GNAT User's Guide, The GNAT Project Manager}
for details. The allowable values for @code{--RTS} and @code{gprconfig} are the
same as for scenario variable @code{RUNTIME}.

@node APEX Bindings
@subsection APEX Bindings

@noindent
Currently, VxWorks MILS provides a minimal subset of the ARINC-653 APEX
facilities.  These include queuing and sampling ports for both the Guest OS and
the HAE. GNAT provides Ada 83 and Ada 95/05 style bindings to these facilities
for both environments.  These can be accessed by an application by withing
@file{apex.gpr} in the GNAT project file, and specifying scenario variable
@code{BINDING} to be @code{apex_mils} or @code{apex_mils_95}. The method for
accessing these precompiled binding without using a GNAT project file is
described in this manual in the VxWorks 653 section
@cite{Using the APEX Binding}.

@node Multiplexed I/O
@subsection Multiplexed I/O

@noindent
VxWorks MILS provides a capability for multiplexing I/O among multiple virtual
boards through a single serial channel.  This facility is decribed in the
@cite{VxWorks MILS VxWorks Guest OS Programmer's Guide, 1.0, Programming Tasks,
Using Application Multiplexed I/O} section.  The monitor program is invoked
on the host computer attached to the target serial port using @file{<WRS root>\vthreads-2.2.2\host\x86-win32\bin\wrmonitor.BAT}.

A virtual board running the AMIO service must be part of the system. The
sources and configuration files for such a partition can be found in
@file{<GNAT root>\share\examples\powerpc-wrs-vxworksmils\mils_example\amioServer}
and @file{<GNAT root>\share\examples\powerpc-wrs-vxworksmils\mils_example\config}. This partition has been extracted from the vThreads demo
provided by WRS at @file{<WRS root>\vthreads-2.2.2\target\vThreads\demos\wbTutorialDemoGuestOS}.

Additionally, any Guest OS using AMIO must contain the files @file{amioSio.c}
and @file{usrAmioSerial.c}. These appear in the @file{receiver} and
@file{sender} directories of the example system, as well as in the WRS
demo directory above.

A HAE application should include the files @file{amioSio.c}, @file{amioSio.h}
and @file{usrAmio.c} that can be found in the @file{baremetal} subdirectory of
the GNAT MILS example.

Finally, the application main in a Guest OS VB should contain the following
code. For a C main or in @file{usrAppInit.c}, which is used to spawn an Ada
main in a Guest OS virtual board:
@smallexample
extern void sysSerialHwInit(void);
extern void sysSerialHwInit2(void);
extern void usrSerialInit(void);

...

sysSerialHwInit();
sysSerialHwInit2();
usrSerialInit();
@end smallexample

For an Ada main in the HAE:
@smallexample
procedure My_Main is
   procedure usrAmioInit;
   pragma Import (C, usrAmioInit, "usrAmioInit");
...
begin
   usrAmioInit;
...
end;
@end smallexample

@node Communication between Virtual Boards
@subsection Communication between Virtual Boards

@noindent
VxWorks MILS provides ports and channels for communication between virtual
boards. These are described in the @cite{VxWorks MILS VxWorks Guest OS Guide}.
Use of ports and channels requires configuration items in the
@file{VirtualBoard} and @file{Channels} configuration documents respectively.

GNAT provides access to APEX queuing ports through the apex_mils and
apex_mils_95 bindings. See the @cite{VxWorks 653 Topics, Using the APEX Binding}
section of this manual for instructions on accessing the APEX bindings.

In order to have consistent message passing behavior between virtual boards,
the following fragment should appear in the MILS kernel configuration document.

@verbatim
	<Interrupts NumInterrupts="4">
		<!-- Global interrupt numbers must be unique -->

		<!-- Software interrupt mapping -->
		<Int Name="vbInterProcessorInt" GlobalIntNumber="3" />
		<Int Name="vbPortInt" GlobalIntNumber="4" />
		<Int Name="vbSharedMemoryInt" GlobalIntNumber="5" />
		<Int Name="vbScheduleStartInt" GlobalIntNumber="6" />
	</Interrupts>
@end verbatim

For the same reason, the following should appear in the virtual board
configuration documents.

@verbatim
	<Interrupts NumIn="1" NumOut="0">
		<In Name="vbScheduleStartInt" Vector="1" />
	</Interrupts>
@end verbatim

@node Debugging on MILS
@subsection Debugging on MILS

@noindent
Debugging on VxWorks MILS requires the use of a dedicated virtual board. This
is described in the @cite{VxWorks MILS Configuration and Build Guide}.
GNAT does not provide a port of gdb for this target, so debugging using the
VxWorks MILS debug agent from Workbench is the standard method.

@node Binding to MILS Header Files
@subsection Binding to MILS Header Files

@noindent
If one wishes to use APIs provided by the MILS header files directly, GNAT
provides a binding generator switch for powerpc-wrs-vxworksmils-gcc and, if
you have a native version of GNAT installed, for g++.  The switch is
@code{-fdump-ada-spec}, and is described in the @cite{GNAT Pro User Guide,
Section 25: Generating Ada Bindings for C and C++ headers}.

@node Applications in the Guest OS Environment
@section Applications in the Guest OS Environment

@noindent

@menu
* Differences Between VxWorks 653 and VxWorks MILS vThreads Implementations::
* Ada Run-time Libraries for the Guest OS ::
* Scheduling ::
* Exceptions and Exception Handling on the Guest OS ::
* Application Stub ::
* Guest OS Virtual Board and Application Configuration Files ::
* Setting Up a Guest OS Application with GNATbench ::
* Guest OS Application Makefiles ::
@end menu

@node Differences Between VxWorks 653 and VxWorks MILS vThreads Implementations
@subsection Differences Between VxWorks 653 and VxWorks MILS vThreads Implementations

@noindent
The VxWorks MILS guest OS is based on the VxWorks 653 vThreads Partition
Operating System.  However, it has a number of differences:

@itemize @bullet
@item
Asynchronous virtual interrupts are provided in VxWorks MILS.  These are
enabled in the @file{VirtualBoardDescription} document. Therefore one
can use the capabilities of @code{Ada.Interrupts} and the other interrupt
handling capabilities described in the @cite{Common VxWorks Topics} section of
this manual.

@item
A Safety Critical log capability replaces Health Monitoring. Therefore the
APEX health monitoring binding is not provided for MILS, and the default Ada
last chance handler does not propagate unhandled exceptions to the health
monitoring system.  The user can override the default handler to log events
to the safety critical log using @code{safeCritEventInject( )} from
@file{safeCrit.h}.

@item
VxWorks MILS provides only queuing ports and (imminently) sampling ports, so
these are the only APEX facilities provided in the apex_mils and apex_mils_95
Ada bindings.

@item
VxWorks MILS does not use stack guard pages.  GNAT uses stack limit checking
to check for stack overflow.  This is still enabled with the compiler switch
@code{-fstack-check}.

@item
VxWorks MILS does not provide hardware floating point overflow exceptions.
Therefore, such overflows for unconstrained floating point types are not passed
to the Ada run-time system.  If you want oveflow detection, use a constrained
floating point type.

@item
Hardware exceptions are not automatically passed to the guest OS.  See the
section on exception handling below for details.

@item
The root task in the guest OS (tRootTask) has a fixed 20KB stack and runs at
the highest priority in the OS. Therefore, we use an application stub to spawn
the Ada environment task as described in the @cite{Application Stub} section
below.

@item
By default, scheduling of vThreads in the VxWorks MILS Guest OS is equivalent
to POSIX sched_fifo (Ada FIFO_Within_Priorities). However, the application
initialization code for a virtual board defines an idle task that is not
preemptible by tasks of the lowest priority under this task dispatching policy.
See the section on Scheduling below.


@end itemize

@node Ada Run-time Libraries for the Guest OS
@subsection Ada Run-time Libraries for the Guest OS

@noindent
Three Ada run-time libraries are provided for the guest OS: ZFP, Ravenscar and
full Ada. These are described in the section above
@cite{Common Considerations for VxWorks MILS Applications}.

For the full run-time library, tasks written in C or C++ can use the facilities
of package @code{GNAT.Threads} to register with the Ada run-time library if
they call Ada code.

For the Ravenscar run-time library, which requires static creation of tasks,
tasks calling Ada and coded in C or C++ must be created on the Ada side, and
then the Ada task can call the C or C++ entry point routine.  Note that this
approach can also be used with the full run-time library.

@node Scheduling
@subsection Scheduling

@noindent
As mentioned in the section on differences between VxWorks 653 and VxWorks MILS
vThreads implementations, the initialization code for a Guest OS application
spawns an idle task that cannot be preempted by other tasks with Ada priority
@code{System.Priority'First} or VxWorks priority 255 once it is scheduled. This
is due to the default scheduling policy of the Guest OS, which is equivalent to
POSIX sched_fifo and Ada dispatching policy FIFO_Within_Priorities.

If your application has tasks with Ada priority @code{System.Priority'First},
or if you assign that priority to the main subprogram, there are ways to
address this issue.

@itemize @bullet
@item
The idle task is spawned in @file{%WIND_BASE%\target\vThreads\config\comps\src\vbMain.c}.
The recommended fix is to add a call to @code{taskDelay(NO_WAIT)} to the routine
@code{usrIdleThread}. This will allow other tasks of the same priority to
execute.

@item
In the application stub, call @code{kernelTimeSlice} with the number of ticks
to allocate to tasks of equal priority.  This changes the dispatching policy to
round robin for all priorities within the virtual board, and so is not quite
the same as the Ada task dispatching policy Round_Robin_Within_Priorities,
which can assign slice lengths to specific ranges of priorities, and which does
not use slicing for priorities in the range of @code{System.Interrupt_Priority}.
The Ada Round_Robin_Within_Priorities task dispatching policy is not
implemented for this target.
@end itemize

@node Exceptions and Exception Handling on the Guest OS
@subsection Exceptions and Exception Handling on the Guest OS

@noindent
There are two considerations mentioned above that make exception handling
different from the VxWorks 653 partition operation system: replacement of the
health monitoring system by the safety critical log, and not passing hardware
exceptions by default to the guest OS.

In the first case, the default last chance handler does not interact with the
safety critical log as it did with the health monitoring system on VxWork 653.
A solution is to override the default handler and log unhandled exceptions
to the safety critical log using @code{safeCritEventInject( )} from
@file{safeCrit.h}.  The compiler binding generator switch @code{-fdump-ada-spec}
 can be used to generate an Ada specification for this library. See
@cite{VxWorks 653 Topic, Application Design Considerations, Replacement of the Default Last Chance Handler}
for the mechanics of replacing the handler.

For the second case, if one wants hardware exceptions to be mapped to Ada
exceptions in the usual way, one must add a @code{PassExceptions} section to
the @file{VirtualBoard} configuration document.  The following XML fragment
provides the usual mappings:

@verbatim
	<PassExceptions NumExcs="4">
		<Exception Vector="0x300" />
		<Exception Vector="0x400" />
		<Exception Vector="0x700" />
		<Exception Vector="0x800" />
	</PassExceptions>
@end verbatim

@node Application Stub
@subsection Application Stub

@noindent
Since tRootTask for the guest OS has a fixed 20KB stack and executes at the
highest priority in the guest OS, the application developer should provide
routine @code{usrAppInit()} in order to perform initializations such as for
multiplexed I/O (AMIO) and to spawn the Ada environment task with a suitably
sized stack.  Note that enabling of stack overflow checking via compiler
switch @code{-fstack-check} requires 12KB above the anticipated stack
requirement of an application task in order to effectively handle stack
overflows (not to be used with the ZFP run-time library).  Additionally note
that for the full and Ravenscar run-time libraries, the VxWorks priority given
to taskSpawn for the environment task will be replaced during elaboration of
the application.  If no @code{pragma Priority} is given in the main
subprogram, the default Ada priority of 122 (equivalent to VxWorks priority
133) will be used.

Here is a sample usrAppInit.c suitable for starting an Ada application:

@verbatim
#include <vxWorks.h>
#include <taskLib.h>

/* AMIO interface if present in the virtual board */

extern void sysSerialHwInit(void);
extern void sysSerialHwInit2(void);
extern void usrSerialInit(void);

/* Ada binder-generated main - ADA_MAIN is passed as a macro from the makefile */

extern void ADA_MAIN(void);

void usrAppInit()

{

	int stackSize = 0x80000;
	int spawnFlags = VX_FP_TASK;

        /* MAIN_TASK_NAME is passed as a macro from the makefile */
	char * mainTaskName = (char *) MAIN_TASK_NAME;
	int priority = 100;

        /* Initialize AMIO if interface is present in the virtual board */

	sysSerialHwInit();
	sysSerialHwInit2();
	usrSerialInit();


	/* Spawn Ada environment task */

	taskSpawn(mainTaskName, priority, spawnFlags, stackSize,
			(FUNCPTR) ADA_MAIN, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
}
@end verbatim

@code{ADA_MAIN} is the name of the Ada main subprogram in lower case (i.e. the
symbol for the entry point of the Ada application). @code{MAIN_TASK_NAME} is
the name you would like associated with the Ada environment task for the
application.  These are typically passed using a @code{-D<symbol>=<value>}
switch to the compiler in the virtual board makefile.

The stack size can be varied to suit the needs of the environment task.  It
must be spawned with at least option @code{VX_FP_TASK}.

A copy of this file can be found in @file{<GNAT root>\share\examples\powerpc-wrs-vxworksmils\mils_example\receiver\usrAppInit.c}

@node Guest OS Virtual Board and Application Configuration Files
@subsection Guest OS Virtual Board and Application Configuration Files

@noindent
In addition to the @code{PassException} fragment in the @file{VirtualBoard}
document, the following fragment should also be added to ensure consistent
message passing behavior. Other interrupts can be added to the section.

@verbatim
	<Interrupts NumIn="1" NumOut="0">
		<In Name="vbScheduleStartInt" Vector="1" />
	</Interrupts>
@end verbatim

Otherwise, nothing is different in the configuration files from those for C or
C++ applications. @file{VirtualBoard}, @file{VirtualBoardDescription} and
application @file{Payload} documents are written, and entries are made in
various system level configuration documents.

Refer to the @cite{VxWorks MILS Configuration and Build Guide} for instructions
on configuring virtual boards and integrating them into a MILS system.

Note that a full example with configuration files is provided in
@file{<GNAT root>\share\examples\powerpc-wrs-vxworksmils\mils_example}.

@node Setting Up a Guest OS Application with GNATbench
@subsection Setting Up a Guest OS Application with GNATbench

@noindent
GNATbench, the AdaCore plugin for Workbench, supports building applications for
the VxWorks virtual board environment and for the HAE.  The example provided
with GNAT Pro contains the file @file{<GNAT root>\share\examples\powerpc-wrs-vxworksmils\mils_example\gnatbench_getting_started-vxmils.pdf}
that gives instructions for creating and importing Guest OS and HAE application
projects that contain Ada code.  Instructions are also given in the GNATbench
documentation that can be found under the Workbench Help menu.

In general, for Guest OS applications, one creates a Guest OS Application
Project in Workbench, then imports sources, application configuration files,
and at least a root GNAT project file.  Then one converts the Workbench
project for use with GNATbench. For Vxworks MILS, the Workbench ``managed
build'' scheme is used.  When the project is converted, GNATbench generates
@file{gpr-mils.makefile} and @file{scenario.makefile} into the project root
directory.  The first contains rules and definition relevant to using gprbuild
to build the project application code.  The second contains
application-specific definitions, including the values of scenario variables
defined in the GNAT project file. This file is updated whenever the user
modifies values in the GNATbench scenario view.  The two files are then used
with the Workbench generated Makefile for the project at build time.

Note that the name of the root GNAT project file need not be the same as the
name of the Workbench project.

@node Guest OS Application Makefiles
@subsection Guest OS Application Makefiles

@noindent
If building a Guest OS virtual board  directly using Makefiles, the following
files can be adapted for the application build part.

This first file is like the @file{scenario.makefile} generated by GNATbench:

@verbatim
# user variables

# Path to root GNAT project file. Use an absolute path.
GPRPATH=C:/Workbench-mils-2.0.1-rc2/workspace/receiver/receiver.gpr

# Name of application / virtual board project
APP_NAME=receiver

# Main subprogram name
MAIN=tf_receiver_init

# Path containing project. Use an absolute path.
PRJ_ROOT_DIR=
_
# APEX binding to use. One of: apex_mils, apex_mils_95
BINDING=apex_mils

# Ada run-time library to use.  One of: zfp, full, ravenscar-cert
RUNTIME=full

# Not to be modified by user:
PLATFORM=powerpc-wrs-vxworksmils
GNAT_SCENARIO_COMMAND=-XBINDING=$(BINDING) -XRUNTIME=$(RUNTIME) -XPLATFORM=$(PLATFORM)
@end verbatim

The second file contains rules for building with gprbuild. @file{gpr-mils.makefile}
can be copied from an existing Guest OS application project that has been
converted for GNATbench use, as no modifications should be needed other than
adaptation to specifics of your build infrastructure.

@verbatim
# Include this file at the end of the virtual board makefile.  Some targets and
# definitions may need to change for compatibility with the virtual board
# makefile.

# Access the application specific definitions from the previous file
-include $(PRJ_ROOT_DIR)/scenario.makefile

# Pass entry point symbol and name for the application environment task into
# usrAppInit.c
ADDED_CFLAGS = -DADA_MAIN=$(MAIN) -DMAIN_TASK_NAME="$(MAIN)"

LDFLAGS_EXTRA=--section-start .text=0x10000 -e 0x10000

# Object directory relative to GPR file location. Needed because the gprbuild
# -o switch requires a location expressed relative to the GPR file.
PM_OBJ_SUBDIR = $(CPU)gnu/$(APP_NAME)-pm/$(MODE_DIR)/Objects

# Absolute path of the project's object directory
PM_OBJ_DIR = $(PRJ_ROOT_DIR)/$(PM_OBJ_SUBDIR)

# Absolute path to GPR config file
CONFIG_FILE = $(PM_OBJ_DIR)/$(PLATFORM).cgpr

# Add main generated by gprbuild to project objects list
MAIN_OBJECT = $(PM_OBJ_DIR)/$(MAIN).o
OBJECTS_$(APP_NAME)-pm += $(MAIN_OBJECT)

# Configure Ada, C and C++ tools for gprbuild
$(CONFIG_FILE) : FORCE
	if [ ! -d "`dirname "$@"`" ]; then mkdir -p "`dirname "$@"`"; fi;
	gprconfig --target=$(PLATFORM) --config=ada,,$(RUNTIME), \
          --config=c,,,,"GCC-WRSMILS" --config=c++,,,,"G++-WRSMILS" --batch \
                 -o $(CONFIG_FILE)

# Build step:
.PHONY: FORCE
FORCE:

external_build ::

$(PROJECT_TARGETS): $(MAIN_OBJECT)

$(MAIN_OBJECT) : $(CONFIG_FILE) FORCE
	@echo "make: building GPR objects"
	if [ ! -d "`dirname "$@"`" ]; then mkdir -p "`dirname "$@"`"; fi;
	gprbuild -p -P "$(GPRPATH)" \
           -o $(PM_OBJ_SUBDIR)/$(MAIN).o \
           --config=$(CONFIG_FILE) \
           $(GNAT_SCENARIO_COMMAND)

# Clean step:
external_clean::
	@echo "make: cleaning GPR objects"
	if [ `ls $(CONFIG_FILE)` ]; then \
	gprclean -r -P "$(GPRPATH)" \
          --config=$(CONFIG_FILE) \
           $(GNAT_SCENARIO_COMMAND); \
           $(RM) $(CONFIG_FILE); \
           fi;
@end verbatim

@node Applications in the High Assurance Environment
@section Applications in the High Assurance Environment

@noindent
GNAT Pro can be used to build Ada, SPARK and mixed-language applications for
execution in the High Assurance Environment (HAE).  SPARK Pro can be used to
apply formal methods as required by EALs 5 and higher to SPARK code.

@menu
* Ada Run-time Libraries for the HAE ::
* Exceptions and Exception Handling in the HAE ::
* Security and Safety Critical Logs ::
* HAE Virtual Board Configuration File ::
* Setting Up a HAE Application with GNATbench ::
* HAE Application Makefiles ::
@end menu

@node Ada Run-time Libraries for the HAE
@subsection Ada Run-time Libraries for the HAE

@noindent
Only the Zero FootPrint run-time library (ZFP) is appropriate for Ada or SPARK
applications that will execute in the HAE. See the
@cite{GNAT Pro User's Guide Supplement for High-Integrity Edition Platforms,
Section 3.2, The Zero Footprint Profile} for a description of the Ada language
features supported by this run-time library.

@node Exceptions and Exception Handling in the HAE
@subsection Exceptions and Exception Handling in the HAE

@noindent
The ZFP run-time library provides two facilities for handling Ada exceptions:
handling an exception within a local scope, and the use of an user-written last
chance handler for unhandled exceptions.

The first facility allows the writing of exception handlers for a given scope.
Any propagation beyond the scope within which an exception is raised goes to
the last chance handler.

The last chance handler has the following profile:

@verbatim
with System;

package Last_Chance_Handler is

   procedure Last_Chance_Handler (Msg : System.Address; Line : Integer);
   pragma Export (C, Last_Chance_Handler, "__gnat_last_chance_handler");
   pragma No_Return (Last_Chance_Handler);

end Last_Chance_Handler;
@end verbatim

It may be used to interact with the security and safety critical logs or to
take other critical actions such as partition restart.

Hardware exceptions can be handled in the HAE using @code{excConnect} from
@file{excLib.h} to associate a procedure for handling an exception.  The
@code{-fdump-ada-spec} switch to @file{powerpc-wrs-vxworksmils-gcc} (or to
@file{g++} if a native version of GNAT Pro is intalled) can be used to generate
an Ada binding to the library headers. As for Guest OS virtual boards, a
@code{PassExceptions} section must be specified in the @file{VirtualBoard}
document for the HAE.  See the @cite{VxWorks MILS High Assurance Environment API Reference}
for a description of @file{excLib}.

Hardware exceptions are not mapped to Ada exceptions in the HAE.

@node Security and Safety Critical Logs
@subsection Security and Safety Critical Logs

@noindent

The HAE is a common place to monitor the security and safety critical logs. The
Blaster demo @file{main.c} provided by WRS illustrates this for the security
log.  The relevant libraries are @file{safeCrit.h} and @file{secAudit.h}. Their
use is described in the @cite{VxWorks MILS High Assurance Environment API
Reference}.

@node HAE Virtual Board Configuration File
@subsection HAE Virtual Board Configuration File

@noindent
An HAE virtual board uses a @file{VirtualBoard} configuration document, but
unlike the Guest OS, does not use a @file{VirtualBoardDescription} document.
There are no special configuration considerations for Ada applications in the
HAE.

@node Setting Up a HAE Application with GNATbench
@subsection Setting Up a HAE Application with GNATbench

@noindent
GNATbench can be used to set up an HAE virtual board project similarly to the
way it is done for a Guest OS virtual board.  The example mentioned previously
explains how to do this, as does the GNATbench documentation available under
the Workbench Help menu.

For the HAE, one starts with a Workbench High Assurance Environment Application
project, then imports sources and a root GNAT project file, then converts
the project for GNATbench use. Files @file{scenario.makefile} and
@file{hae-mils.makefile} are generated as part of the conversion, and
@file{scenario.makefile} is kept in synch with the GNATbench scenario view.

No application stub is needed for the HAE, but note that the entry point to the
Ada application is always @code{main}. If you are using AMIO in the HAE, it
should be initialized in the Ada main subprogram analogously to the way it's
done in @file{usrAppInit.c} for the Guest OS. GNAT Pro can generate an Ada
binding as mentioned previously.

@node HAE Application Makefiles
@subsection HAE Application Makefiles

The makefiles for the HAE are similar to those for the Guest OS.  Some minor
differences occur in the gprbuild rules.

@file{scenario.makefile}:
@verbatim
# user variables

# Path to root GNAT project file. Use an absolute path.
GPRPATH=C:/Workbench-mils-2.0.1-rc2/workspace/receiver/receiver.gpr

# Name of application / virtual board project
APP_NAME=receiver

# Main subprogram name
MAIN=tf_receiver_init

# Path containing project. Use an absolute path.
PRJ_ROOT_DIR=
_
# APEX binding to use. One of: apex_mils, apex_mils_95
BINDING=apex_mils

# Not to be modified by user:

# Ada run-time library to use.
RUNTIME=zfp

PLATFORM=powerpc-wrs-vxworksmils
GNAT_SCENARIO_COMMAND=-XBINDING=$(BINDING) -XRUNTIME=$(RUNTIME) -XPLATFORM=$(PLATFORM)
@end verbatim

The second file contains rules for building with gprbuild. @file{hae-mils.makefile}
can be copied from an existing HAE application project that has been
converted for GNATbench use, as no modifications should be needed other than
adaptation to specifics of your build infrastructure.

@file{hae-mils.makefile}:

@verbatim
# Include this file at the end of the virtual board makefile.  Some targets and
# definitions may need to change for compatibility with the virtual board
# makefile.

# Access the application specific definitions from the previous file
-include $(PRJ_ROOT_DIR)/scenario.makefile

# GPR related definitions:

# Object directory relative to GPR file location. Needed because the gprbuild
#  -o switch requires a location expressed relative to the GPR file.
OBJ_SUBDIR = $(APP_NAME)/$(MODE_DIR)/Objects/$(APP_NAME)

# Path to GPR config file
CONFIG_FILE = $(OBJ_SUBDIR)/$(PLATFORM).cgpr

# Add main generated by gprbuild to project objects list
MAIN_OBJECT = $(PRJ_ROOT_DIR)/$(BUILD_SPEC)/$(OBJ_SUBDIR)/$(MAIN).o
OBJECTS_$(APP_NAME) += $(MAIN_OBJECT)

# Configure Ada and C tools for gprbuild
$(CONFIG_FILE) : FORCE
	if [ ! -d "`dirname "$@"`" ]; then mkdir -p "`dirname "$@"`"; fi;
	gprconfig --target=$(PLATFORM) --config=ada,,$(RUNTIME), \
          --config=c,,, --batch \
                 -o $(CONFIG_FILE)

# Build step:
.PHONY: FORCE
FORCE:

external_build ::

$(PROJECT_TARGETS): $(MAIN_OBJECT)

$(MAIN_OBJECT) : $(CONFIG_FILE) FORCE
	@echo "make: building GPR objects"
	if [ ! -d "`dirname "$@"`" ]; then mkdir -p "`dirname "$@"`"; fi;
	gprbuild -p -P "$(GPRPATH)" \
           -o $(PRJ_ROOT_DIR)/$(BUILD_SPEC)/$(OBJ_SUBDIR)/$(MAIN).o \
           --config=$(CONFIG_FILE) \
           $(GNAT_SCENARIO_COMMAND) \
           -bargs -Mmain

# Clean step:
external_clean::
	@echo "make: cleaning GPR objects"
	if [ `ls $(CONFIG_FILE)` ]; then \
	gprclean -r -P "$(GPRPATH)" \
          --config=$(CONFIG_FILE) \
           $(GNAT_SCENARIO_COMMAND); \
           $(RM) $(CONFIG_FILE); \
           fi;
@end verbatim

@c   *****************
@c   * LynxOS Topics *
@c   *****************
@node LynxOS Topics
@appendix LynxOS Topics

@noindent
This chapter describes topics that are specific to the GNAT for LynxOS
cross configurations.

@menu
* Getting Started with GNAT on LynxOS::
* Kernel Configuration for LynxOS::
* Debugging Issues for LynxOS::
* An Example Cross Debugging Session for LynxOS::
* Issues Linking on LynxOS::
@end menu

@node Getting Started with GNAT on LynxOS
@section Getting Started with GNAT on LynxOS

@noindent
This section is a starting point for using GNAT to develop and
execute Ada programs for LynuxWorks' LynxOS target environment from a
Unix host 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
LynxOS board.

To compile code for a LynxOS system running on a PowerPC
board, the basic compiler command is
@command{powerpc-elf-lynxos-gcc}.

With GNAT, the easiest way to build the basic @code{Hello World} program is
with @code{gnatmake}. For the LynxOS PowerPC target this would look
like:

@smallexample
$ powerpc-elf-lynxos-gnatmake hello
@i{powerpc-elf-lynxos-gcc -c hello.adb
powerpc-elf-lynxos-gnatbind -x hello.ali
powerpc-elf-lynxos-gnatlink hello.ali}
@end smallexample

@noindent
(The first line is the command entered by the user -- the subsequent three
are the programs run by @code{gnatmake}.)

This creates the executable @command{hello}, which you then need to load on the
board (using ftp or an NFS directory for example) to run it.

@node Kernel Configuration for LynxOS
@section Kernel Configuration for LynxOS

@noindent
The appropriate configuration for your LynxOS 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.

Kernel parameters limiting the maximum number of file descriptors,
kernel and user threads, synchronization objects, etc., may be set in the
file @file{uparam.h}. You may also wish to modify the file
@file{/etc/starttab}, which places limits on data, stack, and core file
size. See the documentation provided by LynuxWorks for more information.

@node Debugging Issues for LynxOS
@section Debugging Issues for LynxOS

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

@menu
* Native Debugging on x86 LynxOS::
* Cross Debugging on PPC LynxOS::
@end menu

@node Native Debugging on x86 LynxOS
@subsection Native Debugging on x86 LynxOS

@noindent
Although there is no native GPS port to LynxOS it is possible to use GPS
from a remote host, for instance from Solaris.

You will need to have your working directory mounted on both the host
and the target, and you will need to have a remote shell utility like
@command{rsh} set up to allow password-free execution of commands with the
correct environment on the target. You will also need a project file
for the program you wish to debug.

You can then:

@enumerate
@item
Open your project on the host from GPS.

@item
Open the project editor: @code{Project -> Edit_Project_Properties}

@item
For the ``General'' tab, enter the name of the LynxOS native
machine in the ``Tools host'' text box

@item
Exit the project editor

@item
Open the @code{Preferences} editor: @code{Edit -> Preferences}

@item
>From the Debugger page, disable the option ``Execution Window''
@end enumerate

@noindent
You should then be able to build, execute, and debug your program
from GPS.

@node Cross Debugging on PPC LynxOS
@subsection Cross Debugging on PPC LynxOS

@noindent
The procedure for cross debugging on LynxOS
is similar, but requires two additional steps. First, the executable
must be launched on the target under the utility
@code{gdbserver}, and then
the cross debugger must be started on the host and attached to it.

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

@smallexample
$ powerpc-elf-lynxos-gnatmake -g demo1
powerpc-elf-lynxos-gcc -c -g demo1.adb
powerpc-elf-lynxos-gcc -c -g gen_list.adb
powerpc-elf-lynxos-gcc -c -g instr.adb
powerpc-elf-lynxos-gnatbind -x demo1.ali
powerpc-elf-lynxos-gnatlink -g demo1.ali
@end smallexample

@noindent
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 @file{myboard} and the port chosen is 2345,
issue the following command:

@smallexample
myboard> gdbserver myboard:2345 demo1
@end smallexample

@noindent
Then return to your host environment.

Next, attach from gdb:

@smallexample
(gdb) file my_program
(gdb) target remote myboard:2345
@end smallexample

@noindent
To run the cross debugger from the command line without the visual
interface use the command @code{powerpc-elf-lynxos-gdb}.

You will see something like:

@smallexample
GNU gdb 4.17.gnat.3.14a1
Copyright 1998 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=sparc-sun-solaris2.5.1 --target=powerpc-elf-lynxos".
(gdb)
@end smallexample

@noindent
where @command{(gdb)} is the debugger's prompt. The first thing to do at the
prompt from within @command{gdb} is to load the symbol table from the
executable:

@smallexample
(gdb) file demo1
Reading symbols from demo1...done.
(gdb)
@end smallexample

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

@smallexample
(gdb) target remote myboard:2345
@end smallexample

@noindent
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:

@smallexample
(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)
@end smallexample

@noindent
Here the execution has stopped at the breakpoint set above. Now
you can use the standard @code{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.

@node An Example Cross Debugging Session for LynxOS
@section An Example Cross Debugging Session for LynxOS

@noindent
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:

@smallexample
(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)
@end smallexample

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

@smallexample
(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)
@end smallexample

@noindent
And finally letting the program it run to completion:

@smallexample
(gdb) c
Continuing.

Program exited normally.
(gdb)
@end smallexample

@node Issues Linking on LynxOS
@section Issues Linking on LynxOS

@noindent
On PPC Lynx, certain system libraries contain 24 bit PC relative
jump instructions. For very large applications it may be
impossible for the linker resolve some relocations at link time.

@noindent
In this case you will see an error like the following:

@smallexample
  <object file> : relocation truncated to fit: R_PPC_REL24 exit
  collect2: ld returned 1 exit status
@end smallexample

@noindent
One solution to this problem is to reduce the size of your binary.
There are several approaches you can try, for instance:

@itemize
@item
Turn off run time checks. (-gnatp)
@item
Optimize for space rather than time. (-Os)
@item
Disable stack checking (remove option -fstack-check)
@item
Disable inlining. (-fno-inline)
@end itemize

@noindent
If these workarounds are not sufficient to link your application,
please contact AdaCore support at report@@adacore.com for additional
help.

@c =================
@node AAMP Topics
@appendix AAMP Topics
@noindent
This chapter describes topics that are specific to the GNAT-for-AAMP
cross configurations.

@menu
* Getting Started with GNAT for AAMP (GNAAMP)::
* GNAAMP-Specific Switches::
* Clock Support::
* Debugging for GNAAMP::
@end menu

@node Getting Started with GNAT for AAMP (GNAAMP)
@section Getting Started with GNAT for AAMP (GNAAMP)

@noindent
This section is a starting point for using GNAT for AAMP (GNAAMP) to develop
and execute Ada programs for the Rockwell Collins AAMP target environment
from a Windows host environment. We assume that you know how to use GNAT in
a native environment and how to download a linked AAMP executable to the AAMP
target hardware or run it under control of Facade.

First it's important to understand the naming conventions used for the
GNAAMP compiler and tools, which differ from the conventions normally
used for GNAT cross compilers.  The GNAAMP compiler itself has the
name @command{gnaamp} rather than @command{gcc}, as this compiler does
not use the gcc driver and back end, but rather has its own customized
back end. The other tools that come with the GNAAMP cross-compiler are
generally named by substituting @command{gnaamp} for the usual @command{gnat}
tool prefix. For example, the name of the program build tool is
@command{gnaampmake} rather than @command{gnatmake}. Similarly, the GNAAMP
binder is named @command{gnaampbind} and the GNAAMP linker is
@command{gnaamplink}.

To compile code for an AAMP target, the basic compiler command is
@command{gnaamp}, but the easiest way to build the basic @code{Hello World}
program is by running @code{gnaampmake}, which results in output similar
to the following:

@smallexample
$ gnaampmake hello
@i{gnaamp -c hello.adb
assembling hello.asm ...
MACASM  CPN 613-3583-006  8-Oct-2002
Program Size in Words for Counter 1, Code    = 0009 Hex, 9 Decimal.
Program Size in Words for Counter 2, LitData = 0006 Hex, 6 Decimal.
End MACASM.  0 Errors, 0 Warnings, 0 Messages.
gnaampbind -x hello.ali
gnaamplink hello.ali
assembling b~hello.asm ...
MACASM  CPN 613-3583-006  8-Oct-2002
Program Size in Words for Counter 0, VolData = 0001 Hex, 1 Decimal.
Program Size in Words for Counter 1, Code    = 0068 Hex, 104 Decimal.
Program Size in Words for Counter 2, LitData = 0030 Hex, 48 Decimal.
End MACASM.  0 Errors, 0 Warnings, 0 Messages.
clink -noupper -full hello.lec
CAPS Link Editor 2.0  03-Jan-2002  CPN xxx-xxxx-xxx
End Link.  0 Errors, 0 Warnings, 0 Messages.}
@end smallexample

@noindent
The first line is the command entered by the user, and the subsequent lines
are produced by the programs run by @command{gnatmake}. This creates the
executable @command{hello.axe}. Running @command{gnatmake} will not produce
an ftt file, so if that file is needed by your AAMP execution environment
then you must create it yourself (e.g., by creating a file named hello.ftt
that contains a single at-sign character).

Note that the AAMP macro assembler (@command{macasm}) and the AAMP linker
(@command{clink}) are also provided as part of the cross compiler installation,
and are invoked by @command{gnaamp} and @command{gnaamplink} respectively.
The AAMP assembler is called from the compiler with the following command:

@smallexample
macasm -in_mac <path>\lib\gnaamp\aamp5 -noupper -instr -cross hello.asm
@end smallexample

@noindent
where @i{<path>} indicates the GNAAMP installation directory.

The AAMP linker is invoked from @command{gnaamplink} via an intermediate
tool named @command{aalink} using the following command:

@smallexample
clink -noupper -full hello.lec
@end smallexample

@noindent
Another tool worth knowing about is gnaampcmd, which is the GNAAMP-specific
version of the GNAT command driver. This GNAAMP command driver can be used
to invoke other tools by giving it a tool designator as an argument (for
example, MAKE, LINK, PP, etc.). It also supports the use of project files
in conjunction with tools that don't support them directly, such as gnaamppp
(the GNAAMP version of the gnatpp pretty printer).

As an example, the following project file specifies various switches to
pass to certain of the tools, such as gnaampmake and the gnaamp compiler,
as well as defining the mappings of various tools to their corresponding
GNAAMP names. The project file would reside in a file named gnaamp_app.gpr,
with sources located, in this case, in the same directory as the project file.

@smallexample
@c projectfile
project GNAAMP_App is

   for Source_Dirs use (".");
   for Object_Dir use "obj";
   for Main use ("main_program.adb");

   package Builder is
      for Default_Switches ("ada") use ("-g", "-s",
                                 "-aamp_target=aamp5_small");
   end Builder;

   package Compiler is
      for Default_Switches ("ada") use ("-g", "-O1", "-univ");
   end Compiler;

   package IDE is
      for Compiler_Command ("ada") use "gnaampmake";
      for Gnatlist use "gnaampls";
      for Gnat use "gnaampcmd";  -- needed to invoke gnaamppp
   end IDE;

end GNAAMP_App;
@end smallexample

@noindent
This project file can then be specified when invoking gnaampmake to build
the application main_program:

@smallexample
gnaampmake -Pgnaamp_proj
@end smallexample

@noindent
You can use the following command to run gnaamppp with this project:

@smallexample
gnaampcmd -Pgnaamp_proj PP
@end smallexample

@noindent
For more information on how to use GNAT tools and project files, see
@cite{The @value{GNATEDITION} User's Guide}.

@node GNAAMP-Specific Switches
@section GNAAMP-Specific Switches

@noindent
The switches documented for the GNAT compiler and related tools
are generally available for GNAAMP, but note that switches
that are specific to the GCC back end are typically not applicable
to the GNAAMP compiler. The debugging switch @code{-g} and the optimization
switch @code{-O} are supported, but currently only one level of optimization
is available, so it suffices to apply the @code{-O1} switch to enable
optimization for the @command{gnaamp} and @command{gnaampmake} commands
(i.e., @code{-O2} and @code{-O3} have no additional effect beyond
@code{-O1}).

The following AAMP-specific switches are supported:

@table @code
@item -aamp_target=@var{target_name}
This switch allows users to specify an alternative AAMP target library.
The name given as the switch argument is used to determine the name of
the target library subdirectory under the GNAAMP installation's @code{lib}
directory, as well as indicating the name to use for the target's macro
library. For example, specifying @code{-aamp_target=aamp7} on the
@command{gnaampmake} command directs the compilation tools to locate
library sources and objects under the subdirectory @code{\lib\aamp7}
and to use the macro library named @code{aamp7.mlb} in that same
subdirectory.  An alternative means of specifying the target library is
to set the environment variable @code{aamp_target} to the desired target
name.  The use of the @code{-aamp_target} switch takes precedence over
the environment variable. In the absence of a user specification by the
switch or variable, the default for the target name is @code{aamp5}.
In addition to giving the switch on the @command{gnaamp} and
@command{gnaampmake} commands, @code{-aamp_target} is also allowed on
invocations of @command{gnaamplink}. The only way to specify the target
name on a direct invocation of the @command{gnaampbind} command is
to set the @code{aamp_target} environment variable.

@item -macasm=@var{"arguments"}
This switch supports passing customized arguments through to the AAMP macro
assembler. All arguments to macasm are enclosed in double quotes. For example,
to pass the @code{-timer} argument to macasm: @code{-macasm="-timer"}.
Note that the macasm switch @code{-in_mac} can be passed explicitly using
@code{-macasm} to override the default value specified for that switch
by the compiler.

@item -O
This switch enables the peephole optimization phase in the GNAAMP
back end. The compiler supports passing the optimization switch with
an indicated level (-O1, -O2, or -O3), but all three of these levels
are currently equivalent to passing -O.

@item -univ
This switch enables generation of universal instructions for addressing
global data objects. Application of the switch on the compilation command
is equivalent to giving the pragma @code{Universal_Data} on any compiled
units (see the @cite{@value{GNATEDITION} Reference Manual}).
@end table

@node Clock Support
@section Clock Support

@noindent
The GNAAMP implementation does not provide direct support for a
real-time clock. Instead, there is a default dummy version of the
function _APP_GET_TIME, exported by the AAMP run-time library, that
is used for programs that make use of Ada.Calendar. The dummy
implementation is not a real clock function and simply increments
an internal Duration variable by 1/100th of a second each time it
is called. There is also a procedure exported as _APP_SET_TIME that
allows setting the initial time value. Both of these routines are
declared as part of the Mini_RTE package that is linked with all
programs (see the "rts" subdirectory in your installation directory).
The body of the subunit Mini_RTE.Clock must be customized for an
application to provide a different implementation of these routines.

@node Debugging for GNAAMP
@section Debugging for GNAAMP

@noindent
It is assumed that the user is familiar with the Facade debugging environment
available on Windows for debugging AAMP programs. When compiling Ada programs
to be debugged on GNAAMP, we recommend using the @code{-g} switch, which
enables the generation of debugging information for each unit compiled with
the switch. The @code{-g} switch causes the GNAAMP compiler to include source
line information in object files and to generate a Debugger Symbol Table
file (@file{.dst} file) containing high-level symbol information for
the compiled unit.
See the @cite{Facade User's Guide} published by Rockwell Collins, Inc.,
for further information on debugging.



@c   ***************************
@c   * PowerPC 55xx ELF Topics *
@c   ***************************


@node PowerPC 55xx ELF Topics
@appendix PowerPC 55xx ELF Topics

@noindent
This Appendix describes topics that are specific to the @value{GNATEDITION} for
PowerPC 55xx ELF cross configurations.


@menu
* PowerPC 55xx ELF Topics Introduction::
* PowerPC 55xx ELF Topics Floating Point::
* PowerPC 55xx ELF Topics EABI::
* PowerPC 55xx ELF Topics Debugging::
@end menu

@node PowerPC 55xx ELF Topics Introduction
@section Introduction

@noindent
The PowerPC 55xx ELF toolset targets Book E variants of the PowerPC
architecture.  It was originally developed for the freescale
e200 core used in the 5554 microcontroller.

The prefix generally used for target-specific executables in the PowerPC
55xx ELF toolset is @emph{powerpc-eabispe}.  E.g., the compiler is
@command{powerpc-eabispe-gcc} and the binder is
@command{powerpc-eabispe-gnatbind}.
The one exception is the the debugger, which is shared with
the powerpc-elf toolset and is invoked via the @command{powerpc-elf-gdb}
comand.

The powerpc-elf toolset (which targets 603-like processors) is
used for the discussion in @ref{Bareboard and Custom Kernel Topics},
and understanding the contents of that
section is presumed in this Appendix, which focuses on a few 55xx-specific
topics.

@node PowerPC 55xx ELF Topics Floating Point
@section Floating Point

The processors targeted by @value{GNATEDITION} for the PowerPC 55xx ELF
incorporate an
``Embedded Scalar FPU'' that performs single precision floating-point
operations on values in the general purpose registers. Relative
to the 603, there are different instructions (@code{esfxxxx}), and there
are no floating-point registers nor any of the 603 floating-point
instructions.  The version of the @code{libgcc} library provided with
this toolset implements
double-precision operations in software. The compiler will generate
scalar FPU instructions when appropriate and calls to the double-precision
routines when needed. Developers may want to use
the scalar FPU support for efficiency, and/or avoid the library
routines for certification. For objects and values of
single-precision types, the hardware instructions will be used. However,
some operations that are not simple floating-point operations may require
usage of double-precision values, and therefore generate calls to
to support routines in @code{libgcc}.
For example, Ada semantics for rounding may
force floating-point to integer conversions to use double precision.

For the developer who wants to eliminate or minimize the use
of double precision, the issues are how to detect and how to
work around such usage.  If it is acceptable to eliminate
support from @code{libgcc} entirely, then excluding it from the final
linking step (e.g., using @option{-nostdlib} if linking with @command{gcc},
or simply not naming it if using @command{ld} directly), will
result in error messages and failure to create an executable if
any compiler-generated usage of double precision has occurred.
Then, to identify the source code involved, you can use @command{objdump}
to inspect the object file that @command{ld} flagged as containing the
unresolved reference.
Invoke @command{objdump} (preceded by the prefix) using the
@option{--disassemble} and @option{--source} switches.
(Note: this requires that the code be compiled with debugging enabled.)
The @code{objdump} command will produce a mixed source/assembly listing that
can be searched for the undefined symbol named by @command{ld}.

If some minimal usage is acceptable, then various procedures
are available to find new occurences of double precision, such as
occasionally linking without @code{libgcc} to look for new references,
or inspecting object files with @command{nm}.

Eliminating a call to a
double-precision routine depends upon the particular case and can
involve modifying the source to use different constructs, adding
qualifications or conversions, or providing machine-code insertions.

Notes:
@itemize @bullet
@item
In order for @command{powerpc-eabispe-objdump} to disassemble the scalar
floating-point instructions, the @option{-M e500} option is required.

@item
For CGNAT users: the @option{-fsingle-precision-constant} option to
@command{gcc} will prevent floating-point constants from being
implicitly converted to double precision.
@end itemize

@node PowerPC 55xx ELF Topics EABI
@section EABI

@noindent
The compiler is configured to conform with the EABI by default.
However, we recommend avoiding the small data sections, both for simplicity
and because (as of @value{NOW}) they have not been as thoroughly
exercised by user code as other product features.
By default, gcc
will place some data into @code{.sbss}, @code{.sbss2}, @code{.sdata}
and @code{.sdata2}, and
GPRs 2 and 13 will only be used for relative addressing as
specified by the ABI and the EABI. Also, the compiler
generates a call to @code{__eabi} before main, where the
initialization of 2 and 13 can be made, and @code{libgcc} provides
such a routine. By compiling with @option{-mno-sdata}, no objects will
be placed in any of the @code{.s@i{XXX}} sections and no use will be made
of R2 and R13.  This simplifies the construction of a linker
script and allows the replacement of @code{__eabi} with these lines
in the startup code:

@smallexample
  .global __eabi
__eabi:
 blr
@end smallexample

@noindent
The provision of this dummy @code{__eabi} allows complete
independence from @code{libgcc} for many programs.

@node PowerPC 55xx ELF Topics Debugging
@section Debugging

For bareboard 5554 targets, you can use debugging
hardware that connects to the JTAG or Nexus port of the 5554 and
communicates with @value{GNATEDITION}'s debugger by providing a
@code{gdbserver} interface.
Similar set@-ups exist for many bareboard targets.


@c   **************
@c   * AVR Topics *
@c   **************


@node AVR Topics
@appendix AVR Topics

@noindent
This Appendix describes topics that are specific to the @value{GNATEDITION} for
AVR cross configurations.

@menu
* AVR Topics Introduction::
* AVR Topics Compiler Flags::
* AVR Topics Programming The Chip::
* AVR Topics Registers Description::
* AVR Topics Writing Interrupt Handlers::
* AVR Topics Using Gdb Simulator::
* AVR Topics Using Gdb With Atmel mkII Probe::
@end menu

@node AVR Topics Introduction
@section Introduction to @value{GNATEDITION} for AVR

@noindent
The AVR toolset targets AVR 8-Bit RISC microcontrollers from Atmel.  AVR
microcontrollers have limited resources: 32 8-bit wide registers,
separate instructions and data memory, at most 256KB of flash for the
instructions, and at most 8KB of internal SRAM for the data.

There is a large number of microcontrollers, and although they have the
same instructions set core, they vary in capabilities.
Some low-end models can be programmed
only in assembly, while at the higher end one finds dedicated instructions to
handle a larger amount of memory.

@value{GNATEDITION} has been tested only with the atmega2560, with
less support for the other microcontrollers.

@node AVR Topics Compiler Flags
@section Compiler and Linker Flags for AVR

@noindent
The compiler must know which microcontroller is targeted, because code
generation is affected.  Use option @option{-mmcu=ARCH} where @samp{ARCH}
is the AVR architecture defined as follow:

@itemize @bullet

@item
For @samp{atmega2560} and @samp{atmega2561} use @option{-mmcu=avr6}.

@item
For enhanced cores with 128KB of flash (@samp{atmega128x} and
@samp{at90usb128x}) use @option{-mmcu=avr51}.

@item
For enhanced cores whose flash size is between 8KB and 64KB use
@option{-mmcu=avr5}.

@item
For enhanced cores with less than 8KB of flash use @option{-mmcu=avr4}.
@end itemize

@noindent
Do not try to link object files compiled for different targets, since the
code generated is not compatible.

The target should also be passed to the linker using the @option{-mARCH}
option, since the linker may perform some optimizations or relocations on
certain devices.

The general-purpose registers and the IO registers are mapped to data
memory.  As the number of IO registers is microcontroller specific, you
must also set the start of the data.  Use linker option
@option{-Tdata=0x00800NNN} where @samp{NNN} is the size of the IO
registers in hexadecimal.

For example you can use this command to build program @samp{app}:

@smallexample
  avr-gnatmake app -O -mmcu=avr6 -largs crt1.o -nostdlib -lgcc \
     -Wl,-mavr6,-Tdata=0x00800200
@end smallexample

The option @option{-O} enables optimizations that may help
reduce the code size.

The file @file{crt1.o} is the startup code.  It contains the reset
vector and interrupts table as well as initialization code to be
executed before running compiled code.  A sample startup
code file is provided with the compiler installation.

The option @option{-nostdlib} prevents linking with standard
libraries (such as the C library) which are not provided by
@value{GNATEDITION}, while @option{-lgcc} enables linking with the
compiler support library.  For some complex operations (such as 32-bit
division) the compiler inserts calls to functions defined in this
library.

@node AVR Topics Programming The Chip
@section Programming the AVR Chip

@noindent
Use Atmel tools to programm the chips.  The recommanded method is to
start from an @samp{ihex} file which contains the image of the flash coded
in hexadecimal.  To convert from the output of the linker to the
@samp{ihex} format, use @samp{avr-objcopy}:

@smallexample
  avr-objcopy -O ihex app app.ihex
@end smallexample

@node AVR Topics Registers Description
@section AVR Registers Decription

@noindent
The file @file{atmega2560.ads}, which is included with the AVR-specific
examples,
contains a package with a declaration for each IO register. With this package,
you can directly access the IO registers without needing to
declare them.  Only the version for the @samp{ATmega2560} is provided.


@node AVR Topics Writing Interrupt Handlers
@section Writing Interrupt Handlers

@noindent
It is possible to write an interrupt handler completely in Ada (i.e., with
no assembly code).  You have to add the @samp{signal} machine attribute
to your procedure so that it automatically saves and restores all registers
used, and you also have to add a @code{pragma Export} to attach your procedure
to the correct vector.  The vector depends on the AVR target and is defined
at the beginning of the @file{crt} startup file.

In the following example the procedure @samp{ADC_Interrupt} will be called
when an ADC interrupt is triggered:

@smallexample @c ada
@group
   procedure ADC_Interrupt;
   pragma Machine_Attribute (ADC_Interrupt, "signal");
   pragma Export (C, ADC_Interrupt, "__vector_adc");

   procedure ADC_Interrupt is
   begin
      --  ...
      --  Read current ADC value
      Data := ADC_Data;
      --  ...
   end ADC_Interrupt;
@end group
@end smallexample

@node AVR Topics Using Gdb Simulator
@section Using the gdb Simulator

@noindent
The easiest way to compile your program for the @command{gdb} simulator is
to include the @file{zfp_support.gpr} project like this:

@smallexample @c projectfile
with "zfp_support.gpr";

project hello is
   for Source_Dirs use (".");
   for Main use ("hello.adb");
   package Compiler is
      for Default_Switches ("Ada") use ("-mmcu=avr6", "-g");
   end Compiler;
end hello;
@end smallexample

@noindent
The @file{zfp_support.gpr} project provides a small support library with a very
simplified version of @code{Ada.Text_IO} and an appropriate link command.  To
compile a program, use the following command:

@smallexample
  avr-gnatmake -P hello -XVARIANT=avr-avrtest
@end smallexample

@noindent
Once the binary is created, you can run it within @command{gdb}:

@smallexample
$  gdb hello

(gdb) target sim
(gdb) load
(gdb) run
@end smallexample

@node AVR Topics Using Gdb With Atmel mkII Probe
@section Using Gdb With Atmel mkII Probe

@noindent
The @command{gdb} debugger is able to use the Atmel JTAGICE mkII probe. Be sure
to follow Atmel recommendations while using the probe (in particular, do not
power-up a connected probe if the AVR micro-controller is not powered). Also
do not forget to correctly program the fuse (be sure OCD and JTAG are
enabled).

@noindent
Contrary to the simulator, you can debug a real AVR micro-controller. But due
to limitations in the AVR, you can only use 3 breakpoints. Note that for
some operations (such as the @command{next} command), @command{gdb} uses
temporary breakpoints. Also only connection through JTAG is supported.

@noindent
To use the probe, you simply have to select the @samp{atmel-mkii} target:

@smallexample
$ gdb myprog

(gdb) target atmel-mkii
(gdb) load
(gdb) run
@end smallexample

@noindent
As shown above, @command{gdb} is able to erase and program the AVR with
the @command{load} command.

@c   ***********************
@c   * LEON / ERC32 Topics *
@c   ***********************
@node LEON / ERC32 Topics
@appendix LEON / ERC32 Topics
@noindent
This chapter describes topics that are specific to the @value{GNATEDITION} for
LEON / ERC32 cross configurations.

@menu
* Getting Started with GNAT Pro for LEON / ERC32::
* Executing and Debugging on Simulators::
* Executing and Debugging on Hardware Platforms::
* Adapting the Run-Time System::
* Run-Time Restrictions::
* Console Output::
* Stack Overflow Checking::
* Interrupt Handling::
* Non-Symbolic Traceback::
@end menu

@node Getting Started with GNAT Pro for LEON / ERC32
@section Getting Started with @value{GNATEDITION} for LEON / ERC32

@noindent
This section describes topics that are relevant to @value{GNATEDITION} for
LEON / ERC32, a cross-development system supporting the Ravenscar
tasking model on top of bare LEON / ERC32 computers.

ERC32 is a highly integrated, high-performance 32-bit RISC embedded
processor implementing the SPARC architecture V7 specification. LEON
is a 32-bit synthesisable processor core based on the SPARC V8
architecture. They have been developed with the support of the
European Space Agency (ESA) as the current standard processors for
spacecraft on-board computer systems.

The Ravenscar profile defines a subset of the tasking features of Ada
which is amenable to static analysis for high integrity system
certification, and that can be supported by a small, reliable run-time
system. This profile is founded on state-of-the-art, deterministic
concurrency constructs that define a model which has the required
expressing power for constructing most types of real-time software.

The tasking model defined by the profile includes a fixed set of
library level tasks and protected types and objects, a maximum of one
protected entry with a simple boolean barrier for synchronization, a
real-time clock, absolute delays, deterministic fixed-priority
preemptive scheduling with ceiling locking access to protected
objects, and protected procedure interrupt handlers, as well as some
other features. Other features, such as dynamic tasks and protected
objects, task entries, dynamic priorities, select statements,
asynchronous transfer of control, relative delays, or calendar clock,
are forbidden.

Using the cross-compilation system is very similar to its use in a
native environment. The major difference is that the name of the cross
tools are prefixed by the target name: @code{leon-elf-} / @code{erc32-elf-}.
@smallexample
$ leon-elf-gnatmake main
@end smallexample

@noindent
The result of this compilation is an ELF-32 SPARC executable. The tool chain
has been tested to work on the following environments:

@itemize @bullet

@item
A stand alone ERC32 (@cite{TSC695F Rad-Hard 32-bit Embedded Processor})
computer based board.

@item
A stand alone LEON2-FT (@cite{AT697E Rad-Hard 32-bit SPARC V8 Processor})
computer based board.

@item
A SIS ERC32 simulator (@cite{SPARC Instruction Set Simulator}) running on
the development workstation.

@item
TSIM ERC32 (@cite{TSIM Simulator User's Manual}) running on the development
  workstation.

@item
TSIM LEON (@cite{TSIM Simulator User's Manual}) running on the development
  workstation.

@end itemize

@noindent
The embedded multiplier/divider block in LEON2 AT697E can generate wrong
values when negative operands are used. The @code{-mcpu=v7} compiler switch
must be used to avoid the generation of these potentially problematic
instructions.

A specific Board Support Package (BSP) is available for the Syderal
ICM board using the @code{-micm} linker switch:

@smallexample
$ leon-elf-gnatmake -mcpu=v7 main -largs -micm
@end smallexample

@noindent
It is expected that other LEON / ERC32 boards or simulators could also be
used with minor adaptations without problems.

@node Executing and Debugging on Simulators
@section Executing and Debugging on Simulators

@noindent
The program generated by the compilation toolchain can be executed using an
LEON / ERC32 simulator on the development platform.
@smallexample
$ leon-elf-gnatmake main
$ tsim -freq 50 main
@end smallexample

@noindent
Typing @code{go} from the command prompt starts program execution.

There is another simulator for ERC32, called SIS, which supports the Motorola
S-Record and not the ELF-32 SPARC executable format. Therefore, it requires an
additional step to change the format of the executable.
@smallexample
$ erc32-elf-objcopy -O srec main main.srec
$ sis -freq 20 main.srec
@end smallexample

@noindent
Remote debugging using the simulators is also possible. A remote debugger stub
is needed on the simulator in order to interact with @code{GDB}; this remote
monitor can be either the one embedded into the simulator or the one provided
with the @value{GNATEDITION} development environment
(@code{leon-stub} / @code{leon-stub-prom.srec},
@code{leon2-icm-stub} / @code{leon2-icm-stub-prom.srec},
@code{erc32-stub} / @code{erc32-stub-prom.srec}).

The TSIM simulator embeds a remote protocol for communicating with the debugger
through an IP port (1234 by default) which is activated when using the
@code{-gdb} switch or the @code{gdb} command.
@smallexample
$ tsim -freq 20 -gdb
   ...
gdb interface: using port 1234
@end smallexample

@noindent
The debugger can be launched directly from the command line or from
@code{GPS}. Before loading the program to debug, @code{GDB} must connect
to the simulator using the remote protocol and the required IP port.
@smallexample
$ leon-elf-gdb main
(gdb) target remote localhost:1234
   ...
(gdb) load
   ...
(gdb) continue
   ...
(gdb) detach
   ...
@end smallexample

@noindent
It is also possible to use any LEON / ERC32 simulator to load and execute
the remote debugging stub so that the debugger can be later attached. The
following example launches the remote monitor and connects the UART 2 port
to the pseudo-device @code{/dev/ptypa}:
@smallexample
$ tsim -freq 50 -uart2 /dev/ptypa leon-stub
serial port A on stdin/stdout
serial port B on /dev/ptypa
allocated 4096 K RAM memory, in 1 bank(s)
allocated 2048 K ROM memory
icache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total)
dcache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total)
section: .text, addr: 0x403f8000, size 11320 bytes
section: .data, addr: 0x403fac38, size 32 bytes
tsim> go
   ...
@end smallexample

@noindent
We can then connect @code{GDB} to the remote stub through the
pseudo-device @code{/dev/ttypa} using the remote protocol:
@smallexample
$ leon-elf-gdb main
(gdb) target remote /dev/ttypa
   ...
(gdb) load
   ...
(gdb) continue
   ...
(gdb) detach
   ...
@end smallexample

@node Executing and Debugging on Hardware Platforms
@section Executing and Debugging on Hardware Platforms

@noindent
The compiler generates ELF executables that can be converted into
S-record files using the @command{objcopy} command (details are in the
binutils documentation). :

@smallexample
$ leon-elf-objcopy -O srec main main.srec
$ grmon
grlib> load main.srec
grlib> run
@end smallexample

@noindent
Applications are linked to run from beginning of RAM, at address
@code{0x40000000} for LEON (@code{0x2000000} for ERC32). A boot-PROM can be
created containing the application to be executed on a standalone target by
using the @code{leon-elf-mkprom} / @code{erc32-elf-mkprom} utility. It will
create a boot image that will initialize the board and memory, load the
application into the beginning of RAM, and it will finally start the
application. This utility will set all target dependent parameters, such as
memory size, number of memory banks, waitstates, baudrate, and system clock.
Applications do not set these parameters themselves, and thus do not need to
be relinked for different board architectures.

The example below creates a boot-PROM for a system with 4 Mbyte RAM, 128 Kbyte
ROM, a 50 MHz system clock, and UARTs programmed for 115200 baud rate. A file
called @code{main.srec} is created, whose format is Motorola S-record, which is
usually accepted by PROM recorders. It is possible to use an LEON / ERC32
simulator (SIS or TSIM) to load and test the resulting file.
@smallexample
$ leon-elf-mkprom -ramsize 4096 -romsize 128 -freq 50 -baud 115200 \
     main -o main.srec
@end smallexample

@noindent
Debugging software on the LEON / ERC32 board with @code{GDB} is
possible by either using the provided @code{GDB stub} or using the
remote target capability provided by @code{GRMON}.

A @code{GDB stub} is an embedded executable that provides the
debugging API required by @code{GDB}, implementing the @code{GDB
remote protocol} across a serial line.

The provided @code{GDB stubs} can be found at
@file{<install-dir>/(erc32|leon)-elf/lib}. There are versions that can
be loaded in memory and executed (@code{leon-stub} /
@code{leon2-icm-stub} / @code{erc32-stub}), and others that can be
copied into the boot-PROM (@code{leon-stub-prom.srec} /
@code{leon2-icm-stub-prom.srec} / @code{erc32-stub-prom.srec}). At
startup, this monitor installs itself into the upper 32K of RAM, and
waits for @code{GDB} to be attached.

Remote target debugging requires a serial link between UART 2 (debugging link)
on the remote target and a serial device on the host station. If the program
produces some output to the console, another serial link connection is required
from UART 1 (console on the target) to a terminal emulator on the host to
display it.

The monitor supports break-in into a running program by pressing @code{Ctrl-C}
in @code{GDB}, or interrupt in @code{GPS}. The two timers are stopped during
monitor operation in order to preserve the notion of time for the application.

@smallexample
$ leon-elf-gdb main
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
   ...
(gdb) load
   ...
(gdb) continue
   ...
(gdb) detach
   ...
@end smallexample

@noindent
@code{GRMON} can act as a remote target for @code{GDB} allowing for
symbolic debugging of target applications. This functionality is
activated by launching the monitor with the @code{-gdb} switch or
using the @code{GRMON} @code{gdb} command:

@smallexample
$ grmon -gdb
@end smallexample

@noindent
By default, @code{GRMON} listens on port 2222 for @code{GDB}
connections:

@smallexample
$ leon-elf-gdb main
(gdb) set remotebaud 115200
(gdb) target remote :2222
   ...
(gdb) load
   ...
(gdb) continue
   ...
(gdb) detach
   ...
@end smallexample

@node Adapting the Run-Time System
@section Adapting the Run-Time System

There may be some variations among the different boards, and therefore
some mechanisms have been added to support adapting parameters easily
without modifying the Ada run time.

The linker scripts, such as @file{(erc32|leon|leon2_icm).ld} that
can be found at @file{<install-dir>/(erc32|leon)-elf/lib},
define some basic board parameters, such as memory size and clock
frequency. If these parameters need to be adapted, a local copy of
this script can be created, and the following characteristics can be
modified:

@itemize

@item Clock frequency. The clock frequency (in Hz) can be set
modifying the value of the @code{_CLOCK_SPEED} variable to the desired
value.

@item Memory size. The @code{_RAM_SIZE} variable defines the size of
the RAM memory installed in the board. There is also the memory map
that needs to be tailored:

@smallexample
MEMORY
@{
  ram (rwx) : ORIGIN = 0x40000000, LENGTH = New_Length
@}
@end smallexample

@item Stack size for the environment task. The stack area allocated to
the environment task is defined by the variable @code{_STACK_SIZE}.

@end itemize

@noindent
The local copy of the linker script can be selected from the command
line using:

@smallexample
$ leon-elf-gnatmake main -largs -T my_script.ld
@end smallexample

@node Run-Time Restrictions
@section Run-Time Restrictions

@noindent
The run time supports the tasking model defined by the Ravenscar profile;
it has been specifically designed to take full advantage of this profile,
that allows for a streamlined implementation of the Ada run-time library
directly on top of bare LEON / ERC32 computer.

There are some other additional restrictions due to the bare board constraints,
such as the removal of file system support, and complex text input-output. The
exception handling mechanism that is implemented supports the full semantics of
Ada@w{ }83 exceptions; Ada@w{ }95 enhancements are not included, but it
supports propagation of exceptions and handlers for multiple tasks. It
supports also limited Ada@w{ }95 exception occurrences, and
@code{Ada.Exceptions.Exception_Name}. Mapping of the usual traps for hardware
exceptions (division by zero, data access error, etc.) to Ada exceptions is
also done.

In terms of Annexes supported, the status is the following:

@itemize
@item Annex A (@emph{Predefined Language Environment}) is partially
  supported. Those functionalities related to file systems (A.7, A.8,
  A.14), complex text input-output (A.10, A.11, A.12), and command
  line access (A.15) are excluded.
@item Annex B (@emph{Interface to Other Languages}) is fully supported.
@item Annex C (@emph{System Programming}) is fully supported.
@item Annex D (@emph{Real-Time Systems}) is fully supported, excluding
  those features that are forbidden by the Ravenscar profile (D.4,
  D.5, D.11).
@item Annex E (@emph{Distributed Systems}) is fully excluded.
@item Annex F (@emph{Information Systems}) is partially
  supported. Those features related to text input-output (F.3.3,
  F.3.4) are excluded.
@item Annex G (@emph{Numerics}) is fully supported.
@item Annex H (@emph{Safety and Security}) is fully supported.
@item Annex J (@emph{Obsolescent Features}) is partially
  supported. Those functionalities related to text input-output,
  @code{Ada.Calendar}, and interrupt entries (J.7.1) are excluded.
@end itemize

@node Console Output
@section Console Output

@noindent
The UART 1 port is used as the target console. When using the target hardware,
a serial link connection is required from this UART 1 to a terminal emulator
on the host (such as @code{tip}, @code{minicom}, @code{HyperTerminal},
etc.) to display it.

Package @code{System.IO} can be used for displaying @code{Character},
@code{Integer}, and @code{String}.

@smallexample @c ada
   with System.IO;

   procedure Main is
   begin
      System.IO.Put_Line ("Hello world");
   end Main;
@end smallexample

@node Stack Overflow Checking
@section Stack Overflow Checking

@noindent
GNAT does not perform stack overflow checking by default. This means that if
the main environment task or some other task exceeds the available stack space,
then unpredictable behavior will occur.

To activate stack checking, compile all units with the gcc option
@option{-fstack-check}. For example:

@smallexample
$ leon-elf-gcc -c -fstack-check package1.adb
@end smallexample

@noindent
Units compiled with this option will generate extra instructions to check
that any use of the stack (for procedure calls or for declaring local
variables in declare blocks) do not exceed the available stack space.
If the space is exceeded, then a @code{Storage_Error} exception is raised.

For declared tasks, the stack size is always controlled by the size
given in an applicable @code{Storage_Size} pragma (or is set to
the default size if no pragma is used). For the environment task,
the stack size is defined by the linker script, and can be modified as
described in @ref{Adapting the Run-Time System}.

@node Interrupt Handling
@section Interrupt Handling

@noindent
The Ravenscar profile allows only the use of protected procedures as interrupt
handlers (as defined in Annex@w{ }D of the @cite{Ada Reference Manual}).
Interrupt handlers are declared as parameterless protected procedures,
attached to an interrupt source. All LEON / ERC32 interrupt sources are
identified in package @code{Ada.Interrupts.Names} (including both name and
priority associated). pragma @code{Attach_Handler} provides static attachment,
and @code{Interrupt_Priority} establishes the priority of the handler.
@cindex @code{Interrupt_Priority} pragma
@cindex @code{Attach_Handler} pragma

@smallexample @c ada
   protected Interrupt_Semaphore is
      pragma Interrupt_Priority
        (Ada.Interrupts.Names.External_Interrupt_2_Priority);

      entry Wait;

      procedure Signal;
      pragma Attach_Handler
        (Signal, Ada.Interrupts.Names.External_Interrupt_2);

   private
      Signaled : Boolean := False;
   end Interrupt_Semaphore;
@end smallexample

@noindent
The interrupt handler is executed on its own stack, at the priority given by
the @code{Interrupt_Priority} pragma.
@cindex @code{Interrupt_Priority} pragma

In order to reduce interrupt latency, the floating-point context is not
automatically saved and restored when executing interrupt handlers.
Floating-point computations are usually performed outside the protected
handler, although if the handler is to execute floating-point instructions,
the statements involved must save and restore the floating-point registers
being used, in addition to enabling and disabling the floating-point unit.

An example of an interrupt handler that computes a square root using
floating-point instructions is the following:

@smallexample @c ada
   with System.Machine_Code; use System.Machine_Code;

   procedure Handler is

      type Register_32 is mod 2 ** 32;
      for Register_32'Size use  32;

      PSR : Register_32;
      --  Processor State Register

      FSR : Register_32;
      --  Floating-point State Register

      F0  : Register_32;
      --  Floating-point register

      Operand : Float := 10.0;
      Result  : Float;

   begin
      --  First we enable the floating point unit, by means of setting
      --  the PSR's Enable FPU bit.

      Asm ("rd %%psr, %%l0" & ASCII.LF & ASCII.HT &
           "st %%l0, %0",
           Outputs => Register_32'Asm_Output ("=m", PSR),
           Clobber => "l0");

      PSR := PSR or 16#00001000#;

      Asm ("ld %0, %%l0" & ASCII.LF & ASCII.HT &
           "wr %%l0, %%psr",
           Inputs => Register_32'Asm_Input ("m", PSR),
           Clobber => "l0");

      --  Save the floating point registers that will be used (the
      --  Floating-point State Register and one of the Floating-point
      --  registers).

      Asm ("st %%fsr, %0",
           Outputs => Register_32'Asm_Output ("=m", FSR));

      Asm ("st %%f0, %0",
           Outputs => Register_32'Asm_Output ("=m", F0));

      --  User code (compute the square root)

      Asm ("ld %1, %%f0"       & ASCII.LF & ASCII.HT &
           "fsqrts %%f0, %%f0" & ASCII.LF & ASCII.HT &
           "st %%f0, %0",
           Inputs  => Float'Asm_Input  ("m", Operand),
           Outputs => Float'Asm_Output ("=m", Result),
           Clobber => "f0");

      --  Restore the floating-point registers previously saved

      Asm ("ld %0, %%fsr",
           Inputs => Register_32'Asm_Input ("m", FSR));

      Asm ("ld %0, %%f0",
           Inputs => Register_32'Asm_Input ("m", F0));

      --  Disable floating point operations (clearing
      --  the PSR's Enable FPU bit).

      PSR := PSR and not 16#00001000#;

      Asm ("ld %0, %%l0" & ASCII.LF & ASCII.HT &
           "wr %%l0, %%psr",
           Inputs => Register_32'Asm_Input ("m", PSR),
           Clobber => "l0");

   end Handler;

@end smallexample

@node Non-Symbolic Traceback
@section Non-Symbolic Traceback

@noindent
A non-symbolic traceback is a list of addresses of call
instructions. To enable this feature you must use the @option{-E}
@code{gnatbind}'s option. With this option a stack traceback is stored
as part of the exception occurrence.

Here is a simple example:

@smallexample @c ada
with System.IO;
with Ada.Exceptions.Traceback;
with GNAT.Debug_Utilities;

procedure STB is

   procedure P1 is
      K : Positive := 1;
   begin
      K := K - 1;
   exception
      when E : others =>
         declare
            Buffer : constant Ada.Exceptions.Traceback.Tracebacks_Array :=
              Ada.Exceptions.Traceback.Tracebacks (E);
         begin
            System.IO.Put_Line ("Call stack traceback locations:");

            for J in Buffer'Range loop
               System.IO.Put (GNAT.Debug_Utilities.Image_C (Buffer (J)));
               System.IO.Put (" ");
            end loop;
         end;
   end P1;

   procedure P2 is
   begin
      P1;
   end P2;

begin
   P2;
end STB;
@end smallexample

@smallexample
$ leon-elf-gnatmake stb -bargs -E
$ tsim -freq 50 stb
   ...
tsim> go
resuming at 0x40000000
Call stack traceback locations:
0x40015EDC 0x40015910 0x400158F8 0x400014B8 0x4000118
@end smallexample

@noindent
The location of these call instructions can be inspected with standard
binary oriented tools, such as @code{nm} or
@code{objdump}, or with the @code{addr2line} tool,
that converts addresses into file names and line numbers. It is also
possible to use @code{GDB} with these traceback addresses to debug the
program. For example, we can break at a given code location, as reported
in the stack traceback.

@smallexample
$ leon-elf-addr2line -e stb 0x40015EDC 0x40015910 0x400158F8 \
     0x400014B8 0x4000118

0x40015edc at stb.adb:10
0x40015910 at stb.adb:28
0x400158f8 at stb.adb:32
0x400014b8 at b~stb.adb:116
0x4000118 in ?? at ??:0

$ leon-elf-gdb stb
(gdb) break *0x40015edc
Breakpoint 1 at 0x40015edc: file stb.adb, line 10.
@end smallexample

@noindent
It is important to note that the stack traceback addresses
do not change when debug information is included. This is particularly useful
because it makes it possible to release software without debug information (to
minimize object size), get a field report that includes a stack traceback
whenever an internal bug occurs, and then be able to retrieve the sequence
of calls with the same program compiled with debug information.

By default, unhandled exceptions display the stack traceback
information stored within the exception occurrence.

@c   *****************
@c   * ELinOS Topics *
@c   *****************
@node ELinOS Topics
@appendix ELinOS Topics
@noindent
This chapter describes topics that are specific to the @value{GNATEDITION} for
ELinOS, a cross-development Linux system supporting the Xenomai run-time
kernel extensions.

@menu
* GNAT Pro for ELinOS Installation::
* Kernel Configuration for ELinOS::
* Building a ELinOS Application::
* Debugging an Application on ELinOS::
@end menu

@node GNAT Pro for ELinOS Installation
@section GNAT Pro for ELinOS Installation

@noindent
@value{GNATEDITION} for ELinOS has several installation dependencies
that you need to understand in order to build a user-friendly set@-up.

The package contains in particular the following ELinOS-specific
components:

@itemize @bullet
@item
@i{an Ada run-time library for ELinOS native (non-real-time) applications:}
for this component, no additional information is required at installation
time;

@item
@i{an Ada run-time library for Xenomai (real-time) applications:} this
component needs to have access to the Xenomai libraries; these should have been
built as a part of your ELinOS kernel project;

@item
@i{an Ada-aware cross debugger:} to work properly, this components
needs to have access to both the Xenomai shared libraries and the
non-real-time shared libraries; the former can be found in the ELinOS
kernel project; the latter are installed with the ELinOS tools.

@end itemize

The different library location can be fed to these components at run
time; the following section will give more details about
that. However, the simplest solution is probably to give this
information at install time and let them be initialized once and for
all.

To do so, you will first need to set up a ElinOS project and build a
kernel with Xenomai enabled. The section
@ref{Kernel Configuration for ELinOS}
should help you to take care of this part.

You can then run the GNAT Pro's installation program. You will be
asked to provide the path to the kernel project; the install program
will use this information to generate the appropriate defaults.


@node Kernel Configuration for ELinOS
@section Kernel Configuration for ELinOS

@noindent

ELinOS comes with several tools to configure and build a linux kernel
with the Xenomai real-time extension. For an extensive description of
these tools, refers to the @cite{ELinOS User's Guide}. Here are a few
indications to help you configure your kernel in order to take full
advantage of GNAT Pro for ELinOS:

@itemize @bullet

@item
@i{at project configuration}: First make sure that the kernel version
that you are selecting is supported by @value{GNATEDITION} for ELinOS.
It is also advised, to be able to debug tasking applications on
target, to have unstripped system libraries. To do so, you will have
to switch off the checkbox @code{Tools}@result{}@code{Configure
mkefs}@result{}@code{Strip symbol and debugging information}.


@item
@i{at feature configuration}:
You should include the gdb server.  It can be found in
@code{Debugging}@result{}@code{GDB server for remote debugging}.
In this phase, you should also add Xenomai support by checking
@code{Realtime support (Xenomai)}@result{}@code{Enable Xenomai}.

@end itemize


@node Building a ELinOS Application
@section  Building a ELinOS Application

@noindent
This section is starting point for building an Ada application targetting
an ELinOS system.

Using GNAT Pro for ELinOS, two types of application can be built:

@itemize @bullet
@item
so-called native applications; that is to say, applications that have no
real-time constraints and can run on a regular linux kernel;

@item
real-time applications; i.e. applications that have real-time constraints
and have to take advantage of the Xenomai interface.

@end itemize

GNAT Pro is configured to build native applications by default; As an
example, to build the basic @code{Hello world} example on x86-elinos,
one can invoke @command{gnatmake} with the default run-time options:

@smallexample
$ i686-elinos-linux-gnatmake hello
@i{i686-elinos-linux-gcc -c hello.adb
i686-elinos-linux-gnatbind -x hello.ali
i686-elinos-linux-gnatlink hello.ali}
@end smallexample

@noindent
As for real-time applications, they can be built by adding @code{--RTS=xenomai}
to the builder options:

@smallexample
$ i686-elinos-linux-gnatmake --RTS=xenomai hello
@i{i686-elinos-linux-gcc --RTS=xenomai -c hello.adb
i686-elinos-linux-gnatbind --RTS=xenomai -x hello.ali
i686-elinos-linux-gnatlink hello.ali}
@end smallexample

@noindent
In the real-time case, the linker will link the application against the
Xenomai shared libraries if it knows where to find them. These are in
your ELinOS kernel project directory, in
@code{xenomai-2.6.22/xenomai-build/usr/realtime/lib}; these should have
been set up during the installation of GNAT Pro. If not, the full path
to the Xenomai shared library should be specified, otherwise the
build will fail at link time:

@smallexample
$ i686-elinos-linux-gnatmake --RTS=xenomai hello -largs -L<project dir>/xenomai-2.6.22/xenomai-build/usr/realtime/lib
@i{i686-elinos-linux-gcc --RTS=xenomai -c hello.adb
i686-elinos-linux-gnatbind --RTS=xenomai -x hello.ali
i686-elinos-linux-gnatlink hello.ali -L<project dir>/xenomai-2.6.22/xenomai-build/usr/realtime/lib}
@end smallexample

@node Debugging an Application on ELinOS
@section Debugging an Application on ELinOS

@noindent
This section contains the ELinOS-specific steps needed to run
the ELinOS debugger.

The debugging solution that GNAT Pro provides on this target consists in
three tools:

@itemize @bullet
@item
@i{gdbserver:}
A debugging server on target; it provides an low-level interface
to control the debugged program;

@item
@i{gdb:}
The debugger itself; run on the host, it connects to the gdbserver and
allows the user to control the debugged program through a command-line
interface;

@item
@i{gps:}
The GNAT Programming Studio; it provides a graphical front-end on the
top of @command{gdb}.

@end itemize

@noindent
To start a debugging session, you first need to program under the GDB
server.  Presuming the board has an internet connection to the
development host, that the Internet hostname of the board is
@file{myboard}, that your application is name myapp and that the port
on which the gdbserver will wait for requests is 2345, the command
would be:

@smallexample
myboard> gdbserver myboard:2345 myapp
@end smallexample

@noindent
You may now start the debugger. In GPS, on the @code{Languages} tab of
the project properties page, you would specify the name of the debugger (e.g.
@command{i686-elinos-linux-gdb}). You would then be able to start this
debugger with the command:
@code{Debug}@result{}@code{Initialize}@result{}@code{<No Main Program>}.
Alternatively, you can run the debugger @command{gdb} from the command
line.

To be able to properly debug the program running on target, the
debugger will need to know where to find a copy of the shared
libraries that this program is executing. At installation time, a
script containing these informations has been generated and installed
with the other GNAT tools. The name of the script is gdbinit, prefixed
by the target name: e.g. @command{i686-elinos-linux-gdbinit}. Its content
has the following form:

@smallexample
set solib-absolute-prefix ELINOS_PREFIX/cdk/x86/486/glibc-2.3.4/i486-linux
set solib-search-path \
ELINOS_PROJECT/xenomai-2.6.22/xenomai-build/usr/realtime/lib:\
ELINOS_PREFIX/cdk/x86/486/glibc-2.3.4/i486-linux/lib
@end smallexample

@noindent
...where @code{ELINOS_PREFIX} is set to the location of the ELinOS
installation on the host (typically @code{/opt/elinos-4.2}) and
@code{ELINOS_PROJECT} points to the directory of the kernel project.
The first command of this script (@code{set solib-search-path}) tells
GDB where to find ELinOS' libc libraries on the host; the second
one adds the Xenomai libraries to the search path. This script is
automatically loaded at debugger startup.

Note that this script is not created if you do not specify a valid
path to your ELinOS kernel project at installation time. If it is your
case, you may write it yourself using the example above as a
template.

You are now ready to connect the debugger to the GDB server:

@smallexample
(gdb) target remote myboard:2345
@end smallexample

@noindent
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.
You can then set breakpoints, resume the execution and use the usual
debugger commands:

@smallexample
   ...
(gdb) break some_function
   ...
(gdb) continue
   ...
(gdb) next
   ...
@end smallexample

For further information about the debugger or the GDB server, please
refer to the @cite{GDB User's Manual}.


@c   *****************
@c   * PikeOS Topics *
@c   *****************
@node PikeOS Topics
@appendix PikeOS Topics
@noindent
This chapter describes topics that are specific to the @value{GNATEDITION} for
@code{PikeOS}, a cross-development ARINC-653 system provided by @code{SYSGO}.

@menu
* Kernel Configuration for PikeOS::
* Building an Ada application on PikeOS::
* Building an Ada application on PikeOS using GNATbench::
* Running an Ada application on PikeOS::
* Debugging an Ada application on PikeOS::
* Debugging an Ada application on PikeOS using GNATbench::
* Using the APEX Run-Time Library on PikeOS::
@end menu


@node Kernel Configuration for PikeOS
@section Kernel Configuration for PikeOS

@noindent
There are two possible ways to configure a @code{PikeOS} kernel:

@enumerate
@item
@code{SYSGO}'s set of command-line tools: pikeos-cloneproject,
pikeos-configure...

@item
@code{CODEO}, a visually-oriented Integrated Development Environment based on
the Eclipse framework.
@end enumerate

@noindent
In the following sections, we will explain how to use these tools to build
a @code{PikeOS} kernel so that Ada applications can be run on it. The
procedures will mostly use @code{CODEO}; to know more about @code{PikeOS}
kernel configuration, refers to @code{PikeOS}' user manual
@cite{Installing and Using PikeOS}.

Two main settings are to be looked at when building a @code{PikeOS} kernel:

@enumerate
@item
The partition maximum priority and the process maximum priority:
Ada Ravenscar applications use up to 240 priority levels; in order to run
properly, theirs partitions and processes should have a greater maximum
priority. If this condition is not satisfied, the Ada application will exit
at startup with error @code{MCP too low}.

@item
In order to debug any application on target, a partition should run a
tool called @code{muxa}. @code{muxa} provides several development
services, such as a target console, and some debug channels that can be
connected to AdaCore's debugger.
@end enumerate

@noindent
This will be illustrated by a simple scenario. The following
instructions should help you build a simple kernel integration
project in which Ada application can be run.

@menu
* Creating a PikeOS kernel integration project::
* PikeOS maximum priority setting::
* PikeOS muxa configuration::
@end menu


@node Creating a PikeOS kernel integration project
@subsection Creating a PikeOS kernel integration project

@noindent
Make sure that you have all @code{PikeOS} tools in your @code{PATH};
then launch @code{CODEO}. In @code{CODEO}, create a new project by going to
@code{File}@result{}@code{New}@result{}@code{Project...}.

This should open the @code{New project} wizard. Expand
@code{CODEO}@result{}@code{PikeOS} and select @code{Integration
Project}. Click on @code{Next}. Give a project name and choose a
workspace, then continue.

In the project templates, select @code{devel-pikeos}; it contains a
project pre-configured with the major development features. Then click
on @code{Finish}.

This will open the @code{PikeOS Project Configurator}; this is a visual
editor for the configuration file @file{project.xml.conf}. In this editor,
and for this scenario, select @code{qemu-ppc} in the @code{board} tab.
@code{QEMU} is a simulator provided with @code{CODEO} that allows to easily
run a @code{PikeOS} kernel on host; this will be useful in the context of
this short tutorial. When this is done, click on @code{Save Settings}.

Note that you could also have a created this project from the command line
with the command:

@command{pikeos-cloneproject /opt/pikeos-3.0/demos-integration/devel-pikeos
new_project}


@node PikeOS maximum priority setting
@subsection PikeOS maximum priority setting

@noindent
You should now have a basic integration project; you can then configure it
for Ada Ravenscar applications.

As mentioned previously, in order to run Ada tasking applications on a
@code{PikeOS} process, you should make sure that this process can handle 240
priority levels. To do so, in the @code{Project Explorer}, double-click
on @file{vmit.xml}. This will open the @code{Topology View}.

In this @code{Topology View}, in @code{PartitionTable}, expand
@code{Partition -> pikeos}@result{}@code{ProcessList}, then
click on @code{ProcessEntry -> Proc_pikeos}. In its attribute, change
@code{MaxPrio} to 240.

Then click on @code{Partition -> pikeos}. @code{CODEO} warns you about the
fact that the process @code{Proc_pikeos} has a greater priority than its
partitions; so upgrade the maximum priority for the partition as well.
Set @code{MaxPrio} to 242. Then save your modifications.


@node PikeOS muxa configuration
@subsection PikeOS muxa configuration

@noindent
As explained earlier, console and debugging functionnalities are
provided by a component called @code{muxa} that comes in two parts:
one running on target, one running on host. This section will focus on
how to configure your kernel integration project in order to include
this component on target. How to run the host part will be explained
latter in this chapter (in section
@ref{Debugging an Ada application on PikeOS}).

In the previously-created integration project in @code{CODEO},
double-click on @file{project.xml.conf} in the @code{Project
Explorer}, to open the @code{PikeOS Project Configuration}.  Expand
@code{pikeos}@result{}@code{service} and click on @code{muxa}. This
will open a panel @code{Configuration Options: muxa}. Change the settings
to match your host/target configuration. In our case, as we are building
a kernel for @code{QEMU}, the following values will do:

@itemize @bullet
@item
@i{mode:} networkfp

@item
@i{Device:} eth0:/0

@item
@i{HostIP:} IP address of your host;

@item
@i{HostPort:} port used by the host @code{muxa};
say, 1501;

@item
@i{TargetIP:} IP of the target as seen from target;
say, 10.0.2.1 for @code{QEMU};

@item
@i{TargetPort:} Port on which the target @code{muxa} is listening;
say, 1500;

@item
@i{GatewayIP:} IP of the gateway from target;
say, 10.0.2.2 for @code{QEMU};

@item
@i{ConfigPort:} Port of @code{muxa}'s back office;
say, 1550.

@end itemize

@noindent
You can also change these settings from the command line, with the command

@command{pikeos-configure --editor}.

In order to have debug support for your particular user application, you
will also need to make sure that it has access to the whole file system
of the @code{muxa} partition. This is handled in the @code{Topology View}.
To access to it, click on @file{vmit.xml} in the @code{Project Explorer}.
Then, expand @code{Root -> Default}@result{}@code{PartitionTable} and
go your user partition: in this example, it is named
@code{Partition -> pikeos}. Expand this node, right-click on
@code{FileAccessList} and select @code{Add}. In the attributes of the
newly created @code{FileAccess} node, set @code{muxa:*} for @code{FileName}
and give it all access rights (Stat, Read. Write, Read-Write).

Your kernel integration project is now properly configured to host an
Ada application. The following section will tell you how to build such
an application and how to link it to the kernel.


@node Building an Ada application on PikeOS
@section Building an Ada application on PikeOS

@noindent
This section will give a basic example to illustrate how an Ada
Ravenscar application targeting @code{PikeOS} can be built. Consider
the following Ada program, to be copied in a file named
@file{hello.adb}:

@smallexample @c ada
with GNAT.IO; use GNAT.IO;
with Ada.Real_Time; use Ada.Real_Time;

procedure Hello is
   Next : Time := Clock;
begin
   for J in 1 .. 5 loop
      delay until Next;
      Put_Line ("Hello from Ada!");
      Next := Next + Milliseconds (1_000);
   end loop;

   raise Program_Error;
end Hello;
@end smallexample

@noindent
This program prints @code{Hello from Ada!} five times, then exits on errors.
With the ravenscar run-time library, only global exceptions are supported;
and you have to provide a global handler in a Ada or C routine that
exports @code{__gnat_last_chance_handler}. Here is an example of such a
global handler, that you can save in a file named @file{last_chance_handler.c}:

@smallexample @c C
#include <string.h>
#include <stdio.h>
#include <vm.h>

void
__gnat_last_chance_handler (char *source_location, int line_number)
@{
  static const char header [] = "Ada exception raised";
  static char msg [1024];

  if (strlen (header) + strlen (source_location) + 32 > 1024)
    @{
      sprintf (msg, "%s (no location)", header);
    @}
  else
    @{
      sprintf (msg, "%s at %s:%d", header, source_location, line_number);
    @}

  vm_hm_raise_error (VM_HM_EI_APP_ERROR,
		     VM_HM_ERR_MSG_T_CUSTOM,
		     msg, strlen (msg));
@}
@end smallexample

@noindent
This example uses @code{PikeOS}' health monitor to report the error. To build
this handler, do:

@command{powerpc-elf-pikeos-gcc -c -g  last_chance_handler.c
-I/opt/pikeos-3.0/target/ppc/oea/include/
-I/opt/pikeos-3.0/target/ppc/oea/include/stand/}

You can then build the Ada program and link it against this global handler with
this command:

@command{powerpc-elf-pikeos-gnatmake -g hello.adb -largs last_chance_handler.o}

This will generate a file @file{hello}. You should then add this executable
to your kernel integration project. Using the project created in the previous
section @ref{Kernel Configuration for PikeOS}, here is how you would do:
you would copy @file{hello} into the directory @file{target/}, rename it
to @file{pikeos} (as it is the name of the user application as specified
in this project) and use @code{make boot} to link all pieces together:

@smallexample
$ cp hello @i{<integration project dir>}/target/pikeos
$ cd @i{<integration project dir>}
$ source ./PikeOS.sh
$ make boot
@end smallexample

@noindent
A file will be created: @file{boot/pikeos-qemu-ppc-qemu}; this is a
@code{PikeOS} kernel running your simple Ada application. How to run
it on @code{QEMU} will be explained in the next section.


@node Building an Ada application on PikeOS using GNATbench
@section Building an Ada application on PikeOS using GNATbench

@noindent
This section will show how to use GNATbench to setup an Ada project similar
to the one described in the previous section.

Click on File -> New -> Others and select Ada / Ada Project. Click on next.
Give @code{demo} for the project name. Click on next. Give @code{hello} for the
name of the Ada main subprogram, and check the first checkbox (generate the
file). Click on next. Don't change anything for the directories settings, click
on next. Check the third checkbox (Drive Build with a Makefile). Click on the
scan button to refresh the names of the toolchains installed on the system,
and select the powerpc-elf-pikeos toolchain (make sure that it's the only one
checked). Hit finish.

A new project named demo should have been created. Open the file src/hello.adb,
and paste the Ada code given in the previous section. Create a new file at the
same location, last_chance_handler.c, and paste the corresponding code.

Open the file demo/Makefile. Change the build command to:

@smallexample
build:
	powerpc-elf-pikeos-gcc -c -g  src/last_chance_handler.c \
	-I/opt/pikeos-3.0/target/ppc/oea/include/ \
	-I/opt/pikeos-3.0/target/ppc/oea/include/stand/ \
	-o obj/last_chance_handler.o
	$(GNATMAKE) -d -P "$(GPRPATH)" -largs obj/last_chance_handler.o
	cp obj/hello ../kernel/target/pikeos
@end smallexample

@noindent
Right-click on the project demo, from the project navigator, and select
@code{Build Current Project}. Then right-click on the target directory of the
kernel project and select @code{Refresh}.

@node Running an Ada application on PikeOS
@section Running an Ada application on PikeOS

@noindent
@code{PikeOS} and @code{CODEO} are integrated with a simulator called
@code{QEMU}. This can be a simple way to run and test a @code{PikeOS}
application.

In the previous sections, we have seen how to create a @code{PikeOS} kernel
targeted to this simulator, embedding a simple Ada application. The following
command should run this kernel on @code{QEMU}:

@smallexample
$ /opt/pikeos-3.0/share/qemu/bin/qemu-system-ppc -M prep_bare -serial stdio -nographic -no-reboot -kernel boot/pikeos-qemu-ppc-qemu
@i{PikeOS (C) Copyright 1998-2009 SYSGO AG, Germany
Build: S2151-3.0-443
Arch: PowerPC OEA
Platform: QEMU PPC PREP
Features: RETAIL TRACER-SYSCALL KERNEL-TRACING
PikeOS System Software starting. Build: S2151-3.0-151
PikeOS System Software up and running.
Hello from Ada!
PIKEOS_MON: Started, version: 3.0-131
Trace Server: version: 3.0-147
NE2K: mac addr 52:54:00:12:34:56 autodetected and assigned to Dev eth0:/0
NE2K: mac addr 01:04:9f:00:0a:49 assigned to virtual Dev eth0:/1
NE2K: mac addr 01:04:9f:00:0a:50 assigned to virtual Dev eth0:/2
NE2K: mac addr 01:04:9f:00:0a:51 assigned to virtual Dev eth0:/3
MUXA: version: 3.0-146
Hello from Ada!
Hello from Ada!
Hello from Ada!
Hello from Ada!
Hello from Ada!
ERROR <0001:006>: ERROR raised by Application.
ERROR <0001:006>: Message type: 1, size: 36
ERROR <0001:006>: Message content:
0000  41 64 61 20 65 78 63 65  70 74 69 6f 6e 20 72 61  |Ada exception ra|
0010  69 73 65 64 20 61 74 20  68 65 6c 6c 6f 2e 61 64  |ised at hello.ad|
0020  62 3a 31 33                                       |b:13|
ERROR <0001:006>: System State: PART_INIT
ERROR <0001:006>: Error Identifier: APP_ERROR
ERROR <0001:006>: Error Level: PL
ERROR <0001:006>: Action: ID
}
@end smallexample

@noindent
As expected, the message @code{Hello from Ada!} is printed and an
exception is reported.

To quit @code{QEMU}, type Control-A Control-X.


@node Debugging an Ada application on PikeOS
@section Debugging an Ada application on PikeOS

@noindent
Any application that should be debugged on PikeOS should call a
routine named @code{init_gdbstub} at the early stages of its
execution. To do so with @value{GNATEDITION}, the simplest way will be
to recompile the entry code of your Ada application. This entry point is
a file named @file{pikeos-app.c} in the GNAT run-time library; the path to
the GNAT run-time library is given by @command{powerpc-elf-pikeos-gnatls -v}.
After copying it in your source directory, you can re-compile it with the
following command:

@command{powerpc-elf-pikeos-gcc -c -DDEBUG pikeos-app.c
-I/opt/pikeos-3.0/target/ppc/oea/include/}

Note the presence of an option @code{-DDEBUG}; it enables the gdbstub
hook. After compiling it, you can link it to your application; in the
case of our @code{hello} example, this build command would be:

@command{powerpc-elf-pikeos-gnatmake -f -g hello.adb
-largs pikeos-app.o last_chance_handler.o -lgdbstub -ldebug}

Note that you should also link against @file{libgdbstub.a} and
@file{libdebug.a} using the options @code{-lgdbstub -ldebug}. You can
then re-copy it in the integration project that we created in the
previous sections and re-link the kernel:

@smallexample
cp hello @i{<integration project dir>}/target/pikeos
cd @i{<integration project dir>}
source ./PikeOS.sh
make boot
@end smallexample

@noindent
To run this on @code{QEMU}, you shall specify several options to
configure the network support properly, using the option @code{-net}
and @code{-redir}; these options are documented in the usage message of
@code{QEMU} that you can get by doing @command{qemu-system-ppc --help}.
In our example, a proper setting would be:

@command{/opt/pikeos-3.0/share/qemu/bin/qemu-system-ppc -M prep_bare
-net nic -net user -redir udp:1500:10.0.2.1:1500
-serial stdio -nographic -no-reboot -kernel boot/pikeos-qemu-ppc-qemu}

The next step is to launch the host @code{muxa}. Run it in your kernel
integration project (replacing @i{<host>} by the actual name of your
host machine):

@command{muxa --type eth --host <host>:1550 --eth-host <host>:1501
--eth-target <host>:1500}

You can then connect to it at <host>:1550 and configure your console
and debug channels. For example, to get a console:

@smallexample
$ telnet <host> 1550
Ok: Connected to server.
muxa> lsn
Ok: Channel list, target supports 16 channels.
0  pikeos/Proc_pikeos/dbg
       Host:free      Port:0      Target:open     (Uid:0x000,0x0016,0x0000)
4  Monitor
       Host:free      Port:0      Target:open     (Uid:0x000,0x0004,0x0000)
5  mon_con
       Host:free      Port:0      Target:open     (Uid:0x000,0x0004,0x0008)
6  traceserver
       Host:free      Port:0      Target:open     (Uid:0x000,0x0005,0x0000)

muxa> connect mon_con
Ok: connected
help
PikeOS Monitor Command Shell v1.0
Available commands:
   help                  Help on command
   sysinfo               Info on system
   lsp                   List partition names
   pinfo                 Info on a Partition
   lsc                   List channels
   cinfo                 Info on a channel
   lsq                   List Queuing ports of a partition
   qinfo                 Info on a queuing port
   lss                   List sampling ports of a partition
   sinfo                 Info on a sampling port
   lse                   List processes of a partition
   einfo                 Info on a process
   lsm                   List memory requirements of a partition
   minfo                 Info on a memory requirement
   preboot               Reboot a Partition
   phalt                 Halts a Partition
   treset                Resets the target with the specified mode.
   kinfo                 Info on kernel structures
   ps                    Show Tasks/Threads

Type `help name' to find out more about the command `name'.
PikeOS# lsp
 id name    partd fctid lctid mprio mode
  1 service   1.5     2    21   102 COLD_START
  2 pikeos    1.6    22    22   242 COLD_START
PikeOS# pinfo pikeos
operating mode:      COLD_START
num_kpages:          8
free_kpages:         3
flags:               0
max prio:            242
part daemon:         1.6
first child task:    22
last child task:     22
proc count:          1
queuing port count:  0
sampling port count: 0
max. open files:     32
open files:          1
cookie:              0
@end smallexample

@noindent
...or to connect the application gdbstub to an host port, in order to
debug your application:

@smallexample
$ telnet <host> 1550
Ok: Connected to server.
muxa> lsn
Ok: Channel list, target supports 16 channels.
0  pikeos/Proc_pikeos/dbg
       Host:free      Port:0      Target:open     (Uid:0x000,0x0016,0x0000)
4  Monitor
       Host:free      Port:0      Target:open     (Uid:0x000,0x0004,0x0000)
5  mon_con
       Host:connected Port:1550   Target:open     (Uid:0x000,0x0004,0x0008)
6  traceserver
       Host:free      Port:0      Target:open     (Uid:0x000,0x0005,0x0000)

muxa> connect 1551 pikeos/Proc_pikeos/dbg
Ok: Connected channel
@end smallexample

@noindent
You can then connect the debugger to <host>:1551 using @code{GDB}'s remote
protocol, either from @code{GPS} or from the command line:

@smallexample
(gdb) target remote <host>:1551
Remote debugging using <host>:1551
0x08011d84 in gdbarch_breakpoint ()
(gdb) l hello.adb:2
1       with GNAT.IO; use GNAT.IO;
2       with Ada.Real_Time; use Ada.Real_Time;
3
4       procedure Hello is
5          Next : Time := Clock;
6       begin
7          for J in 1 .. 5 loop
8             delay until Next;
9             Put_Line ("Hello from Ada!");
10            Next := Next + Milliseconds (1_000);
(gdb) b 9
Breakpoint 1 at 0x80102c4: file hello.adb, line 9.
(gdb) c
Continuing.

Breakpoint 1, hello () at hello.adb:9
9             Put_Line ("Hello from Ada!");
(gdb) display J
1: J = 1
(gdb) c
Continuing.

Breakpoint 1, hello () at hello.adb:9
9             Put_Line ("Hello from Ada!");
1: J = 2
@end smallexample

@noindent
For further information about debugging with @value{GNATEDITION},
refer to the @cite{@value{GNATEDITION} User's Guide} and to the
@cite{GDB User's Manual}.

@node Debugging an Ada application on PikeOS using GNATbench
@section Debugging an Ada application on PikeOS using GNATbench

@noindent
The procedure that we just describe can also be integrated in the
project that we create in section
@ref{Building an Ada application on PikeOS using GNATbench}.
To do so, the build target in @file{demo/Makefile}
should now be:

@smallexample
build:
        powerpc-elf-pikeos-gcc -c -g  src/last_chance_handler.c \
        -I/opt/pikeos-3.0/target/ppc/oea/include/ \
        -I/opt/pikeos-3.0/target/ppc/oea/include/stand/ \
        -o obj/last_chance_handler.o
        powerpc-elf-pikeos-gcc -c -DDEBUG src/pikeos-app.c \
        -I/opt/pikeos-3.0/target/ppc/oea/include/ \
        -o obj/pikeos-app.o
        $(GNATMAKE) -f -d -P ``$(GPRPATH)'' \
        -largs obj/last_chance_handler.o obj/pikeos-app.o -lgdbstub -ldebug
        cp obj/hello ../kernel/target/pikeos
@end smallexample

@noindent
And copy @file{pikeos-app.c} in directory @file{demo/src}. Then, rebuild
this project (right-click on demo and @code{Build Current Project}).

You can then run @code{QEMU}, @code{muxa} and connect the debug channel
to port 1551, as explained above.

Then, to run a debug session, right-click on your kernel project and
select @code{Debug As}@result{}@code{Debug Configurations...}. This will
open a debug configuration named pikeos.

In this configuration, click on panel @code{Debugger}; set @code{GDB Debugger}
to @code{powerpc-elf-pikeos-gdb}. Then click on tab @code{Connection}, select
@code{TCP}, and set connection parameters to the debug channel as specify in
muxa; here <host> and 1551.

Click on @code{Apply}, then @code{Debug}; the debug perspective will be opened
in @code{CODEO} and the debugger will be attached to the target application.
You can then navigate into your sources, set breakpoints in @code{hello.adb}
by double-clicking on the line, inspect your local variables...

For further information about debugging from @code{CODEO}, consult
the @cite{CODEO User Guide} in @code{Help}@result{}@code{Help Contents}.

@node Using the APEX Run-Time Library on PikeOS
@section Using the APEX Run-Time Library on PikeOS

@noindent
@value{GNATEDITION} for PikeOS provides two Ravenscar run-time libraries;
one based on the native API, and the second one based on the APEX interface.
The first part of this manual has been focused on the first one; this section
will detail what should be changed to build, run and debug an application with
the APEX Ravenscar run-time library.

@menu
* PikeOS APEX Kernel Configuration::
* Building an Ada Application for PikeOS APEX::
* Debugging an Ada Application for PikeOS APEX::
@end menu

@node PikeOS APEX Kernel Configuration
@subsection PikeOS APEX Kernel Configuration

@noindent
The same configuration as @ref{Kernel Configuration for PikeOS} should
work, with the following addition: an APEX partition will need an
additional set of memory pools named @code{_APEX_KMEM_},
@code{_APEX_HEAP_POOL_}, @code{_APEX_STACK_POOL_}. To create them in
@code{CODEO}, open vmit.xml and expand @code{Root ->
Default}@result{}@code{PartitionTable} and go your user partition: in
our example, @code{Partition -> pikeos}. Under this node, right-click
@code{MemoryRequirementList} and choose @code{Add}. You will have to do it
for the three memory pools mentioned above; in each case, modify the
newly added memory pool as follow:

@itemize @bullet

@item
@code{_APEX_KMEM_}: change the name to @code{_APEX_KMEM_} and the type
to @code{VM_MEM_TYPE_KMEM}; set the size so that the kernel has enough
memory space to create the tasks of your application
(e.g. @code{0x00200000});

@item
@code{_APEX_HEAP_POOL_}: change the name to @code{_APEX_HEAP_POOL_} and
the type to @code{VM_MEM_TYPE_RAM}; set the size to the heap size that
your application needs to run properly (e.g. @code{0x00400000});

@item
@code{_APEX_STACK_POOL_}: change the name to @code{_APEX_STACK_POOL_} and
the type to @code{VM_MEM_TYPE_RAM}; set the size to the stack size that
your application needs to run properly (e.g. @code{0x00400000});

@end itemize

@noindent
Then save your project and rebuild with @code{make boot} (from the
command line or by a right-click on target @code{boot} in panel
@code{Make targets}).


@node Building an Ada Application for PikeOS APEX
@subsection Building an Ada Application for PikeOS APEX

@noindent
APEX gives the user the responsability to start the scheduler after
all its ressources have been allocated; in our case, all tasks of the
application. To do so in Ada, the proper way would be to perform all the
``real'' work in Ada tasks, and let the environment task start the
scheduler. e.g. in the case of the hello example, it would mean to
add a wrapper like this one:

@verbatim
with APEX_Wrapper_Tasking;

procedure APEX_Wrapper is
   procedure Set_Partition_Mode (Mode : Integer; Result : out Integer);
   pragma Import (C, Set_Partition_Mode, "SET_PARTITION_MODE");

   Set_Partition_Result : Integer;
begin
   Set_Partition_Mode (3, Set_Partition_Result);
end APEX_Wrapper;

--

package APEX_Wrapper_Tasking is
   task Env_Task;
end APEX_Wrapper_Tasking;

--

with Hello;

package body APEX_Wrapper_Tasking is
   
   task body Env_Task is
   begin
      Hello;
   end Env_Task;

end APEX_Wrapper_Tasking;
@end verbatim

@noindent
In order to use this particular example of a wrapper, you may copy it
into one file and use @code{powerpc-elf-pikeos-gnatchop} to break it into
several Ada units:

@verbatim
$ powerpc-elf-pikeos-gnatchop -w wr.ada

splitting wr.ada into:
   apex_wrapper.adb
   apex_wrapper_tasking.ads
   apex_wrapper_tasking.adb
@end verbatim

@noindent
You can then use the same build procedure as in the previous section
with the following differences:

@itemize @bullet
@item
The main unit is now @code{apex_wrapper.adb} instead of @code{hello.adb};

@item
The option @code{--RTS=ravenscar-apex} should be added to the options of
@code{powerpc-elf-pikeos-gnatmake};

@item
The options @code{-lapex} and @code{-lxt} should be added to the options of
@code{gnatlink}; that is to say, it should be added in the @code{largs}
section of the @code{gnatmake} command.

@end itemize

@noindent
As an example, the build command given in
@ref{Building an Ada application on PikeOS} now becomes:

@command{powerpc-elf-pikeos-gnatmake -g --RTS=ravenscar-apex apex_wrapper.adb
-largs last_chance_handler.o -lapex -lxt}

@node Debugging an Ada Application for PikeOS APEX
@subsection Debugging an Ada Application for PikeOS APEX

@noindent
To debug an Ada Application using the APEX interface, the procedure is
the same as the one described previously in sections
@ref{Debugging an Ada application on PikeOS} and
@ref{Debugging an Ada application on PikeOS using GNATbench}
for the native interface. Report to these
sections for a detailed example.

A set of differences is worth mentioning: the entry code to recompile
should now be found in a file named @file{pikeos-apex-app.c} in the
GNAT run-time library; the path to the GNAT run-time library is given
by @command{powerpc-elf-pikeos-gnatls -v --RTS=ravenscar-apex}. After
copying it in your source directory, you can re-compile it with the
following command:

@command{powerpc-elf-pikeos-gcc -c -DDEBUG pikeos-apex-app.c
-I/opt/pikeos-3.0/target/ppc/oea/apex/include/}

@noindent
The debug libraries should be different as well; the link options
@code{-lgdbstub}, @code{-lapex_d} and @code{lxt_d} should be added (in
this order). In our example, the build command could be:

@command{powerpc-elf-pikeos-gnatmake -f --RTS=ravenscar-apex -g hello.adb
-largs pikeos-apex-app.o last_chance_handler.o -lgdbstub -lapex_d -lxt_d}

@noindent
As a consequence, the Makefile fragment to be used in CODEO would be slightly
different from the one given in section 
@ref{Debugging an Ada application on PikeOS using GNATbench}:

@smallexample
build:
        powerpc-elf-pikeos-gcc -c -g  src/last_chance_handler.c \
        -I/opt/pikeos-3.0/target/ppc/oea/include/ \
        -I/opt/pikeos-3.0/target/ppc/oea/include/stand/ \
        -o obj/last_chance_handler.o
        powerpc-elf-pikeos-gcc -c -DDEBUG src/pikeos-apex-app.c \
        -I/opt/pikeos-3.0/target/ppc/oea/include/ \
        -o obj/pikeos-apex-app.o
        $(GNATMAKE) --RTS=ravenscar-apex -f -d -P ``$(GPRPATH)'' \
        -largs obj/last_chance_handler.o obj/pikeos-apex-app.o \
        -lgdbstub -lapex_d -lxt_d
        cp obj/hello ../kernel/target/pikeos
@end smallexample


@c **********************************
@c * GNU Free Documentation License *
@c **********************************
@include gfdl.texi
@c GNU Free Documentation License

@node Index
@unnumbered Index

@printindex cp

@contents

@bye
