TOC PREV NEXT INDEX DOC LIST MASTER INDEX



Configuring the User Library

Configuring the user library is optional. Under most circumstances, Apex functions properly without changes to the default configuration. However, enabling special features, customizing runtime behavior for your application, or implementing runtime trade-offs, for example, "fair" scheduling over deterministic performance, are some reasons you may find it necessary or desirable to reconfigure the user library.

The package specification v_usr_conf.1.ada defines and describes the components that you can modify to provide the Apex run-time environment for your application program. Do not modify this file.

To configure the user library, modify the default version of the body of the package, v_usr_conf.2.ada.

The file v_usr_conf_i.1.ada (located in rational.ss) provides the data structures for the small block sizes, configuration tables and floating point control, constants which may be used to select configuration options, and routines for use within the configuration package.


Configuring the User Library

Note: The name of the configuration package must remain V_Usr_Conf.

Follow these steps to configure the user library.

1 . Copy the view from usr_conf.ss to your own subsystem:

GUI Commands
Visit $APEX_BASE/ada/usr_conf.ss
Highlight <UsrConfView>
Select File > Copy Object
Select the Views radio button.
Fill in <MySubSys> in the Destination field
Click OK.

Command Line
copy_view $APEX_BASE/ada/usr_conf.ss/<UsrConfView> <MySubSys>

2 . Edit the copied version of v_usr_conf.2.ada to provide the desired configuration parameters.

GUI Commands
Visit <MySubSys>/<UsrConfView>/v_usr_conf.2.ada
Click Edit
Make your changes
Click Save

Command Line
edit <MySubSys>/<UsrConfView>/v_usr_conf.2.ada

3 . Compile the files in the copied view.

GUI Commands
Visit <MySubSys>/<UsrConfView>
Select <Shift> Code or Select Code and then OK

Command Line
apex code <MySubSys>/<UsrConfView>

4 . Import the copied usr_conf view into the view where your application will be linked:

GUI Commands
Visit <MyApplicationView>
Click Control > Change View Properties
Add <MySubSys>/<UsrConfView> to list of Imports.
Verify that the Add/Replace button is selected.
Click OK

Command Line
apex import <MyApplicationView> <MySubSys>/<UsrConfView>

5 . Link your application. The configuration in your imported usr_conf view will be included instead of the default one provided in the archive library.

GUI Commands
Visit <MyApplicationView>
Highlight <My Application>
Select <Shift>Link or select Link and then OK.

Command Line
apex link <MyApplicationView>/<MyApplication>


Configuration Parameters

This section contains general descriptions and definitions of the user library configuration components.

The components and parameters vary depending on your system architecture and whether or not you are using a threaded version of Apex.

For the specifics of your release, consult the specification of package V_Usr_Conf contained in the file

$APEX_BASE/ada/usr_conf.ss/<UsrConfView>/v_usr_conf.1.ada

and modify the body, v_usr_conf.2.ada in the same view.

The configuration package parameters are grouped as follows:

Memory Management

Note: The definitions in these tables are brief identifiers. See Memory Management for complete descriptions.

Configuration_Table

Heap_Max
specifies the maximum number of storage units to which the heap can grow.
Heap_Extend
specifies the minimum number of storage units requested when the Default_Pool is extended.
Mem_Alloc_Mutex_Attr_Address
points to the mutex attributes that will be used when initializing the mutex used for mutual exclusion during memory allocation/deallocation (at both the collection and storage pool layers).

Mem_Alloc_Conf_Table Parameters Applicable To All Configurations

Malloc_Based_Allocation
specifies, when True, that the storage pool configuration Externally Managed Heap should be used. In this configuration the heap is externally managed
External_Pool_Protection
specifies the mutual exclusion mechanism that should be used for the External_Pool object.
Storage_Pool_Configuration
specifies the routines to be used to create the runtime's standard storage pools.
Mem_Alloc_Conf_Table_Address
points to the Mem_Alloc_Conf_Table which defines additional memory management configuration parameters.

Mem_Alloc_Conf_Table Parameters Applicable Only To Apex Managed Heap

Allocation_Strategy
specifies the strategy to be used when choosing a block from the free list: First_Fit or Best_Fit. The default is First_Fit.
External_Pool_Protection
specifies the mutual exclusion mechanism that should be used for the External_Pool object.
Private_Storage_Pools
specifies, when true, that a reclaimable collection should be assigned a private (rather than a shared) storage pool.
Small_Block_Sizes_Table
is used to control the free block caching of the Default_Pool
Small_Block_Sizes_Address
points to the Small_Block_Sizes_Table
Num_Small_Block_Sizes
specifies the number of small free block lists to be managed in the Default_Pool.
Min_List_Length
specifies the minimum list length of a small blocks list.
Min_Size
specifies the minimum size object that the user intends to allocate.

Storage Pool Configuration

Storage Pool Configuration describes the routines to be used to create the runtime's standard storage pools.

