This appendix contains the lay-out of the API headers, as they are generated by EuroSim for C and Fortran model code. As EuroSim does not generate API headers for Ada-95 model code, the information in this appendix can be used to create API headers for Ada-95 model code by hand.
The API header is contained in a comment block at the top of the source code
/* */ in C, on lines starting with
C in Fortran and on lines
-- in Ada-95). In Ada-95 and Fortran, make sure that if the original
source code started with a comment block, that there is an empty line between
the API header and the source code comments.
Each API header consists of the following four keywords (see Section 2.5 for more information):
The first three keywords are used to describe the variables in the source code, and the last keyword is used to describe the entry points. The first keyword is used once per source file, the last three once per entry point.
Each keyword is preceded by a straight quote.
Global state variables are the variables which are used in the current source file only, and should not be seen by other source files.
The syntax of the keyword is:
'Global_State_Variables VariableType VariableName
The VariableType and VariableName are as they are defined in
the source file. The Attributes can be zero or more of the attributes
described below. If more than one attribute is used, they should be separated
by spaces or newlines. If more than one variable is defined with the keyword,
each VariableType VariableName
: Attributes set should
be separated by commas.
This defines text as the unit of the variable. The string text can be any string.
This defines a string text which is used as description of the variable.
No additional information. It defines a variable as `parameter', meaning that EuroSim should not allow the value of the variable to be changed during a simulation (only during initialization).
This defines value as the initial value for the variable. value should be in the correct syntax for the associated variable.
These two define the minimum and maximum values of the variable. value should be in the correct syntax for the associated variable.
This keyword is used to define the variables that are used by the current source file, and which are set to a value by another source file. The syntax of the keyword is the same as for global state variables.
This keyword is used to define the variables that are used by other source files, and which are set to a value by the current source file. The syntax of the keyword is the same as for global state variables.
This keyword is used once per function/procedure that has to be available for the scheduler. See Appendix H for more information on restrictions on functions/procedures to be used as entry points.
The syntax of the keyword is:
It is also possible to `publish' variables from the data dictionary. There are several functions that set the address where a variable or entry point in a certain data dictionary is stored, thus making it accessible from the outside. This is useful for people who want to make their own model interfaces.
The publish functions are divided in two categories, a function to get the runtime data dictionary and functions to publish data variables and entry points in a data dictionary.
When a EuroSim simulation application program needs access to the
runtime data dictionary it must call
esimDict(void). This function
returns a pointer to the runtime data dictionary (
DICT*) and is
defined in the header file esimDict.h.
dictPublish(DICT *dict, const char *name, const void *address) sets
the address of the variable specified by name in the data dictionary
specified by dict to address. This function can be
called from C or Ada.
dictpublish_(DICT *dict, const char *name, const void *address, int namelen) is
the Fortran wrapper for
dictPublish. It has an extra parameter with the
length of the name parameter. This is required by the calling
convention of Fortran functions.
dictPubEntry(DICT *dict, const char *name, EntryPtr address) sets the function
address of the entry point specified by name in the runtime
data dictionary to address. This function can be called from
C or Ada.
dictpubentry_(DICT *dict, const char *name, EntryPtr address, int namelen) is
the Fortran wrapper for
dictPubEntry. It has an extra parameter with
the length of the name parameter. This is required by the
calling convention of Fortran.
The prototypes for these functions can be found in DictPublish.h.
As an example, the API header from the Thruster.c file used in the case study is shown below (see Section 4.5 for the source code and the API information).
/* 'Entry_Point Thruster: DESCRIPTION="The thruster brings the satellite to" " the correct altitude." 'Global_Input_Variables int lowerAltitudeLimit: UNIT="km" DESCRIPTION="Below this limit, the thruster must" " be turned on." INIT="210" MIN="0" MAX="1000", int sateliteAscentSpeed: UNIT="km/h" DESCRIPTION="The ascent speed of the satellite." INIT="10" MIN="1" MAX="200", int thrusterOnOff: UNIT="On/Off" DESCRIPTION="Indicates whether the thruster is" " on or off." INIT="1" MIN="0" MAX="1", int upperAltitudeLimit: UNIT="km" DESCRIPTION="The upper limit at which the thrust" "er is to be switched of." INIT="280" MIN="0" MAX="1000" 'Global_Output_Variables int thrusterOnOff: UNIT="On/Off" DESCRIPTION="Indicates whether the thruster is" " on or off." INIT="1" MIN="0" MAX="1" */
Note that there is no restriction on line length for the API headers, but that the API Editor generates no lines longer than 80 characters. This is done to ensure good readability on most terminals.
Also note that variables which act both as input as well as output variables are defined twice in the API header.
--------------------------------------------------------- -- -- Name: ball.adb -- Type: Ada-95 implementation. -- -- Author: John Graat (NLR). -- Date: 19961125 -- Changes: none -- -- -- Purpose: Model for the Simulation of a Bouncing Ball. -- -- The Bouncing Ball describes a ball that is thrown -- straight-up from the ground with an initial velocity -- or dropped from an initial height. -- In the absence of friction, the ball should reach -- exactly the same maximum height time and time again. -- The ball is described as a mass point. -- -- Parameters: GRAVITY Gravitation constant [m/s2] -- -- State: Height Height of the ball above the ground [m]. -- Velocity Velocity of the ball [m/s]. -- -- Additional: DeltaT Time Step for the Model. -- LoadLoop Loop counter to increase computation time. -- Duration Duration of the Ball Model. -- -- Remark: The mass of the ball has mplicitly been set to 1 [kg]. -- -- API Header required for the correct Data Dictionary: -- -- 'Entry_Point ball.Ball: -- DESCRIPTION="Computation of one time step of the ball" -- "." -- 'Global_Input_Variables -- Long_Float ball.deltat: -- UNIT="s" -- DESCRIPTION="Time step for the Ball Sub-Model." -- MIN="0" -- MAX="1", -- Long_Float ball.height: -- UNIT="m" -- DESCRIPTION="Height of the ball." -- MIN="0" -- MAX="100", -- Integer ball.loadloop: -- UNIT="-" -- DESCRIPTION="Loop counter to increase load." -- MIN="0", -- Long_Float ball.velocity: -- UNIT="m/s" -- DESCRIPTION="Velocity of the Ball." -- 'Global_Output_Variables -- Long_Float ball.deltat, -- Long_Float ball.height, -- Long_Float ball.velocity, -- Long_Float ball.duration: -- DESCRIPTION="Duration of the Ball Model." -- --------------------------------------------------------------- with integr; with esim; use esim; package body Ball is GRAVITY : constant Long_Float := 9.80664999; -- Global variables of the Bouncing Ball -- Actual declaration of these variables can be found in ball.ads -- Height, Velocity, DeltaT : Long_Float; -- Duration : Long_Float; -- LoadLoop : Integer; procedure Ball is -- Local Variables of the Bouncing Ball State, Dot : Integr.Vector; Rate, Fine : Long_Float; Loopcnt : Integer; Start, Stop : Long_Float; begin -- Get the Start time from the Wall Clock. Start := esimGetWallclocktime; -- Get DeltaT Time from the EuroSim Tool. Rate := EsimGetTaskrate; DeltaT := 1.000/Rate; Fine := DeltaT/Long_Float(100); for Counter in 1 .. 100 loop State(1) := Height; State(2) := Velocity; Dot(1) := Velocity; Dot(2) := -GRAVITY; -- Forward Euler Integration. Integr.intEulerADA( State, Dot, 2, Fine ); -- Check on events, e.g. Ball touches the ground. if State(1) < 0.0 then State(2) := -State(2); end if; Height := State(1); Velocity := State(2); end loop; Loopcnt := 0; -- Loop to increase the computation time of the model. for Counter in 1..LoadLoop loop Loopcnt := Loopcnt + 1; end loop; -- Get Stop time from the Wall Clock and calculate Duration. Stop := esimGetWallclocktime; Duration := Stop - Start; end Ball; end Ball;