Files
fpp/docs/spec/Definitions/Component-Definitions.adoc
Rob Bocchino 6bfd19cbc8 Revise spec
Add port matching specifiers as component members
2025-09-29 08:20:17 -07:00

408 lines
11 KiB
Plaintext

=== Component Definitions
A *component definition* defines an F Prime component.
A component is a unit of function in the F Prime framework.
Component instances communicate with each other across
<<Definitions_Port-Definitions,ports>>.
==== Syntax
_component-kind_ `component`
<<Lexical-Elements_Identifiers,_identifier_>>
`{` _component-member-sequence_ `}`
_component-kind_ is one of the following:
* `active`
* `passive`
* `queued`
_component-member-sequence_ is an
<<Element-Sequences,element sequence>> in
which each element is a *component member*,
and the terminating punctuation is a semicolon.
A component member is one of the following:
* A <<Definitions_Constant-Definitions,constant definition>>
* A <<Definitions_State-Machine-Definitions,state machine definition>>
* A <<Definitions_Struct-Definitions,struct definition>>
* A <<Specifiers_Command-Specifiers,command specifier>>.
All commands specified in a component must have distinct names and opcodes.
* A <<Specifiers_Container-Specifiers,container specifier>>.
All containers specified in a component must have distinct names and identifier
values.
* A <<Specifiers_Parameter-Specifiers,parameter specifier>>.
All parameters specified in a component must have distinct names and identifier
values.
* A <<Specifiers_Port-Instance-Specifiers,port instance specifier>>
* A <<Specifiers_Port-Matching-Specifiers,port matching specifier>>
* A <<Specifiers_Record-Specifiers,record specifier>>.
All records specified in a component must have distinct names and identifier
values.
* A <<Specifiers_State-Machine-Instance-Specifiers,state machine instance specifier>>.
All state machine instances specified in a component must have distinct names.
* A <<Specifiers_Telemetry-Channel-Specifiers,telemetry channel specifier>>.
All telemetry channels specified in a component must have distinct names and
identifier values.
* An <<Definitions_Abstract-Type-Definitions,abstract type definition>>
* An <<Definitions_Alias-Type-Definitions,alias type definition>>
* An <<Definitions_Array-Definitions,array definition>>
* An <<Definitions_Enum-Definitions,enum definition>>
* An <<Specifiers_Event-Specifiers,event specifier>>.
All events specified in a component must have distinct names and identifier
values.
* An <<Specifiers_Include-Specifiers,include specifier>>
* An <<Specifiers_Internal-Port-Specifiers,internal port specifier>>
* An <<Specifiers_Interface-Import-Specifiers,interface import specifier>>
The command, event, parameter, telemetry, record, and container
specifiers are collectively referred to as *dictionary specifiers*.
The record and container specifiers are collectively referred to
as *data product specifiers*.
==== Semantics
The identifier is the name of the component.
The definitions inside the body of the component are
qualified with the component name, as for
<<Definitions_Module-Definitions,module definitions>>.
Each state machine instance specifier must have a distinct name.
Each component definition has a set of *port specifiers*, consisting of
(1) the port instance specifiers that appear as members of the component;
(2) the port instance specifiers added by
<<Specifiers_Interface-Import-Specifiers,resolving any interface import
specifiers that are members of the component>>;
and (3) the internal port specifiers that appear as members of the component.
The port specifiers must satisfy the following rules:
. Each port specifier must have a distinct name.
. No passive component may have an `async` general or special
port specifier, an internal
port specifier, an `async` command specifier, or a state machine instance
specifier.
. Each active or queued component must have at least one `async` general
or special port specifier, internal port specifier,
`async` command specifier, or state machine instance specifier.
. Each component may have at most one of each special port kind.
. Each component must provide ports as shown in the table below.
|===
|Condition|Requirement
|If there are any command specifiers
|There must be specifiers for ports `command recv`, `command reg`, and `command resp`.
|If there are any event specifiers
|There must be specifiers for ports `event`, `text event`, and `time get`.
|If there are any parameter specifiers
|There must be specifiers for ports `command recv`, `command reg`, `command resp`,
`param get`, and `param set`.
|If there are any telemetry specifiers
|There must be specifiers for ports `telemetry` and `time get`.
|If there are any data product specifiers
|There must be a specifier for either port `product` `get` or
port `product` `request`.
There must be specifiers for ports `product` `send` and `time` `get`.
|If there is a specifier for `product` `request`
|There must be a specifier for port `product` `recv`.
|===
The dictionary specifiers must satisfy the following rules:
. All commands must have distinct names and opcodes.
. All events must have distinct names and identifier values.
. All parameters must have distinct names and identifier values.
. All telemetry channels must have distinct names and identifier values.
. All records must have distinct names and identifier values.
. All containers must have distinct names and identifier values.
. If there are any container specifiers, then there must be at least one
record specifier, and vice versa.
==== Examples
[source,fpp]
----
@ Receives commands from the ground or from a sequencer
@ Dispatches commands to other components
active component CommandDispatcher {
# ----------------------------------------------------------------------
# Constants
# ----------------------------------------------------------------------
@ The number of com command input ports
constant numComCmdInPorts = 10
@ The number of command output ports
constant numCmdOutPorts = 20
# ----------------------------------------------------------------------
# General ports
# ----------------------------------------------------------------------
@ Dispatches commands
output port cmdOut: [numCmdOutPorts] Fw.Cmd
@ Forwards received command responses
output port cmdResponseInOut: [numComCmdInPorts] Fw.CmdResponse
@ Receives com packets containing serialized commands
async input port comCmdIn: [numComCmdInPorts] Fw.Com
@ Receives command registration requests
guarded input port cmdRegIn: [numCmdOutPorts] Fw.CmdReg
@ Receives command responses
async input port cmdResponseIn: Fw.CmdResponse
# ----------------------------------------------------------------------
# Special ports
# ----------------------------------------------------------------------
@ Command receive port
command recv port cmdIn
@ Command registration port
command reg port cmdRegOut
@ Command response port
command resp cmdResponseOut
@ Event port
event port eventOut
@ Telemetry port
telemetry port tlmOut
@ Text event port
text event port textEventOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ No-op command
async command NO_OP
@ No-op string command
async command NO_OP_STRING(
arg1: string size 256 @< The string command argument
)
...
# ----------------------------------------------------------------------
# Events
# ----------------------------------------------------------------------
@ Opcode registered event
event OpcodeRegistered(
regOpcode: Opcode @< The opcode to register
regPort: U32 @< The registration port
dispatchSlot: U32 @< The dispatch slot
) severity diagnostic \
format "Opcode {} registered to port {} slot {}"
@ Opcode dispatched event
event OpcodeDispatched(
dispatchOpcode: Opcode @< The opcode dispatched
dispatchPort: U32 @< The dispatch port
) severity command \
format "Opcode {} dispatched to port {}"
...
# ----------------------------------------------------------------------
# Telemetry
# ----------------------------------------------------------------------
@ Number of commands dispatched
telemetry CommandsDispatched: U32 update on change
@ Number of command errors
telemetry CommandErrors: U32 update on change
}
----
[source,fpp]
----
@ Produces and sends images
active component Imager {
# ----------------------------------------------------------------------
# Special ports
# ----------------------------------------------------------------------
@ Command receive port
command recv port cmdIn
@ Command registration port
command reg port cmdRegOut
@ Command response port
command resp cmdResponseOut
@ Event port
event port eventOut
@ Telemetry port
telemetry port tlmOut
@ Text event port
text event port textEventOut
@ Time get port
time get port timeGetOut
@ Product request port
product request port productRequestOut
@ Product receive port
product recv port productRecvIn
@ Product send port
product send port productSendOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ Take an image and send it as a data product
async command TAKE_IMAGE
...
# ----------------------------------------------------------------------
# Events
# ----------------------------------------------------------------------
@ Image taken
event ImageTaken severity activity low format "Image taken"
...
# ----------------------------------------------------------------------
# Telemetry
# ----------------------------------------------------------------------
@ Number of images taken
telemetry NumImagesTaken: U32 update on change
...
# ----------------------------------------------------------------------
# Data products
# ----------------------------------------------------------------------
@ A container for images
product container ImageContainer
@ A record for holding an image
product record ImageRecord: Image
}
----
[source,fpp]
----
@ A component with state machines
active component DeviceMgr {
# ----------------------------------------------------------------------
# State machines
# ----------------------------------------------------------------------
@ A state machine representing a device
state machine Device {
@ Start the device
signal Start
@ Stop the device
signal Stop
@ Initial state is IDLE
initial enter IDLE
@ The IDLE state
state IDLE {
on Start enter RUNNING
}
@ The RUNNING state
state RUNNING {
on Stop enter IDLE
}
}
@ State machine instance for device 1
state machine instance device1: Device
@ State machine instance for device 2
state machine instance device2: Device
# ----------------------------------------------------------------------
# Special ports
# ----------------------------------------------------------------------
...
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ Send a Start event to the specified device
async command START(
@ The device number
deviceNum: U8
)
@ Send a Stop event to the specified device
async command STOP(
@ The device number
deviceNum: U8
)
}
----