External_Pool
is an object that provides the lowest level memory management interface for the application.
Kernel_Pool
is an object that provides the lowest level memory management interface for the kernel.
Default_Pool
is an object that is the default heap manager for the application if Apex Managed Heap is configured.
Null_Pool
in an object that does not support allocations, that is, any attempt to allocate memory from the pool results in the raising of a Storage_Error exception.
Heterogeneous_Pool
is an object created for collections that have a non-default initial size (when Apex Managed Heap is configured).
Homogeneous_Pool
is an object created for collections that have a non-default initial size (when Apex Managed Heap is configured).
User defined standard storage pool
must return an object of a specific (Ada95) type and must have specific parameter profiles.

External Pool Callouts

External Pool Callouts provide a mechanism for easily customizing the External_Pool's external interface.

V_Extern_Alloc_Callout
is called by the (default configured) External_Pool when it needs to allocate memory.
V_Extern_Free_Callout
is called by the (default configured) External_Pool when it wants to deallocate memory.
V_Extern_Size_Callout
is called by the (default configured) External_Pool to determine the maximum amount of memory that could be allocated.

Multitask_Safe Malloc

Multitask-Safe Malloc is an Apex provided implementation of malloc, free, and several other standard C heap management routines. It is in the alloc subdirectory of non-threaded usr_conf.ss views.

Kernel Pool Callouts

Kernel Pool Callouts provide a mechanism for customizing the Kernel_Pool's internal interface. These subprograms are called by the kernel when it needs to allocate/deallocate memory.

V_Krn_Alloc_Callout
is called by the kernel when it needs to allocate memory.
V_Krn_Free_Callout
is called by the kernel when it wants to deallocate memory.
V_Krn_Pool_Init_Callout
is called by the kernel to initialize its underlying memory management support.
V_Krn_Pool_Finalize_Callout
is called by the kernel to finalize its underlying memory management support.

Stack Configuration Parameters

For applications that do not use tasking, managing stack usage is straightforward. The stack is simply the process stack.

For applications that use tasking, main task still uses the process stack, but each additional task gets a stack allocated from the heap.

Main_Task_Stack_Size
is the size of the main task's stack.
Default_Task_Stack_Size
is the default size for each task's stack area.
Exception_Stack_Size
is amount of additional task stack space reserved for exception handling.
Idle_Stack_Size
is size of the idle task's stack.
Signal_Task_Stack_Size
is size of the stacks used for task entries bound to interrupts.
Wait_Stack_Size
is the size of the additional stack space used to support Apex's fast task rendezvous optimization.
Zero_Stacks_Enabled
provides support for the Apex debugger's stack analysis.

Code Coverage

CCA Configuration Data

Intr_Number
is the entry in the Interrupt Vector Table reserved for CCA use. This number can be changed to force CCA to use a different entry in the Interrupt Vector Table.
Cca_Table_Max
is space used by db_iface to write the trap information into the VOX file's data space before loading the VOX file onto the target. If db_iface determines that there is not enough room to write all the trap information into the VOX file, it will print an error message telling you to decrease the total number of traps or increase the trap table size. To increase the trap table size, change Cca_Table_Max, recompile v_usr_conf.2.ada, and re-link your program.

Note: Cca_Table_Max is initially very small (in order to minimize impact on non code coverage programs). Increase it before collecting coverage information for your program.


Do not modify the other data in this section of v_usr_conf.2.ada

CCA Configuration Parameters

Note: The code coverage configuration parameters effect only programs collecting code coverage information.

Send_Sigint_To_Cca
is a boolean that controls the behavior of the program upon receiving a SIGINT. If Send_Sigint_To_Cca is True, SIGINT is sent to CCA and coverage information is recorded in cca.out and the program immediately terminates. If False, SIGINT is not sent to CCA. The default setting is True.

Trace Configuration Data

Trace_Buffer_Size
is the number of records in the event buffer. If you are using hardware logging, it specifies the number of hardware logging records, (two words).
Trace_Buffer_Address
is the address of an I/O buffer area if you require a fixed location. If this value is null, a buffer will be allocated for you.
Hardware_Logging
enables hardware logging when set to True (available only on certain targets).
Note: With Hardware_Logging set to True, Trace_Io_Base_Address, Trace_Control_Base_Address, and Hardware_Timer_Resolution are used.
Trace_Io_Base_Address
is the physical base address of the I/O write addresses for tracing.
Trace_Control_Base_Address
is the physical base address of the I/O control registers for tracing.
Hardware_Timer_Resolution
selects hardware timer resolution. It is copied into Timer_Increment and Timer_Precision.
Note: If Hardware_Logging is False, these parameters are ignored and Kernel_Logging is read from the load module.
Kernel_Logging
generates a log of kernel events when this boolean is set to True. Unlike runtime events used by trace analysis, kernel events are used by runtime developers. Events and arguments are subject to change.

Taskdeb Configuration Structure

The Taskdeb configuration record in the body of this package is initialized and it's address is stored in the Configuration_Table.

Note: For tasking programs with small memory configurations, you can store No_Addr and provide a null __TASKDEB_INITIALIZE routine.

Configuring Taskdeb has no hidden memory requirements for non-tasking programs.

To remove task level debugging from the configuration, assign Taskdeb_Config_Address to No_Addr and remove the taskdeb configuration record, that is, remove the section Taskdeb Configuration Structure from v_usr_conf.2.ada in your view.

Taskdeb Configuration Structure parameters are grouped into the following categories:

Initialization Procedure Address

Initialize_Proc_Addr
is the address of a procedure that is called to initialize the task level debugging support in the runtime system. By default, the address of the procedure __TASKDEB_INITIALIZE is set to Taskdeb_Intinitialize. This address is found in the tasking archives.

Signal Number Configuration

Self_Signal
is pending, on self debuggers, when the program is set in motion with a task debugging command. The signal handler then starts debug_task. Note: If the underlying micro kernel is Rational Exec Microkernel, not threads, SIGALRM is used. If the underlying micro kernel is not Rational Exec Microkernel, but threads, Apex is layered on top of a UNIX threads kernel that uses SIGALRM and a different signal must be chosen.

Trap Instruction Configuration

Trap_Instruction_Use
is set to True if trap instructions are required. This boolean is normally set to True for cross targets.
Trap_Instruction
is the trap instruction.
Trap_Instruction_Length
is the number of bytes in the trap instruction.
Trap_Intr_Vector_Id
is the vector associated with Trap_Instruction. This vector ID is passed to Ada_Krn_I.Isr_Attach.

Note: UNIX-based self debuggers start the target program with Self_Signal.

Cross debuggers do not. The target program must be started by a trap instruction inserted at the next instruction executed.

Debug and Call Task Configuration

Debug_Task_Stack_Size
is the tack size of the debug task.
Debug_Task_Attr
is the address of a task attribute for the debug task, Assign the value No_Addr to use the default task attribute.
Debug_Task_Prio
is the task priority of the debug task.
Call_Task_Stack_Size
is the stack size of the call task.
Call_Task_Attr
is the address of a task attribute for the call task. Assign No_Addr to use the default task attribute.
Call_Task_Prio
is the task priority of the call task.

Taskdeb Configuration Record

Taskdeb_Config_Address
is the address of the Taskdeb configuration record.

ADAPATH References

Referencing the external symbol __ADAPATH_ includes a number of extra variables (about 16 addresses) and extra symbols with the names __ADAPATH_.... in the Ada executable. These symbols determine the directories that contain the runtime system libraries.

These variables are used for debugging in the development process. This section may be removed in user configurations to save a few bytes of memory in each ada executable.

Configuration_Table Structure

Modify the constant Configuration_Table in the body of this package to describe your user program environment to Apex.

This record is passed to Ts_Initialize during user program startup to control initialization. The declaration of the record's type is in package V_Usr_Conf_I.

Each parameter is described in detail. The parameters are grouped into the following categories:

Exception_Unwind_Safe package

This package is used to call initialization procedures and tables of procedures, that is, the elaboration table.

Floating Point Coprocessor Configuration Parameters

Floating_Point_Support
sets Floating_Point_Support to V_Ada_Info.Fp_Native if any task executes a floating-point instruction. Otherwise, to reduce task context switch times, set Floating_Point_Support to V_Ada_Info.Fp_Software.
Floating_Point_Control
is a structure that specifies the initial value for the Floating-Point Control Register (FPCR). This structure and its subcomponents are declared in the package V_I_Types found in vads_compatibility.ss/standard. Fields of the subcomponents and their values are as specified in the architecture manual for your target.

For information about floating point coprocessor control registers, see the documentation for your coprocessor.

Multithreaded Ada Configuration Parameters

Note: For a description of Apex support for Multithreaded Ada, threads, and POSIX threaded runtimes, see the Using Multithreaded Ada.

Concurrency_Level
suggests how many kernel execution vehicles should be in the multiplexing pool for threads with process level contention scope. This can affect the use of multiple processors by Ada tasks implemented with such threads, depending on the hardware and threads implementation.
Enable_Signals_Mask
is used during startup to initialize the main task's signal mask. All subsequently created threads/tasks inherit this signal mask. Normally, all asynchronous signals should be disabled. However, since SIGTERM is used to terminate a thread it shouldn't be disabled. A separate Ada task is created for each attached signal handler. This task does an Psignal.Sigwait() for the attached signal. A handler may only be attached for a signal disabled by these enable masks.
Exit_Signals_Mask
is the set of signals that, if not otherwise handled, will cause the program to exit. Exit signals not included in the enable signals masks are ignored. A special exit signals thread is created that does an Psignal.Sigwait() for any signal set in these exit signal masks.
Intr_Task_Prio
is the priority of an interrupt task doing an Psignal.Sigwait for an attached signal.
Intr_Task_Stack_Size
is the size of the stack for an interrupt task.

UNIX Signal Configuration Parameters

Disable_Signals_Mask
is the mask used in the kernel when signals are disabled. The kernel does not support nested asynchronous signals. You are cautioned against enabling additional signals.
Numeric_Signal_Enable
is used when calling foreign packages that use or ignore SIGFPE. If Numeric_Signal_Enable is True, the Ada program uses the UNIX SIGFPE signal to catch numeric errors. If it is False, numeric errors will not be caught as per the Ada RM and the Ada program will not affect SIGFPE.
Storage_Signal_Enable
is like Numeric_Signal_Enable, except that it catches storage violations with SIGSEGV and generates Storage_Error.

Time Slice Configuration Parameters (For Non-Threaded Versions)

