TOC PREV NEXT INDEX DOC LIST MASTER INDEX



User Library Configuration Parameters


Introduction

The user library contains support routines for user programs. Many of the functions in the user library are called implicitly by the compiler-generated code.

This section contains the target-processor specific configuration information for users who wish to customize their configuration or create a new configuration. If you are using one of the board support packages supplied by Rational, the configuration instructions in the "Getting Started" chapter of Programming for Rational Exec are sufficient for your needs.

The following topics are covered in this chapter:


User's Board Support Model Contents

The user's board support model contains some switches that are unique to the embedded development environment. Below is a list of switches from the Policy/Switches file in an example user's board support model:

The second "include" line references a list of link addresses that is shared by the user program, kernel and TDM.


Usr_Conf Configuration Components

This configuration consists of the following routines and structures.

Each of these components is discussed in detail below. To find any one of these components in the source files, search for the title string of the desired component. In the source file, the code for each component begins with a line similar to the following:

The file v_usr_conf_i.1.ada (in rational.ss) provides the data structures for the small block sizes and configuration tables, constants used to select configuration options, and routines used within the configuration package.

The components of this package interact directly with Apex environment and should not be accessed explicitly by application code. The entire specification is private.

Small_Block_Sizes_Table Structure

The constant, Small_Block_Sizes_Table is declared in this package. This formation is used only if a cached storage pool is used (see "Memory Management" in Using the Ada Runtime). This aggregate lists the small block sizes. If Small_Block_Sizes_Table is initialized to (8, 16, 128), three small block lists are created that hold objects of 8 bytes, 16 bytes and 128 bytes respectively. Allocation sizes between these values yield an object of the larger small block size. For example, user objects of size 20 are allocated as 128 byte small blocks.

Sizes must be multiples of 2 * (Address'Size / Storage_Unit).

Sizes must be in ascending order.

The address of Small_Block_Sizes_Table must be assigned to the parameter Small_Block_Sizes_Address in the Mem_Alloc_Conf_Table.

This information is ignored if Malloc_Based_Allocation is selected. See Memory Allocation Configuration Table.

Memory Allocation Parameters

For additional information about memory management in Apex, see "Memory Management" in the Ada Runtime Guide.

Min_Size

Min_Size defines the minimum size object to be allocated. It determines the size at which an over-large space is broken into a perfect fit and a new free storage block. For example, a user asks for 1000 bytes and the next free slot has 1500 bytes. If Min_Size < 500, exactly 1000 bytes of the free space are allocated and the remainder (500 bytes less header overhead) is put back on the free list. If Min_Size > 500, 1500 bytes are allocated. This value should never be larger than the smallest small block. This controls fragment size.

This information is ignored if Malloc_Based_Allocation is True.

Num_Small_Block_Sizes

Num_Small_Block_Sizes gives the number of small object sizes to be handled by the allocator. This is the number of elements in the Small_Block_Sizes_Table.

This information is ignored if Malloc_Based_Allocation is True.

Small_Block_Sizes_Address

Small_Block_Sizes_Address indicates the starting address of the Small_Block_Sizes table defined above.

Min_List_Length

Min_List_Length specifies the minimum list length of a small blocks list to keep the allocator from coalescing blocks off of it. When deallocating a block, the allocator also decides whether it should go back on the small blocks list or attempt to be coalesced with its neighbors and put on the regular free list. Note that the actual length is often shorter when little or no deallocation is being done.

Malloc_Based_Allocation

Malloc_Based_Allocation specifies, when True, that malloc should be used for all allocations (instead of using runtime managed heaps layered over sbrk).

External_Pool_Protection

External_Pool_Protection specifies the protection mechanism to use for the External_Storage_Pool (configured in Storage_Pool_Configuration). The default value is set appropriately for the external storage pool specified in Storage_Pool_Configuration. If the external storage pool is changed, the protection may also need to be changed.

Specify None if the application is non-tasking or if the external allocation mechanism is multitasking safe, for example, malloc in a threaded environment. This is the default for applications that are non-tasking or use a multitasking safe external storage pool.

Specify Lock_Mutex if allocations by tasks require mutex but kernel allocations do not, that is, if concurrent calls to the external allocator from the kernel and a task cannot interfere with each other.

Specify Disable_Preemption if allocations (from the external storage pool) by tasks could interfere with allocations by the kernel (as well as each other). This is the default for multitasking applications that use a non-threaded runtime.

Private_Storage_Pools

Private_Storage_Pools specifies, when True, that a reclaimable collection should be assigned a private (rather than a shared) storage pool.

This configuration parameter is ignored if Malloc_Based_Allocation is True.

Storage_Pool_Configuration

Storage_Pool_Configuration specifies the routines used to create the runtime standard storage pools:

To use the runtime default set a table entry to Use_Standard_Pool_Routine.

To disable the use of a pool, set its entry to Use_No_Pool_Routine or provide a user defined storage pool creation routine.

Note: Only the heterogeneous and homogeneous private pools and the default pool (a shared heterogeneous pool) can be disabled. If the heterogeneous/homogeneous pool is disabled, the default pool is used instead. If the default pool is disabled, the external pool is used.

User defined storage pool creation routines must return an object of the (Ada95, tagged) type

and have the following parameter profiles:

Allocation_Strategy

Allocation_Strategy specifies the strategy to be used when choosing a block from the free list: FIRST_FIT or BEST_FIT.

This parameter is ignored if Malloc_Based_Allocation is True.

CCA Configuration Data

Cca_Intr_Number

This is the entry in the interrupt vector table reserved for CCA use. This number may be changed to force CCA to use a different entry in the interrupt vector table.

Other CCA Configuration Data

Do not modify the other data in this section.

Prof Configuration Data

A detailed discussion of the Statistical Profiler is in the Utilities Guide.

Profile_Intr_Number

This is the entry in the interrupt vector table reserved for use by the statistical profiler. This number may be changed to force a different entry in the interrupt vector table.

Trace Configuration Data

Tracing is discussed in the Tasking Logic Analyzer Guide.

Trace_Buffer_Size

This 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).

