###### tags: `F'` `Flight software` `tm` `master`
# Creating new component - Quick guide
To create a `[name]` component in a `App` topology
### Create component
- Create component directory `App/[name]`
- Create `App/[name]/ComponentAi.xml` description file
```xml=
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="../../Autocoders/schema/ISF/component_schema.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<!--
[name] component : [description]
-->
<component name="[name]" kind="[active/passive/queued]" namespace="App" modeler="true">
<!-- Import command ports -->
<import_port_type>Fw/Cmd/CmdPortAi.xml</import_port_type>
<import_port_type>Fw/Cmd/CmdRegPortAi.xml</import_port_type>
<import_port_type>Fw/Cmd/CmdResponsePortAi.xml</import_port_type>
<!-- Import event ports -->
<import_port_type>Fw/Log/LogPortAi.xml</import_port_type>
<import_port_type>Fw/Log/LogTextPortAi.xml</import_port_type>
<!-- Import telemetry ports -->
<import_port_type>Fw/Tlm/TlmPortAi.xml</import_port_type>
<ports>
<!-- Command port definitions: command input receives commands, command reg out, and response out are
ports used to register with the command dispatcher, and return responses to it -->
<port name="cmdDisp" data_type="Fw::Cmd" kind="input" role="Cmd" max_number="1">
</port>
<port name="cmdRegOut" data_type="Fw::CmdReg" kind="output" role="CmdRegistration" max_number="1">
</port>
<port name="cmdResponseOut" data_type="Fw::CmdResponse" kind="output" role="CmdResponse" max_number="1">
</port>
<!-- Event ports: send events, and text formated events -->
<port name="eventOut" data_type="Fw::Log" kind="output" role="LogEvent" max_number="1">
</port>
<port name="textEventOut" data_type="Fw::LogText" kind="output" role="LogTextEvent" max_number="1">
</port>
<!-- Telemetry ports -->
<port name="tlmOut" data_type="Fw::Tlm" kind="output" role="Telemetry" max_number="1">
</port>
<!-- Custom ports -->
</port>
</ports>
<commands>
<command kind="async" opcode="0" mnemonic="EVAC_RUN">
<comment>Run component</comment>
</command>
</commands>
<events>
<event id="0" name="[abr]_EVENT" severity="ACTIVITY_HI" format_string="Event : %s">
<comment>An event occured</comment>
<args>
<arg name="arg1" type="string" size="40">
<comment>Event arg</comment>
</arg>
</args>
</event>
</events>
</component>
```
- Create `App/[name]/CMakeLists.txt`
```cmake=
####
# : App/[name]/CMakeLists.txt
#
# SOURCE_FILES: combined list of source and autocoding files
# MOD_DEPS: (optional) module dependencies
#
# This file will setup the build for the [name] component. This is done by defining the SOURCE_FILES variable and then
# registering the component as an F prime module. This allows autocoding and more!
####
set(SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/[name]Ai.xml"
)
register_fprime_module()
```
- Update `CMakeLists.txt` in `App` directory
```cmake=33
##
# Section 3: Components and Topology
#
# This section includes deployment specific directories. This allows use of non- core components in the topology,
# which is also added here.
##
# Add component subdirectories
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/[name]/")
```
### Build component
- Generate build directory
```
cd App
fprime-util purge --force
fprime-util generate
```
- Generate implementation files and code implemetation
```
cd App/[name]
fprime-util impl
mv [name]ComponentImpl.cpp-template [name]ComponentImpl.cpp
mv [name]ComponentImpl.hpp-template [name]ComponentImpl.hpp
```
- Add component implementation in `[name]/CMakeLists.txt`
```=10
set(SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/[name]Ai.xml"
"${CMAKE_CURRENT_LIST_DIR}/[name]ComponentImpl.cpp"
)
register_fprime_module()
```
- Build component
```
cd App
fprime-util build
```
### Add component to the toplogy
#### Update `App/AppTopologyAppAi.xml`
- Import component type
```xml
<import_component_type>App/[name]/[name]ComponentAi.xml</import_component_type>
```
- Declare component instance
```xml
<instance namespace="App" name="[instanceName]" type="[name]" base_id="xxxx" base_id_window="20" />
```
- List connections
```xml
<connection name = "[name]Connection">
<source component = "[name]" port = "cmdRegOut" type = "CmdReg" num = "0"/>
<target component = "cmdDisp" port = "compCmdReg" type = "CmdReg" num = "15"/>
</connection>
```
#### Import component in `App/Top/Components.hpp`
- Import header file
```cpp=30
#include <App/[name]/[name]ComponentImpl.hpp>
```
- Add extern component variable
```cpp=30
extern App::[name]ComponentImpl [instanceName];
```
#### Complete `App/Top/Topology.cpp`
- Create component instance
```cpp=103
App::[name]ComponentImpl [instanceName](FW_OPTIONAL_NAME("[instanceName]"));
```
- Fill `constructApp()` method :
*Init component*
```cpp=171
[name].init(10, 0);
```
*Register component*
```cpp=200
[name].regCommands();
```
*readParamFile(), loadParameters() and register PingEntry if need(), see [Math tutorial](https://nasa.github.io/fprime/Tutorials/MathComponent/Tutorial.html)*
*For active component, start thread*
```cpp=250
[name].start(0, 100, 10*1024);
```
- Fill `exitTasks()` method:
```cpp
[name].exit();
(void) [name].ActiveComponentBase::join(NULL);
```