Time_Slicing_Enabled
is set to True to enable time slicing.
Time_Slice_Interval
is the task's initial time slice value. An individual task's time slice can be changed at runtime from the user program by invoking V_Xtasking.Set_Time_Slice. The default time slice interval is 1.0 seconds.
Time_Slice_Priority
is the threshold priority for time slicing. If time slicing is enabled, it is applicable only to tasks whose priority is less than or equal to this threshold priority.

Attributes Configuration Parameters

Default_Task_Attributes
sets the default task attributes passed to the Ada kernel layer at task create. It is a type Ada_Kern_Defs.Task_Attr_T. The Prio field of Default_Task_Attributes specifies the Ada priority of created tasks. It can be set to the distinguished value Unspecified_Prio (the default) to defer to pragma Priority or the Ada default priority. Pragma Task_Attributes can be used to override Default_Task_Attributes on a per task or task type basis. On Most Systems: Default_Task_Attributes has the addresses of the default mutex attributes and condition variable attributes to be used to initialize the mutex and condition variable objects implicitly created for each task. Set these to null to use the default attributes. Otherwise, set them to the addresses of Ada_Krn_Defs.Mutex_Attr_T or Ada_Krn_Defs.Cond_Attr_T records, respectively, initialized in V_Init_Attr. On POSIX Threads: Default_Task_Attributes references the default POSIX attributeobject (Pthread_Attr_T) used to create the threads used to implement Ada tasks. It is initialized in V_Usr_Conf.V_Init_Attr.
Main_Task_Attr_Address
points to the task attributes to be used for the main task. Set it to No_Addr to use Default_Task_Attributes. Otherwise, set it to the address of an Ada_Krn_Defs.Task_Attr_T record initialized in V_Init_Attr.
Signal_Task_Attr_Address
points to the task attributes used for tasks created to rendezvous with interrupt entries. Set this parameter to No_Addr to use Default_Task_Attributes. Otherwise, set it to the address of an Ada_Krn_Defs.Task_Attr_T record initialized in V_Init_Attr. The priority of a signal task defaults to the priority of the attached task containing the interrupt entry. To override this priority, use the new style interrupt entry which contains the address of an Ada_Krn_Defs.Intr_Entry_T record. The Intr_Entry_T record has a Prio field.
Masters_Mutex_Attr_Address
points to the mutex attributes used to initialize the Ada kernel's master mutex. Set it to No_Addr to use Default_Mutex_Attributes. Otherwise, set it to the address of an Ada_Krn_Defs.Mutex_Attr_T record initialized in V_Init_Attr.
Mem_Alloc_Mutex_Attr_Address
points to the mutex attributes used to initialize the mutex for mutual exclusion during memory allocation. Set it to No_Addr to use Default_Mutex_Attributes. Otherwise, set to the address of an Ada_Krn_Defs.Mutex_Attr_T record initialized in V_Init_Attr.
Ada_Io_Mutex_Attr_Address
points to the mutex attributes to be used to initialize the mutex used for mutual exclusion during Ada I/O operations. Set to No_Addr to use the default mutex attributes. Otherwise, set to the address of an ada_krn_defs.mutex_attr_t record initialized in V_Init_Attr.

Miscellaneous Configuration Parameters

Old_Style_Max_Intr_Entry
In the current Ada RTS, the address specified in the interrupt entry for <entry>'Address use clause points to an Intr_Entry_T record defined in Ada_Krn_Defs. The Intr_Entry_T record contains two fields: the interrupt vector and the task priority to execute the interrupt entry's accept body. In earlier releases, the address in the for <entry>'Address use at clause specified the interrupt vector. For backwards compatibility, if the address in the for <entry>'Address use at clause is <= Old_Style_Max_Intr_Entry, it contains the interrupt vector value and not a pointer to an Ada_Krn_Defs.Intr_Entry_T record. Setting Old_Style_Max_Intr_Entry to 0 (No_Addr) disables the old interpretation.
Task_Storage_Size
specifies the size in bytes of the area set aside in the task control block for user storage. The Apex Extensions, Allocate_Task_Storage and Get_Task_Storage, manage this area in the task control block.
Pending_Count
specifies the maximum number of kernel service requests from an ISR, or nested ISR, held pending until the outer-most ISR completes. When the outer-most ISR completes, the kernel processes the queue of pending requests.
Timer_Min_Delay
specifies the minimum duration for an Ada delay. Normally, Timer_Min_Delay is set to the host's time between ticks. If the host's kernel was configured to use a faster timer, Timer_Min_Delay can be decreased accordingly. Absolute minimum is 0.000100 (100 microseconds).
Timer_Adjustment
is added to all timer delay requests. On some hosts, the setitimer service generates a SIGALRM before the time interval has expired. This may happen when the host's timer generates an interrupt for each tick. When a premature SIGALRM is received, the setitimer/SIGALRM sequence is repeated. If an adjustment is necessary, set Timer_Adjustment to the host's time between ticks. If you are willing to tolerate an occasional premature SIGALRM, Timer_Adjustment can be set to 0.0.

V_Signal_Isr Routine

The compiler emits code to call this routine for an interrupt entry in an active task. The interrupt entry acts as a signal that is posted when the interrupt occurs.

