9.9 KiB
1. Introduction
This tutorial shows how to develop, test, and deploy a simple topology consisting of two components:
-
MathSender: A component that receives commands and forwards work toMathReceiver. -
MathReceiver: A component that carries out arithmetic operations and returns the results toMathSender.
See the diagram below.
What is covered: The tutorial covers the following concepts:
-
Using the FPP modeling language to specify the types and ports used by the components.
-
Using the F Prime build system to build the types and ports.
-
Developing the
MathSendercomponent: Specifying the component, building the component, completing the C++ component implementation, and writing component unit tests. -
Developing the
MathReceivercomponent. -
Adding the new components and connections to the F Prime
Refapplication. -
Using the F Prime Ground Data System (GDS) to run the updated
Refapplication.
Prerequisites: This tutorial assumes the following:
-
Basic knowledge of Unix: How to navigate in a shell and execute programs.
-
Basic knowledge of git: How to create a branch.
-
Basic knowledge of C++, including class declarations, inheritance, and virtual functions.
If you have not yet installed F Prime on your system, do so now.
Follow the installation guide at INSTALL.md
in the F Prime git repository.
You may also wish to work through the Getting Started tutorial at
docs/GettingStarted/Tutorial.md.
Git branch: This tutorial is designed to work on the branch release/v3.0.0.
Working on this tutorial will modify some files under version control in the F Prime git repository. Therefore it is a good idea to do this work on a new branch. For example:
git checkout release/v3.0.0
git checkout -b math-tutorial
If you wish, you can save your work by committing to this branch.
2. The MathOp Type
In F Prime, a type definition defines a kind of data that you can pass between components or use in commands and telemetry.
For this tutorial, we need one type definition.
It defines an enumeration called MathOp, which
represents a mathematical operation.
We will add the specification for the MathOp type to the
Ref topology.
We will do this in three stages:
-
Construct the FPP model.
-
Add the model to the project.
-
Build the model.
2.1. Construct the FPP Model
Create the MathTypes directory:
Go to the directory Ref at the top-level of the
F Prime repository and run mkdir MathTypes.
This step creates a new directory Ref/MathTypes.
This directory will contain our new type.
Create the FPP model file:
Now go into the directory Ref/MathTypes.
In that directory, create a file MathTypes.fpp with the following contents:
module Ref {
@ A math operation
enum MathOp {
ADD @< Addition
SUB @< Subtraction
MUL @< Multiplication
DIV @< Division
}
}
You can do this by typing, or by copy-paste.
This file defines an enumeration or enum with enumerated constants ADD,
SUB, MUL, and DIV.
These four constants represent the operations of addition, subtraction,
multiplication, and division.
The enum also defines a type MathOp; the enumerated constants are the values
of this type.
For more information on enums, see The FPP User's
Guide.
The enum MathTypes resides in an FPP module Ref.
An FPP module is like a C++ namespace: it encloses several definitions, each of which is qualified with the name of the module. For more information on FPP modules, see The FPP User's Guide.
The text following a symbol @ or @< is called an annotation.
These annotations are carried through the parsing and become comments in the
generated code.
For more information, see The FPP User's
Guide.
2.2. Add the Model to the Project
Create Ref/MathTypes/CMakeLists.txt:
Create a file Ref/MathTypes/CMakeLists.txt with the following contents:
set(SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/MathTypes.fpp"
)
register_fprime_module()
This code will tell the build system how to build the FPP model.
Update Ref/CMakeLists.txt:
Now we need to add the new directory to the Ref project.
To do that, open the file Ref/CMakeLists.txt.
This file should already exist; it was put there by the developers
of the Ref topology.
In this file, you should see several lines starting with add_fprime_subdirectory.
Immediately after the last of those lines, add the following new line:
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/MathTypes/")
2.3. Build the Model
Run the build: Do the following:
-
Go to the directory
Ref/MathTypes. -
If you have not already run
fprime-util generate, then do so now. -
Run the command
fprime-util build.
The output should indicate that the model built without any errors. If not, try to identify and correct what is wrong, either by deciphering the error output, or by going over the steps again. If you get stuck, you can look at the reference implementation.
Inspect the generated code:
Now go to the directory Ref/build-fprime-automatic-native/Ref/MathTypes
(you may want to use pushd, or do this in a separate shell,
so you don't lose your current working directory).
The directory build-fprime-automatic-native is where all the
generated code lives for the "automatic native" build of the Ref
project.
Within that directory is a directory tree that mirrors the project
structure.
In particular, Ref/build-fprime-automatic-native/Ref/MathTypes
contains the generated code for Ref/MathTypes.
Run ls.
You should see something like this:
CMakeFiles MathOpEnumAc.cpp MathOpEnumAi.xml.prev cmake_install.cmake
Makefile MathOpEnumAc.hpp autocoder
The files MathOpEnumAc.hpp and
MathOpEnumAc.cpp are the auto-generated C++ files
corresponding to the MathOp enum.
You may wish to study the file MathOpEnumAc.hpp.
This file gives the interface to the C++ class Ref::MathOp.
All enum types have a similar auto-generated class
interface.
2.4. Reference Implementation
A reference implementation for this section is available at
docs/Tutorials/MathComponent/MathTypes.
To build this implementation from a clean repository,
do the following:
-
Go to the
Refdirectory. -
Run
cp -R ../docs/Tutorials/MathComponent/MathTypes . -
Update
Ref/CMakeLists.txtas stated above. -
Follow the steps for building the model.
If you have modified the repo, revise the steps accordingly.
For example, switch git branches, use git stash to stash
your changes, or move MathTypes to another directory such
as MathTypes-saved.
3. The MathOp and MathResult Ports
A port is the endpoint of a connection between two components. A port definition is like a function signature; it defines the type of the data carried on a port.
For this tutorial, we need two port definitions:
-
MathOpfor sending an arithmetic operation request fromMathSendertoMathReceiver. -
MathResultfor sending the result of an arithmetic operation fromMathReceivertoMathSender.
We follow the same three steps as in the previous section.
3.1. Construct the FPP Model
Create the MathPorts directory:
Go to the directory Ref at the top-level of the
F Prime repository and run mkdir MathPorts.
This directory will contain our new ports.
Create the FPP model file:
Now go into the directory Ref/MathPorts.
Create a file MathPorts.fpp with the following contents:
module Ref {
@ Port for requesting an operation on two numbers
port MathOp(
val1: F32 @< The first operand
op: MathOp @< The operation
val2: F32 @< The second operand
)
@ Port for returning the result of a math operation
port MathResult(
result: F32 @< the result of the operation
)
}
This file defines the ports MathOp and MathResult.
MathOp has three formal parameters: a first operand, an
operation, and a second operand.
The operands have type F32, which represents a 32-bit
floating-point number.
The operation has type MathOp, which is the enum type
we defined in the previous section.
MathResult has a single formal parameter, the value of type F32
returned as the result of the operation.
For more information about port definitions, see The FPP User's Guide.
3.2. Add the Model to the Project
Add add the model
Ref/MathPorts/MathPorts.fpp to the Ref project.
Carry out the steps in the
previous section, after
substituting MathPorts for MathTypes.
3.3. Build the Model
Carry out the steps in the
previous section,
in directory MathPorts instead of MathTypes.
The generated code will go in
Ref/build-fprime-automatic-native/Ref/MathPorts.
For port definitions, the names of the auto-generated C++
files end in PortAc.hpp and PortAc.cpp.
You can look at this code if you wish.
However, the auto-generated C++ port files are used
by the autocoded component implementations (described below);
you won't ever program directly against their interfaces.
3.4. Reference Implementation
A reference implementation for this section is available at
docs/Tutorials/MathComponent/MathPorts.
To build this implementation, follow the steps
described for MathTypes.