These symbols are read from your load module unless you are using hardware logging.

Kernel_Logging

Kernel events are used internally by run-time developers unlike runtime events which are used by tasking logic analysis. Events and arguments are subject to change. If you wish to generate them, change this boolean to True.

Taskdeb Configuration Structure

The Taskdeb Configuration structure configures task level debugging.

The Taskdeb Configuration record in the body of this package is initialized and it's address is stored in the Configuration_Table. It is possible to store No_Addr and provide a null __Taskdeb_Initialize routine for tasking programs with small memory configurations. Configuring Taskdeb has no hidden memory requirements for non-tasking programs.

To eliminate task level debugging from the configuration, remove the definition of the Taskdeb_Config_Rec record from v_usr_conf.2.ada and specify No_Addr as the address of Taskdeb_Config_Address.

Initialization Procedure Address

Initialize_Proc_Addr

Address of a procedure that is called to initialize the task level debugging support in the runtime system. Normally the address of the procedure __Taskdeb_Initialize is configured. This address is found in the tasking archives.

Signal Number Configuration

Self_Signal

Debuggers cannot start programs with signals pending. This value should be 0.

Trap Instruction Configuration

Embedded debuggers cannot start the target program with Self_Signal, so a trap instruction must be inserted at the next instruction that the program would execute. The following parameters describe the trap instruction:

Trap_Instruction_Use

Set this boolean to True if trap instructions are required. This is normally set to True for embedded targets.

Trap_Instruction

This is the actual trap instruction.

Trap_Instruction_Length

This is the number of bytes in the trap instruction.

Trap_Intr_Vector_Id

This is the vector associated with Trap_Instruction. This vector ID is passed to Ada_Krn_I.Isr_Attach.

Debug and Call Task Configuration

Debug_Task_Stack_Size

Stack size of the debug task. [Default: 8000]

Debug_Task_Attr

Address of a task attribute for the debug task. No_Addr uses the default task attribute.

Debug_Task_Prio

Task priority of the debug task.

Call_Task_Stack_Size

Stack size of the call task.

Call_Task_Attr

Address of a task attribute for the call task. No_Addr uses the default task attribute. [Default: No_Addr]

Call_Task_Prio

Task priority of the call task.

Adapath Reference

Referencing the external symbol __ADAPATH_ causes a number of extra variables (about 16 addresses) and extra symbols with the names __ADAPATH_ to be included in the ada executable. From these symbols the directories that contain the run time system libraries can be determined. These variables are used for debugging during development.

This section may be removed in user configurations to save a few bytes of memory in each ada executable.

Configuration_Table Structure

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

This record is copied into the variable Configuration_Table and then is modified as required by the application.

V_Pragma_Main_Adjust, V_Init_Usr_Data

These procedures modify the Configuration_Table variable as specified by application pragmas. V_Pragma_Main_Adjust modifies it according to the Main pragma, if any, specified for the application; V_Init_Usr_Data modifies it for certain other pragmas such as Task_Dispatching_Policy.

If support for pragma Main is not required, V_Pragma_Main_Adjust and the call to it in V_Start_Program_Common can be removed; if support for the other tasking related pragmas is not required, V_Init_Usr_Data and its call can be removed. If both are removed, Configuration_Table can be made a constant (that is, the name of Initial_Configuration_Table can be changed to Configuration_Table to replace the Configuration_Table variable).