The starting address of Interrupt_Entry_Isr is passed to the Attach_Isr kernel service to install the ISR for the interrupt entry. When the interrupt occurs:

is executed which in turn calls this routine.

Additionally, the compiler emits code to call the Create_Signal kernel service to create a signal associated with the entry. This signal is posted by this routine.

This routine is called for all active task interrupt entry ISR's.

The body for this routine can be modified to do user specific processing before posting the interrupt entry's signal.

V_Pending_Overflow_Callout Routine (For Non-Threaded Versions)

Routine called when an ISR (signal handler) calls a kernel service and the queue of pending requests is full.

The default action for a pending kernel service request queue overflow is to print a diagnostic message and then exit.


Initialize/Finalize Routines

V_Start_Program

is the default entry point into the Ada program.

V_Start_Program_Self

is called from the operating system environment on a native system in the standard manner. On UNIX, for example, this is with parameters argc, argv, envp.

V_Start Program_Common

Completes the preliminary program initialization and calls Ts_Initialize.

Ts_Initialize

The address of V_Start_Program_Continue is passed as a parameter to Ts_Initialize. When Ts_Initialize completes its tasking initialization, it calls V_Start_Program_Continue.

V_Start_Program_Continue

V_Start_Program_Continue does any further initialization and does the program elaboration by executing each procedure in the elaboration table.

V_Integrated_Init

May be called during the initialization/elaboration of the foreign language portion of the program that is tightly integrated with Ada. This routine will do the initialization required to share memory management and exception unwinding with the foreign language. If the foreign language is provided by a vendor other than Rational, this routine will not be called.

V_Adainit

Initializes and elaborates the Ada portion of a program.

V_Adafinal

Finalizes the Ada portion of a program.


Configuring Ada.Real_Time

Annex D of the Ada Language Reference Manual (LRM) defines the Ada.Real_Time package to provide a standard interface to real time services (LRM D.8). In particular, the Time type represents real time with a precision defined by the Time_Unit constant, and the Clock function returns the current time, updated at intervals specified by the Tick constant. Values of the Time type can also be used in delay until clauses, suspending tasks until the specified real time has arrived.

Ultimately, the Clock function and delay clauses must be implemented by the Ada runtime using the underlying hardware. The support provided by the hardware will vary in the granularity and range of the hardware clock, the intervals at which delays can be checked, and the degree to which these features can be configured by programming the hardware. One way of accommodating these differences would be for the Apex to use a uniform implementation of the Time type across all platforms and translate between this and the hardware time representation used by the underlying clock and delay facilities. However, it is more useful for the Ada.Real_Time package to reflect the hardware as closely as possible. This can increase the efficiency and accuracy of translations between the Ada and hardware representations of time and provides Ada applications with information about the underlying support for time.

The Apex implementation of the Time type is a compromise between these two extremes. For all versions of Apex, the Time type is a 64 bit signed integer count of Time_Unit intervals from a fixed epoch (note that Time_Span has the same representation but is interpreted as an interval).

While the format of Time as a 64 bit integer is fixed, Time_Unit itself is not, and is configured to reflect the hardware representation of time. For example, if the clock is implemented by a hardware register that is incremented at a fixed interval, e.g. the Time Base (TB) register of PowerPC processors, then the Time_Unit is most naturally defined to be equal to this interval. The value of Tick is also configured to reflect the rate at which the clock hardware is updated. In some cases the underlying time base may not have sufficient resolution for Time_Unit, which must be no greater than 20 microseconds; in such cases the time base should be evenly divisible by Time_Unit to avoid roundoff errors.

The epoch will vary from platform to platform, and Ada.Real_Time provides no way to associate a Time value with an external date and time. This service is provided by the Ada.Calendar package which defines its own Time type and Clock function. While the LRM does not define a relationship between Ada.Calendar.Time and Ada.Real_Time.Time, in Apex these two types have identical representations, and the two Clock functions share the same underlying implementation.

Time Configuration Packages

This section describes the various packages that allow the behavior of Ada.Real_Time to be configured. Following sections document how these general descriptions apply to specific Apex products.

Ada.Real_Time

The Ada.Real_Time package itself is provided as modifiable source in Apex Embedded for Rational Exec and for Tornado. However, the only definitions that need to be configured to match the underlying support for time are Time_Unit and Tick, and these are derived from the Apex_Real_Time_Conf package, described below. Ada.Real_Time itself should never need to be changed.

Real_Time

The Real_Time package in the usr_conf.ss subsystem is configurable in all Apex products. Do not confuse this with the Ada.Real_Time package in real_time_systems.ss. Ada.Real_Time presents the interface defined in Annex D of the Ada LRM; Real_Time package provides the runtime implementation of much of Ada.Real_Time, in particular time arithmetic and conversions between one representation of time and another, as between Time_Span and Duration values. The version provided by Rational will always work, but the operations may be more general than desired; it may be possible to simplify some of the arithmetic using board-specific information. For example, if:

that is, if the representation of Duration is the same as that of Time_Span, it would be advantageous to replace the arithmetic in Real_Time.To_Duration and Real_Time.To_Time_Span with unchecked conversion.

