Prerequisites: INSTALL.md
This tutorial will walk the user through the basic usage of the F´ development suite. This assumes that the user has run through the above installation guide, and has a working F´ installation.
The goal of this Tutorial is to build familiarity with the F´environment and tools. It does not walk the user through
creation of new F´ items, but rather users the existing F´ Ref
example as a place to operate the tools, learn the
environment, and learn F´.
The full development process is covered in the Math Component Tutorial, which will build on the knowledge learned here.
The goal of this tutorial is to demonstrate the F´ tool suite as it applies to the F´ development process. Users will first gain some understanding of F´ terminology followed by the F´ development process. Then they will use the tools to walk the F´ development process steps against existing reference goals.
This section will cover basic terminology used in this and other tutorial with respect to F´. It may be used as a reference for keywords that have specific meaning in an F´ project.
Port: a port represents a connection between Components. These act as communication channels in F´. This allows Components to interact with each other. A set of Ports acts as a defined interface to a Component.
Component: the location of program behavior. Components execute the software logic of the system and typically define an interface of Ports that act allow them to interact with other Components. Components additionally may define Commands, Events, Channels, and Parameters, which define standard data patterns in F´.
Topology: a topology represents the full F´ system. It is a set of Components and the connections between those Components. The Topology specifies the full system and all the communication channels.
Event: an event, also known as an EVR, is a type of downlinked data that represents a single event in the system. An event is composed of a name, format string, and set of arguments that described what happened. Events represent a history of the system. Events are defined per-component.
Channel: a channel, also known as a telemetry item, is a single value read and downlinked. Channels are consist of a type, a format specifier, and a value. Channels represent current system state. Channels are defined per-component.
Command: a command is uplinked data items that instructs the system to perform an action. Commands consist of an opcode, a mnemonic, and a list of arguments to the command. Commands are defined per-component.
Deployment: a deployment is a single instance of F´. Although a single F´ project can use/define multiple deployments, a deployment represents one build/executable.
Build Directory/Build Cache: this directory, created by the fprime-util
described below, is required to build
CMake projects. It stores all by-products, generated code, and build products from an F´ build.
Ground System: the computer system running to collect the data from the running F´ deployment. There is a basic ground system supplied with F´ for development purposes.
Toolchain: a set of build tools to build for a specific architecture. i.e. the "raspberrypi" toolchain will build F´ deployments for the arm/Linux architecture of the raspberry pi.
F´ development typically starts with creating new Ports and Components as these can be built and tested as units and then the full F´ system deployment topology can be assembled for integrated systems testing and release/operations. This can be done iteratively by creating a few Components then integrating them into the system topology and then repeating with the next most critical components.
F´ development is a design-first approach. To start, a developer should design any unique ports that the Component will need. If desired, the port can be built and compiled to ensure that the design is correct. Since the port will be entirely auto-generated, developers usually refrain from unit testing the port and defer unit testing to the Component.
Next, developers design components. Components are designed by specifying the ports that represent the Component's
interface and the Commands, Events and Channels that the Component handles. This tutorial focuses on the tool suite, so
the design is already in-place. Users can see the design by inspecting Components in the Ref
directory. Creation of
new components from design through test is demonstrated in the Math Component Tutorial.
The next step for developing a Component is to implement the code. To do this, one can generate template stubs to fill with the developer's stubs. To do this, a user runs the F´ tool suite to generate these stubs. Then implements, builds, and tests from there. Unit tests template stubs are generated in the same way, and should test-driven development be preferred, these tests stubs could be generated and implemented before the Component's code.
Finally, the Component is integrated into the deployment and the entire deployment may be built and installed.
This tutorial will walk developers through generating the templates, building example Components, and
building/installing the full deployment. It will use the Ref
application as an example for this.
In order to ease in development, the F´ team has created a small wrapper for the CMake build system. This will recover the advantages of previous F´ development patterns, while allowing for the power and configurability of CMake as an underlying build tool.
In order to run CMake, a build cache needs to be generated. This is typically done once for each platform the user wishes to compile against. It is usually done right after F´ is checked-out and repeated for each platform as they are added. It is a setup step and isn't formally part of the F´ development process.
To run this tool, the developer will use the generate
subcommand. It take one optional argument: the toolchain file
used in CMake to compile for a specific platform. If not supplied, the native
toolchain will be used and F´ will be
setup to run on the current platform (typically Mac OS, or Linux depending on the developer's chosen OS).
Generate the Ref Application for Native Compilation
To generate a native build, follow the commands shown below. It is assumed that the user has checked out the fprime repository and is performing commands relative to the location of that checkout.
cd fprime/Ref
fprime-util generate
Here the utility will create two standard builds: one for the standard build, and one for the unit test build. This will enable
the user to take advantage of all parts of F´ without generating their own CMake build caches. Note: should a developer
be developing or improving F´ provided infrastructure components, then the generate
command should be run in the F´
root directory. However, most developers do not need this functionality.
Generate Cross-Compile of the Ref Application for Raspberry PI Platform
Most developers wish to run F´ on embedded hardware. This is done by generating a cross-compile using a different CMake toolchain by providing the toolchain argument. The above invocations assume the default "native" toolchain.
Here, the "raspberrypi" toolchain supplied by F´ is used. This will generate a cross-compile for the raspberry pi architecture. The user should ensure to follow the Raspberry PI setup steps found at: RPI
cd fprime/Ref
fprime-util generate raspberrypi
Once the build system cache is generated, developers will need to generate the stubbed implementations of a Component's C++
files. This can be done using the impl
command of the F´ utility. These commands assume a default build has been generated.
Typically passing in a toolchain is unnecessary as these templates are platform agnostic.
Generating Implementation Stubs of SignalGen
cd fprime/Ref/SignalGen
fprime-util impl
This creates two files for the component. These are <Component>Impl.cpp-template
and <Component>Impl.hpp-template
.
The user can then rename these files to remove -template
. The file is then ready for C++ development. By generating
-template
files, we won't accidentally overwrite any existing implementation should the developer need to repeat this
step.
Once the build system cache is generated, developers will need to generate the stubbed implementations for creating
unit tests for a Component's C++. This can be done using the impl --ut
command of the F´ utility. These commands
assume a default build has been generated. They can be run passing in a toolchain, but this is typically not done because
they are toolchain agnostic.
Generating Unit Test Stubs of SignalGen
cd fprime/Ref/SignalGen
fprime-util impl --ut
This creates the following files, that are typically moved to a sub folder called test/ut
. The files created are
placed in the current directory and named:
Tester.cpp
Tester.hpp
GTestBase.cpp
GTestBase.hpp
TesterBase.cpp
TesterBase.hpp
TestMain.cpp
Once a developer has implemented a component, it is time to build that component and test that component. In order to build
a component the build
subcommand needs to be run. This will build the "current directory" that the developer is in.
That means that should the user change into a deployment directory then the build command will build the full deployment.
Should the user desire to build a component, navigate into the Component's directory and run the build command.
Build SignalGen Component
cd fprime/Ref/SignalGen
fprime-util build
The user can also build a deployment by navigating to the deployment directory and running the build
command. This is
shown below:
Build Ref Deployment
cd fprime/Ref
fprime-util build
Note: the user almost always wants to run the "install" command on deployments. This builds the binary like "build"
but also copies the binary to the deployments "bin" directory, i.e. fprime/Ref/bin
. Install is described below.
This process also built the Dictionaries for the project and places the dictionary in the "Top" folder of the deployment. This happens any time the "install" or "build" command are run on a deployment.
The user can also build a component or deployment for a cross-compile by specifying the toolchain. A previous generate for that toolchain should have been run. Again for deployments, the user typically should run "install", see below. These steps require the setup described here: RPI
cd fprime/Ref/SignalGen
fprime-util build raspberrypi
cd fprime/Ref
fprime-util build raspberrypi
Once the deployment is built, it would be nice to be able to install the binary and dictionaries. This will enable the users to
quickly find and run the deployment. This installation can be run using the following command. Everything will be installed to
the directory defining the deployment. i.e. fprime/Ref/bin
. Install will also invoke build
so users should use this in-place
of build for deployments.
Installing the Ref Deployment and Running the Binary Assuming Linux
cd fprime/Ref
fprime-util build
./bin/Linux/Ref # Run the deployment
CTRL-C # Exit the application
Running the application as part of the development ground data system is shown below.
The user can also install a cross-compile.
cd fprime/Ref
fprime-util build raspberrypi
Unit tests can be build using the the build --ut
command of the fprime-util
. This will allow us to build the unit tests
in preparation to run them. The user can also just run check
to build and run the unit tests.
Before building unit tests, the unit test build cache must be generated:
cd fprime/Ref
fprime-util generate --ut
Building Unit Test of SignalGen
cd fprime/Ref/SignalGen
fprime-util build --ut
Once built, the unit test can be run using the following command. Note: this will produce a message warning of no tests run because SigGen has no unit tests defined.
cd fprime/Ref/SignalGen
fprime-util check
The user can also build the unit test, but must copy it to the hardware and run it here. This can be done with a cross- compile by running the following commands.
Cross-Compile Unit Test of SignalGen
cd fprime/Ref/SignalGen
fprime-util build raspberrypi --ut
The user should now be familiar with F´ terminology and with the fprime-util
tool used to build and develop F´
applications. The next step is to follow the full MathComponent
tutorial to create new Ports, Components, and
Topologies. This will walk the user through the entire development process, using the tool commands we learned here.
Next: Math Component Tutorial Also See: GPS Component Tutorial for a cross-compiling tutorial.