diff --git a/README.md b/README.md index fb3be429e..484d65c07 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,12 @@ a starting point. The [configuration section](doc/README-config.md#top) provides [1. High-level overview](doc/README-highlevel.md#top)
[2. Core components](doc/README-core.md#top)
-[3. OSAL overview](doc/README-osal.md#top)
-[4. PUS services](doc/README-pus.md#top)
-[5. Device Handler overview](doc/README-devicehandlers.md#top)
-[6. Controller overview](doc/README-controllers.md#top)
-[7. Local Data Pools](doc/README-localpools.md#top)
+[3. Configuration](doc/README-config.md#top)
+[4. OSAL overview](doc/README-osal.md#top)
+[5. PUS services](doc/README-pus.md#top)
+[6. Device Handler overview](doc/README-devicehandlers.md#top)
+[7. Controller overview](doc/README-controllers.md#top)
+[8. Local Data Pools](doc/README-localpools.md#top)
diff --git a/doc/README-config.md b/doc/README-config.md index 036a7d14c..d71feb97b 100644 --- a/doc/README-config.md +++ b/doc/README-config.md @@ -1,12 +1,30 @@ - -## Configuring the FSFW +Configuring the FSFW +====== The FSFW can be configured via the `fsfwconfig` folder. A template folder has been provided to have a starting point for this. The folder should be added -to the include path. +to the include path. The primary configuration file is the `FSFWConfig.h` folder. Some +of the available options will be explained in more detail here. +# Auto-Translation of Events -### Configuring the Event Manager +The FSFW allows the automatic translation of events, which allows developers to track triggered +events directly via console output. Using this feature requires: + +1. `FSFW_OBJ_EVENT_TRANSLATION` set to 1 in the configuration file. +2. Special auto-generated translation files which translate event IDs and object IDs into + human readable strings. These files can be generated using the + [modgen Python scripts](https://git.ksat-stuttgart.de/source/modgen.git). +3. The generated translation files for the object IDs should be named `translatesObjects.cpp` + and `translateObjects.h` and should be copied to the `fsfwconfig/objects` folder +4. The generated translation files for the event IDs should be named `translateEvents.cpp` and + `translateEvents.h` and should be copied to the `fsfwconfig/events` folder + +An example implementations of these translation file generators can be found as part +of the [SOURCE project here](https://git.ksat-stuttgart.de/source/sourceobsw/-/tree/development/generators) +or the [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/generators) + +## Configuring the Event Manager The number of allowed subscriptions can be modified with the following parameters: @@ -18,4 +36,5 @@ static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240; static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120; static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120; } -``` \ No newline at end of file +``` + diff --git a/doc/README-core.md b/doc/README-core.md index 6431b8311..e34890aef 100644 --- a/doc/README-core.md +++ b/doc/README-core.md @@ -19,8 +19,9 @@ A nullptr check of the returning Pointer must be done. This function is based on ```cpp template T* ObjectManagerIF::get( object_id_t id ) ``` -* A typical way to create all objects on startup is a handing a static produce function to the ObjectManager on creation. -By calling objectManager->initialize() the produce function will be called and all SystemObjects will be initialized afterwards. +* A typical way to create all objects on startup is a handing a static produce function to the + ObjectManager on creation. By calling objectManager->initialize() the produce function will be + called and all SystemObjects will be initialized afterwards. ### Event Manager @@ -36,14 +37,19 @@ By calling objectManager->initialize() the produce function will be called and a ### Stores -* The message based communication can only exchange a few bytes of information inside the message itself. Therefore, additional information can - be exchanged with Stores. With this, only the store address must be exchanged in the message. -* Internally, the FSFW uses an IPC Store to exchange data between processes. For incoming TCs a TC Store is used. For outgoing TM a TM store is used. +* The message based communication can only exchange a few bytes of information inside the message + itself. Therefore, additional information can be exchanged with Stores. With this, only the + store address must be exchanged in the message. +* Internally, the FSFW uses an IPC Store to exchange data between processes. For incoming TCs a TC + Store is used. For outgoing TM a TM store is used. * All of them should use the Thread Safe Class storagemanager/PoolManager ### Tasks There are two different types of tasks: - * The PeriodicTask just executes objects that are of type ExecutableObjectIF in the order of the insertion to the Tasks. - * FixedTimeslotTask executes a list of calls in the order of the given list. This is intended for DeviceHandlers, where polling should be in a defined order. An example can be found in defaultcfg/fsfwconfig/pollingSequence + * The PeriodicTask just executes objects that are of type ExecutableObjectIF in the order of the + insertion to the Tasks. + * FixedTimeslotTask executes a list of calls in the order of the given list. This is intended for + DeviceHandlers, where polling should be in a defined order. An example can be found in + `defaultcfg/fsfwconfig/pollingSequence` folder diff --git a/doc/README-highlevel.md b/doc/README-highlevel.md index fac89c536..262138a7c 100644 --- a/doc/README-highlevel.md +++ b/doc/README-highlevel.md @@ -1,99 +1,135 @@ -# High-level overview +High-level overview +====== -## Structure +# Structure The general structure is driven by the usage of interfaces provided by objects. -The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be widely available, even with older compilers. +The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be +widely available, even with older compilers. The FSFW uses dynamic allocation during the initialization but provides static containers during runtime. This simplifies the instantiation of objects and allows the usage of some standard containers. -Dynamic Allocation after initialization is discouraged and different solutions are provided in the FSFW to achieve that. -The fsfw uses run-time type information but exceptions are not allowed. +Dynamic Allocation after initialization is discouraged and different solutions are provided in the +FSFW to achieve that. The fsfw uses run-time type information but exceptions are not allowed. -### Failure Handling +# Failure Handling -Functions should return a defined ReturnValue_t to signal to the caller that something has gone wrong. -Returnvalues must be unique. For this the function HasReturnvaluesIF::makeReturnCode or the Macro MAKE_RETURN can be used. -The CLASS_ID is a unique id for that type of object. See returnvalues/FwClassIds. +Functions should return a defined `ReturnValue_t` to signal to the caller that something has +gone wrong. Returnvalues must be unique. For this the function `HasReturnvaluesIF::makeReturnCode` +or the macro `MAKE_RETURN` can be used. The `CLASS_ID` is a unique id for that type of object. +See `returnvalues/FwClassIds` folder. The user can add custom `CLASS_ID`s via the +`fsfwconfig` folder. -### OSAL +# OSAL The FSFW provides operation system abstraction layers for Linux, FreeRTOS and RTEMS. The OSAL provides periodic tasks, message queues, clocks and semaphores as well as mutexes. -The [OSAL README](doc/README-osal.md#top) provides more detailed information on provided components and how to use them. +The [OSAL README](doc/README-osal.md#top) provides more detailed information on provided components +and how to use them. -### Core Components +# Core Components The FSFW has following core components. More detailed informations can be found in the [core component section](doc/README-core.md#top): -1. Tasks: Abstraction for different (periodic) task types like periodic tasks or tasks with fixed timeslots -2. ObjectManager: This module stores all `SystemObjects` by mapping a provided unique object ID to the object handles. -3. Static Stores: Different stores are provided to store data of variable size (like telecommands or small telemetry) in a pool structure without - using dynamic memory allocation. These pools are allocated up front. +1. Tasks: Abstraction for different (periodic) task types like periodic tasks or tasks + with fixed timeslots +2. ObjectManager: This module stores all `SystemObjects` by mapping a provided unique object ID + to the object handles. +3. Static Stores: Different stores are provided to store data of variable size (like telecommands + or small telemetry) in a pool structure without using dynamic memory allocation. + These pools are allocated up front. 3. Clock: This module provided common time related functions 4. EventManager: This module allows routing of events generated by `SystemObjects` 5. HealthTable: A component which stores the health states of objects -### Static IDs in the framework +# Static IDs in the framework Some parts of the framework use a static routing address for communication. -An example setup of ids can be found in the example config in "defaultcft/fsfwconfig/objects/Factory::setStaticFrameworkObjectIds()". +An example setup of ids can be found in the example config in `defaultcft/fsfwconfig/objects` + inside the function `Factory::setStaticFrameworkObjectIds()`. -### Events +# Events -Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT. This works analog to the returnvalues. -Every object that needs own EventIds has to get a unique SUBSYSTEM_ID. -Every SystemObject can call triggerEvent from the parent class. -Therefore, event messages contain the specific EventId and the objectId of the object that has triggered. +Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT. +This works analog to the returnvalues. Every object that needs own EventIds has to get a +unique SUBSYSTEM_ID. Every SystemObject can call triggerEvent from the parent class. +Therefore, event messages contain the specific EventId and the objectId of the object that +has triggered. -### Internal Communication +# Internal Communication -Components communicate mostly over Message through Queues. -Those queues are created by calling the singleton QueueFactory::instance()->create(). +Components communicate mostly via Messages through Queues. +Those queues are created by calling the singleton `QueueFactory::instance()->create()` which +will create `MessageQueue` instances for the used OSAL. -### External Communication +# External Communication The external communication with the mission control system is mostly up to the user implementation. The FSFW provides PUS Services which can be used to but don't need to be used. The services can be seen as a conversion from a TC to a message based communication and back. -#### CCSDS Frames, CCSDS Space Packets and PUS +## TMTC Communication -If the communication is based on CCSDS Frames and Space Packets, several classes can be used to distributed the packets to the corresponding services. Those can be found in tcdistribution. -If Space Packets are used, a timestamper must be created. -An example can be found in the timemanager folder, this uses CCSDSTime::CDS_short. +The FSFW provides some components to facilitate TMTC handling via the PUS commands. +For example, a UDP or TCP PUS server socket can be opened on a specific port using the +files located in `osal/common`. The FSFW example uses this functionality to allow sending telecommands +and receiving telemetry using the [TMTC commander application](https://github.com/spacefisch/tmtccmd). +Simple commands like the PUS Service 17 ping service can be tested by simply running the +`tmtc_client_cli.py` or `tmtc_client_gui.py` utility in +the [example tmtc folder](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example_public/src/branch/master/tmtc) +while the `fsfw_example` application is running. -#### Device Handlers +More generally, any class responsible for handling incoming telecommands and sending telemetry +can implement the generic `TmTcBridge` class located in `tmtcservices`. Many applications +also use a dedicated polling task for reading telecommands which passes telecommands +to the `TmTcBridge` implementation. + +## CCSDS Frames, CCSDS Space Packets and PUS + +If the communication is based on CCSDS Frames and Space Packets, several classes can be used to +distributed the packets to the corresponding services. Those can be found in `tcdistribution`. +If Space Packets are used, a timestamper has to be provided by the user. +An example can be found in the `timemanager` folder, which uses `CCSDSTime::CDS_short`. + +# Device Handlers DeviceHandlers are another important component of the FSFW. -The idea is, to have a software counterpart of every physical device to provide a simple mode, health and commanding interface. -By separating the underlying Communication Interface with DeviceCommunicationIF, a device handler (DH) can be tested on different hardware. -The DH has mechanisms to monitor the communication with the physical device which allow for FDIR reaction. -Device Handlers can be created by overriding `DeviceHandlerBase`. -A standard FDIR component for the DH will be created automatically but can be overwritten by the user. -More information on DeviceHandlers can be found in the related [documentation section](doc/README-devicehandlers.md#top). +The idea is, to have a software counterpart of every physical device to provide a simple mode, +health and commanding interface. By separating the underlying Communication Interface with +`DeviceCommunicationIF`, a device handler (DH) can be tested on different hardware. +The DH has mechanisms to monitor the communication with the physical device which allow +for FDIR reaction. Device Handlers can be created by implementing `DeviceHandlerBase`. +A standard FDIR component for the DH will be created automatically but can +be overwritten by the user. More information on DeviceHandlers can be found in the +related [documentation section](doc/README-devicehandlers.md#top). -#### Modes, Health +# Modes and Health -The two interfaces HasModesIF and HasHealthIF provide access for commanding and monitoring of components. -On-board Mode Management is implement in hierarchy system. +The two interfaces `HasModesIF` and `HasHealthIF` provide access for commanding and monitoring +of components. On-board Mode Management is implement in hierarchy system. DeviceHandlers and Controllers are the lowest part of the hierarchy. -The next layer are Assemblies. Those assemblies act as a component which handle redundancies of handlers. -Assemblies share a common core with the next level which are the Subsystems. +The next layer are Assemblies. Those assemblies act as a component which handle +redundancies of handlers. Assemblies share a common core with the next level which +are the Subsystems. -Those Assemblies are intended to act as auto-generated components from a database which describes the subsystem modes. -The definitions contain transition and target tables which contain the DH, Assembly and Controller Modes to be commanded. -Transition tables contain as many steps as needed to reach the mode from any other mode, e.g. a switch into any higher AOCS mode might first turn on the sensors, than the actuators and the controller as last component. +Those Assemblies are intended to act as auto-generated components from a database which describes +the subsystem modes. The definitions contain transition and target tables which contain the DH, +Assembly and Controller Modes to be commanded. +Transition tables contain as many steps as needed to reach the mode from any other mode, e.g. a +switch into any higher AOCS mode might first turn on the sensors, than the actuators and the +controller as last component. The target table is used to describe the state that is checked continuously by the subsystem. All of this allows System Modes to be generated as Subsystem object as well from the same database. This System contains list of subsystem modes in the transition and target tables. -Therefore, it allows a modular system to create system modes and easy commanding of those, because only the highest components must be commanded. +Therefore, it allows a modular system to create system modes and easy commanding of those, because +only the highest components must be commanded. The health state represents if the component is able to perform its tasks. This can be used to signal the system to avoid using this component instead of a redundant one. The on-board FDIR uses the health state for isolation and recovery. -## Unit Tests +# Unit Tests -Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include catch2 itself. More information on how to run these tests can be found in the separate +Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include +catch2 itself. More information on how to run these tests can be found in the separate [`fsfw_tests` reposoitory](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_tests) diff --git a/events/fwSubsystemIdRanges.h b/events/fwSubsystemIdRanges.h index 1b0b238e2..88dee9b4e 100644 --- a/events/fwSubsystemIdRanges.h +++ b/events/fwSubsystemIdRanges.h @@ -1,30 +1,37 @@ #ifndef FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ #define FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ +#include + namespace SUBSYSTEM_ID { -enum { - MEMORY = 22, - OBSW = 26, - CDH = 28, - TCS_1 = 59, - PCDU_1 = 42, - PCDU_2 = 43, - HEATER = 50, - T_SENSORS = 52, - FDIR = 70, - FDIR_1 = 71, - FDIR_2 = 72, - HK = 73, - SYSTEM_MANAGER = 74, - SYSTEM_MANAGER_1 = 75, - SYSTEM_1 = 79, - PUS_SERVICE_1 = 80, - PUS_SERVICE_9 = 89, - PUS_SERVICE_17 = 97, - FW_SUBSYSTEM_ID_RANGE +enum: uint8_t { + MEMORY = 22, + OBSW = 26, + CDH = 28, + TCS_1 = 59, + PCDU_1 = 42, + PCDU_2 = 43, + HEATER = 50, + T_SENSORS = 52, + FDIR = 70, + FDIR_1 = 71, + FDIR_2 = 72, + HK = 73, + SYSTEM_MANAGER = 74, + SYSTEM_MANAGER_1 = 75, + SYSTEM_1 = 79, + PUS_SERVICE_1 = 80, + PUS_SERVICE_2 = 82, + PUS_SERVICE_3 = 83, + PUS_SERVICE_5 = 85, + PUS_SERVICE_6 = 86, + PUS_SERVICE_8 = 88, + PUS_SERVICE_9 = 89, + PUS_SERVICE_17 = 97, + PUS_SERVICE_23 = 103, + + FW_SUBSYSTEM_ID_RANGE }; } - - #endif /* FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ */ diff --git a/objectmanager/frameworkObjects.h b/objectmanager/frameworkObjects.h index 2174f829a..360108079 100644 --- a/objectmanager/frameworkObjects.h +++ b/objectmanager/frameworkObjects.h @@ -1,8 +1,9 @@ #ifndef FSFW_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ #define FSFW_OBJECTMANAGER_FRAMEWORKOBJECTS_H_ -#include +#include "SystemObjectIF.h" +// The objects will be instantiated in the ID order namespace objects { enum framework_objects: object_id_t { FSFW_OBJECTS_START = 0x53000000, @@ -16,6 +17,7 @@ enum framework_objects: object_id_t { PUS_SERVICE_17_TEST = 0x53000017, PUS_SERVICE_20_PARAMETERS = 0x53000020, PUS_SERVICE_200_MODE_MGMT = 0x53000200, + PUS_SERVICE_201_HEALTH = 0x53000201, //Generic IDs for IPC, modes, health, events HEALTH_TABLE = 0x53010000, diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index 4c9f022ba..17c37a79d 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -1,72 +1,78 @@ #ifndef FSFW_RETURNVALUES_FWCLASSIDS_H_ #define FSFW_RETURNVALUES_FWCLASSIDS_H_ +#include + +// The comment block at the end is used by the returnvalue exporter. +// It is recommended to add it as well for mission returnvalues namespace CLASS_ID { -enum { - OPERATING_SYSTEM_ABSTRACTION = 1, //OS - OBJECT_MANAGER_IF, //OM - DEVICE_HANDLER_BASE, //DHB - RMAP_CHANNEL, //RMP - POWER_SWITCH_IF, //PS - HAS_MEMORY_IF, //PP - DEVICE_STATE_MACHINE_BASE, //DSMB - DATA_SET_CLASS, //DPS - POOL_RAW_ACCESS_CLASS, //DPR - CONTROLLER_BASE, //CTR - SUBSYSTEM_BASE, //SB - MODE_STORE_IF, //MS - SUBSYSTEM, //SS - HAS_MODES_IF, //HM - COMMAND_MESSAGE, //CM - CCSDS_TIME_HELPER_CLASS, //TIM - ARRAY_LIST, //AL - ASSEMBLY_BASE, //AB - MEMORY_HELPER, //MH - SERIALIZE_IF, //SE - FIXED_MAP, //FM - FIXED_MULTIMAP, //FMM - HAS_HEALTH_IF, //HHI - FIFO_CLASS, //FF - MESSAGE_PROXY, //MQP - TRIPLE_REDUNDACY_CHECK, //TRC - TC_PACKET_CHECK, //TCC - PACKET_DISTRIBUTION, //TCD - ACCEPTS_TELECOMMANDS_IF, //PUS - DEVICE_SERVICE_BASE, //DSB - COMMAND_SERVICE_BASE, //CSB - TM_STORE_BACKEND_IF, //TMB - TM_STORE_FRONTEND_IF, //TMF - STORAGE_AND_RETRIEVAL_SERVICE, //SR - MATCH_TREE_CLASS, //MT - EVENT_MANAGER_IF, //EV - HANDLES_FAILURES_IF, //FDI - DEVICE_HANDLER_IF, //DHI - STORAGE_MANAGER_IF, //SM - THERMAL_COMPONENT_IF, //TC - INTERNAL_ERROR_CODES, //IEC - TRAP, //TRP - CCSDS_HANDLER_IF, //CCS - PARAMETER_WRAPPER, //PAW - HAS_PARAMETERS_IF, //HPA - ASCII_CONVERTER, //ASC - POWER_SWITCHER, //POS - LIMITS_IF, //LIM - COMMANDS_ACTIONS_IF, //CF - HAS_ACTIONS_IF, //HF - DEVICE_COMMUNICATION_IF, //DC - BSP, //BSP - TIME_STAMPER_IF, //TSI 53 - SGP4PROPAGATOR_CLASS, //SGP4 54 - MUTEX_IF, //MUX 55 - MESSAGE_QUEUE_IF,//MQI 56 - SEMAPHORE_IF, //SPH 57 - LOCAL_POOL_OWNER_IF, //LPIF 58 - POOL_VARIABLE_IF, //PVA 59 - HOUSEKEEPING_MANAGER, //HKM 60 - DLE_ENCODER, //DLEE 61 - PUS_SERVICE_9, //PUS9 62 - FILE_SYSTEM, //FILS 63 - FW_CLASS_ID_COUNT //is actually count + 1 ! +enum: uint8_t { + FW_CLASS_ID_START = 0, // [EXPORT] : [START] + OPERATING_SYSTEM_ABSTRACTION, //OS + OBJECT_MANAGER_IF, //OM + DEVICE_HANDLER_BASE, //DHB + RMAP_CHANNEL, //RMP + POWER_SWITCH_IF, //PS + HAS_MEMORY_IF, //PP + DEVICE_STATE_MACHINE_BASE, //DSMB + DATA_SET_CLASS, //DPS + POOL_RAW_ACCESS_CLASS, //DPR + CONTROLLER_BASE, //CTR + SUBSYSTEM_BASE, //SB + MODE_STORE_IF, //MS + SUBSYSTEM, //SS + HAS_MODES_IF, //HM + COMMAND_MESSAGE, //CM + CCSDS_TIME_HELPER_CLASS, //TIM + ARRAY_LIST, //AL + ASSEMBLY_BASE, //AB + MEMORY_HELPER, //MH + SERIALIZE_IF, //SE + FIXED_MAP, //FM + FIXED_MULTIMAP, //FMM + HAS_HEALTH_IF, //HHI + FIFO_CLASS, //FF + MESSAGE_PROXY, //MQP + TRIPLE_REDUNDACY_CHECK, //TRC + TC_PACKET_CHECK, //TCC + PACKET_DISTRIBUTION, //TCD + ACCEPTS_TELECOMMANDS_IF, //PUS + DEVICE_SERVICE_BASE, //DSB + COMMAND_SERVICE_BASE, //CSB + TM_STORE_BACKEND_IF, //TMB + TM_STORE_FRONTEND_IF, //TMF + STORAGE_AND_RETRIEVAL_SERVICE, //SR + MATCH_TREE_CLASS, //MT + EVENT_MANAGER_IF, //EV + HANDLES_FAILURES_IF, //FDI + DEVICE_HANDLER_IF, //DHI + STORAGE_MANAGER_IF, //SM + THERMAL_COMPONENT_IF, //TC + INTERNAL_ERROR_CODES, //IEC + TRAP, //TRP + CCSDS_HANDLER_IF, //CCS + PARAMETER_WRAPPER, //PAW + HAS_PARAMETERS_IF, //HPA + ASCII_CONVERTER, //ASC + POWER_SWITCHER, //POS + LIMITS_IF, //LIM + COMMANDS_ACTIONS_IF, //CF + HAS_ACTIONS_IF, //HF + DEVICE_COMMUNICATION_IF, //DC + BSP, //BSP + TIME_STAMPER_IF, //TSI + SGP4PROPAGATOR_CLASS, //SGP4 + MUTEX_IF, //MUX + MESSAGE_QUEUE_IF,//MQI + SEMAPHORE_IF, //SPH + LOCAL_POOL_OWNER_IF, //LPIF + POOL_VARIABLE_IF, //PVA + HOUSEKEEPING_MANAGER, //HKM + DLE_ENCODER, //DLEE + PUS_SERVICE_3, //PUS3 + PUS_SERVICE_9, //PUS9 + FILE_SYSTEM, //FILS + FW_CLASS_ID_COUNT // [EXPORT] : [END] }; }