Apex_Real_Time_Conf

The Apex_Real_Time_Conf package in real_time_systems.ss defines the relationship between the Ada representation of time and that supported by the hardware. It is present, but not necessarily configurable, in all Apex products. When configurable, Apex_Real_Time_Conf provides the simplest and most direct means of time configuration, and modifying it has a consistent effect on the other time-related packages. Of course, the hardware will not always be able to support a particular configuration of Apex_Real_Time_Conf. Even when it can, the software drivers may not take advantage of all of the features of the hardware. In such cases, the configuration should be rejected by terminating the program. All definitions in Apex_Real_Time_Conf are static constants of universal numeric types. (Except Hardware_Ticks_Per_Ada_Tick, which is an integer variable on POSIX based platforms). This is necessary in the case of Time_Unit, which is defined in Annex D as a universal real constant:

Other values are kept as universal constants to avoid roundoff errors until they are used by the runtime system.

There are at least six such constants for all Apex platforms (see Table 10). These constants are often redundant. For example, in configurations provided by Rational, Hardware_Ticks_Per_Ada_Tick is either 1, meaning that the Clock function accesses the hardware time base directly, or the same as Hardware_Ticks_Per_Delay_Interrupt, meaning that the runtime updates current time when it checks for pending delay clauses. This will probably be true of all platforms, but two separate definitions clarifies the configuration model.

Other constants besides these six are allowed, usually representing aspects of the hardware from which the six required constants are derived. For example, PowerPC platforms use the Time Base (TB) register of the CPU to implement the clock. This register is incremented once for every four bus clock cycles. Rather than defining the hardware tick value directly, it is clearer if its relationship to the CPU bus clock is made explicit. For example, if the processor bus frequency is 66 MHz, Time_Unit and the hardware tick value can be calculated as:

One common motivation for modifying Apex_Real_Time_Conf is to increase the resolution of the Time type by decreasing the value of Time_Unit. Since Time_Units_Per_Hardware_Tick is dependent on the value of Time_Unit, changing just the latter would also reconfigure the underlying hardware time base. To change the resolution of Time without affecting the hardware configuration, both of these constants must be changed together such that

remains constant. It is generally best to make Time_Units_Per_Hardware_Tick a power of two as noted in Table 10.

An example of a case where Time has greater resolution than the underlying time base is the default Tornado configuration. It defines the hardware time base (Tornado tick) to be 1/60 second. This is too small for the LRM definition of Time_Unit, which specifies a maximum of 20 microseconds, so Time_Units_Per_Hardware_Tick is defined to be 1024, the smallest power of two that satisfies this requirement. Time_Unit is therefore 1.0/(1024.0*60.0) seconds, or about 16.3 microseconds.

V_Krn_Conf.V_Timer_Support

The V_Krn_Conf.V_Timer_Support is only provided with Apex Embedded for Rational Exec and Tornado; it is always configurable. It provides an interface to the underlying hardware time facilities, but is very different in these two embedded products, as described below.

POSIX Time Configuration

Most aspects of Ada.Real_Time are fixed for POSIX based Apex products, including all native Apex products and Apex Embedded for LynxOS. These operating systems provide the POSIX representation of time as an integer count of seconds and nanoseconds. Since the Apex runtime has no direct access to the hardware, it reflects the POSIX representation in this fixed configuration, defining Time_Unit as 1 nanosecond; the Time type is therefore a 64 bit count of nanoseconds from the epoch. Ada.Real_Time.Tick is similarly derived from the POSIX operation clock_getres(), which provides the rate at which the POSIX clock (as reported by clock_gettime()) changes.

The Apex_Real_Time_Conf package is provided with these products, but the real_time_systems.ss subsystem is a nonconfigurable API. There is no V_Krn_Conf package.

The Real_Time in usr_conf.ss is configurable, though since the representation of the Time type is fixed there is less motivation for configuring arithmetic and conversion operators for it. If you modify Real_Time, the instructions for using the modified package are essentially the same as that for the Calendar_Configuration package described below, also in usr_conf.ss:

1 . Follow steps 1-2 in Configuring the User Library for creating a new usr_conf.ss view.

2 . Edit the context clause of v_usr_conf.2.ada in this new view to add:

3 . Modify Real_Time in the new usr_conf.ss view

4 . Proceed with steps 3-5 in Configuring the User Library.

Time Configuration for Apex Embedded Platforms

Apex Embedded (except for LynxOS) provides the Apex_Real_Time_Conf, Real_Time, Ada.Real_Time, and V_Krn_Conf.V_Timer_Support packages in source form, so the representation of time and time related behavior can be configured by modifying any or all of these packages. Changes to these configuration files may require recoding one or more of the real_time_systems.ss, usr_conf.ss, and krn_conf.ss views; if in doubt about dependencies it is safest to recode all of them before linking an application.

V_Krn_Conf is part of the kernel configuration built in the krn_conf.ss subsystem. Modifying this package and making the changes available to application programs is covered in the appropriate configuration guides for the Rational Exec microkernel and Tornado products.

Object code resulting from the compilation of the Real_Time package is included in the link closure of application programs as specified by the Link.des file in the usr_conf.ss subsystem. Changes to this package can therefore be incorporated by simply compiling the package and relinking the application.

