mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
parent
728a022e9c
commit
bcd4641c91
2
.github/actions/spelling/expect.txt
vendored
2
.github/actions/spelling/expect.txt
vendored
@ -633,7 +633,7 @@ tcflush
|
||||
tcgetattr
|
||||
TCPCLIENT
|
||||
TCPHELPER
|
||||
tcpserver
|
||||
TCPSERVER
|
||||
TCSANOW
|
||||
Telecommand
|
||||
telem
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly name = "ByteStreamExample">
|
||||
<import_component_type>Svc/GroundInterface/GroundInterfaceComponentAi.xml</import_component_type>
|
||||
<import_component_type>Drv/ByteStreamDriverModel/ByteStreamDriverComponentAi.xml</import_component_type>
|
||||
|
||||
<!-- Declare component instances - must match names in Components.hpp -->
|
||||
<instance namespace="Svc" name="ground" type="GroundInterface" base_id="0" base_id_window="20" />
|
||||
<instance namespace="Drv" name="comm" type="ByteStreamDriverModel" base_id="100" base_id_window="20" />
|
||||
|
||||
<!-- Connections -->
|
||||
<!-- Communications driver connections -->
|
||||
<!-- @FPL START CommDriver -->
|
||||
<connection name = "CommunicationSend">
|
||||
<source component = "ground" port = "write" type = "Fw::BufferSend" num = "0"/>
|
||||
<target component = "comm" port = "send" type = "Drv::ByteStreamRecv" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "CommunicationRecv">
|
||||
<source component = "ground" port = "readPoll" type = "Fw::BufferSend" num = "0"/>
|
||||
<target component = "comm" port = "poll" type = "Drv::ByteStreamSend" num = "0"/>
|
||||
</connection>
|
||||
<!-- @FPL END -->
|
||||
</assembly>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB |
@ -19,8 +19,6 @@ These responses are an enumeration whose values are described in the following t
|
||||
|
||||
### Receive
|
||||
|
||||

|
||||
|
||||
In the callback formation, the byte stream driver component initiates the transfer of received data by calling the
|
||||
"recv" output port. This port transfers any read data in a `Fw::Buffer` along with a status for the receive.
|
||||
This status is an enumeration whose values are described in the following table:
|
||||
@ -35,9 +33,8 @@ The following components implement the byte stream model using a callback format
|
||||
- [`Drv::TcpClient`](../../TcpClient/docs/sdd.md): a F´ component wrapper of the tcp client
|
||||
- [`Drv::TcpServer`](../../TcpServer/docs/sdd.md): a F´ component wrapper of the tcp server
|
||||
- [`Drv::Udp`](../../Udp/docs/sdd.md): a F´ component wrapper of the udp
|
||||
- `Drv::LinuxUartDriver`
|
||||
|
||||
## Class Diagram
|
||||

|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@ -42,8 +42,6 @@ void exitTasks() {
|
||||
(void) comm.join();
|
||||
}
|
||||
```
|
||||
## Class Diagram
|
||||

|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@ -57,8 +57,6 @@ void exitTasks() {
|
||||
(void) comm.join();
|
||||
}
|
||||
```
|
||||
## Class Diagram
|
||||