The Configuration_Table record is passed to Ts_Initialize (accessed through the external name, Usr_Configuration_Table) during user program startup to control its initialization. The declaration of this record's type is in the package V_Usr_Conf_I.

Stack Configuration Parameters

The following parameters are used to specify different user configurable stack sizes.

All task stacks are allocated from the kernel's area when created. You can display the task stack size by using the debugger command, lt use. Simply run the program under the debugger and enter lt use when you want to display the task stack usage and location.

Main_Task_Stack_Size

Main_Task_Stack_Size is the size of the main subprogram's stack. The stack size excludes room at the bottom for exception handling. The stack is allocated from the kernel's heap/stack area.

Default_Task_Stack_Size

Default_Task_Stack_Size is the size of each task's stack area. This value can be overridden with the for T'Storage_Size use ### length clause.

The debugger command, lt use, displays maximum stack usage. This usage feedback can be used to refine your estimates for the different stack sizes.

Exception_Stack_Size

Exception_Stack_Size is the size of the space set aside below the bottom of the task stack for exception unwinding.

Idle_Stack_Size

Idle_Stack_Size is the size of the stack for the idle task.

It is not used for the VADS_MICRO cross targets. Instead, the Idle_Stack_Size found in V_Krn_Conf's configuration table is used.

Signal_Task_Stack_Size

Signal_Task_Stack_Size is the size of the stack for tasks created for doing rendezvous with interrupt entries. The Ada tasking RTS creates a signal task for each interrupt entry.

Fast_Rendezvous_Enabled

Normally, the accept body of an Ada rendezvous is executed only in the context of the acceptor task. Setting this parameter to True, allows the accept body to be executed in the context of the caller task, if the acceptor task is already waiting. By doing this optimization, we are able to eliminate task context switches and dramatically improve rendezvous performance.

This parameter is set to False only for multi-processor Ada where the accept body must execute in the acceptor task bound to a processor. The default is True.

Wait_Stack_Size

For a fast rendezvous, the acceptor task saves its register context, switches to a wait stack and waits. Eventually, the caller task restores and uses the acceptor task's saved register context.

Wait_Stack_Size specifies how much stack is needed when the acceptor task switches from its normal task stack to a special stack it can use to call a kernel service to block itself.

Wait_Stack_Size is only used if Fast_Rendezvous_Enabled is True. Setting Wait_Stack_Size to zero also disables the fast rendezvous optimization.

Heap Memory Callout Configuration Parameters

These parameters are used by the default memory allocation strategy. When the user program executes an allocator, the allocated object uses up memory from the heap.

Heap_Extend

Heap_Extend defines the minimum number of storage units requested when the Default_Storage_Pool is extended (because the amount of memory left in the pool is insufficient to satisfy a requested allocation). This parameter is ignored if Malloc_Based_Allocation is True.

Memory Allocation Configuration Table

Mem_Alloc_Conf_Table_Address

Mem_Alloc_Conf_Table_Address points to the memory allocation table containing parameters specific to the particular allocation routines being used. If you write your own allocation routines, you can point this address to your own configuration table.

Attributes Configuration Parameters

When an task is created, attributes that initialize the task are passed to the underlying microkernel. The attributes configuration parameters contain the default task attributes and the attributes for the main task.

The tasking, memory allocation, and I/O routines use mutexes to protect their data structures. When a task needs to block, it waits on a condition variable. The attributes configuration parameters initialize the mutex and condition variable objects implicitly created by the RTS routines.

In general you can use the default mutex and condition variable attributes. With these defaults:

Default_Task_Attributes

These are the default task attributes to be passed to the underlying OS at task create. This is the task attribute record, Task_Attr_T, defined in ada_krn_defs.1.ada.

It 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 to No_Addr to use the default mutex or condition variable attributes. Otherwise, set to the address of an Ada_Krn_Defs.Mutex_Attr_T or Ada_Krn_Defs.Cond_Attr_T record initialized in V_Init_Attr.

It also has the address of the default sporadic attributes. Sporadic tasks are unsupported in Apex.

The prio field in the default task attributes isn't used. The default task priority is 0 (Ada 83) or System.Default_Priority (Ada 95). This can be overridden by using either pragma Priority() or pragma Task_Attributes() on a per task or task type basis.

Mutex_Attr

Mutex_Attr points to the mutex attributes that can be used to create the runtime mutex associated with each task. This mutex is used to synchronize various Ada tasking operations by or on this task.

Cond_Attr

Cond_Attr points to the default attributes that can be used to create the runtime condition variable associated with each task. This condition variable is used by the runtime to suspend the task as required to implement Ada tasking.

V_Init_Attr

If you do not want to use the default mutex or condition variable attributes to create tasks, change the V_Init_Attr routine to initialize the Mutex_Attr and Cond_Attr records provided in the body of V_Usr_Conf and change the corresponding parameters in the Default_Task_Attributes to point to them.

