2.10. System Calls

A system call is the means by which application programs call an operating system. System calls are mostly used for input-output. The predefined Ada package Ada.Text_IO and the smaller package XGC.Text_IO map all input and output operations onto the system calls read and write. Also the C language input-output functions declared in <stdio.h> use the same system calls.

With XGC Ada, we have no operating system as such, just the run-time system module art0. However, we support the system call mechanism using the BEX instruction and when running on the simulator we map system calls to host system calls so that application programs can access host computer files. This is especially useful during program development.

When running on the the target, any system call will bring your program to an abnormal termination because the required system call handler is absent in the default configuration. The default system call handler is located in libc and supports an appropriate subset of calls. For example, read and write are directed to UARTA and may be used in a console dialog. You may wish to customise the default handler so that calls that would otherwise be non-operational could do something useful. For example, the call to get the time could be implemented to read the time form some external clock.

This can be done quite easily and an example system call handler is included with the source files in /opt/m1750-ada-1.7/m1750-coff/src/libc/sys/schandler.c. The handler is attached to the system call trap in the same fashion as other interrupts are attached to their handlers. In the example, a C function is provided to do the attaching.

2.10.1. How to Use Text_IO Without System Calls

Another way to support Text_IO is to replace the various system calls with calls to application code. For example, if all you need is the Put functionality in Text_IO, you can create your own version of write and have it do whatever you want. When your program is linked, the linker will use your version of write in place of the library version.

Example 2-10. Code to Support Write


   protected UART is
      procedure Write (Ch : Character);
      pragma Interrupt_Handler (Write);
   end UART;

   protected body UART is
      procedure Write (Ch : Character) is
      begin
         --  Code to write one character
      end Write;
   end UART;

   --  Export pragmas required for compatibility with C

   procedure Write (
      Result : out Integer;
      Fd : in Natural;
      Buf : in System.Address;
      Count : in Natural);
   pragma Export (C, Write, "write");
   pragma Export_Valued_Procedure (Write, "write");

   procedure Write (
      Result : out Integer;
      Fd : in Natural;
      Buf : in System.Address;
      Count : in Natural)
   is
      Ada_Buf : String (1 .. Count);
      for Ada_Buf'Address use Buf;
   begin
      for I in 1 .. Count loop
         UART.Write (Ada_Buf (I));
      end loop;

      Result := Count;
   end Write;