|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@ -57,9 +57,6 @@ void exitTasks() {
|
||||
(void) comm.join();
|
||||
}
|
||||
```
|
||||
## Class Diagram
|
||||
|
||||

|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
# CMakeLists.txt
|
||||
# ======================================================================
|
||||
|
||||
# We need to declare the XML source files this way to invoke the autocoder.
|
||||
# However, only the UT build is allowed here.
|
||||
set(SOURCE_FILES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/implicit.fpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/explicit.fpp"
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
# CMakeLists.txt
|
||||
# ======================================================================
|
||||
|
||||
# We need to declare the XML source files this way to invoke the autocoder.
|
||||
# However, only the UT build is allowed here.
|
||||
set(SOURCE_FILES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/struct.fpp"
|
||||
)
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
CmdPortAi.xml - XML definition of a command port, which is used to send commands to components
|
||||
CmdResponseAi.xml - XML definition of command response port, which is used to report the completion status of a command
|
||||
CmdRegPortAi.xml - XML definition of a command registration port, which is used by components to register their set of commands
|
||||
CmdArgBuffer.hpp(.cpp) - C++ Definition of command argument buffer. Buffer is used to store serialized arguments for component commands
|
||||
CmdString.hpp(.cpp) - C++ Definition of a command string argument. Used by the code generator when a command has a string argument
|
||||
CmdPacket.hpp(.cpp) - C++ Definition of command packet. It is a derived class of ComPacket, which is the type used to send and receive data from ground or test software
|
||||
@ -1,3 +0,0 @@
|
||||
ComPortAi.xml - Port description for communication buffers
|
||||
ComBuffer.hpp(.cpp) - A buffer holding a serialized communication buffer
|
||||
ComPacket.hpp(.cpp) - A packet type that holds a communication buffer
|
||||
@ -1,7 +0,0 @@
|
||||
File Contents:
|
||||
|
||||
LogPortAi.xml - XML Definition of a binary log port. Used by the code generator when event items are defined by components
|
||||
LogTextPortAi.xml - XML Definition of a text log port. Used by the code generator to emit text versions of events
|
||||
LogBuffer.hpp(.cpp) - C++ definition of a log buffer. The buffer holds a serialized version of the event arguments
|
||||
LogString.hpp(.cpp) - C++ definition of a log string argument type. Used by the code generator when a string argument type is declared.
|
||||
LogPacket.hpp(.cpp) - C++ definition of a log packet type. Derived from ComPacket and is used for sending events to ground software or a test interface
|
||||
@ -1,6 +0,0 @@
|
||||
File Contents:
|
||||
|
||||
PrmPortAi.xml - XML Definition of a telemetry port. Used by the code generator when telemetry items are defined by components
|
||||
PrmBuffer.hpp(.cpp) - C++ definition of a telemetry buffer. The buffer holds a serialized version of the telemetry item value
|
||||
PrmString.hpp(.cpp) - C++ definition of a string telemetry type. Used by the code generator when a string telemetry type is declared.
|
||||
PrmPacket.hpp(.cpp) - C++ definition of a telemetry packet type. Derived from ComPacket and is used for sending telemetry to ground software or a test interface
|
||||
@ -1,4 +0,0 @@
|
||||
File Contents:
|
||||
|
||||
TimePortAi.xml - XML Definition of a time port. Used by the code generator when telemetry or event items are defined by components
|
||||
Time.hpp(.cpp) - C++ definition of a time value. The type is an argument to the port
|
||||
@ -1,6 +0,0 @@
|
||||
File Contents:
|
||||
|
||||
TlmPortAi.xml - XML Definition of a telemetry port. Used by the code generator when telemetry items are defined by components
|
||||
TlmBuffer.hpp(.cpp) - C++ definition of a telemetry buffer. The buffer holds a serialized version of the telemetry item value
|
||||
TlmString.hpp(.cpp) - C++ definition of a string telemetry type. Used by the code generator when a string telemetry type is declared.
|
||||
TlmPacket.hpp(.cpp) - C++ definition of a telemetry packet type. Derived from ComPacket and is used for sending telemetry to ground software or a test interface
|
||||
@ -140,12 +140,12 @@ CTRL-C in both terminals will stop the software from running.
|
||||
|
||||
**Things to look at**
|
||||
|
||||
The demo consists of a single component along with all the infrastructure components that are part of the repository. The demo component can be found in `RPI/RpiDemo`. The topology for the demo can be found in `RPI/Top`. That directory contains the program `main()` as well as the topology XML (`RPITopologyAppAi.xml`). You can modify and reuse the demo component, or you can create a whole series of interconnected components to do a project. Developers are encouraged to fork the repo to add functionality to the basic demo to enable whatever projects they have in mind.
|
||||
The demo consists of a single component along with all the infrastructure components that are part of the repository. The demo component can be found in `RPI/RpiDemo`. The topology for the demo can be found in `RPI/Top`. That directory contains the program `main()` as well as the topology FPP (`topology.fpp`). You can modify and reuse the demo component, or you can create a whole series of interconnected components to do a project. Developers are encouraged to fork the repo to add functionality to the basic demo to enable whatever projects they have in mind.
|
||||
|
||||
**Some tips:**
|
||||
|
||||
* If you would like to add your own components, read the User's manual on how to add new directories to the build.
|
||||
* If you have defined some component XML, you can generate an empty implementation class by typing `fprime-util impl`.
|
||||
* If you have defined some component FPP, you can generate an empty implementation class by typing `fprime-util impl`.
|
||||
* You can see the telemetry and events in `RPI/logs/<date>/channel.log` and `RPI/logs/<date>/event.log` respectively.
|
||||
* Sometimes you see the error: Could not connect to socket at host addr localhost, port 50000, or address in use
|
||||
This means that the GUI was restarted before the socket was released by Linux. Wait a minute or so and try again.
|
||||
|
||||
@ -48,7 +48,7 @@ There is a set of useful utility components that can be used on supported operat
|
||||
|
||||
## 2. Topology
|
||||
|
||||
The topology of the reference example is the interconnection of all the components used in the reference deployment (a deployment is a set of components connected together and compiled into a binary). There are a large number of connections so it is not feasible to show them all in one diagram. The following sections have views of the topology that show the connections for a particular purpose. The topology diagrams will be broken down into the core set of Command and Data Handling (C&DH) connections that would be reused from project to project as well as the connections unique to the reference example. The diagrams were generated using MagicDraw, while the XML defining the topology connections was generated using the MagicDraw plug-in developed for ISF.
|
||||
The topology of the reference example is the interconnection of all the components used in the reference deployment (a deployment is a set of components connected together and compiled into a binary). There are a large number of connections so it is not feasible to show them all in one diagram. The following sections have views of the topology that show the connections for a particular purpose. The topology diagrams will be broken down into the core set of Command and Data Handling (C&DH) connections that would be reused from project to project as well as the connections unique to the reference example. The diagrams were generated using MagicDraw, while the FPP defining the topology connections was generated using the MagicDraw plug-in developed for ISF.
|
||||
|
||||
### 2.1 Commanding
|
||||
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
This directory defines an ActiveLogger component. This is an active component that stores events generated in the system.
|
||||
It has the ability to filter the types of events for storage and for sending.
|
||||
|
||||
ActiveLoggerComponentAi.xml - Defines the active logger component type
|
||||
ActiveLoggerImpl.hpp(.cpp) - The implementation class for the active logger
|
||||
ActiveLoggerImplCfg.hpp - Set of configuration settings for logger
|
||||
@ -40,7 +40,7 @@ Port Data Type | Name | Direction | Kind | Usage
|
||||
### 3.2 Functional Description
|
||||
|
||||
The `Svc::ActiveLogger` component provides an event logging function for the software. The framework autocoder allows
|
||||
developers to specify a set of events in the component XML
|
||||
developers to specify a set of events in the component FPP.
|
||||
(see [Events](../../../docs/user-manual/overview/04-cmd-evt-chn-prm.md). For these components, the
|
||||
autocoder will add an `Fw::Log` output port to send events in serialized form. The ActiveLogger receives these port
|
||||
calls and provides commands to filter these events. The filtered events are sent to other components such as the ground
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
This directory contains the implementation of the Active Rate Group.
|
||||
The Active Rate Group is a component that executes components assigned to the rate group.
|
||||
A call to the input run port wakes the task and causes it to call all the components connected to the output ports in order.
|
||||
|
||||
ActiveRateGroupComponentAi.xml - The XML description of the active rate group component
|
||||
ActiveRateGroup.hpp(.cpp) - The implementation of the component
|
||||
@ -1,6 +0,0 @@
|
||||
This directory contains the CmdDispatcher component. This component takes incoming Com packets that have commands encoded in them and decodes them.
|
||||
It looks up opcodes in a table build by component registrations. It also handles completions, passing the status back to the sender of the packet.
|
||||
|
||||
CommandDispatcherComponentAi.xml - Command dispatcher component specification
|
||||
CommandDispatcherImpl.hpp(.cpp) - Command dispatcher implementation
|
||||
CommandDispatcherImplCfg.hpp - Command dispatcher configuration
|
||||
@ -1,37 +0,0 @@
|
||||
# Svc::ComSplitter
|
||||
|
||||
This is the build directory for the ComSplitter component.
|
||||
|
||||
## Redo Targets
|
||||
|
||||
**Main targets:** The following `redo` targets are available:
|
||||
|
||||
* `Dictionary`: Create a directory `Dictionary` containing a dictionary for the ISF Ground Support Equipment (GSE).
|
||||
|
||||
* `Docs`: Create a directory `Docs` containing ISF-style component documentation.
|
||||
|
||||
* `Interface`: Create a directory `Interface` containing a component interface.
|
||||
|
||||
* `NCSL`: Create a directory `NCSL` containing counts of non-commented source lines of code.
|
||||
|
||||
* `README`: Generate this `README` file.
|
||||
|
||||
* `Template`: Create a directory `Template` containing an ISF component template.
|
||||
|
||||
* `all`: Build the target `Build/$TARGET/$MODE/lib.a`, where `TARGET` and `MODE` are environment variables. The targets are Darwin, Linux, PI, and CORTEX160. The modes are Unit, Integration, and Flight. If `TARGET` is not set, the system will use the native environment (Darwin or Linux) as the default. If `MODE` is not set, the system will use Unit as the default.
|
||||
|
||||
* `clean`: Clean this directory and its subdirectories.
|
||||
|
||||
* `refresh`: Regenerate `ComSplitterComponentAi.xml` from `Model`.
|
||||
|
||||
**Helper targets:** The main targets use the following helper targets.
|
||||
You should not have to invoke these targets directly,
|
||||
except when developing or debugging the build system.
|
||||
|
||||
* `Table`: Create a directory `Table` containing the part of the table interface that is not represented in the ISF XML.
|
||||
|
||||
* `default.a`: Build a component library target `Build/`*target*`/`*mode*`/lib.a`.
|
||||
|
||||
* `default.ncsl.txt`: Generate an NCSL file.
|
||||
|
||||
* `default.o`: Build target of the form `Build/`*target*`/`*mode*`/`*path*`/`*file*`.o`, where *path* may be empty.
|
||||
@ -1,6 +0,0 @@
|
||||
This directory contains the definition of a FATAL event port.
|
||||
This port will be invoked by ActiveLogger when a FATAL happens.
|
||||
It can be connected to a component that will decide what to do with
|
||||
the FATAL.
|
||||
|
||||
FatalAnnouncePortAi.xml - Defines the FATAL port
|
||||
@ -1,20 +0,0 @@
|
||||
Name
|
||||
Role
|
||||
|
||||
timeCaller
|
||||
TimeGet
|
||||
|
||||
cmdIn
|
||||
Cmd
|
||||
|
||||
tlmOut
|
||||
Telemetry
|
||||
|
||||
cmdResponseOut
|
||||
CmdResponse
|
||||
|
||||
eventOut
|
||||
LogEvent
|
||||
|
||||
cmdRegOut
|
||||
CmdRegistration
|
||||
@ -1,3 +0,0 @@
|
||||
Commands.xml
|
||||
Telemetry.xml
|
||||
Events.xml
|
||||
@ -1 +0,0 @@
|
||||
active
|
||||
@ -1,145 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
WARNING: this file sets up for visualization images in the SDD. It does not build as a topology
|
||||
-->
|
||||
<assembly name = "ByteStreamExample">
|
||||
|
||||
<import_component_type>Svc/GroundInterface/GroundInterfaceComponentAi.xml</import_component_type>
|
||||
<import_component_type>Drv/ByteStreamDriverModel/ByteStreamDriverComponentAi.xml</import_component_type>
|
||||
<import_component_type>Ref/SignalGen/SignalGenComponentAi.xml</import_component_type>
|
||||
|
||||
<!-- Declare component instances - must match names in Components.hpp -->
|
||||
<instance namespace="Svc" name="cmdDisp" type="CommandDispatcher" base_id="121" base_id_window="20" />
|
||||
<instance namespace="Svc" name="hub1" type="GenericHub" base_id="0" base_id_window="20" />
|
||||
<instance namespace="Svc" name="hub2" type="GenericHub" base_id="10" base_id_window="20" />
|
||||
<instance namespace="Drv" name="comm1" type="ByteStreamDriverModel" base_id="100" base_id_window="20" />
|
||||
<instance namespace="Drv" name="comm2" type="ByteStreamDriverModel" base_id="100" base_id_window="20" />
|
||||
|
||||
<instance namespace="Svc" name="fileDownlink" type="FileDownlink" base_id="501" base_id_window="20" />
|
||||
<instance namespace="Svc" name="fileUplink" type="FileUplink" base_id="501" base_id_window="20" />
|
||||
<instance namespace="Ref" name="signal1" type="SignalGen" base_id="181" base_id_window="20" />
|
||||
<instance namespace="Ref" name="signal2" type="SignalGen" base_id="201" base_id_window="20" />
|
||||
|
||||
<!-- Connections -->
|
||||
<!-- Communications driver connections -->
|
||||
<!-- @FPL START GenericHub 1 -->
|
||||
<connection name = "SG1Disp">
|
||||
<source component = "cmdDisp" port = "compCmdSend" type = "Cmd" num = "0"/>
|
||||
<target component = "hub1" port = "portIn" type = "Serial" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG2Disp">
|
||||
<source component = "cmdDisp" port = "compCmdSend" type = "Cmd" num = "1"/>
|
||||
<target component = "hub1" port = "portIn" type = "Serial" num = "1"/>
|
||||
</connection>
|
||||
|
||||
<connection name = "CommunicationSend">
|
||||
<source component = "hub1" port = "dataOut" type = "Drv::ByteStreamSend" num = "0"/>
|
||||
<target component = "comm1" port = "send" type = "Drv::ByteStreamRSend" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "CommunicationRecv">
|
||||
<source component = "comm1" port = "readRecv" type = "Drv::ByteStreamRecv" num = "0"/>
|
||||
<target component = "hub1" port = "dataIn" type = "Drv::ByteStreamRecv" num = "0"/>
|
||||
</connection>
|
||||
|
||||
<connection name = "SG1Reg">
|
||||
<source component = "hub1" port = "portOut" type = "Serial" num = "0"/>
|
||||
<target component = "cmdDisp" port = "compCmdReg" type = "Cmd" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG1Reg">
|
||||
<source component = "hub1" port = "portOut" type = "Serial" num = "1"/>
|
||||
<target component = "cmdDisp" port = "compCmdReg" type = "Cmd" num = "1"/>
|
||||
</connection>
|
||||
|
||||
|
||||
<!-- @FPL END -->
|
||||
<!-- @FPL START Top -->
|
||||
|
||||
<!-- FAKE connection -->
|
||||
<connection name = "SG1Disp">
|
||||
<source component = "cmdDisp" port = "compCmdSend" type = "Cmd" num = "0"/>
|
||||
<target component = "hub1" port = "portIn" type = "Serial" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG2Disp">
|
||||
<source component = "cmdDisp" port = "compCmdSend" type = "Cmd" num = "1"/>
|
||||
<target component = "hub1" port = "portIn" type = "Serial" num = "1"/>
|
||||
</connection>
|
||||
|
||||
|
||||
|
||||
<connection name = "SG1Reg">
|
||||
<source component = "hub1" port = "portOut" type = "Serial" num = "0"/>
|
||||
<target component = "cmdDisp" port = "compCmdReg" type = "Cmd" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG1Reg">
|
||||
<source component = "hub1" port = "portOut" type = "Serial" num = "1"/>
|
||||
<target component = "cmdDisp" port = "compCmdReg" type = "Cmd" num = "1"/>
|
||||
</connection>
|
||||
<connection name = "hub2">
|
||||
<source component = "hub1" port = "-- address bridge --" type = "bytes" num = "0"/>
|
||||
<target component = "hub2" port = "-- address bridge --" type = "bytes" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG1Disp">
|
||||
<source component = "hub2" port = "portOut" type = "Cmd" num = "0"/>
|
||||
<target component = "signal1" port = "cmdIn" type = "Serial" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG2Disp">
|
||||
<source component = "hub2" port = "portOut" type = "Cmd" num = "1"/>
|
||||
<target component = "signal2" port = "cmdIn" type = "Serial" num = "0"/>
|
||||
</connection>
|
||||
|
||||
|
||||
|
||||
<connection name = "SG1Reg2">
|
||||
<source component = "signal1" port = "cmdRegOut" type = "CmdReg" num = "0"/>
|
||||
<target component = "hub2" port = "Serial" type = "portIn" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG2Reg2">
|
||||
<source component = "signal2" port = "cmdRegOut" type = "CmdReg" num = "0"/>
|
||||
<target component = "hub2" port = "Serial" type = "portIn" num = "1"/>
|
||||
</connection>
|
||||
<!-- @FPL END -->
|
||||
|
||||
<!-- @FPL START TopFile-->
|
||||
<connection name = "fileDownlinkBufferSend">
|
||||
<source component = "fileDownlink" port = "bufferSendOut" type = "BufferSend" num = "0"/>
|
||||
<target component = "hub1" port = "buffersIn" type = "BufferSend" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "hub2">
|
||||
<source component = "hub1" port = "-- address bridge --" type = "bytes" num = "0"/>
|
||||
<target component = "hub2" port = "-- address bridge --" type = "bytes" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "groundIfIfFileUplinkBufferSend">
|
||||
<source component = "hub2" port = "buffersOut" type = "BufferSend" num = "0"/>
|
||||
<target component = "fileUplink" port = "bufferSendIn" type = "BufferSend" num = "0"/>
|
||||
</connection>
|
||||
<!-- @FPL END -->
|
||||
|
||||
<!-- @FPL START Generic Hub 2-->
|
||||
<connection name = "CommunicationRecv">
|
||||
<source component = "comm2" port = "readRecv" type = "Drv::ByteStreamRecv" num = "0"/>
|
||||
<target component = "hub2" port = "dataIn" type = "Drv::ByteStreamRecv" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "CommunicationSend">
|
||||
<source component = "hub2" port = "dataOut" type = "Drv::ByteStreamSend" num = "0"/>
|
||||
<target component = "comm2" port = "send" type = "Drv::ByteStreamRSend" num = "0"/>
|
||||
</connection>
|
||||
|
||||
<connection name = "SG1Disp">
|
||||
<source component = "hub2" port = "portOut" type = "Cmd" num = "0"/>
|
||||
<target component = "signal1" port = "cmdIn" type = "Serial" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG2Disp">
|
||||
<source component = "hub2" port = "portOut" type = "Cmd" num = "1"/>
|
||||
<target component = "signal2" port = "cmdIn" type = "Serial" num = "0"/>
|
||||
</connection>
|
||||
|
||||
<connection name = "SG1Reg2">
|
||||
<source component = "signal1" port = "cmdRegOut" type = "CmdReg" num = "0"/>
|
||||
<target component = "hub2" port = "Serial" type = "portIn" num = "0"/>
|
||||
</connection>
|
||||
<connection name = "SG2Reg2">
|
||||
<source component = "signal2" port = "cmdRegOut" type = "CmdReg" num = "0"/>
|
||||
<target component = "hub2" port = "Serial" type = "portIn" num = "1"/>
|
||||
</connection>
|
||||
<!-- @FPL END -->
|
||||
</assembly>
|
||||
@ -1,6 +0,0 @@
|
||||
This component implements a PolyType database that can be used to save and retrieve telemetry needed in the software.
|
||||
It has guarded ports that control access to the database.
|
||||
|
||||
PolyDbComponentAi.xml - The XML definition of the PolyDb component
|
||||
PolyDbImpl.hpp(.cpp) - The implementation file for PolyDb
|
||||
PolyDbImplCfg.hpp - configuration for implementation class
|
||||
@ -1,4 +0,0 @@
|
||||
This contains the definition for a PolyPort, or a port that passes a PolyType.
|
||||
It is used to set and get values for the PolyDb component.
|
||||
|
||||
PolyPortAi.xml - XML definition for a port that passes PolyType values
|
||||
@ -1,9 +0,0 @@
|
||||
This component implements storage for parameters. It implements the framework setPrm and getPrm ports.
|
||||
Parameter values are stored as a table based on parameter ID. It reads a file during initialization that contains the
|
||||
parameter values and loads them into memory. Subsequent calls to getPrm will get the loaded file.
|
||||
Parameter values in the components can be updated by command and saved to PrmDb.
|
||||
The PrmDb component can be commanded to save the updated values to a file.
|
||||
|
||||
PrmDbComponentAi.xml - XML definition for parameter database component
|
||||
PrmDbImpl.hpp(.cpp) - Implementation of parameter database component
|
||||
PrmDbImplCfg.hpp - Configuration for parameter database
|
||||
@ -1,9 +0,0 @@
|
||||
This component takes a primary clock tick in the system and divides it down to drive output ports.
|
||||
Constructor arguments define the divisors for each port.
|
||||
The dividers argument define the divisors for each port as well as an offset to allow the triggering
|
||||
for the rate group to be offset from each other.
|
||||
The output ports are meant to be connected to the input ports of rate groups to drive them at the
|
||||
correct rate.
|
||||
|
||||
RateGroupDriverComponentAi.xml - XML definition of rate group driver component
|
||||
RateGroupDriverImpl.hpp(.cpp) - Implementation for rate group driver
|
||||
@ -1,3 +0,0 @@
|
||||
This directory contains the definition of a scheduler port. This port is used to invoke rate groups and their members.
|
||||
|
||||
SchedPortAi.xml - Defines the scheduler port
|
||||
@ -1,258 +0,0 @@
|
||||
import os.path
|
||||
import pickle
|
||||
from optparse import OptionParser
|
||||
|
||||
from lxml import etree
|
||||
|
||||
"""
|
||||
This script is meant to serve as "sanity" checker for the MagicDraw generated topology XML files
|
||||
"""
|
||||
|
||||
|
||||
def setup_opt_parse():
|
||||
usage = "usage: %prog [options] [topology_filename]"
|
||||
parser = OptionParser(usage)
|
||||
|
||||
parser.add_option(
|
||||
"-d",
|
||||
"--xml_diff",
|
||||
dest="xml_diff_flag",
|
||||
help="Performs a diff on the specified XML files.",
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-c",
|
||||
"--command_index_print",
|
||||
dest="command_index_print_flag",
|
||||
help="Prints a table of the command indexes.",
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def validate_xml(xml_list):
|
||||
"""
|
||||
Iterates through XML list, shows an error if an XML file is not an XML file or does not exist.
|
||||
|
||||
A list of valid XML files is returned (Not valid files are thrown out)
|
||||
"""
|
||||
|
||||
out_list = []
|
||||
for xml_path in xml_list:
|
||||
if os.path.isfile(xml_path):
|
||||
out_list.append(xml_path)
|
||||
else:
|
||||
print(
|
||||
"WARNING: XML {} is not a valid file. Rejecting file.".format(xml_path)
|
||||
)
|
||||
|
||||
return out_list
|
||||
|
||||
|
||||
def recursive_xml_parse(tree_obj):
|
||||
"""
|
||||
returns a list of items
|
||||
[tagName , [(argKey:argVal)] , [" " or [tagName , [] , []] ] ]
|
||||
"""
|
||||
out_obj = [tree_obj.tag, [], []]
|
||||
|
||||
for att in tree_obj.attrib:
|
||||
out_obj[1].append((att, tree_obj.attrib[att]))
|
||||
|
||||
internal_text = tree_obj.text
|
||||
if internal_text is not None:
|
||||
internal_text = internal_text.strip()
|
||||
if internal_text != "":
|
||||
out_obj[2].append(internal_text)
|
||||
|
||||
for internal_item in tree_obj:
|
||||
out_obj[2].append(recursive_xml_parse(internal_item))
|
||||
|
||||
return out_obj
|
||||
|
||||
|
||||
def tag_object_to_string(tag_obj):
|
||||
out = "<{}{}>".format(
|
||||
tag_obj[0], "".join(" " + x[0] + "=" + '"' + x[1] + '"' for x in tag_obj[1])
|
||||
)
|
||||
|
||||
final_line_break = ""
|
||||
for internal_item in tag_obj[2]:
|
||||
if type(internal_item) == str:
|
||||
out += internal_item
|
||||
else:
|
||||
out += "\n\t" + tag_object_to_string(internal_item).replace("\n", "\n\t")
|
||||
final_line_break = "\n"
|
||||
|
||||
out += final_line_break + "</" + tag_obj[0] + ">"
|
||||
return out
|
||||
|
||||
|
||||
def diff_files(xml_list):
|
||||
"""
|
||||
Finds the difference between topology XML files, ignoring ordering and names in "connection" tags
|
||||
|
||||
Iterate through root tag elements
|
||||
Create a dictionary with file_dict[tag] = [list of tag objects]
|
||||
"""
|
||||
if len(xml_list) < 2:
|
||||
print("Less than two XML files were specified. Exiting.")
|
||||
return
|
||||
|
||||
master_tag_dict = {}
|
||||
for xml_path in xml_list:
|
||||
# Create etree object
|
||||
fd = open(xml_path, "r")
|
||||
xml_parser = etree.XMLParser(remove_comments=True)
|
||||
element_tree = etree.parse(fd, parser=xml_parser)
|
||||
fd.close()
|
||||
|
||||
# Internal Parsing
|
||||
xml_dict = recursive_xml_parse(element_tree.getroot())
|
||||
|
||||
for tag_obj in xml_dict[2]:
|
||||
if tag_obj[0] == "connection":
|
||||
tag_obj[1] = []
|
||||
|
||||
pickled_obj = pickle.dumps(tag_obj)
|
||||
|
||||
if pickled_obj not in master_tag_dict:
|
||||
# del master_tag_dict[pickled_obj]
|
||||
master_tag_dict[pickled_obj] = []
|
||||
|
||||
master_tag_dict[pickled_obj].append(xml_path)
|
||||
|
||||
# Separate by XML path
|
||||
tag_to_object = {} # tag_to_object[xml_path] = [obj]
|
||||
for pickled_obj in master_tag_dict:
|
||||
if len(master_tag_dict[pickled_obj]) == 1:
|
||||
if master_tag_dict[pickled_obj][0] not in tag_to_object:
|
||||
tag_to_object[master_tag_dict[pickled_obj][0]] = []
|
||||
tag_to_object[master_tag_dict[pickled_obj][0]].append(pickled_obj)
|
||||
|
||||
for xml_path in tag_to_object:
|
||||
print(xml_path + "\n")
|
||||
# sort pickled obj lists
|
||||
tag_to_object[xml_path].sort()
|
||||
for pickled_obj in tag_to_object[xml_path]:
|
||||
tag_obj = pickle.loads(pickled_obj)
|
||||
print(tag_object_to_string(tag_obj))
|
||||
print("\n")
|
||||
print("\n")
|
||||
|
||||
|
||||
def command_index_print(xml_list):
|
||||
for xml_path in xml_list:
|
||||
# Create etree object
|
||||
fd = open(xml_path, "r")
|
||||
xml_parser = etree.XMLParser(remove_comments=True)
|
||||
element_tree = etree.parse(fd, parser=xml_parser)
|
||||
fd.close()
|
||||
|
||||
# Internal Parsing
|
||||
xml_dict = recursive_xml_parse(element_tree.getroot())
|
||||
|
||||
connection_information = [] # [{target/source: {attribKey:attribVal}}]
|
||||
|
||||
# Gather connection data
|
||||
for tag_obj in xml_dict[2]:
|
||||
if tag_obj[0] == "connection":
|
||||
in_dict = {"SOURCE": None, "TARGET": None}
|
||||
for conn_obj in tag_obj[2]:
|
||||
if type(conn_obj) != str:
|
||||
attrib_dict = {}
|
||||
for attrib in conn_obj[1]:
|
||||
attrib_dict[attrib[0].upper()] = attrib[1].upper()
|
||||
in_dict[conn_obj[0].upper()] = attrib_dict
|
||||
connection_information.append(in_dict)
|
||||
|
||||
component_to_cmd_info = (
|
||||
{}
|
||||
) # component_to_cmd_info[componentName] = {cmdIndex:index , cmdRegIndex:index}
|
||||
|
||||
# Create dict mapping components to their mult values on the cmdDisp
|
||||
for conn_info in connection_information:
|
||||
source_dict = conn_info["SOURCE"]
|
||||
target_dict = conn_info["TARGET"]
|
||||
|
||||
source_comp_name = source_dict["COMPONENT"]
|
||||
target_comp_name = target_dict["COMPONENT"]
|
||||
|
||||
if source_comp_name not in component_to_cmd_info:
|
||||
component_to_cmd_info[source_comp_name] = {
|
||||
"cmdIndex": None,
|
||||
"cmdRegIndex": None,
|
||||
}
|
||||
if target_comp_name not in component_to_cmd_info:
|
||||
component_to_cmd_info[target_comp_name] = {
|
||||
"cmdIndex": None,
|
||||
"cmdRegIndex": None,
|
||||
}
|
||||
|
||||
if source_dict["TYPE"] == "CMD":
|
||||
component_to_cmd_info[target_comp_name]["cmdIndex"] = source_dict["NUM"]
|
||||
|
||||
if target_dict["TYPE"] == "CMDREG":
|
||||
component_to_cmd_info[source_comp_name]["cmdRegIndex"] = target_dict[
|
||||
"NUM"
|
||||
]
|
||||
|
||||
# sort by num
|
||||
sorted_list = []
|
||||
for comp_info in component_to_cmd_info:
|
||||
sorted_list.append([comp_info, component_to_cmd_info[comp_info]])
|
||||
|
||||
sorted_list.sort(
|
||||
key=lambda x: int(float(x[1]["cmdIndex"]))
|
||||
if x[1]["cmdIndex"] is not None
|
||||
else -1
|
||||
)
|
||||
|
||||
# Print table
|
||||
print(xml_path + "\n")
|
||||
header_list = [
|
||||
"\t\tComponent Name\t\t",
|
||||
"Command Index",
|
||||
"Command Registration Index",
|
||||
]
|
||||
len_list = [len(x) for x in header_list]
|
||||
|
||||
print("| " + " | ".join(x for x in header_list) + " |")
|
||||
for comp_info in sorted_list:
|
||||
print_list = [
|
||||
comp_info[0],
|
||||
comp_info[1]["cmdIndex"],
|
||||
comp_info[1]["cmdRegIndex"],
|
||||
]
|
||||
i = 0
|
||||
row_string = ""
|
||||
while i != len(header_list):
|
||||
if i != 0:
|
||||
row_string += " | "
|
||||
format_string = "{0:^" + str(len_list[i]) + "}"
|
||||
row_string += format_string.format(print_list[i])
|
||||
i += 1
|
||||
print("| " + row_string + " |")
|
||||
|
||||
print("\n\n")
|
||||
|
||||
|
||||
def main():
|
||||
parser = setup_opt_parse()
|
||||
(opt, args) = parser.parse_args()
|
||||
|
||||
xml_list = validate_xml(args)
|
||||
|
||||
if opt.command_index_print_flag:
|
||||
command_index_print(xml_list)
|
||||
|
||||
if opt.xml_diff_flag:
|
||||
diff_files(xml_list)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -11,9 +11,8 @@ include("utilities")
|
||||
# Macro `autocoder_support_by_suffix`:
|
||||
#
|
||||
# This sets up an autocoder to handle files based on a suffix. For example, passing in "*.fpp" will support all files
|
||||
# ending in ".fpp" i.e. FPP files or passing in "ComponentAi.xml" will support all component XMLs. It is implemented as
|
||||
# a macro such that users need not do anything other than call it with the suffix to setup the system correctly. This
|
||||
# performs raw ascii comparison, not regular expression matching.
|
||||
# ending in ".fpp" i.e. FPP files. It is implemented as a macro such that users need not do anything other than call it
|
||||
# with the suffix to setup the system correctly. This performs raw ascii comparison, not regular expression matching.
|
||||
#
|
||||
# **Note:** this will set the appropriate variable in PARENT_SCOPE and since it is macro this will be the parent scope
|
||||
# of the caller.
|
||||
|
||||
@ -222,8 +222,8 @@ this component is built as an F´ module. This call passes in the above variabl
|
||||
# SOURCE_FILES: Handcoded C++ source files
|
||||
|
||||
set(SOURCE_FILES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiverComponentAi.xml"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiverComponentImpl.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiver.fpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PingReceiver.cpp"
|
||||
)
|
||||
|
||||
# Note: no MOD_DEPS needed.
|
||||
@ -256,7 +256,7 @@ Topology `CMakeLists.txt` follow the same format as the Module files with two de
|
||||
# MOD_DEPS: Modules needed by this deployment
|
||||
|
||||
set(SOURCE_FILES
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RefTopologyAppAi.xml"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RefTopology.fpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Topology.cpp"
|
||||
)
|
||||
|
||||
@ -375,9 +375,9 @@ Module functions are designed to create a library (static or shared) out of an F
|
||||
module name is determined from the directory path relative to the root of the repository.
|
||||
i.e. `Fw/Comp` becomes *Fw_Comp* and yields `libFw_Comp.a`. This library is added as an output of
|
||||
the CMake system. This library is built from `SOURCE_FILES`, which are split into inputs to the
|
||||
autocoder (*.xml and *.txt) and normal source files. Specific dependencies can be supplied using
|
||||
autocoder (*.fpp and/or *.txt) and normal source files. Specific dependencies can be supplied using
|
||||
the `MOD_DEPS` variable, but is only required when the dependencies are not detected via a recursive
|
||||
search of all *.xml includes in the autocoder files. The autocoder generation steps are registered
|
||||
search of all *.fpp includes in the autocoder files. The autocoder generation steps are registered
|
||||
for each of the autocoder input files. These autocoder input files are also used to detect all
|
||||
dependencies of the given module. The normal source files are supplied to the build directory.
|
||||
|
||||
|
||||
@ -33,7 +33,6 @@ endif()
|
||||
|
||||
message(STATUS "[python3] python3 found at: ${PYTHON}")
|
||||
message(STATUS "[fpp-tools] fpp-depend found at: ${FPP_DEPEND}")
|
||||
message(STATUS "[fpp-tools] fpp-to-xml found at: ${FPP_TO_XML}")
|
||||
message(STATUS "[fpp-tools] fpp-to-cpp found at: ${FPP_TO_CPP}")
|
||||
message(STATUS "[fpp-tools] fpp-to-dict found at: ${FPP_TO_DICT}")
|
||||
message(STATUS "[fpp-tools] fpp-locate-defs found at: ${FPP_LOCATE_DEFS}")
|
||||
|
||||
@ -3,33 +3,8 @@
|
||||
#
|
||||
# Functions supporting the F prime target additions. These targets allow building against modules
|
||||
# and top-level targets. This allows for multi-part builds like `sloc` or `dict` where some part
|
||||
# applies to the module and is rolled up into some global command. Target files must define two
|
||||
# functions `add_module_target` and `add_global_target`.
|
||||
# applies to the module and is rolled up into some global command.
|
||||
#
|
||||
# ### `add_global_target` Specification:
|
||||
#
|
||||
# Adds a global target for the custom target. This handles the top-level target for the build.
|
||||
# Think `make dict`. It is the global root for all of the children module defines. This should call
|
||||
# CMake's `add_custom_target("${TARGET_NAME}" ...)` at some point in the function. Also pass the
|
||||
# `ALL` argument if it should be built as part of a standard build i.e. `make`.
|
||||
#
|
||||
# **Arguments passed in:**
|
||||
# - **TARGET_NAME:** target name to be added. **Must** be passed to a call to `add_custom_target`
|
||||
#
|
||||
# ### `add_module_target` Specification:
|
||||
#
|
||||
# Adds a module-by-module target for this given target. Any subtargets for each module and their
|
||||
# commands should be registered via CMake's `add_custom_target("${TARGET_NAME}" ...)`. This command
|
||||
# is supplied with all of the modules knowledge. Add a `DEPENDS` call on AC_OUTPUTS to come after
|
||||
# the autocoding step.
|
||||
#
|
||||
# **Arguments passed in:**
|
||||
# - **MODULE_NAME:** name of the module being built.
|
||||
# - **TARGET_NAME:** target name to be added. **Must** be passed to a call to `add_custom_target`
|
||||
# - **AC_INPUTS:** list of autocoder inputs. These are Ai.xml files
|
||||
# - **SOURCE_FILES:** list of source file inputs. These are handwritten *.cpp and *.hpp.
|
||||
# - **AC_OUTPUTS:** list of autocoder outputs. These are Ac.cpp and Ac.hpp files.
|
||||
# - **MOD_DEPS:** list of specified dependencies of target. Use: fprime_ai_info for Ai.xml info
|
||||
####
|
||||
include_guard()
|
||||
|
||||
|
||||
@ -296,11 +296,7 @@ void teardownTopology(const TopologyState& state){
|
||||
```
|
||||
<!-- {% endraw %} -->
|
||||
|
||||
Lastly, since our RNG component has some telemetry, we need to include (or ignore) these channels within the `Packets.xml` file in this folder. As with any other component that is added to a deployment, you use the same syntax with the name of the instance followed by the name of the telemetry channel. For example:
|
||||
|
||||
```xml
|
||||
<channel name="rng.RNGValue"/> <!-- based on our instance name -->
|
||||
```
|
||||
Lastly, since our RNG component has some telemetry, we need to include (or ignore) these channels within the `Packets.fppi` file in this folder. As with any other component that is added to a deployment, you use the same syntax with the name of the instance followed by the name of the telemetry channel.
|
||||
|
||||
Now go ahead and run and build your deployment, and you should see that you have a built deployment that uses a subtopology.
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ arguments can consist of any basic types shown below.
|
||||
|
||||
- bool C++ Boolean type
|
||||
|
||||
These types are used in XML specifications. Note that not all types are
|
||||
These types are used in FPP specifications. Note that not all types are
|
||||
available on all processor architectures. The types that are available
|
||||
is a configurable feature of the architecture and is typically set by
|
||||
compiler arguments.
|
||||
|
||||
@ -153,12 +153,11 @@ Retrieval Options:
|
||||
|
||||
As mentioned, these CLI commands let you interact with the GDS through events and commands, and telemetry channels.
|
||||
Through a *project F´ dictionary* the CLI can understand what commands, events and telemetry channels are available.
|
||||
Every F´ project deployment will have a `*Dictionary.xml` file that's created when the project's deployment is built
|
||||
In the `Ref` example project, it'll be the `Ref/Top/RefTopologyAppDictionary.xml` file. By reading this file, the CLI
|
||||
tool knows what to look for when it's reading or sending data to the GDS. If it doesn't know where the dictionary is,
|
||||
then the CLI tool can't do much beyond printing out help messages.
|
||||
Every F´ project deployment will have a `*Dictionary.json` file that's created when the project's deployment is built
|
||||
By reading this file, the CLI tool knows what to look for when it's reading or sending data to the GDS. If it doesn't
|
||||
know where the dictionary is, then the CLI tool can't do much beyond printing out help messages.
|
||||
|
||||
When you run one of the CLI commands, the tool will automatically look for files ending in `Dictionary.xml` in your
|
||||
When you run one of the CLI commands, the tool will automatically look for files ending in `Dictionary.json` in your
|
||||
current working directory and use the first one it can find. This behavior is similar to how `fprime-gds` searches for
|
||||
dictionaries it uses to construct the browser GUI. If it can't find any dictionaries, it will print out an error message
|
||||
like this:
|
||||
@ -169,7 +168,8 @@ fprime-cli: error: No valid project dictionary found
|
||||
|
||||
Running commands from your project folder (e.g. inside `fprime/Ref`) should work to find a dictionary, but if you want
|
||||
to run commands for a different deployment or project, you can specify the dictionary file exactly using the
|
||||
`--dictionary` option with the file's path. `fprime-cli command-send --dictionary Ref/Top/RefTopologyAppDictionary.xml`.
|
||||
`--dictionary` option with the file's path.
|
||||
`fprime-cli command-send --dictionary build-artifacts/Linux/Ref/Top/RefTopologyDictionary.json`.
|
||||
|
||||
### Using the Tools
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ Below is an example of how to run the sample example sequence with the Ref dicti
|
||||
dictionary will not be generated.
|
||||
|
||||
```
|
||||
fprime-seqgen fprime/Gds/examples/simple_sequence.seq -d fprime/Ref/build-artifacts/*/dict/RefTopologyAppDictionary.xml
|
||||
fprime-seqgen fprime/Gds/examples/simple_sequence.seq -d fprime/build-artifacts/*/Ref/dict/RefTopologyDictionary.json
|
||||
```
|
||||
|
||||
Here the output file is not specified, so it will be a new file in the same directory as the sequence but ending with
|
||||
|
||||
@ -96,8 +96,8 @@ It's recommended that ports are kept in their own directories, separate from com
|
||||
To create a new port:
|
||||
|
||||
1. If necessary, create a new port directory
|
||||
2. Create a new port `*Ai.xml` file, possibly by copying from an existing port.
|
||||
3. Add the new port xml file to `SOURCE_FILES` in the `CMakeLists.txt` file in the directory
|
||||
2. Create a new port `*.fpp` file, possibly by copying from an existing port.
|
||||
3. Add the new port file to `SOURCE_FILES` in the `CMakeLists.txt` file in the directory
|
||||
4. If necessary, add the port directory to the deployment's cmake file with `add_fprime_subdirectory`.
|
||||
|
||||
Alternatively, you may use `fprime-util new --port` from the fprime-tools package. This will
|
||||
@ -105,7 +105,7 @@ walk the user through a few prompts about the port they want to create. Then the
|
||||
will be done automatically:
|
||||
|
||||
1. If the specified directory for the port does not exist, it will be created
|
||||
2. The `*Ai.xml` file will be generated, with information and arguments filled in
|
||||
2. The `*.fpp` file will be generated, with information and arguments filled in
|
||||
3. The port will be added to the source files of `CMakeLists.txt`. If there is no `CMakeLists.txt`
|
||||
file, one will be automatically generated and filled out
|
||||
4. If necessary, the port directory will be added to the deployment's cmake file with
|
||||
@ -113,18 +113,18 @@ will be done automatically:
|
||||
|
||||
### Creating a Component Definition
|
||||
|
||||
The first step in creating a component is to create the component xml definition, which defines
|
||||
The first step in creating a component is to create the component FPP definition, which defines
|
||||
which interfaces it implements, what commands it supports, which telemetry it provides, and what
|
||||
events it produces. This can be done by hand or by using `fprime-util new --component`.
|
||||
|
||||
To create a new component definition by hand:
|
||||
|
||||
1. Create a new component directory
|
||||
2. Create a new component `*Ai.xml` file, possibly by copying from an existing component.
|
||||
3. Optional, create a commands xml file for GDS commands and include it in the component xml file.
|
||||
4. Optional, create an events xml file and include it in the component xml file.
|
||||
5. Optional, create a telemetry xml for telemetry channels and include it in the component xml file.
|
||||
6. Create a component `CMakeLists.txt` test file and add the component xml file to `SOURCE_FILES`
|
||||
2. Create a new component `*.fpp` file, possibly by copying from an existing component.
|
||||
3. Optional, create a commands `.fppi` file for GDS commands and include it in the component file.
|
||||
4. Optional, create an events `.fppi` file and include it in the component file.
|
||||
5. Optional, create a telemetry `.fppi` for telemetry channels and include it in the component file.
|
||||
6. Create a component `CMakeLists.txt` test file and add the component file to `SOURCE_FILES`
|
||||
variable in the file.
|
||||
7. Add component directory to the deployment's cmake file with `add_fprime_subdirectory`.
|
||||
|
||||
@ -133,10 +133,10 @@ walk the user through a few prompts about the component they are creating. Then
|
||||
will be done automatically:
|
||||
|
||||
1. A new component directory will be created
|
||||
2. The `*Ai.xml` file will be generated and filled out with all of the information provided by the user
|
||||
3. Commands, telemetry, events, and parameters will be added to the xml file based on what the user chooses through the prompts
|
||||
4. Ports necessary for commands, telemetry, events, and parameters will be automatically added to the `*Ai.xml` file depending which elements the user chooses to include
|
||||
5. A component `CMakeLists.txt` file will be generated and the component xml will be added
|
||||
2. The `*.fpp` file will be generated and filled out with all of the information provided by the user
|
||||
3. Commands, telemetry, events, and parameters will be added to the file based on what the user chooses through the prompts
|
||||
4. Ports necessary for commands, telemetry, events, and parameters will be automatically added to the `*.fpp` file depending which elements the user chooses to include
|
||||
5. A component `CMakeLists.txt` file will be generated and the component will be added
|
||||
to the source files.
|
||||
6. The component directory will be added to the deployments cmake file with
|
||||
`add_fprime-subdirectory`
|
||||
@ -187,15 +187,11 @@ the project. The full deployment should be built at this stage to ensure that th
|
||||
|
||||
To add a component to the topology:
|
||||
|
||||
1. In the topology `*Ai.xml` file
|
||||
- Import the component `*Ai.xml` xml file.
|
||||
1. In the topology `*.fpp` file
|
||||
- Instantiate the component as many times as necessary.
|
||||
- Connect component output ports with the corresponding input port and vice versa.
|
||||
2. In the topology `Components.hpp` file, declare the component with the same name as the topology
|
||||
xml file.
|
||||
3. In the topology `Topology.cpp` file:
|
||||
2. In the topology `Topology.cpp` file:
|
||||
- Instantiate the component.
|
||||
- Call the component's `init` function.
|
||||
- If additional setup is required, call a user-defined setup function.
|
||||
- If using commands, register the component's commands.
|
||||
- If using health checking, add the component to ping entries.
|
||||
|
||||
@ -42,20 +42,6 @@ and port numbers to be changed without modifying the component FPP itself.
|
||||
The Types directory contains basic types and other base classes used in
|
||||
the architecture, as shown in Table 2.
|
||||
|
||||
**Table 2.** Types directory
|
||||
files.
|
||||
|
||||
| File | Description |
|
||||
| --------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| BasicTypes.hpp | Defines portable built-in data types and common macros |
|
||||
| Assert.hpp(.cpp) | Defines macros to declare an assertion in C++ code |
|
||||
| CAssert.hpp | Defines macros to declare an assertion in C code |
|
||||
| StringType.hpp(.cpp) | Declares a string base class |
|
||||
| Serializable.hpp(.cpp) | Declares the serializable base classes and helper functions |
|
||||
| PolyType.hpp(.cpp) | Describes a serializable polymorphic type class that can be used to uniformly store different types |
|
||||
| String.hpp(.cpp) | A fixed length string available for general usage if the developer does not wish to write one |
|
||||
| InternalInterfaceString.hpp(.cpp) | A string class used by internal interfaces when a string argument is specified |
|
||||
|
||||
### Obj
|
||||
|
||||
The Obj directory contains class declarations and implementations for
|
||||
@ -69,27 +55,11 @@ representation of each object. Components and ports use the object class
|
||||
as a base class. Table 3 lists the files and their descriptions.
|
||||
|
||||
|
||||
**Table 3.** Obj directory files.
|
||||
|
||||
| File | Description |
|
||||
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| ObjBase.hpp(.cpp) | Declaration for object base class |
|
||||
| SimpleObjRegistry.hpp(.cpp) | An implementation of a simple object registry: This registry simply stores created object pointers in an array and calls their toString() method when asked. |
|
||||
|
||||
### Port
|
||||
|
||||
The Port directory contains the base classes for ports. Table 4 lists
|
||||
the files and their descriptions.
|
||||
|
||||
**Table 4.** Port directory files.
|
||||
|
||||
| File | Description |
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| PortBase.hpp(.cpp) | Port base class; contains methods and attributes common to all ports |
|
||||
| InputPort.hpp(.cpp) | Input port base class that is derived from port base class; contains methods and attributes common to all input ports |
|
||||
| OutputPort.hpp(.cpp) | Output port base class that is derived from port base class; contains methods and attributes common to all output ports |
|
||||
| InputSerializePort.hpp(.cpp) | Input serialize port class: Typed output ports can be connected to input serialize ports. The typed output port will serialize its arguments prior to invoking the port. |
|
||||
| OutputSerializePort.hpp(.cpp) | Output serialize port class: Output serialize ports can be connected to typed input port. The serialize port passes the typed port a buffer representing the serialized arguments, which the typed port deserializes. |
|
||||
|
||||
### Comp
|
||||
|
||||
@ -98,42 +68,24 @@ of components. These classes act as base classes for components created
|
||||
by the code generation and are not directly used by developers. Table 5
|
||||
lists the files and their descriptions.
|
||||
|
||||
**Table 5.** Comp directory files.
|
||||
|
||||
| File | Description |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| PassiveComponentBase.hpp(.cpp) | The base class for unthreaded passive components: These components have no thread of execution associated with them. This class derives from the object base class. |
|
||||
| QueuedComponentBase.hpp(.cpp) | The base class for queued components: These components have a message queue but no thread. It is derived from the passive component base class. |
|
||||
| ActiveComponentBase.hpp(.cpp) | The base class for active components: Active components have a thread of execution as well as a message queue. It is derived from the queued component class. |
|
||||
|
||||
### Cmd
|
||||
|
||||
This Cmd directory contains XML and class declarations used to generate
|
||||
code for command interfaces to components. The XML generates port
|
||||
This Cmd directory contains FPP and class declarations used to generate
|
||||
code for command interfaces to components. The FPP generates port
|
||||
classes in the normal way via the code generator. The code generator
|
||||
then uses those generated classes as special command input ports for
|
||||
components that define commands in their component XML. Since the ports
|
||||
components that define commands in their component FPP. Since the ports
|
||||
themselves are generated in the same way as any other port, they can be
|
||||
used by developers in other components that process commands, such as command dispatchers. Table 6 lists the files and their descriptions.
|
||||
|
||||
**Table 6.** Cmd directory files.
|
||||
|
||||
| File | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| CmdPortAi.xml | XML description of a command port |
|
||||
| CmdResponsePortAi.xml | XML description of a command response port |
|
||||
| CmdRegPortAi.xml | XML description of a command registration port |
|
||||
| CmdArgBuffer.hpp(.cpp) | A class used by the command port that is a data buffer containing the serialized form of the command arguments |
|
||||
| CmdString.hpp(.cpp) | A string class used by the command code generator for string arguments |
|
||||
| CmdPacket.hpp(.cpp) | A class representing an encoded command packet that contains a command opcode and arguments: The code generator does not depend on this class, so it can be modified or not used. |
|
||||
|
||||
### Tlm
|
||||
|
||||
This Tlm directory contains XML and class declarations used to generate
|
||||
This Tlm directory contains FPP and class declarations used to generate
|
||||
code for channelized telemetry interfaces for components. Channelized
|
||||
telemetry has historically been a snapshot in time of a set of data. Every
|
||||
value of that data is not necessarily stored permanently, but is
|
||||
sampled. The XML generates port classes in the normal way via the code
|
||||
sampled. The FPP generates port classes in the normal way via the code
|
||||
generator. The code generator then uses those generated classes as
|
||||
special telemetry output ports for components needing telemetry. Since
|
||||
the ports themselves are generated in the same way as any other port,
|
||||
@ -141,63 +93,36 @@ they can be used by developers in other components that process
|
||||
telemetry, such as a telemetry buffer for downlinking telemetry. Table 7
|
||||
lists the files and their descriptions.
|
||||
|
||||
**Table 7.** Tlm directory files.
|
||||
|
||||
| File | Description |
|
||||
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| TlmPortAi.xml | XML description of a telemetry port |
|
||||
| TlmBuffer.hpp(.cpp) | A data buffer class that represents the serialized form of the telemetry channel |
|
||||
| TlmString.hpp(.cpp) | A string class used by the telemetry code generator when a string is the telemetry channel |
|
||||
| TlmPacket.hpp(.cpp) | A notional class representing an encoded telemetry packet that contains a telemetry channel identifier and serialized value: The code generator does not depend on this class, so it can be modified or not used. |
|
||||
|
||||
### Log
|
||||
|
||||
This Log directory contains XML and class declarations used to generate
|
||||
This Log directory contains FPP and class declarations used to generate
|
||||
code logging (event) interfaces for components. Developer implementation
|
||||
code sends log events to capture all the events of interest in a system
|
||||
as they happen. Other components serve to store events for forwarding to
|
||||
a ground interface or test software. An XML definition for telemetry
|
||||
a ground interface or test software. An FPP definition for telemetry
|
||||
ports is defined, which the code generator then uses as special logging
|
||||
output ports for components. Since the ports themselves are generated in
|
||||
the same way as any other port, they can be used by developers in other
|
||||
components that process logging, such as a logging history. Table 8
|
||||
lists the files and their descriptions.
|
||||
|
||||
**Table 8.** Log directory files.
|
||||
|
||||
| File | Description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| LogPortAi.xml | XML description of a logging port |
|
||||
| LogTextPortAi.xml | XML description of an optional text logging port: This port generates a string representing the logged event. The code generator generates code to use both kinds of logging ports, but the text log can be disabled. |
|
||||
| LogBuffer.hpp(.cpp) | A data buffer class that represents the serialized form of the log entry |
|
||||
| LogString.hpp(.cpp) | A string class used by the log code generator when a string is the telemetry channel |
|
||||
| TextLogString.hpp(.cpp) | A string class used by the text log interface to pass strings |
|
||||
| LogPacket.hpp(.cpp) | A notional class representing an encoded log packet that contains a log entry identifier and serialized set of values: The code generator does not depend on this class, so it can be modified or not used. |
|
||||
|
||||
### Prm
|
||||
|
||||
This Prm directory contains XML and class declarations used to generate
|
||||
This Prm directory contains FPP and class declarations used to generate
|
||||
parameter interfaces for components. Parameters are values are meant to
|
||||
be stored in nonvolatile storage that affect various properties of the
|
||||
software. Parameters are loaded at run time and given to components on
|
||||
request. An XML definition for a parameter port is used by the code
|
||||
request. An FPP definition for a parameter port is used by the code
|
||||
generator to create special parameter output ports for components. Since
|
||||
the ports themselves are generated in the same way as any other port,
|
||||
they can be used by developers in other components that provide
|
||||
parameters. Table 9 lists the files and their descriptions.
|
||||
|
||||
**Table 9.** Prm directory files.
|
||||
|
||||
| File | Description |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| PrmPortAi.xml | XML description of a parameter port |
|
||||
| PrmBuffer.hpp(.cpp) | A data buffer that represents a serialized parameter |
|
||||
| PrmString.hpp(.cpp) | A string class used by the parameter code generator when a string is the parameter value |
|
||||
| PrmPacket.hpp(.cpp) | A notional class representing an encoded parameter packet that contains a parameter identifier and serialized value: The code generator does not depend on this class, so it can be modified or not used. |
|
||||
|
||||
### Time
|
||||
|
||||
This Time directory contains XML and class declarations used to generate
|
||||
This Time directory contains FPP and class declarations used to generate
|
||||
time interfaces for components. The time interface port is created by
|
||||
the code generator as a source of time for time-tagging telemetry
|
||||
samples and log events. Since the ports themselves are generated in the
|
||||
@ -205,13 +130,6 @@ same way as any other port, they can be used by developers in other
|
||||
components that provide time from whatever sources are present in the
|
||||
system. Table 10 lists the files and their descriptions.
|
||||
|
||||
**Table 10.** Time directory files.
|
||||
|
||||
| File | Description |
|
||||
| -------------- | ---------------------------------------------------------------------------------- |
|
||||
| TimePortAi.xml | XML description of a time port |
|
||||
| Time.hpp | A class containing a time value that represents the time when the port was invoked |
|
||||
|
||||
|
||||
### Com
|
||||
|
||||
@ -220,13 +138,7 @@ port could be used as an interface to components that send and receive
|
||||
data to ground or test software. Table 11 lists the files and their
|
||||
descriptions.
|
||||
|
||||
**Table 11.** Com directory files.
|
||||
|
||||
| File | Description |
|
||||
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| ComPortAi.xml | XML description of a communication port |
|
||||
| ComBuffer.hpp(.cpp) | A data buffer class used to represent a packet of serialized communication data |
|
||||
| ComPacket.hpp(.cpp) | A data packet class representing data from one of the telemetry or command types: The specific packet types are derived classes. |
|
||||
|
||||
## Svc
|
||||
|
||||
@ -238,7 +150,7 @@ ports, and other types are examples of how the architecture can be
|
||||
applied. The component example implementations are very simple; flight
|
||||
versions would most likely be more sophisticated. The way development is
|
||||
done is that the developer will define the components and their
|
||||
properties in XML. The code generator will generate C++ classes that
|
||||
properties in FPP. The code generator will generate C++ classes that
|
||||
encapsulate the features of the component. The developer will then write
|
||||
a class that derives from those generated classes and implement the port
|
||||
methods. For these directories, each file will not be described, but a
|
||||
@ -247,7 +159,7 @@ instead. The descriptions are as follows.
|
||||
|
||||
### ActiveLogger
|
||||
|
||||
This directory contains a component XML description and implementation
|
||||
This directory contains a component FPP description and implementation
|
||||
for an active component that accepts serialized log events. The input
|
||||
port accepting log entries puts them in a message queue for the
|
||||
component thread. The component thread calls the port handler in the
|
||||
@ -307,7 +219,7 @@ component when it receives a FATAL event from a component.
|
||||
|
||||
### GndIf
|
||||
|
||||
The directory contains just the XML definition of a component that could
|
||||
The directory contains just the FPP definition of a component that could
|
||||
be used to send and receive communications packets. The uplink port
|
||||
would be connected to the command dispatcher for executing commands, and
|
||||
the downlink port would be connected by components collecting downlink
|
||||
@ -414,7 +326,7 @@ connected to telemetry sources and the command dispatcher.
|
||||
|
||||
### Time
|
||||
|
||||
This directory contains the XML definition for the time source base
|
||||
This directory contains the FPP definition for the time source base
|
||||
class. A time source is necessary for time-tagging the telemetry and log
|
||||
events in components. Various implementations that derive from this base
|
||||
class will provide time.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user