Ada.Real_Time is imported into applications directly using with clauses; when such applications are relinked the Apex compiler will notice any changes and recompile the package.

Apex_Real_Time_Conf consists of compile-time constants, and as such generates no object code. However, it is on the closure of the remaining three packages, so changes to it should be treated as changes to all of them, requiring recompilation and relinking of the kernel, recompilation of Real_Time, and relinking of the application.

Time Configuration for Apex Embedded for Rational Exec

The Rational Exec product interfaces to the platform hardware through a Board Support Package (BSP). BSPs for a number of boards are available directly from Rational; others may be obtained from third parties, or you can write your own. These BSPs contain code that programs the hardware directly, without the mediation of an operating system or monitor.

The code that controls the timer hardware is in the BSP kernel configuration package V_Krn_Conf.V_Timer_Support, in the krn_conf.ss subsystem. This provides the most flexible configuration option; the drive code can be completely rewritten, even to support different timer hardware. By the same token, it is the most difficult, and requires a good working knowledge of the timer hardware. In any case, it should ensure compliance with the constants defined in the Apex_Real_Time_Conf package described above, otherwise the Ada Clock function, delay clauses, and time arithmetic will not reflect the behavior of the timer hardware. Further details on the configuration of V_Timer_Support can be found in "Timer Models for the Rational Exec Microkernel" in Chapter 2 of the Configuring Rational Exec Guide.

Time Configuration for Apex Embedded for Tornado

The Tornado OS provides software to control timer hardware and provides clock and alarm services. The Apex Embedded for Tornado runtime layers the implementation of the Time type, the Clock function, and delay clauses over this OS support. The function of the Apex time configuration in this case is largely to describe the Tornado OS support. In particular, the BSP and therefore configuration of the hardware drivers themselves is part of Tornado configuration.

Tornado represents time and duration as an integer count of ticks. The interval represented by a tick varies with BSP; the default value is typically 1/60 or 1/100 second. The Apex_Real_Time_Conf package must reflect the value of this tick, satisfying:

where sysClkRateGet is the Tornado function returning the number of ticks per second.

The typical default for the Tornado tick is too large to comply with the Ada definition of Ada.Real_Time.Tick, which must be a millisecond or less, or of Ada.Real_Time.Time_Unit, which must be 20 microseconds or less. Time_Unit can be brought into compliance by defining Time_Units_Per_Hardware_Tick large enough, but Tick is a measure of how often the clock changes, and so must be identical with the Tornado tick interval.

Tornado does allow the system tick to be adjusted using the sysClkRateSet() function. However, the default runtime configuration does not attempt to do this, since the tick is a system global, and Apex applications may not be the only ones that depend on it. Instead, the Apex_Real_Time_Conf configuration file is checked for compatibility with the Tornado system tick during runtime initialization, in Real_Time.Real_Time_Init. If this check fails, the runtime prints a message and terminates the program, e.g.:

This BSP is configured for a VxWorks tick of  100.
The VxWorks sysClkRateGet() function returns  60.
Try reconfiguring real_time.ss//apex_real_time_conf.1.ada such that
1.0 / (Time_Unit * Time_Units_Per_Hardware_Tick) 
is equal to the VxWorks tick.  In most cases, this can be done with:
    Hardware_Ticks_Per_Second : constant :=  60;

It is possible to modify Real_Time_Init to call sysClkRateSet() to force the Tornado tick to comply automatically; see comments in the source code for more details.

Both the Ada Clock function and delay clauses are implemented using Tornado services. The Tornado tick interval defines the granularity of all of these services, so the only supported value for Hardware_Ticks_Per_Delay_Interrupt and Hardware_Ticks_Per_Ada_Tick are therefore both 1. The default Real_Time_Init checks these values as well, printing out error messages and terminating the application for other values:

As with Rational Exec, the Apex Embedded for Tornado defines a V_Krn_Conf.V_Timer_Support package in the krn_conf.ss subsystem. Unlike Rational Exec, the subprograms in this package do no interface to the hardware but instead provide for translation between Ada Time and duration types and VxWorks tick counts. The Ada kernel layer of the Apex runtime archive library implements Ada time services by accessing the Tornado operations directly, but these operations need time in VxWorks ticks. The Ada kernel is precompiled and cannot use the constants in Apex_Real_Time_Conf directly, so V_Timer_Support provides translation between Ada Time_Span and Duration types and ticks for this purpose. In general, the only reason to configure this package would be to optimize the translation arithmetic based on special knowledge of the relationship between Ada and Tornado time representations. For example, if one is a power of two multiple of the other, multiplication and division can be replaced by shift operations. Note that this particular optimization is provided by the default configuration for Time_Span translation based on the values of the Use_Log_Time_Units_Per_Hardware_Tick and Log_Time_Units_Per_Hardware_Tick constants described above.


Configuring Ada.Calendar

Ada.Calendar is a standard package defined in LRM 9.6. It defines a Time type, a Clock function returning the current time as a value of this type, a set of subprograms relating Time values to times and dates appropriate to an implementation-defined time zone, and arithmetic operations on Time.

