This tutorial will show you how to set up compiler infrastructure, write a minimal runtime system, write a simple test program, and compare it with an equivalent C program.
- GCC compiler
- make
- AVRDUDE (optional for flashing the MCU)
- Simulide (optional for simulations)
Download and unpack GCC compiler (gnat-avr-elf-*.tar.gz) from Alire builds. Set it to the PATH of your operating system.
All files should be located in the same folder without any subfolders.
Every Ada program requires a runtime system, regardless if it is being run on an operating system or on bare metal. Absolute minimum is a system.ads file in which you describe your environment.
system.ads consists of the following sections:
- Configuration pragmas
- Restriction pragmas
- Program unit level restrictions
- System private part
For details of each section please consult following documentation:
- GNAT Reference Manual
- GNAT User’s Guide for Native Platforms
- GNAT User’s Guide Supplement for Cross Platforms
- GCC source code
Other system files are not necessary for basic functionality. For some instructions (CLI, SEI) you can reference external builtin functions from the C library which comes with GCC.
For more advanced functionality, like using data from the flash memory, you will have to use assembly code. To use assembly code, you have to define the procedure Asm which must be in the package System.Machine_Code in the s-maccod.ads file.
Test program is implemented in Ada and in C. Although the test program is rather small, it demonstrates the following functionalities:
- Access variables from flash memory
- Implement an empty interrupt handler
- Use the GCC C library's built-in functions
Build test program (both versions):
makeClean builds:
make cleanGet help:
make helpGet EEPROM, flash, and RAM usage:
make size-ada_program
make size-c_programDisassemble code:
make disasm-ada_program
make disasm-c_programFlash .hex file to the MCU:
avrdude -c usbasp -p m32 -U lfuse:w:0xff:m -U hfuse:w:0xc9:m -U flash:w:ada_program.hex:i
avrdude -c usbasp -p m32 -U lfuse:w:0xff:m -U hfuse:w:0xc9:m -U flash:w:c_program.hex:i| Language | Flash usage | RAM usage |
|---|---|---|
| Ada | 132 | 0 |
| C | 132 | 0 |
If we compare sizes, we can see that Ada uses the same number of bytes as a C program. The same compiler generates code from both languages, and the resulting code will be very similar if not identical (as we can see in this example). If there is a concern about code size and performance in critical sections (interrupt handlers), it is possible to disable Ada generated checks with the usage of an appropriate pragma.
Open simulation.sim1 in Simulide, load appropriate .hex file and start simulation.
- For more complete Run Time System, library, and examples, you can visit Rolf Ebert's GitHub page.
- For more detailed studies, you can visit Adacore's learning resources.
- Real world example of program for audio systems