-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "Migrate HelloWorld tutorial to F' community (#2095)"
This reverts commit 339d5d3.
- Loading branch information
Showing
7 changed files
with
554 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
# Getting Started: Integration and Testing With F´ Deployments | ||
|
||
This section will walk new users through creating a new F´ [deployment](./Tutorial.md#deployment). This deployment will | ||
build a [topology](./Tutorial.md#topology) containing the standard F´ stack of components and a single `HelloWorld` | ||
component instance. The `HelloWorld` was created in the [last section](./HelloWorld.md). The tutorial will close by | ||
testing the deployment and `HelloWorld` component through the `fprime-gds`. | ||
|
||
### Prerequisites: | ||
- [Getting Started: F´ Hello World Component](./HelloWorld.md) | ||
|
||
### Tutorial Steps: | ||
- [Creating A New Deployment](#creating-a-new-deployment) | ||
- [Adding The Hello World Component](#adding-the-hello-world-component) | ||
- [Testing With `fprime-gds`](#testing-with-fprime-gds) | ||
- [Conclusion](#conclusion) | ||
|
||
## Creating A New Deployment | ||
|
||
F´ deployments represent one flight software executable. All the components we develop for F´ run within a deployment. | ||
The deployment created here will contain the standard command and data handling stack. This stack enables | ||
ground control and data collection of the deployment. | ||
|
||
To create a deployment, run the following commands: | ||
```bash | ||
# In: MyProject | ||
fprime-util new --deployment | ||
``` | ||
This command will ask for some input. Respond with the following answers: | ||
|
||
``` | ||
deployment_name [MyDeployment]: MyDeployment | ||
path_to_fprime [./fprime]: | ||
``` | ||
|
||
> For any other questions, select the default response. | ||
At this point, the `MyDeployment` has been created, but our `HelloWorld` component has not been added. | ||
|
||
## Adding The Hello World Component | ||
|
||
First, the project's components should be added to this deployment's build. This can be done by adding the following | ||
to `MyDeployment/CMakeLists.txt`. | ||
|
||
```cmake | ||
... | ||
### | ||
# Components and Topology | ||
### | ||
include("${FPRIME_PROJECT_ROOT}/project.cmake") | ||
... | ||
``` | ||
> To build this new deployment generate a build cache and then build. | ||
> ```bash | ||
> # In: MyProject/MyDeployment | ||
> fprime-util generate | ||
> fprime-util build | ||
> ``` | ||
> > Notice `fprime-util generate` was used again. This is because this new deployment builds in a separate environment. | ||
In this section the `HelloWorld` component will be added to the `MyDeployment` deployment. This can be done by adding | ||
the component to the topology defined in `MyDeployment/Top`. | ||
Topologies instantiate all the components in a running system and link them together. For some port types, like the | ||
commanding, event, and telemetry ports used by `HelloWorld`, the connections are made automatically. In addition, the | ||
topology specifies how to construct the component instance. This is also done automatically unless the component has | ||
specific configuration. | ||
In order to add a component to the topology, it must be added to the topology model. An instance definition and an | ||
instance initializer must both be added. | ||
To add an instance definition, add `instance helloWorld` to the instance definition list in the `topology MyDeployment` section | ||
of `MyDeployment/Top/topology.fpp`. This is shown below. | ||
Edit `MyDeployment/Top/topology.fpp`: | ||
``` | ||
... | ||
topology MyDeployment { | ||
# ---------------------------------------------------------------------- | ||
# Instances used in the topology | ||
# ---------------------------------------------------------------------- | ||
instance ... | ||
instance ... | ||
instance helloWorld | ||
``` | ||
> Be careful to not remove any other instances from the list. | ||
`helloWorld` is the name of the component instance. Like variable names, component instance names should be descriptive | ||
and are typically named in camel or snake case. | ||
Next, an instance initializer must be added to topology instances defined in `MyDeploymment/Top/instances.fpp` file. | ||
Since the `HelloWorld` component is an `active` component it should be added to the active components section and should | ||
define a priority and queue depth options. This is shown below. | ||
Add to `MyDeploymment/Top/instances.fpp`: | ||
``` | ||
... | ||
# ---------------------------------------------------------------------- | ||
# Active component instances | ||
# ---------------------------------------------------------------------- | ||
instance ... | ||
... | ||
... | ||
... | ||
instance ... | ||
instance helloWorld: MyComponents.HelloWorld base id 0x0F00 \ | ||
queue size Default.QUEUE_SIZE \ | ||
stack size Default.STACK_SIZE \ | ||
priority 50 | ||
``` | ||
> The user must ensure that the base id (0x0F00) does not conflict with any other base ids in the topology. 0x0F00 | ||
> should be safe for deployments created with `fprime-util new --deployment`. | ||
> Make sure to use the same instance name (i.e. helloWorld) as defined in the instance definition just added to | ||
> `topology.fpp`. | ||
Finally, our new telemetry channel should be added to our telemetry packet specification. For this tutorial the | ||
channel can be ignored as the deployment will not use the telemetry packetizer. Add the following to the `ignore` | ||
section of `MyDeployment/Top/MyDeploymentPackets.xml`. | ||
Update `MyDeployment/Top/MyDeploymentPackets.xml`: | ||
``` | ||
<ignore> | ||
... | ||
<channel name="helloWorld.GreetingCount"/> | ||
</ignore> | ||
``` | ||
Since this component has no custom ports nor does it require special configuration, our addition to the topology is | ||
completed. The deployment can now be set up and built using the following commands: | ||
``` | ||
# In: MyProject/MyDeployment | ||
fprime-util build -j4 | ||
``` | ||
> Resolve any errors that occur before continuing to the running section. | ||
## Running With `fprime-gds` | ||
It is now time to test the `HelloWorld` component by running the deployment created in this section. This can be | ||
accomplished by running the `fprime-gds` command in the deployment, verifying connection, sending the new SEND_HELLO | ||
command and verifying that the `Hello` event and `GreetingCount` channel appears. | ||
To start the deployment with default settings, run: | ||
```bash | ||
fprime-gds | ||
``` | ||
The F´ GDS control page should open up in your web browser. If it does not open up, navigate to `http://127.0.0.1:5000`. | ||
Once the F´ GDS page is visible, look for a green circle icon in the upper right corner. This shows that the flight | ||
software deployment has connected to the GDS system. If a red X appears instead, navigate to the Logs tab and look for | ||
errors in the various logs. | ||
Now that communication is verified, navigate to the "Commanding" tab and select `helloWorld.SAY_HELLO` from the | ||
dropdown list. Type a greeting into the argument input box and click the button "Send Command". If the argument has | ||
validated successfully the command will send. Resolve all errors and ensure the command has sent. | ||
> Notice commands are instance specific. Had several HelloWorld component instances been used, there would be multiple | ||
> `SAY_HELLO` listings, one for each component instance. | ||
Now that the command has sent, navigate to the "Events" tab. Ensure that the event list contains the Hello event with | ||
the text entered when sending the command. | ||
Lastly, navigate to the "Channels" tab. Look for "helloWorld.GreetingCount" in the channel list. Ensure it has recorded | ||
the number of times a `helloWorld.SAY_HELLO` was sent. | ||
Congratulations, you have now set up a project, component, and deployment in F´. | ||
## Conclusion | ||
This concludes both the adding deployment section of the Getting Started tutorial and the tutorial itself. The user has | ||
been able to perform the following actions: | ||
1. Create a new blank F´ projects | ||
2. Create a new F´ components | ||
3. Create a new F´ deployments and add components it | ||
To explore components more in-depth and see how components communicate with one another, see the | ||
[Math Component Tutorial](../MathComponent/Tutorial.md). | ||
**Next:** [Math Component Tutorial](../MathComponent/Tutorial.md) | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
# Getting Started: Creating an F´ Hello World Component | ||
|
||
This tutorial will walk new users through creating a basic F´ component. Users should have completed the new project | ||
tutorial and have the tools sourced as shown in the [conclusion](./NewProject.md#conclusion) portion of that tutorial. | ||
|
||
F´ components encapsulate the various parts of system behavior. These components can interact with the ground system | ||
through [commands](Tutorial.md#command), [events](./Tutorial.md#event), and | ||
[telemetry channels](./Tutorial.md#telemetry-channel). Components communicate with other components through | ||
[ports](./Tutorial.md#port), which covered in-depth in [another tutorial](../MathComponent/Tutorial.md). | ||
|
||
### Prerequisites: | ||
- [Getting Started: Creating an F´ Project](./NewProject.md) | ||
|
||
### Tutorial Steps: | ||
- [Hello World Component](#hello-world-component-requirements) | ||
- [Creating the Hello World Component](#creating-the-hello-world-component) | ||
- [Editing the Component Model](#editing-the-component-model) | ||
- [Implementing Component Behavior](#implementing-component-behavior) | ||
- [Conclusion](#conclusion) | ||
|
||
## Hello World Component Requirements | ||
|
||
The first step for creating a new component is understanding what it is that we wish to implement. This is called | ||
defining requirements. In the spirit of "Hello World" this component will encapsulate greeting behavior. The component | ||
will define three items to implement greeting behaviour: | ||
|
||
1. A [command](./Tutorial.md#command) called `SAY_HELLO` that will command the component to send a greeting | ||
2. An [event](./Tutorial.md#event) called `Hello` that is the greeting sent in response to the `SAY_HELLO` command | ||
3. A [telemetry channel](./Tutorial.md#telemetry-channel) called `GreetingCount` that will count each `Hello` event sent | ||
|
||
These are a simple set of requirements for this component. | ||
|
||
## Creating the Hello World Component | ||
|
||
The next step is to create the new component. First, create a directory called `MyComponents` to contain this project's | ||
components and change into that directory. | ||
|
||
```bash | ||
# In: MyProject | ||
mkdir -p MyComponents | ||
cd MyComponents | ||
``` | ||
|
||
Creating a new component is accomplished with the following command: | ||
|
||
```bash | ||
# In: MyProject/MyComponents | ||
fprime-util new --component | ||
``` | ||
This command will ask for some input. You should respond with the following answers: | ||
|
||
``` | ||
[INFO] Cookiecutter source: using builtin | ||
component_name [MyComponent]: HelloWorld | ||
component_short_description [Example Component for F Prime FSW framework.]: Hello World Tutorial Component | ||
component_namespace [HelloWorld]: MyComponents | ||
Select component_kind: | ||
1 - active | ||
2 - passive | ||
3 - queued | ||
Choose from 1, 2, 3 [1]: 1 | ||
Select enable_commands: | ||
1 - yes | ||
2 - no | ||
Choose from 1, 2 [1]: 1 | ||
Select enable_telemetry: | ||
1 - yes | ||
2 - no | ||
Choose from 1, 2 [1]: 1 | ||
Select enable_events: | ||
1 - yes | ||
2 - no | ||
Choose from 1, 2 [1]: 1 | ||
Select enable_parameters: | ||
1 - yes | ||
2 - no | ||
Choose from 1, 2 [1]: 1 | ||
[INFO] Found CMake file at 'MyProject/project.cmake' | ||
Add component MyComponents/HelloWorld to MyProject/project.cmake at end of file (yes/no)? yes | ||
Generate implementation files (yes/no)? yes | ||
``` | ||
|
||
> For any other questions, select the default response. | ||
This will create a new component called "HelloWorld" in the "MyProject" namespace. This new component will be able to | ||
define commands, events, telemetry channels, and parameters. | ||
|
||
We should navigate to the component's directory and look around: | ||
|
||
```bash | ||
# In: MyProject/MyComponents | ||
cd HelloWorld | ||
ls | ||
``` | ||
This will show the following files: | ||
1. `HelloWorld.fpp`: design model for the component | ||
2. `HelloWorld.hpp` and `HelloWorld.cpp`: C++ implementation files for the component, currently empty. | ||
3. `CMakeList.txt`: build definitions for the component. | ||
4. `docs` folder to place component documentation | ||
|
||
To build this component run `fprime-util build` in the current folder. | ||
|
||
> Any component in F´ can be built by navigating to the component's folder and running `fprime-util build`. | ||
## Editing the Component Model | ||
|
||
A component model defines the interface of the component with the rest of the F´ system and with the ground system F´ | ||
communicates with. In this case we intend to define a command, an event, and a telemetry channel as specified above. | ||
|
||
Open the model file `HelloWorld.fpp` and add replace the line: | ||
|
||
``` | ||
async command TODO opcode 0 | ||
``` | ||
|
||
with the following: | ||
|
||
``` | ||
@ Command to issue greeting with maximum length of 20 characters | ||
async command SAY_HELLO( | ||
greeting: string size 20 @< Greeting to repeat in the Hello event | ||
) | ||
@ Greeting event with maximum greeting length of 20 characters | ||
event Hello( | ||
greeting: string size 20 @< Greeting supplied from the SAY_HELLO command | ||
) severity activity high format "I say: {}" | ||
@ A count of the number of greetings issued | ||
telemetry GreetingCount: U32 | ||
``` | ||
> You should ensure to replace any existing command, event, and channel definitions with those supplied above but leave | ||
> the 'Standard AC Ports' section untouched. | ||
With this step completed you can generate a basic implementation with the following command: | ||
|
||
```bash | ||
# In: MyProject/MyComponents/HelloWorld | ||
fprime-util impl | ||
``` | ||
|
||
This creates `HelloWorld.hpp-template` and `HelloWorld.cpp-template` files that contain our new fill-in template. While | ||
normally one would merge new templates with the existing code, we will instead overwrite the existing implementations as | ||
we have not edited those files yet. To do this: | ||
|
||
```bash | ||
mv HelloWorld.hpp-template HelloWorld.hpp | ||
mv HelloWorld.cpp-template HelloWorld.cpp | ||
``` | ||
We are now ready for implementing component behavior. | ||
|
||
## Implementing Component Behavior | ||
|
||
F´ behavior is implemented in two types of methods command handler functions to implement command behavior and handler | ||
functions to implement port behavior (as described in the next tutorial). For this tutorial we need to implement the | ||
`SAY_HELLO` command, so we need to edit the `SAY_HELLO_cmdHandler` function in the `HelloWorld.cpp` file. Ensure its | ||
contents look like: | ||
|
||
```c++ | ||
void HelloWorld:: SAY_HELLO_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg& greeting) { | ||
// Copy the command string input into an event string for the Hello event | ||
Fw::LogStringArg eventGreeting(greeting.toChar()); | ||
// Emit the Hello event with the copied string | ||
this->log_ACTIVITY_HI_Hello(eventGreeting); | ||
|
||
this->tlmWrite_GreetingCount(++this->m_greetingCount); | ||
|
||
// Tell the fprime command system that we have completed the processing of the supplied command with OK status | ||
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); | ||
} | ||
``` | ||
> We must also add the m_greetingCount member variable to the class defined in `HelloWorld.hpp` and the constructor | ||
> defined in `HelloWorld.cpp`. This looks like: | ||
> | ||
> **HelloWorld.hpp: Adding New Member Variable** | ||
> ```c++ | ||
> private: | ||
> U32 m_greetingCount; | ||
> ``` | ||
> Should be added inside the `class` definition in `HelloWorld.hpp`. | ||
> | ||
> **HelloWorld.cpp: Updating Constructor** | ||
> ```c++ | ||
> HelloWorld:: HelloWorld(const char *const compName) : HelloWorldComponentBase(compName), | ||
> m_greetingCount(0) | ||
> { | ||
> ``` | ||
> Should be added to the `HelloWorld` constructor at the top of the file. | ||
The component should build without errors by running `fprime-util build`. Resolve any errors that occur before | ||
proceeding to the next section. | ||
## Conclusion | ||
This tutorial has walked through the creation of component that implements a "Hello World" style greeting behavior for | ||
our F´ system. In the next tutorial, this component will be hooked-up to an F´ deployment and tested! | ||
**Next:** [Getting Started: Integration and Testing With F´ Deployments](./Deployments.md) |
Oops, something went wrong.