The Apex runtime provides default implementations of the Time interpretation subprograms that will work for many applications. In the case of native runtimes for POSIX operating systems, the default implementation uses operations provided by the OS for date and time interpretation (localtime_r() and mktime()). This allows adjustment of time interpretation, in particular the time zone, using the TZ environment variable. The default implementation also initializes the clock internal to the Apex runtime using the OS clock service. This is also the default implementation provided with Apex Embedded for LynxOS and Apex Embedded for Tornado, both of which provide the required operations.

The Apex Exec cross-compilation systems for embedded platforms provides a different default implementation since there is no underlying OS to provide the current time or interpret time and dates. The default implementation for Ada.Calendar initializes the runtime clock to an arbitrary start date and provides and interprets time as Greenwich Meridian Time (GMT) with no Daylight Savings Time (DST) correction.

Those using Apex to program Embedded platforms will often find the interpretations provided by the default Ada.Calendar implementation inadequate for their purposes, if only because the time zone or daylight savings time convention is incorrect for their location. Those using Apex to create native applications will usually find the default adequate, though there are occasions where special interpretations may be useful. For example, one solution proposed for two-digit year (Y2K) problems is to set the date back 28 years (since the correspondence between days of the week and dates from 1901 to 2099 repeat at that interval) and then adjust the resulting output in a post-processing step. Ada.Calendar can be adjusted to perform this conversion by subtracting 28 from year numbers in Split and adding 28 to year numbers in Time_Of.

The Calendar_Configuration Package

To allow for configuration of Ada.Calendar, the source code for the time interpretation subprograms is exposed in the Calendar_Configuration package, located in the usr_conf.ss subsystem together with the general V_Usr_Conf runtime configuration package. Calendar_Configuration exports time interpretation subprograms which are in turn imported by Ada.Calendar to implement those defined by the LRM. Modifying or replacing these routines will change the behavior of the corresponding Ada.Calendar operations.

Most of the exported subprograms are identical to those in Ada.Calendar:

The corresponding exported names are uniformly modified to ensure uniqueness during the link:

The Calendar_Configuration package is not part of the applications closure but is instead linked in directly, so no elaboration is performed. To allow for any required initialization, the runtime calls an initialization procedure in Calendar_Configuration during application startup. This is especially useful for setting the Ada runtime clock with the current time:

These subprogram declarations and the corresponding exported link names should not be modified.

Modifying Calendar_Configuration

It should generally be sufficient to modify the body of Calendar_Configuration, calendar_configuration.2.ada. The most common modifications will be to Apex Embedded for Rational Exec products, to configure the time zone and (optionally) set the current time from a hardware Real Time Clock (RTC).

At the beginning of the embedded version of calendar_configuration.2.ada there are declarations specifying the time zone and daylight savings time conventions; comments provide instructions for changing these to match your location.

If your hardware provides an RTC, you can use this to set the clock in the runtime from the Initialize procedure. How this is done will depend on the format in which the clock hardware provides the time and date. In general, it will have to be converted into time and date values that can be passed into the Time_Of function to convert it to the corresponding Time value. V_I_Time.Set_Time (in the rational.ss subsystem) can then be used to set the runtime clock. Note that V_I_Time.Set_Time takes an argument of type V_I_Types.Time_T, the underlying runtime time type. The Time value returned by Time_Of can be converted to Time_T using the To_Time function provided in the body of Calendar_Configuration.

The default implementation of Calendar_Configuration.Initialize provided with Apex Embedded for Tornado products sets the Ada clock from the Tornado system clock as reported by the POSIX function clock_gettime(). This in turn depends on the Tornado clock being set correctly before the Apex application is started. Tornado doesn't always do this automatically, frequently resulting in a system time, and therefore an Ada time, of the POSIX epoch (January 1, 1970). If Tornado can't be configured to set the system time automatically, it should be possible to use a separate application to set it using the POSIX clock_settime() function.

For other modifications, and for modification of the Calendar_Configuration package shipped with Apex native systems, the only general guidelines are to adhere to the parameter profiles of the subprograms exported in the package spec.

Using a Modified Calendar_Configuration Package

As with the V_Usr_Conf package, the default version of Calendar_Configuration is included in the runtime library archives linked with each application. To replace it with a modified version, follow these steps:

1 . Follow steps 1-2 in Configuring the User Library for creating a new usr_conf.ss view.

2 . Edit the context clause of v_usr_conf.2.ada in this new view to add:

3 . Modify Calendar_Configuration in the new usr_conf.ss view

4 . Proceed with steps 3-5 in Configuring the User Library

The modified Calendar_Configuration will be included instead of the default one in the archive library. Note that V_Usr_Conf will also be replaced; it is not possible to replace only Calendar_Configuration. However, an unmodified V_Usr_Conf is just the source code for the default version and so will not change any of the default configuration.


Task Names

The runtime assigns a unique name to each Ada task. Part of this name is a pseudorandom identifier based on the source code used to specify the task. The function used to generate this pseudorandom identifier is declared in usr_conf.ss views and can be configured. For more information see Task Names.


Rational Software Corporation 
http://www.rational.com
support@rational.com
techpubs@rational.com
Copyright © 1993-2002, Rational Software Corporation. All rights reserved.
TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS