mirror of
https://github.com/nasa/fpp.git
synced 2025-12-16 21:35:53 -06:00
714 lines
22 KiB
Plaintext
714 lines
22 KiB
Plaintext
== Defining Types
|
|
|
|
An FPP model may include one or more *type definitions*.
|
|
These definitions describe named types that may be used elsewhere in the
|
|
model and that may generate code in the target language.
|
|
For example,
|
|
an FPP type definition may become a class definition in {cpp}.
|
|
|
|
There are four kinds of type definitions:
|
|
|
|
* Array type definitions
|
|
* Struct type definitions
|
|
* Abstract type definitions
|
|
* Alias type definitions
|
|
|
|
Type definitions may appear at the top level or inside a
|
|
<<Defining-Modules,module definition>>.
|
|
A type definition is an
|
|
<<Writing-Comments-and-Annotations_Annotations,annotatable element>>.
|
|
|
|
=== Array Type Definitions
|
|
|
|
An *array type definition* associates a name with an *array type*.
|
|
An array type describes the shape of an
|
|
<<Defining-Constants_Expressions_Array-Values,array value>>.
|
|
It specifies an element type and a size.
|
|
|
|
==== Writing an Array Type Definition
|
|
|
|
As an example, here is an array type definition that associates
|
|
the name `A` with an array of three values, each of which is a 32-bit unsigned
|
|
integer:
|
|
|
|
[source,fpp]
|
|
----
|
|
array A = [3] U32
|
|
----
|
|
|
|
In general, to write an array type definition, you write the following:
|
|
|
|
* The keyword `array`.
|
|
* The <<Defining-Constants_Names,name>> of the array type.
|
|
* An equals sign `=`.
|
|
* An <<Defining-Constants_Expressions,expression>>
|
|
enclosed in square brackets `[` ... `]` denoting the size (number of elements) of the array.
|
|
* A type name denoting the element type.
|
|
The available type names are discussed below.
|
|
|
|
Notice that the size expression precedes the element type, and the whole
|
|
type reads left to right.
|
|
For example, you may read the type `[3] U32` as "array of 3 `U32`."
|
|
|
|
The size may be any legal expression.
|
|
It doesn't have to be a literal integer.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
constant numElements = 10
|
|
array A = [numElements] U32
|
|
----
|
|
|
|
==== Type Names
|
|
|
|
The following type names are available for the element types:
|
|
|
|
* The type names `U8`, `U16`, `U32`, and `U64`, denoting the type of unsigned
|
|
integers of width 8, 16, 32, and 64 bits.
|
|
|
|
* The type names `I8`, `I16`, `I32`, and `I64`, denoting the type of signed integers
|
|
of width 8, 16, 32, and 64 bits.
|
|
|
|
* The type names `F32` and `F64`, denoting the type of floating-point values
|
|
of width 32 and 64 bits.
|
|
|
|
* The type name `bool`, denoting the type of Boolean values (`true` and `false`).
|
|
|
|
* The type name `string`, denoting the type of
|
|
<<Defining-Constants_Expressions_String-Values,string values>>.
|
|
This type has a default maximum size.
|
|
For example:
|
|
+
|
|
[source,fpp]
|
|
----
|
|
# A is an array of 3 strings with default maximum size
|
|
array A = [3] string
|
|
----
|
|
|
|
* The type name `string size` _e_, where _e_ is a numeric expression
|
|
specifying a maximum string size.
|
|
+
|
|
[source,fpp]
|
|
----
|
|
# A is an array of 3 strings with maximum size 40
|
|
array A = [3] string size 40
|
|
----
|
|
|
|
* A name associated with another type definition.
|
|
In particular, an array definition may have another array definition as
|
|
its element type; this situation is discussed further below.
|
|
|
|
An array type definition may not refer to itself (array type definitions are not
|
|
recursive). For example, this definition is illegal:
|
|
|
|
[source,fpp]
|
|
--------
|
|
array A = [3] A # Illegal: the definition of A may not refer to itself
|
|
--------
|
|
|
|
==== Default Values
|
|
|
|
Optionally, you can specify a default value for an array type.
|
|
To do this, you write the keyword `default` and an expression
|
|
that evaluates to an <<Defining-Constants_Expressions_Array-Values,array value>>.
|
|
For example, here is an array type `A` with default value `[ 1, 2, 3 ]`:
|
|
|
|
[source,fpp]
|
|
----
|
|
array A = [3] U32 default [ 1, 2, 3 ]
|
|
----
|
|
|
|
A default value expression need not be a literal array value; it
|
|
can be any expression with the correct type.
|
|
For example, you can create a named constant with an array
|
|
value and use it multiple times, like this:
|
|
|
|
[source,fpp]
|
|
----
|
|
constant a = [ 1, 2, 3 ]
|
|
array A = [3] U8 default a # default value is [ 1, 2, 3 ]
|
|
array B = [3] U16 default a # default value is [ 1, 2, 3 ]
|
|
----
|
|
|
|
If you don't specify a default value, then the type gets an automatic default value,
|
|
consisting of the default value for each element.
|
|
The default numeric value is zero, the default Boolean value is `false`,
|
|
the default string value is `""`, and the default value of an array type
|
|
is specified in the type definition.
|
|
|
|
The type of the default expression must match the size and element type of the
|
|
array, with type conversions allowed as discussed for
|
|
<<Defining-Constants_Expressions_Array-Values,array values>>.
|
|
For example, this default expression is allowed, because we can convert integer
|
|
values to floating-point values, and we can promote a single value to an array
|
|
of three values:
|
|
|
|
[source,fpp]
|
|
----
|
|
array A = [3] F32 default 1 # default value is [ 1.0, 1.0, 1.0 ]
|
|
----
|
|
|
|
However, these default expressions are not allowed:
|
|
|
|
[source,fpp]
|
|
--------
|
|
array A = [3] U32 default [ 1, 2 ] # Error: size does not match
|
|
--------
|
|
|
|
[source,fpp]
|
|
--------
|
|
array B = [3] U32 default [ "a", "b", "c" ] # Error: element type does not match
|
|
--------
|
|
|
|
==== Format Strings
|
|
|
|
You can specify an optional *format string* which says how to display
|
|
each element value and optionally provides some surrounding text.
|
|
For example, here is an array definition that interprets three integer
|
|
values as wheel speeds measured in RPMs:
|
|
|
|
[source,fpp]
|
|
----
|
|
array WheelSpeeds = [3] U32 format "{} RPM"
|
|
----
|
|
|
|
Then an element with value 100 would have the format `100 RPM`.
|
|
|
|
Note that the format string specifies the format for an _element_, not the
|
|
entire array.
|
|
The way an entire array is displayed is implementation-specific.
|
|
A standard way is a comma-separated list enclosed in square brackets.
|
|
For example, a value `[ 100, 200, 300 ]` of type `WheelSpeeds` might
|
|
be displayed as `[ 100 RPM, 200 RPM, 300 RPM ]`.
|
|
Or, since the format is the same for all elements, the implementation could
|
|
display the array as `[ 100, 200, 300 ] RPM`.
|
|
|
|
The special character sequence `{}` is called a *replacement field*; it says
|
|
where to put the value in the format text.
|
|
Each format string must have exactly one replacement field.
|
|
The following replacement fields are allowed:
|
|
|
|
* The field `{}` for displaying element values in their default format.
|
|
|
|
* The field `{c}` for displaying a character value
|
|
|
|
* The field `{d}` for displaying a decimal value
|
|
|
|
* The field `{x}` for displaying a hexadecimal value
|
|
|
|
* The field `{o}` for displaying an octal value
|
|
|
|
* The field `{e}` for displaying a rational value in exponent notation, e.g.,
|
|
`1.234e2`.
|
|
|
|
* The field `{f}` for displaying a rational value in fixed-point notation,
|
|
e.g., `123.4`.
|
|
|
|
* The field `{g}` for displaying a rational value in general format
|
|
(fixed-point notation up to an implementation-dependent size and exponent
|
|
notation for larger sizes).
|
|
|
|
For field types `c`, `d`, `x`, and `o`, the element type must be an integer
|
|
type.
|
|
For field types `e`, `f`, and `g`, the element type must be a floating-point
|
|
type.
|
|
For example, the following format string is illegal, because
|
|
type `string` is not an integer type:
|
|
|
|
[source,fpp]
|
|
--------
|
|
array A = [3] string format "{d}" # Illegal: string is not an integer type
|
|
--------
|
|
|
|
For field types `e`, `f`, and `g`, you can optionally specify a precision
|
|
by writing a decimal point and an integer before the field type. For example,
|
|
the replacement field `{.3f}`, specifies fixed-point notation with a precision
|
|
of 3.
|
|
|
|
To include the literal character `{` in the formatted output, you can write
|
|
`{{`, and similarly for `}` and `}}`. For example, the following definition
|
|
|
|
[source,fpp]
|
|
----
|
|
array A = [3] U32 format "{{element {}}}"
|
|
----
|
|
|
|
specifies a format string `element {0}` for element value 0.
|
|
|
|
No other use of `{` or `}` in a format string is allowed. For example, this is illegal:
|
|
|
|
[source,fpp]
|
|
--------
|
|
array A = [3] U32 format "{" # Illegal use of { character
|
|
--------
|
|
|
|
You can include both a default value and a format; in this case, the default
|
|
value must come first. For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
array WheelSpeeds = [3] U32 default 100 format "{} RPM"
|
|
----
|
|
|
|
If you don't specify an element format, then each element is displayed
|
|
using the default format for its type.
|
|
Therefore, omitting the format string is equivalent to writing the format
|
|
string `"{}"`.
|
|
|
|
==== Arrays of Arrays
|
|
|
|
An array type may have another array type as its element type.
|
|
In this way you can construct an array of arrays.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
array A = [3] U32
|
|
array B = [3] A # An array of 3 A, which is an array of 3 U32
|
|
----
|
|
|
|
When constructing an array of arrays, you may provide any legal
|
|
default expression, so long as the types are compatible.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
array A = [2] U32 default 10 # default value is [ 10, 10 ]
|
|
array B1 = [2] A # default value is [ [ 10, 10 ], [ 10, 10 ] ]
|
|
array B2 = [2] A default 1 # default value is [ [ 1, 1 ], [ 1, 1 ] ]
|
|
array B3 = [2] A default [ 1, 2 ] # default value is [ [ 1, 1 ], [ 2, 2 ] ]
|
|
array B4 = [2] A default [ [ 1, 2 ], [ 3, 4 ] ]
|
|
----
|
|
|
|
=== Struct Type Definitions
|
|
|
|
A *struct type definition* associates a name with a *struct type*.
|
|
A struct type describes the shape of a
|
|
<<Defining-Constants_Expressions_Struct-Values,struct value>>.
|
|
It specifies a mapping from element names to their types.
|
|
As discussed below, it also specifies a serialization order
|
|
for the struct elements.
|
|
|
|
==== Writing a Struct Type Definition
|
|
|
|
As an example, here is a struct type definition that associates the name `S` with
|
|
a struct type containing two members: `x` of type `U32`, and `y` of type `string`:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S { x: U32, y: string }
|
|
----
|
|
|
|
In general, to write a struct type definition, you write the following:
|
|
|
|
* The keyword `struct`.
|
|
* The <<Defining-Constants_Names,name>> of the struct type.
|
|
* A sequence of *struct type members* enclosed in curly braces `{` ... `}`.
|
|
|
|
A struct type member consists of a name, a colon, and a
|
|
<<Defining-Types_Array-Type-Definitions_Type-Names,type name>>,
|
|
for example `x: U32`.
|
|
|
|
The struct type members form an
|
|
<<Defining-Constants_Multiple-Definitions-and-Element-Sequences,element
|
|
sequence>>
|
|
in which the optional terminating punctuation is a comma.
|
|
As usual for element sequences, you can omit the comma and use
|
|
a newline instead.
|
|
So, for example, we can write the definition shown above in this alternate way:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S {
|
|
x: U32
|
|
y: string
|
|
}
|
|
----
|
|
|
|
==== Annotating a Struct Type Definition
|
|
|
|
As noted in the beginning of this section, a type definition is
|
|
an annotatable element, so you can attach pre and post annotations
|
|
to it.
|
|
A struct type member is also an annotatable element, so any
|
|
struct type member can have pre and post annotations as well.
|
|
Here is an example:
|
|
|
|
[source,fpp]
|
|
----
|
|
@ This is a pre annotation for struct S
|
|
struct S {
|
|
@ This is a pre annotation for member x
|
|
x: U32 @< This is a post annotation for member x
|
|
@ This is a pre annotation for member y
|
|
y: string @< This is a post annotation for member y
|
|
} @< This is a post annotation for struct S
|
|
----
|
|
|
|
==== Default Values
|
|
|
|
You can specify an optional default value for a struct definition.
|
|
To do this, you write the keyword `default` and an expression
|
|
that evaluates to a <<Defining-Constants_Expressions_Struct-Values,struct
|
|
value>>.
|
|
For example, here is a struct type `S` with default value `{ x = 1, y = "abc"
|
|
}`:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S { x: U32, y: string } default { x = 1, y = "abc" }
|
|
----
|
|
|
|
A default value expression need not be a literal struct value; it
|
|
can be any expression with the correct type.
|
|
For example, you can create a named constant with a struct
|
|
value and use it multiple times, like this:
|
|
|
|
[source,fpp]
|
|
----
|
|
constant s = { x = 1, y = "abc" }
|
|
struct S1 { x: U8, y: string } default s
|
|
struct S2 { x: U32, y: string } default s
|
|
----
|
|
|
|
If you don't specify a default value, then the struct type gets an automatic default
|
|
value,
|
|
consisting of the default value for each member.
|
|
|
|
The type of the default expression must match the type of the struct, with type
|
|
conversions allowed as discussed for
|
|
<<Defining-Constants_Expressions_Struct-Values,struct values>>.
|
|
For example, this default expression is allowed, because we can convert integer
|
|
values to floating-point values, and we can promote a single value to a
|
|
struct with numeric members:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S { x: F32, y: F32 } default 1 # default value is { x = 1.0, y = 1.0 }
|
|
----
|
|
|
|
And this default expression is allowed, because if we omit a member of a struct,
|
|
then FPP will fill in the member and give it the default value:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S { x: F32, y: F32 } default { x = 1 } # default value is { x = 1.0, y = 0.0 }
|
|
----
|
|
|
|
However, these default expressions are not allowed:
|
|
|
|
[source,fpp]
|
|
--------
|
|
struct S1 { x: U32, y: string } default { z = 1 } # Error: member z does not match
|
|
--------
|
|
|
|
[source,fpp]
|
|
--------
|
|
struct S2 { x: U32, y: string } default { x = "abc" } # Error: type of member x does not match
|
|
--------
|
|
|
|
==== Member Arrays
|
|
|
|
For any struct member, you can specify that the member
|
|
is an array of elements.
|
|
To do this you, write an array the size enclosed in square brackets
|
|
before the member type.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S {
|
|
x: [3] U32
|
|
}
|
|
----
|
|
|
|
This definition says that struct `S` has one element `x`,
|
|
which is an array consisting of three `U32` values.
|
|
We call this array a *member array*.
|
|
|
|
*Member arrays vs. array types:*
|
|
Member arrays let you include an array
|
|
of elements as a member of a struct type,
|
|
without defining a separate
|
|
<<Defining-Types_Array-Type-Definitions,named array type>>.
|
|
Also, member arrays generate less code than named arrays.
|
|
Whereas a member size array is a native {cpp} array,
|
|
each named array is a {cpp} class.
|
|
|
|
On the other hand, defining a named array is usually
|
|
a good choice when
|
|
|
|
* You want to use the array outside of any structure.
|
|
|
|
* You want the convenience of a generated array class,
|
|
which has a richer interface than the bare
|
|
{cpp} array.
|
|
|
|
In particular, the generated array class provides
|
|
*bounds-checked* access operations:
|
|
it causes a runtime failure if an out-of-bounds access
|
|
occurs.
|
|
The bounds checking provides an additional degree of memory
|
|
safety when accessing array elements.
|
|
|
|
*Member arrays and default values:*
|
|
FPP ignores member array sizes when checking the types of
|
|
default values.
|
|
For example, this code is accepted:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S {
|
|
x: [3] U32
|
|
} default { x = 10 }
|
|
----
|
|
|
|
The member `x` of the struct `S` gets three copies of the value
|
|
10 specified for `x` in the default value expression.
|
|
|
|
==== Member Format Strings
|
|
|
|
For any struct member, you can include an optional format.
|
|
To do this, write the keyword `format` and a format string.
|
|
The format string for a struct member has the same form as for an
|
|
<<Defining-Types_Array-Type-Definitions_Format-Strings,array member>>.
|
|
For example, the following struct definition specifies
|
|
that member `x` should be displayed as a hexadecimal value:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct Channel {
|
|
name: string
|
|
offset: U32 format "offset 0x{x}"
|
|
}
|
|
----
|
|
|
|
How the entire struct is displayed depends on the implementation.
|
|
As an example, the value of `S` with `name = "momentum"` and `offset = 1024`
|
|
might look like this when displayed:
|
|
|
|
----
|
|
Channel { name = "momentum", offset = 0x400 }
|
|
----
|
|
|
|
If you don't specify a format for a struct member, then the system uses the default
|
|
format for the type of that member.
|
|
|
|
If the member has a size greater than one, then the format
|
|
is applied to each element.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct Telemetry {
|
|
velocity: [3] F32 format "{} m/s"
|
|
}
|
|
----
|
|
|
|
The format string is applied to each of the three
|
|
elements of the member `velocity`.
|
|
|
|
==== Struct Types Containing Named Types
|
|
|
|
A struct type may have an array or struct type as a member type.
|
|
In this way you can define a struct that has arrays or structs as members.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
array Speeds = [3] U32
|
|
# Member speeds has type Speeds, which is an array of 3 U32 values
|
|
struct Wheel { name: string, speeds: Speeds }
|
|
----
|
|
|
|
When initializing a struct, you may provide any legal
|
|
default expression, so long as the types are compatible.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
array A = [2] U32
|
|
struct S1 { x: U32, y: string }
|
|
|
|
# default value is { s1 = { x = 0, y = "" }, a = [ 0, 0 ] }
|
|
struct S2 { s1: S1, a: A }
|
|
|
|
# default value is { s1 = { x = 0, y = "abc" }, a = [ 5, 5 ] }
|
|
struct S3 { s1: S1, a: A } default { s1 = { y = "abc" }, a = 5 }
|
|
----
|
|
|
|
==== The Order of Members
|
|
|
|
For <<Defining-Constants_Expressions_Struct-Values,struct values>>,
|
|
we said that the order in which the members appear in the value is not
|
|
significant.
|
|
For example, the expressions `{ x = 1, y = 2 }` and `{ y = 2, x = 1 }` denote
|
|
the same value.
|
|
For struct types, the rule is different.
|
|
The order in which the members appear is significant, because
|
|
it governs the order in which the members appear in the generated
|
|
code.
|
|
|
|
For example, the type `struct S1 { x: U32, y : string }` might generate a {cpp}
|
|
class `S1` with members `x` and `y` laid out with `x` first; while `struct S2
|
|
{ y : string, x : U32 }`
|
|
might generate a {cpp} class `S2` with members `x` and `y` laid out with `y`
|
|
first.
|
|
Since class members are generally serialized in the order in which they appear in
|
|
the class,
|
|
the members of `S1` would be serialized with `x` first, and the members of
|
|
`S2`
|
|
would be serialized with `y` first.
|
|
Serializing `S1` to data and then trying to deserialize it to `S2` would
|
|
produce garbage.
|
|
|
|
The order matters only for purposes of defining the type, not for
|
|
assigning default values to it.
|
|
For example, this code is legal:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S { x: U32, y: string } default { y = "abc", x = 5 }
|
|
----
|
|
|
|
FPP struct _values_ have no inherent order associated with their members.
|
|
However, once those values are assigned to a named struct _type_,
|
|
the order becomes fixed.
|
|
|
|
=== Abstract Type Definitions
|
|
|
|
An array or struct type definition specifies a complete type:
|
|
in addition to the name of the type, it provides the names and types
|
|
of all the members.
|
|
An *abstract type*, by contrast, has an incomplete or opaque definition.
|
|
It provides only a name _N_.
|
|
Its purpose is to tell the analyzer that a type with name _N_ exists and will
|
|
be defined elsewhere.
|
|
For example, if the target language is {cpp}, then the type is a {cpp}
|
|
class.
|
|
|
|
To define an abstract type, you write the keyword `type` followed
|
|
by the name of the type.
|
|
For example, you can define an abstract type `T`; then you can construct
|
|
an array `A` with member type `T`:
|
|
|
|
[source,fpp]
|
|
----
|
|
type T # T is an abstract type
|
|
array A = [3] T # A is an array of 3 values of type T
|
|
----
|
|
|
|
This code says the following:
|
|
|
|
* A type `T` exists. It is defined in the implementation,
|
|
but not in the model.
|
|
* `A` is an array of three values, each of type `T`.
|
|
|
|
Now suppose that the target language is {cpp}.
|
|
Then the following happens when generating code:
|
|
|
|
* The definition `type T` does not cause any code to be generated.
|
|
* The definition `array A =` ... causes a {cpp} class `A`
|
|
to be generated.
|
|
By F Prime convention, the generated files are `AArrayAc.hpp` and `AArrayAc.cpp`.
|
|
* File `AArrayAc.hpp` includes a header file `T.hpp`.
|
|
|
|
It is up to the user to implement a {cpp} class `T` with
|
|
a header file `T.hpp`.
|
|
This header file must define `T` in a way that is compatible
|
|
with the way that `T` is used in `A`.
|
|
We will have more to say about this topic in the section on
|
|
<<Writing-C-Plus-Plus-Implementations_Implementing-Abstract-Types,
|
|
implementing abstract types>>.
|
|
|
|
In general, an abstract type `T` is opaque in the FPP model
|
|
and has no values that are expressible in the model.
|
|
Thus, every use of an abstract type `T` represents the default value
|
|
for `T`.
|
|
The implementation of `T` in the target language
|
|
provides the default value.
|
|
In particular, when the target language is {cpp}, the default
|
|
value is the zero-argument constructor `T()`.
|
|
|
|
=== Alias Type Definitions
|
|
|
|
An *alias type definition* provides an alternate name for
|
|
a type that is defined elsewhere.
|
|
The alternate name is called an *alias* of the original type.
|
|
For example, here is an alias type definition specifying that the type
|
|
`T` is an alias of the type `U32`:
|
|
|
|
[source,fpp]
|
|
----
|
|
type T = U32
|
|
----
|
|
|
|
Wherever this definition is available, the type `T` may be used
|
|
interchangeably with the type `U32`.
|
|
For example:
|
|
|
|
[source,fpp]
|
|
----
|
|
type T = U32
|
|
array A = [3] T
|
|
----
|
|
|
|
An alias type definition may refer to any type, including another
|
|
alias type, except that it may not refer to itself, either directly or through
|
|
another alias.
|
|
For example, here is an alias type definition specifying that the type
|
|
`T` is an alias of the struct type `S`:
|
|
|
|
[source,fpp]
|
|
----
|
|
struct S { x: U32, y: I32 }
|
|
type T = S
|
|
----
|
|
|
|
Here is a pair of definitions specifying that `S` is an alias of `T`,
|
|
and `T` is an alias of `F32`:
|
|
|
|
[source,fpp]
|
|
----
|
|
type S = T
|
|
type T = F32
|
|
----
|
|
|
|
Here is a pair of alias type definitions that is illegal, because each of
|
|
the definitions indirectly refers to itself:
|
|
|
|
[source,fpp]
|
|
--------
|
|
type S = T
|
|
type T = S
|
|
--------
|
|
|
|
Alias type definitions are useful for specifying configurations.
|
|
Part of a model can use a type `T`, without
|
|
defining `T`; elsewhere, configuration code can define
|
|
`T` to be the alias of another type.
|
|
F Prime uses this method to provide basic type whose definitions
|
|
configure the framework.
|
|
These types are defined in the file `config/FpConfig.fpp`.
|
|
|
|
=== Framework Types
|
|
|
|
Certain types defined in FPP have a special meaning in the F Prime
|
|
framework.
|
|
These types are called *framework types*.
|
|
For example, the type `FwOpcodeType` defines the type of
|
|
a command opcode.
|
|
(Commands are an F Prime feature that we describe
|
|
<<Defining-Components_Commands,in a later section of this manual>>.)
|
|
|
|
Framework types are like <<Defining-Constants_Framework-Constants,framework
|
|
constants>>:
|
|
you typically define them by overriding configuration files
|
|
provided by F Prime, and if they are defined, then they must
|
|
conform to certain rules.
|
|
https://nasa.github.io/fpp/fpp-spec.html#Definitions_Framework-Definitions_Type-Definitions[_The
|
|
FPP Language Specification_] has all the details.
|
|
|
|
|