LEON3 Topics
This appendix describes topics relevant to GNAT for bareboard LEON3.
Supported Processors and Run-Time Libraries
GNAT for bareboard LEON3 supports the LEON3 and LEON4 processor families. The following uniprocessor run-time libraries are pre-built:
light-leon3
light-tasking-leon3
embedded-leon3
The following multiprocessor run-time libraries are pre-built:
light-tasking-leon3-smp
embedded-leon3-smp
All pre-built run-time libraries include the necessary low-level hardware startup and initialization functionality required to run applications on LEON3 and LEON4 processor families.
Getting Started
Developing with GNAT for bareboard LEON3 is similar to native GNAT development, with two important differences. First, when building for a bareboard target, you need to specify both the target processor and the run-time library. This can be defined in a project file (either directly or via the project properties dialog in GNAT Studio) or on the command line. For details on how to specify the target and run-time library for your project, see Introduction to GNAT for Cross Platforms. For LEON3 and LEON4 processors the target ‘leon3-elf’ needs to be specified.
For example, the following project file fragment shows both the target and the run-time library specified via their respective attributes. In this example, the LEON3 target and the ‘Zero Foot Print’ LEON3 run-time library is specified:
project Demo is
...
for Runtime ("Ada") use "light-leon3";
for Target use "leon3-elf";
...
end Demo;
The second difference is how programs are run and debugged. This is dependent on your setup and the tools you use. In many cases, GNAT Studio can be used to debug your program. See Debugging for details.
Executing and Debugging on Emulators
The program compiled by the toolchain can be executed using GNATemulator or Gaisler’s TSIM. GNATemulator can execute or debug with the program either directly from the command line or from within GNAT Studio.
Within GNAT Studio, the program can be run on the emulator using the Run with
Emulator
toolbar button or the Build/Emulator->Run with Emulator menu
entry. As the program executes, it will display its output, if any, in the
leon3-elf-gnatemu view. Alternatively, GNATemulator can run the program from
the command line:
$ leon-elf-gnatemu main
To debug a program from within GNAT Studio, click on the Debug with Emulator
toolbar button. This will launch the emulator along with a gdb remote debugging
session connected to the emulator. Debugging the program through GNAT Studio is similar
to debugging a native program. Alternatively from the command line, launch
GNATemulator using the -g
debugger switch:
$ leon-elf-gnatemu -g main
The debugger can then be launched directly from the command line or from
GNAT Studio
. Before loading the program to debug, GDB
must connect to the
simulator using the remote protocol and the required IP port (by default
localhost:1234
).
$ leon3-elf-gdb main
(gdb) target remote localhost:1234
...
(gdb) continue
...
(gdb) detach
...
Further information about GNATemulator can be found in GNATemulator Documentation
Executing and Debugging on Hardware Platforms
The compiler generates ELF executables that can be loaded onto the target board
using the GRMON
debug monitor or tools provided by your board supplier.
Debugging LEON3 programs with GDB
is done through the remote target
capability provided by GRMON
debug monitor. This functionality is
activated by launching the GRMON
monitor with the -gdb
switch or
using the GRMON
gdb
command:
$ grmon -gdb
From the grmon window the program can be loaded with:
grmon> load main
It is important to load the program through the GRMON
as it will initialize
the .data and .bss sections.
GDB may now be started from GNAT Studio or the command line. By default, GRMON
listens on port 2222 for GDB``connections. From GNAT Studio, you may configure in the
project settings the remote connection details so GNAT Studio can automatically connect
to ``GRMON
. From the command line:
$ leon-elf-gdb main
(gdb) target remote monnitor_address:2222
(gdb) <insert your breakpoints here>
To resume the execution, we first need to set the PC to the start address and then resume from there. This can be done in a single command:
(gdb) jump start
This part assumes that the entry point is a function named “start”, which is
the case for the pre-built runtimes we provide with GNAT Pro. If you are
building your own version of the runtime, the name of the entry point is found
via the “ENTRY” statement in the linker script. See for instance the linker
script leon3-elf/lib/gnat/embedded-leon3/ld/leon.ld
in your GNAT Pro
install for an example of such script.
SMP Support
The “embedded-leon3-smp” and “light-tasking-leon3-smp” runtime libraries support symmetric multi-processing (SMP) and are pre-configured to support two processors. Processors are numbered beginning at one, therefore applications can assign tasks to either CPU #1 or CPU #2.
The number of processors supported can be increased by changing the value
of Max_Number_Of_CPUs
in package System.BB.Board_Parameters
and then
rebuilding the runtime library.
Per the Ada language standard (RM D.13/11), under the Ravenscar profile all tasks execute on a single processor unless the application explicitly uses aspect “CPU” to assign tasks to processors. (This is due to the No_Dynamic_CPU_Assignment restriction.) Therefore, CPU #1 is used by default.
All runtime and library unit elaboration is done on CPU #1. After that code completes CPU #2 is started. Note that the configuration pragma Partition_Elaboration_Policy (RM H.6) can be used, as usual, to control how library unit elaboration is performed regarding task activations and interrupt handler attachment, but a single processor is used nonetheless.
The implementation of delay statements is such that the resulting timer interrupt always goes to CPU #1, then to CPU #2 (via software interrupt) if that’s where the task requesting the delay is located. Thus there will be some overhead in that case.
Adapting the Run-Time System
There may be some variations among the different boards. The RAM and ROM sizes can be modified via the a custom linker script while other properties including clock speed and multiprocessor support requires modifying the LEON3 BSP sources and rebuilding the run-time library. For the latter see Customized Bareboard Run-Time Libraries for instructions on how to perform these modifications.
The default linker script located at
leon3-elf/lib/gnat/<runtime_library>/ld/leon.ld
defines the size of
memory in the system and the default stack size. If these parameters need to be
adapted a local copy of this script can be created and modified:
Memory size: the
_RAM_SIZE
and_PROM_SIZE
variables defines the size of the RAM and ROM memory installed on the board respectively. The memory map also needs tailoring when_RAM_SIZE
is changed.MEMORY { ram (rwx) : ORIGIN = 0x40000000, LENGTH = New_Length }
Default stack size for the environment task is set through
_STACK_SIZE
variable. This variable can be overridden at the command line without creating a new linker script, see Environment Task Primary Stack Size for further information.
The new linker script can be selected by setting the environment variable
LDSCRIPT
to the path of the script or alternatively passed on the command
line to gprbuild:
gprbuild -P prj.gpr -XLDSCRIPT=my_system.ld
User specific hardware initialization can be performed before the elaboration
of Ada code through the __gnat_hw_initialize
procedure. By default, this
procedure returns immediately. It can be replaced by providing your own version
of this procedure. As the procedure is called before memory initialization,
it should be written in assembly. Routine calls are possible as long as there
is no window overflow. Finally, be sure that your routine is linked in
the executable (double check with objdump). If needed, force the link when
using gprbuild by using a 'globl
pseudo assembly instruction, like this:
with System.Machine_Code;
System.Machine_Code.Asm(".globl __gnat_hw_initialize",
Volatile => True);
LEON3FT RETT Restart Errata
All of the LEON3 run-times implement the workaround #1 of the LEON3FT RETT Restart Errata (GRLIB-TN-0018). Please refer to the Gaisler documentation for more information about the triggering of the errata. If the errata is not applicable to your project, the workaround can be disabled by commenting out the definition of the LEON3_ERRATA_GRLIB_TN_0018 macro in the crt0.S source file of the run-time, and then recompiling the run-time.
Console Output
UART 1 is used as the target console.