Main_Task_Attr_Address

Main_Task_Attr_Address points to the task attributes to be used for the main task. Set it to No_Addr to use the above default task attributes. Otherwise, set it to the address of an Ada_Krn_Defs.Task_Attr_T record initialized in V_Init_Attr.

The prio field in the main task attributes isn't used. The default priority for the main task is 0. This can be overridden by using pragma Priority() in the main procedure.

Signal_Task_Attr_Address

Signal_Task_Attr_Address points to the task attributes to be used for the tasks created to rendezvous with interrupt entries. Set it to No_Addr to use the above default task attributes. Otherwise, set it to the address of an Ada_Krn_Defs.Task_Attr_T record initialized in V_Init_Attr.

The prio field in the signal task attributes is not used. The priority of a signal task defaults to the priority of the attached task containing the interrupt entry. This priority is overridden by using the new style of an 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

Masters_Mutex_Attr_Address points to the mutex attributes to be used to initialize the kernel's master mutex. Set Masters_Mutex_Attr_Address to No_Addr to use the default mutex attributes.

Mem_Alloc_Mutex_Attr_Address

Mem_Alloc_Mutex_Attr_Address points to the mutex attributes to be used to initialize the mutexes used for mutual exclusion during memory allocation. Set Mem_Alloc_Mutex_Attr_Address to No_Addr to use the default mutex attributes. Otherwise, set it to the address of an Ada_krn_Defs.Mutex_Attr_T record initialized in V_Init_Attr.

Ada_Io_Mutex_Attr_Address

This points to the mutex attributes to be used to initialize the mutex used for mutual exclusion during Ada I/O operations. Set it 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.

Code Coverage Configuration Parameters

Send_Sigint_To_Cca

This boolean controls the behavior of the program upon receiving a SIGINT. If Send_Sigint_To_Cca is True, then SIGINT is sent to cca: coverage information is recorded in cca.out and then the program immediately terminates. If False, SIGINT is not sent to cca. Default setting is True.

Miscellaneous Configuration Parameters

Old_Style_Max_Intr_Entry

In the current Ada RTS, the address specified in the interrupt entry for use at clause points to an Intr_Entry_T record defined in Ada_Krn_Defs. The Intr_Entry_T record contains two fields: interrupt vector and the task priority for executing the interrupt entry's accept body. In earlier releases, the address in the for use at clause specified the interrupt vector.

For backwards compatibility, if the address in the for use at clause is <= Old_Style_Max_Intr_Entry, then, 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 way of interpretation.

V_Signal_Isr Routine

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

When an interrupt entry is recognized, the compiler emits the following code:

The starting address of the above code (Interrupt_Entry_Isr) is passed to the Attach_Isr kernel service to install the ISR for the interrupt entry. When the interrupt occurs, the above code 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 referenced by the ISR header record. This signal is posted by V_Signal_Isr.

Note: This routine is called for all interrupt entry ISRs.

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

V_Taskdeb_Isr Routine

The runtime attaches a hidden procedure to the taskdeb trap defined above. This hidden procedure calls V_Taskdeb_Isr with the address of a procedure that needs to be called.

V_Taskdeb_Isr is responsible for the following:

V_Traps Package

V_Traps defines the routines for doing the traps to TDM or kernel.

Note: Only the trap number constants in this package's body should be changed.

The following routines do the traps:

Storage Management Callout Routines

The lowest level of the (default configured) External_Storage_Pool makes use of the callout routines supplied in the body of this package.

V_Extern_Alloc_Callout

V_Extern_Alloc_Callout is called by the (default configured) External_Storage_Pool when it needs to allocate memory. The default implementation of this callout calls Krn_Call_I.Krn_Alloc.

V_Extern_Free_Callout

V_Extern_Free_Callout is called by the (default configured) External_Storage_Pool when it wants to deallocate memory. The default implementation of this callout calls Krn_Call_I.Krn_Free.

V_Extern_Size_Callout

V_Extern_Size_Callout is called by the (default configured) External_Storage_Pool to determine the maximum amount of memory that could be allocated. The default implementation of this callout returns Alloc_T'Last.

V_Start_Program and V_Start_Program_Continue Routines

Don't use the runtime to initialize an Ada environment for V_Start_Program. The runtime hasn't been sufficiently initialized at this point.


V_Start_Program is the default entry point into the Ada program. pragma External_Name associates this routine with the external symbol __start, the default program entry point. V_Start_Program does preliminary initialization and calls Ts_Initialize, passing the address of V_Start_Program_Continue as a parameter to Ts_Initialize. When Ts_Initialize completes its tasking initialization, it calls 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.


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