Merge remote-tracking branch 'upstream/development' into eive/develop
This commit is contained in:
commit
65f493b230
12
CHANGELOG
12
CHANGELOG
@ -70,3 +70,15 @@ now
|
|||||||
### Commanding Service Base
|
### Commanding Service Base
|
||||||
|
|
||||||
- CSB uses the new fsfwconfig::FSFW_CSB_FIFO_DEPTH variable to determine the FIFO depth for each CSB instance. This variable has to be set in the FSFWConfig.h file
|
- CSB uses the new fsfwconfig::FSFW_CSB_FIFO_DEPTH variable to determine the FIFO depth for each CSB instance. This variable has to be set in the FSFWConfig.h file
|
||||||
|
|
||||||
|
### Service Interface
|
||||||
|
|
||||||
|
- Proper printf support contained in ServiceInterfacePrinter.h
|
||||||
|
- CPP ostream support now optional (can reduce executable size by 150 - 250 kB)
|
||||||
|
- Amalagated header which determines automatically which service interface to use depending on FSFWConfig.h configuration.
|
||||||
|
Users can just use #include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
- If CPP streams are excluded, sif:: calls won't work anymore and need to be replaced by their printf counterparts.
|
||||||
|
For the fsfw, this can be done by checking the processor define FSFW_CPP_OSTREAM_ENABLED from FSFWConfig.h.
|
||||||
|
For mission code, developers need to replace sif:: calls by the printf counterparts, but only if the CPP stream are excluded.
|
||||||
|
If this is not the case, everything should work as usual.
|
||||||
|
-
|
@ -106,10 +106,12 @@ else()
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
set(WARNING_FLAGS
|
if(NOT DEFINED FSFW_WARNING_FLAGS)
|
||||||
|
set(FSFW_WARNING_FLAGS
|
||||||
-Wall
|
-Wall
|
||||||
-Wextra
|
-Wextra
|
||||||
|
-Wshadow=local
|
||||||
-Wimplicit-fallthrough=1
|
-Wimplicit-fallthrough=1
|
||||||
-Wno-unused-parameter
|
-Wno-unused-parameter
|
||||||
-Wno-psabi
|
-Wno-psabi
|
||||||
@ -122,6 +124,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
if(WARNING_SHADOW_LOCAL)
|
if(WARNING_SHADOW_LOCAL)
|
||||||
list(APPEND WARNING_FLAGS "-Wshadow=local")
|
list(APPEND WARNING_FLAGS "-Wshadow=local")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
@ -142,9 +145,7 @@ target_include_directories(${LIB_FSFW_NAME} PRIVATE
|
|||||||
${FSFW_CONFIG_PATH_ABSOLUTE}
|
${FSFW_CONFIG_PATH_ABSOLUTE}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Machine specific options can be set with the ABI_FLAGS variable.
|
|
||||||
target_compile_options(${LIB_FSFW_NAME} PRIVATE
|
target_compile_options(${LIB_FSFW_NAME} PRIVATE
|
||||||
${WARNING_FLAGS}
|
${FSFW_WARNING_FLAGS}
|
||||||
${COMPILER_FLAGS}
|
${COMPILER_FLAGS}
|
||||||
${ABI_FLAGS}
|
|
||||||
)
|
)
|
||||||
|
133
README.md
133
README.md
@ -9,121 +9,40 @@ The initial version of the Flight Software Framework was developed during
|
|||||||
the Flying Laptop Project by the University of Stuttgart in cooperation
|
the Flying Laptop Project by the University of Stuttgart in cooperation
|
||||||
with Airbus Defence and Space GmbH.
|
with Airbus Defence and Space GmbH.
|
||||||
|
|
||||||
## Intended Use
|
## Quick facts
|
||||||
|
|
||||||
The framework is designed for systems, which communicate with external devices, perform control loops, receive telecommands and send telemetry, and need to maintain a high level of availability.
|
The framework is designed for systems, which communicate with external devices, perform control loops, receive telecommands and send telemetry, and need to maintain a high level of availability. Therefore, a mode and health system provides control over the states of the software and the controlled devices. In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well.
|
||||||
Therefore, a mode and health system provides control over the states of the software and the controlled devices.
|
|
||||||
In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well.
|
|
||||||
|
|
||||||
The recommended hardware is a microprocessor with more than 1 MB of RAM and 1 MB of non-volatile Memory.
|
The FSFW provides abstraction layers for operating systems to provide a uniform operating system abstraction layer (OSAL). Some components of this OSAL are required internally by the FSFW but is also very useful for developers to implement the same application logic on different operating systems with a uniform interface.
|
||||||
For reference, current Applications use a Cobham Gaisler UT699 (LEON3FT), a ISISPACE IOBC or a Zynq-7020 SoC.
|
|
||||||
The `fsfw` was also tested on the STM32H743ZI-Nucleo board.
|
|
||||||
|
|
||||||
## How to Use
|
Currently, the FSFW provides the following OSALs:
|
||||||
|
|
||||||
|
- Linux
|
||||||
|
- Host
|
||||||
|
- FreeRTOS
|
||||||
|
- RTEMS
|
||||||
|
|
||||||
|
The recommended hardware is a microprocessor with more than 1 MB of RAM and 1 MB of non-volatile Memory. For reference, current applications use a Cobham Gaisler UT699 (LEON3FT), a ISISPACE IOBC or a Zynq-7020 SoC. The `fsfw` was also successfully run on the STM32H743ZI-Nucleo board and on a Raspberry Pi and is currently running on the active satellite mission Flying Laptop.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
The [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example) provides a good starting point and a demo to see the FSFW capabilities and build it with the Make or the CMake build system. It is recommended to evaluate the FSFW by building and playing around with the demo application.
|
||||||
|
|
||||||
The [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example) provides a good starting point and a demo
|
|
||||||
to see the FSFW capabilities and build it with the Make or the CMake build system.
|
|
||||||
Generally, the FSFW is included in a project by compiling the FSFW sources and providing
|
Generally, the FSFW is included in a project by compiling the FSFW sources and providing
|
||||||
a configuration folder and adding it to the include path.
|
a configuration folder and adding it to the include path. There are some functions like `printChar` which are different depending on the target architecture and need to be implemented by the mission developer.
|
||||||
|
|
||||||
A template configuration folder was provided and can be copied into the project root to have
|
A template configuration folder was provided and can be copied into the project root to have
|
||||||
a starting point. The [configuration section](doc/README-config.md#top) provides more specific information about
|
a starting point. The [configuration section](doc/README-config.md#top) provides more specific information about the possible options.
|
||||||
the possible options.
|
|
||||||
|
|
||||||
## Structure
|
## Index
|
||||||
|
|
||||||
The general structure is driven by the usage of interfaces provided by objects.
|
[1. High-level overview](doc/README-highlevel.md#top) <br>
|
||||||
The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be widely available, even with older compilers.
|
[2. Core components](doc/README-core.md#top) <br>
|
||||||
The FSFW uses dynamic allocation during the initialization but provides static containers during runtime.
|
[3. OSAL overview](doc/README-osal.md#top) <br>
|
||||||
This simplifies the instantiation of objects and allows the usage of some standard containers.
|
[4. PUS services](doc/README-pus.md#top) <br>
|
||||||
Dynamic Allocation after initialization is discouraged and different solutions are provided in the FSFW to achieve that.
|
[5. Device Handler overview](doc/README-devicehandlers.md#top) <br>
|
||||||
The fsfw uses run-time type information but exceptions are not allowed.
|
[6. Controller overview](doc/README-controllers.md#top) <br>
|
||||||
|
[7. Local Data Pools](doc/README-localpools.md#top) <br>
|
||||||
|
|
||||||
### 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.
|
|
||||||
|
|
||||||
### OSAL
|
|
||||||
|
|
||||||
The FSFW provides operation system abstraction layers for Linux, FreeRTOS and RTEMS.
|
|
||||||
A independent Host OSAL is in development which will provide abstraction for common type of
|
|
||||||
host OSes (tested for Linux and Windows, not for MacOS yet).
|
|
||||||
The OSAL provides periodic tasks, message queues, clocks and semaphores as well as mutexes.
|
|
||||||
|
|
||||||
### 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.
|
|
||||||
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
|
|
||||||
|
|
||||||
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()".
|
|
||||||
|
|
||||||
### 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.
|
|
||||||
|
|
||||||
### Internal Communication
|
|
||||||
|
|
||||||
Components communicate mostly over Message through Queues.
|
|
||||||
Those queues are created by calling the singleton QueueFactory::instance()->create().
|
|
||||||
|
|
||||||
### 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
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
#### 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).
|
|
||||||
|
|
||||||
#### Modes, Health
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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 are provided in the unittest folder. Those use the catch2 framework but do not include catch2 itself.
|
|
||||||
See README.md in the unittest Folder.
|
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "ArrayList.h"
|
#include "ArrayList.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An associative container which allows multiple entries of the same key.
|
* @brief An associative container which allows multiple entries of the same key.
|
||||||
|
@ -47,9 +47,11 @@ ReturnValue_t SharedRingBuffer::initialize() {
|
|||||||
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
|
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
|
||||||
if(receiveSizesFIFO == nullptr) {
|
if(receiveSizesFIFO == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
||||||
<< " was not configured to have sizes FIFO, returning nullptr!"
|
<< " was not configured to have sizes FIFO, returning nullptr!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return receiveSizesFIFO;
|
return receiveSizesFIFO;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId,
|
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId,
|
||||||
object_id_t parentId, size_t commandQueueDepth):
|
object_id_t parentId, size_t commandQueueDepth):
|
||||||
ControllerBase(objectId, parentId, commandQueueDepth),
|
ControllerBase(objectId, parentId, commandQueueDepth),
|
||||||
localPoolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
actionHelper(this, commandQueue) {
|
actionHelper(this, commandQueue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
|||||||
|
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::initializeLocalDataPool(
|
ReturnValue_t ExtendedControllerBase::initializeLocalDataPool(
|
||||||
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
|
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
|
||||||
// needs to be overriden and implemented by child class.
|
// needs to be overriden and implemented by child class.
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -26,10 +26,6 @@ object_id_t ExtendedControllerBase::getObjectId() const {
|
|||||||
return SystemObject::getObjectId();
|
return SystemObject::getObjectId();
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDataPoolManager* ExtendedControllerBase::getHkManagerHandle() {
|
|
||||||
return &localPoolManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const {
|
uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const {
|
||||||
return this->executingTask->getPeriodMs();
|
return this->executingTask->getPeriodMs();
|
||||||
}
|
}
|
||||||
@ -40,7 +36,7 @@ ReturnValue_t ExtendedControllerBase::handleCommandMessage(
|
|||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return localPoolManager.handleHousekeepingMessage(message);
|
return poolManager.handleHousekeepingMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtendedControllerBase::handleQueue() {
|
void ExtendedControllerBase::handleQueue() {
|
||||||
@ -64,7 +60,7 @@ void ExtendedControllerBase::handleQueue() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = localPoolManager.handleHousekeepingMessage(&command);
|
result = poolManager.handleHousekeepingMessage(&command);
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -88,16 +84,16 @@ ReturnValue_t ExtendedControllerBase::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return localPoolManager.initialize(commandQueue);
|
return poolManager.initialize(commandQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
|
ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
|
||||||
return localPoolManager.initializeAfterTaskCreation();
|
return poolManager.initializeAfterTaskCreation();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
|
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
|
||||||
handleQueue();
|
handleQueue();
|
||||||
localPoolManager.performHkOperation();
|
poolManager.performHkOperation();
|
||||||
performControlOperation();
|
performControlOperation();
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -107,7 +103,13 @@ MessageQueueId_t ExtendedControllerBase::getCommandQueue() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) {
|
LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "ExtendedControllerBase::getDataSetHandle: No child "
|
sif::warning << "ExtendedControllerBase::getDataSetHandle: No child "
|
||||||
<< " implementation provided, returning nullptr!" << std::endl;
|
<< " implementation provided, returning nullptr!" << std::endl;
|
||||||
|
#endif
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalDataPoolManager* ExtendedControllerBase::getHkManagerHandle() {
|
||||||
|
return &poolManager;
|
||||||
|
}
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LocalDataPoolManager localPoolManager;
|
LocalDataPoolManager poolManager;
|
||||||
ActionHelper actionHelper;
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,11 +58,11 @@ protected:
|
|||||||
size_t size) override;
|
size_t size) override;
|
||||||
|
|
||||||
/** HasLocalDatapoolIF overrides */
|
/** HasLocalDatapoolIF overrides */
|
||||||
|
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
||||||
virtual object_id_t getObjectId() const override;
|
virtual object_id_t getObjectId() const override;
|
||||||
virtual ReturnValue_t initializeLocalDataPool(
|
virtual ReturnValue_t initializeLocalDataPool(
|
||||||
LocalDataPool& localDataPoolMap,
|
localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
|
||||||
virtual uint32_t getPeriodicOperationFrequency() const override;
|
virtual uint32_t getPeriodicOperationFrequency() const override;
|
||||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
};
|
};
|
||||||
|
@ -55,7 +55,9 @@ void Clcw::setBitLock(bool bitLock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clcw::print() {
|
void Clcw::print() {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl;
|
sif::debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clcw::setWhole(uint32_t rawClcw) {
|
void Clcw::setWhole(uint32_t rawClcw) {
|
||||||
|
@ -98,8 +98,10 @@ ReturnValue_t DataLinkLayer::processFrame(uint16_t length) {
|
|||||||
receivedDataLength = length;
|
receivedDataLength = length;
|
||||||
ReturnValue_t status = allFramesReception();
|
ReturnValue_t status = allFramesReception();
|
||||||
if (status != RETURN_OK) {
|
if (status != RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DataLinkLayer::processFrame: frame reception failed. "
|
sif::error << "DataLinkLayer::processFrame: frame reception failed. "
|
||||||
"Error code: " << std::hex << status << std::dec << std::endl;
|
"Error code: " << std::hex << status << std::dec << std::endl;
|
||||||
|
#endif
|
||||||
// currentFrame.print();
|
// currentFrame.print();
|
||||||
return status;
|
return status;
|
||||||
} else {
|
} else {
|
||||||
@ -124,7 +126,9 @@ ReturnValue_t DataLinkLayer::initialize() {
|
|||||||
if ( virtualChannels.begin() != virtualChannels.end() ) {
|
if ( virtualChannels.begin() != virtualChannels.end() ) {
|
||||||
clcw->setVirtualChannel( virtualChannels.begin()->second->getChannelId() );
|
clcw->setVirtualChannel( virtualChannels.begin()->second->getChannelId() );
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DataLinkLayer::initialize: No VC assigned to this DLL instance! " << std::endl;
|
sif::error << "DataLinkLayer::initialize: No VC assigned to this DLL instance! " << std::endl;
|
||||||
|
#endif
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,9 +29,11 @@ ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
|
|||||||
bufferPosition = &packetBuffer[packetLength];
|
bufferPosition = &packetBuffer[packetLength];
|
||||||
status = RETURN_OK;
|
status = RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error
|
sif::error
|
||||||
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
|
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
|
||||||
<< packetLength << std::endl;
|
<< packetLength << std::endl;
|
||||||
|
#endif
|
||||||
clearBuffers();
|
clearBuffers();
|
||||||
status = CONTENT_TOO_LARGE;
|
status = CONTENT_TOO_LARGE;
|
||||||
}
|
}
|
||||||
@ -51,24 +53,30 @@ ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
|
|||||||
}
|
}
|
||||||
status = RETURN_OK;
|
status = RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error
|
sif::error
|
||||||
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
|
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
|
||||||
<< packetLength << std::endl;
|
<< packetLength << std::endl;
|
||||||
|
#endif
|
||||||
clearBuffers();
|
clearBuffers();
|
||||||
status = CONTENT_TOO_LARGE;
|
status = CONTENT_TOO_LARGE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error
|
sif::error
|
||||||
<< "MapPacketExtraction::extractPackets. Illegal segment! Last flag: "
|
<< "MapPacketExtraction::extractPackets. Illegal segment! Last flag: "
|
||||||
<< (int) lastSegmentationFlag << std::endl;
|
<< (int) lastSegmentationFlag << std::endl;
|
||||||
|
#endif
|
||||||
clearBuffers();
|
clearBuffers();
|
||||||
status = ILLEGAL_SEGMENTATION_FLAG;
|
status = ILLEGAL_SEGMENTATION_FLAG;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error
|
sif::error
|
||||||
<< "MapPacketExtraction::extractPackets. Illegal segmentationFlag: "
|
<< "MapPacketExtraction::extractPackets. Illegal segmentationFlag: "
|
||||||
<< (int) segmentationFlag << std::endl;
|
<< (int) segmentationFlag << std::endl;
|
||||||
|
#endif
|
||||||
clearBuffers();
|
clearBuffers();
|
||||||
status = DATA_CORRUPTED;
|
status = DATA_CORRUPTED;
|
||||||
break;
|
break;
|
||||||
@ -135,10 +143,14 @@ ReturnValue_t MapPacketExtraction::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MapPacketExtraction::printPacketBuffer(void) {
|
void MapPacketExtraction::printPacketBuffer(void) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "DLL: packet_buffer contains: " << std::endl;
|
sif::debug << "DLL: packet_buffer contains: " << std::endl;
|
||||||
|
#endif
|
||||||
for (uint32_t i = 0; i < this->packetLength; ++i) {
|
for (uint32_t i = 0; i < this->packetLength; ++i) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "packet_buffer[" << std::dec << i << "]: 0x" << std::hex
|
sif::debug << "packet_buffer[" << std::dec << i << "]: 0x" << std::hex
|
||||||
<< (uint16_t) this->packetBuffer[i] << std::endl;
|
<< (uint16_t) this->packetBuffer[i] << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,16 +87,25 @@ uint8_t* TcTransferFrame::getFullDataField() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TcTransferFrame::print() {
|
void TcTransferFrame::print() {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Raw Frame: " << std::hex << std::endl;
|
sif::debug << "Raw Frame: " << std::hex << std::endl;
|
||||||
for (uint16_t count = 0; count < this->getFullSize(); count++ ) {
|
for (uint16_t count = 0; count < this->getFullSize(); count++ ) {
|
||||||
sif::debug << (uint16_t)this->getFullFrame()[count] << " ";
|
sif::debug << (uint16_t)this->getFullFrame()[count] << " ";
|
||||||
}
|
}
|
||||||
sif::debug << std::dec << std::endl;
|
sif::debug << std::dec << std::endl;
|
||||||
// debug << "Frame Header:" << std::endl;
|
|
||||||
// debug << "Version Number: " << std::hex << (uint16_t)this->current_frame.getVersionNumber() << std::endl;
|
sif::debug << "Frame Header:" << std::endl;
|
||||||
// debug << "Bypass Flag set?| Ctrl Cmd Flag set?: " << (uint16_t)this->current_frame.bypassFlagSet() << " | " << (uint16_t)this->current_frame.controlCommandFlagSet() << std::endl;
|
sif::debug << "Version Number: " << std::hex
|
||||||
// debug << "SCID : " << this->current_frame.getSpacecraftId() << std::endl;
|
<< (uint16_t)this->getVersionNumber() << std::endl;
|
||||||
// debug << "VCID : " << (uint16_t)this->current_frame.getVirtualChannelId() << std::endl;
|
sif::debug << "Bypass Flag set?| Ctrl Cmd Flag set?: "
|
||||||
// debug << "Frame length: " << std::dec << this->current_frame.getFrameLength() << std::endl;
|
<< (uint16_t)this->bypassFlagSet() << " | "
|
||||||
// debug << "Sequence Number: " << (uint16_t)this->current_frame.getSequenceNumber() << std::endl;
|
<< (uint16_t)this->controlCommandFlagSet() << std::endl;
|
||||||
|
sif::debug << "SCID : " << this->getSpacecraftId() << std::endl;
|
||||||
|
sif::debug << "VCID : " << (uint16_t)this->getVirtualChannelId()
|
||||||
|
<< std::endl;
|
||||||
|
sif::debug << "Frame length: " << std::dec << this->getFrameLength()
|
||||||
|
<< std::endl;
|
||||||
|
sif::debug << "Sequence Number: " << (uint16_t)this->getSequenceNumber()
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,9 @@ TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uin
|
|||||||
this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8;
|
this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8;
|
||||||
this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF);
|
this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF);
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "TcTransferFrameLocal: dataSize too large: " << dataSize << std::endl;
|
sif::debug << "TcTransferFrameLocal: dataSize too large: " << dataSize << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//No data in frame
|
//No data in frame
|
||||||
|
@ -102,8 +102,10 @@ uint8_t VirtualChannelReception::getChannelId() const {
|
|||||||
ReturnValue_t VirtualChannelReception::initialize() {
|
ReturnValue_t VirtualChannelReception::initialize() {
|
||||||
ReturnValue_t returnValue = RETURN_FAILED;
|
ReturnValue_t returnValue = RETURN_FAILED;
|
||||||
if ((slidingWindowWidth > 254) || (slidingWindowWidth % 2 != 0)) {
|
if ((slidingWindowWidth > 254) || (slidingWindowWidth % 2 != 0)) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "VirtualChannelReception::initialize: Illegal sliding window width: "
|
sif::error << "VirtualChannelReception::initialize: Illegal sliding window width: "
|
||||||
<< (int) slidingWindowWidth << std::endl;
|
<< (int) slidingWindowWidth << std::endl;
|
||||||
|
#endif
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
for (mapChannelIterator iterator = mapChannels.begin(); iterator != mapChannels.end();
|
for (mapChannelIterator iterator = mapChannels.begin(); iterator != mapChannels.end();
|
||||||
|
@ -9,21 +9,28 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
|||||||
|
|
||||||
PoolDataSetBase::~PoolDataSetBase() {}
|
PoolDataSetBase::~PoolDataSetBase() {}
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::registerVariable(
|
ReturnValue_t PoolDataSetBase::registerVariable(
|
||||||
PoolVariableIF *variable) {
|
PoolVariableIF *variable) {
|
||||||
if (state != States::DATA_SET_UNINITIALISED) {
|
if (state != States::STATE_SET_UNINITIALISED) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DataSet::registerVariable: "
|
sif::error << "DataSet::registerVariable: "
|
||||||
"Call made in wrong position." << std::endl;
|
"Call made in wrong position." << std::endl;
|
||||||
|
#endif
|
||||||
return DataSetIF::DATA_SET_UNINITIALISED;
|
return DataSetIF::DATA_SET_UNINITIALISED;
|
||||||
}
|
}
|
||||||
if (variable == nullptr) {
|
if (variable == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DataSet::registerVariable: "
|
sif::error << "DataSet::registerVariable: "
|
||||||
"Pool variable is nullptr." << std::endl;
|
"Pool variable is nullptr." << std::endl;
|
||||||
|
#endif
|
||||||
return DataSetIF::POOL_VAR_NULL;
|
return DataSetIF::POOL_VAR_NULL;
|
||||||
}
|
}
|
||||||
if (fillCount >= maxFillCount) {
|
if (fillCount >= maxFillCount) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DataSet::registerVariable: "
|
sif::error << "DataSet::registerVariable: "
|
||||||
"DataSet is full." << std::endl;
|
"DataSet is full." << std::endl;
|
||||||
|
#endif
|
||||||
return DataSetIF::DATA_SET_FULL;
|
return DataSetIF::DATA_SET_FULL;
|
||||||
}
|
}
|
||||||
registeredVariables[fillCount] = variable;
|
registeredVariables[fillCount] = variable;
|
||||||
@ -31,25 +38,33 @@ ReturnValue_t PoolDataSetBase::registerVariable(
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::read(uint32_t lockTimeout) {
|
ReturnValue_t PoolDataSetBase::read(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t lockTimeout) {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
if (state == States::DATA_SET_UNINITIALISED) {
|
ReturnValue_t error = result;
|
||||||
lockDataPool(lockTimeout);
|
if (state == States::STATE_SET_UNINITIALISED) {
|
||||||
|
lockDataPool(timeoutType, lockTimeout);
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
result = readVariable(count);
|
result = readVariable(count);
|
||||||
if(result != RETURN_OK) {
|
if(result != RETURN_OK) {
|
||||||
break;
|
error = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state = States::DATA_SET_WAS_READ;
|
state = States::STATE_SET_WAS_READ;
|
||||||
unlockDataPool();
|
unlockDataPool();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DataSet::read(): "
|
sif::error << "DataSet::read(): "
|
||||||
"Call made in wrong position. Don't forget to commit"
|
"Call made in wrong position. Don't forget to commit"
|
||||||
" member datasets!" << std::endl;
|
" member datasets!" << std::endl;
|
||||||
|
#endif
|
||||||
result = SET_WAS_ALREADY_READ;
|
result = SET_WAS_ALREADY_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(error != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
result = error;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +86,15 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
|||||||
registeredVariables[count]->getDataPoolId()
|
registeredVariables[count]->getDataPoolId()
|
||||||
!= PoolVariableIF::NO_PARAMETER)
|
!= PoolVariableIF::NO_PARAMETER)
|
||||||
{
|
{
|
||||||
|
if(protectEveryReadCommitCall) {
|
||||||
|
result = registeredVariables[count]->read(
|
||||||
|
timeoutTypeForSingleVars,
|
||||||
|
mutexTimeoutForSingleVars);
|
||||||
|
}
|
||||||
|
else {
|
||||||
result = registeredVariables[count]->readWithoutLock();
|
result = registeredVariables[count]->readWithoutLock();
|
||||||
|
}
|
||||||
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
result = INVALID_PARAMETER_DEFINITION;
|
result = INVALID_PARAMETER_DEFINITION;
|
||||||
}
|
}
|
||||||
@ -79,55 +102,76 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::commit(uint32_t lockTimeout) {
|
ReturnValue_t PoolDataSetBase::commit(MutexIF::TimeoutType timeoutType,
|
||||||
if (state == States::DATA_SET_WAS_READ) {
|
uint32_t lockTimeout) {
|
||||||
handleAlreadyReadDatasetCommit(lockTimeout);
|
if (state == States::STATE_SET_WAS_READ) {
|
||||||
|
handleAlreadyReadDatasetCommit(timeoutType, lockTimeout);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return handleUnreadDatasetCommit(lockTimeout);
|
return handleUnreadDatasetCommit(timeoutType, lockTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PoolDataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) {
|
void PoolDataSetBase::handleAlreadyReadDatasetCommit(
|
||||||
lockDataPool(lockTimeout);
|
MutexIF::TimeoutType timeoutType, uint32_t lockTimeout) {
|
||||||
|
lockDataPool(timeoutType, lockTimeout);
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
if (registeredVariables[count]->getReadWriteMode()
|
if (registeredVariables[count]->getReadWriteMode()
|
||||||
!= PoolVariableIF::VAR_READ
|
!= PoolVariableIF::VAR_READ
|
||||||
&& registeredVariables[count]->getDataPoolId()
|
&& registeredVariables[count]->getDataPoolId()
|
||||||
!= PoolVariableIF::NO_PARAMETER) {
|
!= PoolVariableIF::NO_PARAMETER) {
|
||||||
|
if(protectEveryReadCommitCall) {
|
||||||
|
registeredVariables[count]->commit(
|
||||||
|
timeoutTypeForSingleVars,
|
||||||
|
mutexTimeoutForSingleVars);
|
||||||
|
}
|
||||||
|
else {
|
||||||
registeredVariables[count]->commitWithoutLock();
|
registeredVariables[count]->commitWithoutLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state = States::DATA_SET_UNINITIALISED;
|
}
|
||||||
|
state = States::STATE_SET_UNINITIALISED;
|
||||||
unlockDataPool();
|
unlockDataPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) {
|
ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(
|
||||||
|
MutexIF::TimeoutType timeoutType, uint32_t lockTimeout) {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
lockDataPool(lockTimeout);
|
lockDataPool(timeoutType, lockTimeout);
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
if (registeredVariables[count]->getReadWriteMode()
|
if (registeredVariables[count]->getReadWriteMode()
|
||||||
== PoolVariableIF::VAR_WRITE
|
== PoolVariableIF::VAR_WRITE
|
||||||
&& registeredVariables[count]->getDataPoolId()
|
&& registeredVariables[count]->getDataPoolId()
|
||||||
!= PoolVariableIF::NO_PARAMETER) {
|
!= PoolVariableIF::NO_PARAMETER) {
|
||||||
registeredVariables[count]->commitWithoutLock();
|
if(protectEveryReadCommitCall) {
|
||||||
|
result = registeredVariables[count]->commit(
|
||||||
|
timeoutTypeForSingleVars,
|
||||||
|
mutexTimeoutForSingleVars);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = registeredVariables[count]->commitWithoutLock();
|
||||||
|
}
|
||||||
|
|
||||||
} else if (registeredVariables[count]->getDataPoolId()
|
} else if (registeredVariables[count]->getDataPoolId()
|
||||||
!= PoolVariableIF::NO_PARAMETER) {
|
!= PoolVariableIF::NO_PARAMETER) {
|
||||||
if (result != COMMITING_WITHOUT_READING) {
|
if (result != COMMITING_WITHOUT_READING) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DataSet::commit(): commit-without-read call made "
|
sif::error << "DataSet::commit(): commit-without-read call made "
|
||||||
"with non write-only variable." << std::endl;
|
"with non write-only variable." << std::endl;
|
||||||
|
#endif
|
||||||
result = COMMITING_WITHOUT_READING;
|
result = COMMITING_WITHOUT_READING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state = States::DATA_SET_UNINITIALISED;
|
state = States::STATE_SET_UNINITIALISED;
|
||||||
unlockDataPool();
|
unlockDataPool();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::lockDataPool(uint32_t timeoutMs) {
|
ReturnValue_t PoolDataSetBase::lockDataPool(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t lockTimeout) {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,3 +216,15 @@ size_t PoolDataSetBase::getSerializedSize() const {
|
|||||||
void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
|
void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
|
||||||
this->registeredVariables = variablesContainer;
|
this->registeredVariables = variablesContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PoolVariableIF** PoolDataSetBase::getContainer() const {
|
||||||
|
return registeredVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PoolDataSetBase::setReadCommitProtectionBehaviour(
|
||||||
|
bool protectEveryReadCommit, MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t mutexTimeout) {
|
||||||
|
this->protectEveryReadCommitCall = protectEveryReadCommit;
|
||||||
|
this->timeoutTypeForSingleVars = timeoutType;
|
||||||
|
this->mutexTimeoutForSingleVars = mutexTimeout;
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "PoolDataSetIF.h"
|
#include "PoolDataSetIF.h"
|
||||||
#include "PoolVariableIF.h"
|
#include "PoolVariableIF.h"
|
||||||
|
#include "../serialize/SerializeIF.h"
|
||||||
#include "../ipc/MutexIF.h"
|
#include "../ipc/MutexIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,6 +45,7 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The read call initializes reading out all registered variables.
|
* @brief The read call initializes reading out all registered variables.
|
||||||
|
* It is mandatory to call commit after every read call!
|
||||||
* @details
|
* @details
|
||||||
* It iterates through the list of registered variables and calls all read()
|
* It iterates through the list of registered variables and calls all read()
|
||||||
* functions of the registered pool variables (which read out their values
|
* functions of the registered pool variables (which read out their values
|
||||||
@ -52,16 +54,18 @@ public:
|
|||||||
* the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned.
|
* the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned.
|
||||||
*
|
*
|
||||||
* The data pool is locked during the whole read operation and
|
* The data pool is locked during the whole read operation and
|
||||||
* freed afterwards.The state changes to "was written" after this operation.
|
* freed afterwards. It is mandatory to call commit after a read call,
|
||||||
|
* even if the read operation is not successful!
|
||||||
* @return
|
* @return
|
||||||
* - @c RETURN_OK if all variables were read successfully.
|
* - @c RETURN_OK if all variables were read successfully.
|
||||||
* - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the
|
* - @c INVALID_PARAMETER_DEFINITION if a pool entry does not exist or there
|
||||||
* requested variable is invalid.
|
* is a type conflict.
|
||||||
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
||||||
* commit() in between
|
* commit() in between
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t read(uint32_t lockTimeout =
|
virtual ReturnValue_t read(
|
||||||
MutexIF::BLOCKING) override;
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t lockTimeout = 20) override;
|
||||||
/**
|
/**
|
||||||
* @brief The commit call initializes writing back the registered variables.
|
* @brief The commit call initializes writing back the registered variables.
|
||||||
* @details
|
* @details
|
||||||
@ -75,13 +79,14 @@ public:
|
|||||||
* If the set does contain at least one variable which is not write-only
|
* If the set does contain at least one variable which is not write-only
|
||||||
* commit() can only be called after read(). If the set only contains
|
* commit() can only be called after read(). If the set only contains
|
||||||
* variables which are write only, commit() can be called without a
|
* variables which are write only, commit() can be called without a
|
||||||
* preceding read() call.
|
* preceding read() call. Every read call must be followed by a commit call!
|
||||||
* @return - @c RETURN_OK if all variables were read successfully.
|
* @return - @c RETURN_OK if all variables were read successfully.
|
||||||
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
||||||
* contains non write-only variables
|
* contains non write-only variables
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t commit(uint32_t lockTimeout =
|
virtual ReturnValue_t commit(
|
||||||
MutexIF::BLOCKING) override;
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t lockTimeout = 20) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the passed pool variable instance into the data set.
|
* Register the passed pool variable instance into the data set.
|
||||||
@ -89,13 +94,15 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override;
|
virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the means to lock the underlying data structure to ensure
|
* Provides the means to lock the underlying data structure to ensure
|
||||||
* thread-safety. Default implementation is empty
|
* thread-safety. Default implementation is empty
|
||||||
* @return Always returns -@c RETURN_OK
|
* @return Always returns -@c RETURN_OK
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t lockDataPool(uint32_t timeoutMs =
|
virtual ReturnValue_t lockDataPool(
|
||||||
MutexIF::BLOCKING) override;
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20) override;
|
||||||
/**
|
/**
|
||||||
* Provides the means to unlock the underlying data structure to ensure
|
* Provides the means to unlock the underlying data structure to ensure
|
||||||
* thread-safety. Default implementation is empty
|
* thread-safety. Default implementation is empty
|
||||||
@ -113,7 +120,16 @@ public:
|
|||||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
SerializeIF::Endianness streamEndianness) override;
|
SerializeIF::Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to individually protect every read and commit call.
|
||||||
|
* @param protectEveryReadCommit
|
||||||
|
* @param mutexTimeout
|
||||||
|
*/
|
||||||
|
void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t mutexTimeout = 20);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The fill_count attribute ensures that the variables
|
* @brief The fill_count attribute ensures that the variables
|
||||||
* register in the correct array position and that the maximum
|
* register in the correct array position and that the maximum
|
||||||
@ -124,14 +140,14 @@ protected:
|
|||||||
* States of the seet.
|
* States of the seet.
|
||||||
*/
|
*/
|
||||||
enum class States {
|
enum class States {
|
||||||
DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
|
STATE_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
|
||||||
DATA_SET_WAS_READ //!< DATA_SET_WAS_READ
|
STATE_SET_WAS_READ //!< DATA_SET_WAS_READ
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @brief state manages the internal state of the data set,
|
* @brief state manages the internal state of the data set,
|
||||||
* which is important e.g. for the behavior on destruction.
|
* which is important e.g. for the behavior on destruction.
|
||||||
*/
|
*/
|
||||||
States state = States::DATA_SET_UNINITIALISED;
|
States state = States::STATE_SET_UNINITIALISED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This array represents all pool variables registered in this set.
|
* @brief This array represents all pool variables registered in this set.
|
||||||
@ -142,11 +158,20 @@ protected:
|
|||||||
const size_t maxFillCount = 0;
|
const size_t maxFillCount = 0;
|
||||||
|
|
||||||
void setContainer(PoolVariableIF** variablesContainer);
|
void setContainer(PoolVariableIF** variablesContainer);
|
||||||
|
PoolVariableIF** getContainer() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool protectEveryReadCommitCall = false;
|
||||||
|
MutexIF::TimeoutType timeoutTypeForSingleVars = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t mutexTimeoutForSingleVars = 20;
|
||||||
|
|
||||||
ReturnValue_t readVariable(uint16_t count);
|
ReturnValue_t readVariable(uint16_t count);
|
||||||
void handleAlreadyReadDatasetCommit(uint32_t lockTimeout);
|
void handleAlreadyReadDatasetCommit(
|
||||||
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20);
|
||||||
|
ReturnValue_t handleUnreadDatasetCommit(
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOL_POOLDATASETBASE_H_ */
|
#endif /* FSFW_DATAPOOL_POOLDATASETBASE_H_ */
|
||||||
|
@ -1,26 +1,27 @@
|
|||||||
#ifndef FSFW_DATAPOOL_POOLDATASETIF_H_
|
#ifndef FSFW_DATAPOOL_POOLDATASETIF_H_
|
||||||
#define FSFW_DATAPOOL_POOLDATASETIF_H_
|
#define FSFW_DATAPOOL_POOLDATASETIF_H_
|
||||||
|
|
||||||
|
#include "ReadCommitIF.h"
|
||||||
#include "DataSetIF.h"
|
#include "DataSetIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extendes the DataSetIF by adding abstract functions to lock
|
* @brief Extendes the DataSetIF by adding abstract functions to lock
|
||||||
* and unlock a data pool and read/commit semantics.
|
* and unlock a data pool and read/commit semantics.
|
||||||
*/
|
*/
|
||||||
class PoolDataSetIF: public DataSetIF {
|
class PoolDataSetIF: public DataSetIF, public ReadCommitIF {
|
||||||
public:
|
public:
|
||||||
virtual~ PoolDataSetIF() {};
|
virtual~ PoolDataSetIF() {};
|
||||||
|
|
||||||
virtual ReturnValue_t read(dur_millis_t lockTimeout) = 0;
|
|
||||||
virtual ReturnValue_t commit(dur_millis_t lockTimeout) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Most underlying data structures will have a pool like structure
|
* @brief Most underlying data structures will have a pool like structure
|
||||||
* and will require a lock and unlock mechanism to ensure
|
* and will require a lock and unlock mechanism to ensure
|
||||||
* thread-safety
|
* thread-safety
|
||||||
* @return Lock operation result
|
* @return Lock operation result
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t lockDataPool(dur_millis_t timeoutMs) = 0;
|
virtual ReturnValue_t lockDataPool(
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unlock call corresponding to the lock call.
|
* @brief Unlock call corresponding to the lock call.
|
||||||
* @return Unlock operation result
|
* @return Unlock operation result
|
||||||
|
@ -1,29 +1,24 @@
|
|||||||
#include "PoolEntry.h"
|
#include "PoolEntry.h"
|
||||||
|
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../globalfunctions/arrayprinter.h"
|
#include "../globalfunctions/arrayprinter.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength,
|
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, bool setValid ):
|
||||||
bool setValid ) : length(setLength), valid(setValid) {
|
length(initValue.size()), valid(setValid) {
|
||||||
this->address = new T[this->length];
|
this->address = new T[this->length];
|
||||||
if(initValue.size() == 0) {
|
if(initValue.size() == 0) {
|
||||||
std::memset(this->address, 0, this->getByteSize());
|
std::memset(this->address, 0, this->getByteSize());
|
||||||
}
|
}
|
||||||
else if (initValue.size() != setLength){
|
|
||||||
sif::warning << "PoolEntry: setLength is not equal to initializer list"
|
|
||||||
"length! Performing zero initialization with given setLength"
|
|
||||||
<< std::endl;
|
|
||||||
std::memset(this->address, 0, this->getByteSize());
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
std::copy(initValue.begin(), initValue.end(), this->address);
|
std::copy(initValue.begin(), initValue.end(), this->address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
PoolEntry<T>::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) :
|
PoolEntry<T>::PoolEntry(T* initValue, uint8_t setLength, bool setValid):
|
||||||
length(setLength), valid(setValid) {
|
length(setLength), valid(setValid) {
|
||||||
this->address = new T[this->length];
|
this->address = new T[this->length];
|
||||||
if (initValue != nullptr) {
|
if (initValue != nullptr) {
|
||||||
@ -67,10 +62,26 @@ bool PoolEntry<T>::getValid() {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PoolEntry<T>::print() {
|
void PoolEntry<T>::print() {
|
||||||
sif::debug << "Pool Entry Validity: " <<
|
const char* validString = nullptr;
|
||||||
(this->valid? " (valid) " : " (invalid) ") << std::endl;
|
if(valid) {
|
||||||
arrayprinter::print(reinterpret_cast<uint8_t*>(address), length);
|
validString = "Valid";
|
||||||
sif::debug << std::dec << std::endl;
|
}
|
||||||
|
else {
|
||||||
|
validString = "Invalid";
|
||||||
|
}
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::info << "PoolEntry information." << std::endl;
|
||||||
|
sif::info << "PoolEntry validity: " << validString << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printInfo("PoolEntry information.\n");
|
||||||
|
sif::printInfo("PoolEntry validity: %s\n", validString);
|
||||||
|
#endif
|
||||||
|
arrayprinter::print(reinterpret_cast<uint8_t*>(address), getByteSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T* PoolEntry<T>::getDataPtr() {
|
||||||
|
return this->address;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -81,8 +92,10 @@ Type PoolEntry<T>::getType() {
|
|||||||
template class PoolEntry<uint8_t>;
|
template class PoolEntry<uint8_t>;
|
||||||
template class PoolEntry<uint16_t>;
|
template class PoolEntry<uint16_t>;
|
||||||
template class PoolEntry<uint32_t>;
|
template class PoolEntry<uint32_t>;
|
||||||
|
template class PoolEntry<uint64_t>;
|
||||||
template class PoolEntry<int8_t>;
|
template class PoolEntry<int8_t>;
|
||||||
template class PoolEntry<int16_t>;
|
template class PoolEntry<int16_t>;
|
||||||
template class PoolEntry<int32_t>;
|
template class PoolEntry<int32_t>;
|
||||||
|
template class PoolEntry<int64_t>;
|
||||||
template class PoolEntry<float>;
|
template class PoolEntry<float>;
|
||||||
template class PoolEntry<double>;
|
template class PoolEntry<double>;
|
||||||
|
@ -35,24 +35,22 @@ public:
|
|||||||
"uint8_t");
|
"uint8_t");
|
||||||
/**
|
/**
|
||||||
* @brief In the classe's constructor, space is allocated on the heap and
|
* @brief In the classe's constructor, space is allocated on the heap and
|
||||||
* potential init values are copied to that space.
|
* potential initialization values are copied to that space.
|
||||||
* @details
|
* @details
|
||||||
* Not passing any arguments will initialize an non-array pool entry
|
* Not passing any arguments will initialize an non-array pool entry
|
||||||
* (setLength = 1) with an initial invalid state.
|
* with an initial invalid state and the value 0.
|
||||||
* Please note that if an initializer list is passed, the correct
|
* Please note that if an initializer list is passed, the length of the
|
||||||
* corresponding length should be passed too, otherwise a zero
|
* initializer list needs to be correct for vector entries because
|
||||||
* initialization will be performed with the given setLength.
|
* required allocated space will be deduced from the initializer list length
|
||||||
|
* and the pool entry type.
|
||||||
* @param initValue
|
* @param initValue
|
||||||
* Initializer list with values to initialize with, for example {0,0} to
|
* Initializer list with values to initialize with, for example {0, 0} to
|
||||||
* initialize the two entries to zero.
|
* initialize the a pool entry of a vector with two entries to 0.
|
||||||
* @param setLength
|
|
||||||
* Defines the array length of this entry. Should be equal to the
|
|
||||||
* intializer list length.
|
|
||||||
* @param setValid
|
* @param setValid
|
||||||
* Sets the initialization flag. It is invalid by default.
|
* Sets the initialization flag. It is invalid by default.
|
||||||
*/
|
*/
|
||||||
PoolEntry(std::initializer_list<T> initValue = {}, uint8_t setLength = 1,
|
PoolEntry(std::initializer_list<T> initValue = {0}, bool setValid = false);
|
||||||
bool setValid = false);
|
|
||||||
/**
|
/**
|
||||||
* @brief In the classe's constructor, space is allocated on the heap and
|
* @brief In the classe's constructor, space is allocated on the heap and
|
||||||
* potential init values are copied to that space.
|
* potential init values are copied to that space.
|
||||||
@ -66,9 +64,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false);
|
PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false);
|
||||||
|
|
||||||
//! Explicitely deleted copy ctor, copying is not allowed!
|
//! Explicitely deleted copy ctor, copying is not allowed.
|
||||||
PoolEntry(const PoolEntry&) = delete;
|
PoolEntry(const PoolEntry&) = delete;
|
||||||
//! Explicitely deleted copy assignment, copying is not allowed!
|
//! Explicitely deleted copy assignment, copying is not allowed.
|
||||||
PoolEntry& operator=(const PoolEntry&) = delete;
|
PoolEntry& operator=(const PoolEntry&) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,21 +80,16 @@ public:
|
|||||||
~PoolEntry();
|
~PoolEntry();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the address pointing to the allocated memory.
|
* Return typed pointer to start of data.
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
T* address;
|
T* getDataPtr();
|
||||||
/**
|
|
||||||
* @brief This attribute stores the length information.
|
|
||||||
*/
|
|
||||||
uint8_t length;
|
|
||||||
/**
|
|
||||||
* @brief Here, the validity information for a variable is stored.
|
|
||||||
* Every entry (single variable or vector) has one valid flag.
|
|
||||||
*/
|
|
||||||
uint8_t valid;
|
|
||||||
/**
|
/**
|
||||||
* @brief getSize returns the array size of the entry.
|
* @brief getSize returns the array size of the entry.
|
||||||
* @details A single parameter has size 1.
|
* @details
|
||||||
|
* For non-array pool entries return type size, for vector entries
|
||||||
|
* return type size times the number of entries.
|
||||||
*/
|
*/
|
||||||
uint8_t getSize();
|
uint8_t getSize();
|
||||||
/**
|
/**
|
||||||
@ -123,8 +116,22 @@ public:
|
|||||||
* information to the screen. It prints all array entries in a row.
|
* information to the screen. It prints all array entries in a row.
|
||||||
*/
|
*/
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
Type getType();
|
Type getType();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief This attribute stores the length information.
|
||||||
|
*/
|
||||||
|
uint8_t length;
|
||||||
|
/**
|
||||||
|
* @brief Here, the validity information for a variable is stored.
|
||||||
|
* Every entry (single variable or vector) has one valid flag.
|
||||||
|
*/
|
||||||
|
uint8_t valid;
|
||||||
|
/**
|
||||||
|
* @brief This is the address pointing to the allocated memory.
|
||||||
|
*/
|
||||||
|
T* address;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOL_POOLENTRY_H_ */
|
#endif /* FSFW_DATAPOOL_POOLENTRY_H_ */
|
||||||
|
51
datapool/PoolReadHelper.h
Normal file
51
datapool/PoolReadHelper.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef FSFW_DATAPOOL_POOLREADHELPER_H_
|
||||||
|
#define FSFW_DATAPOOL_POOLREADHELPER_H_
|
||||||
|
|
||||||
|
#include "ReadCommitIF.h"
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
|
#include <FSFWConfig.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper class to read data sets or pool variables
|
||||||
|
*/
|
||||||
|
class PoolReadHelper {
|
||||||
|
public:
|
||||||
|
PoolReadHelper(ReadCommitIF* readObject,
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t mutexTimeout = 20):
|
||||||
|
readObject(readObject), mutexTimeout(mutexTimeout) {
|
||||||
|
if(readObject != nullptr) {
|
||||||
|
readResult = readObject->read(timeoutType, mutexTimeout);
|
||||||
|
if(readResult != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL == 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "PoolReadHelper: Read failed!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("PoolReadHelper: Read failed!\n");
|
||||||
|
#endif /* FSFW_PRINT_VERBOSITY_LEVEL == 1 */
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t getReadResult() const {
|
||||||
|
return readResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PoolReadHelper() {
|
||||||
|
if(readObject != nullptr) {
|
||||||
|
readObject->commit(timeoutType, mutexTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReadCommitIF* readObject = nullptr;
|
||||||
|
ReturnValue_t readResult = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t mutexTimeout = 20;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOL_POOLREADHELPER_H_ */
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
|
#include "ReadCommitIF.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This interface is used to control data pool
|
* @brief This interface is used to control data pool
|
||||||
@ -17,13 +18,14 @@
|
|||||||
* @author Bastian Baetz
|
* @author Bastian Baetz
|
||||||
* @ingroup data_pool
|
* @ingroup data_pool
|
||||||
*/
|
*/
|
||||||
class PoolVariableIF : public SerializeIF {
|
class PoolVariableIF : public SerializeIF,
|
||||||
|
public ReadCommitIF {
|
||||||
friend class PoolDataSetBase;
|
friend class PoolDataSetBase;
|
||||||
friend class GlobDataSet;
|
|
||||||
friend class LocalPoolDataSetBase;
|
friend class LocalPoolDataSetBase;
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF;
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF;
|
||||||
static constexpr ReturnValue_t INVALID_READ_WRITE_MODE = MAKE_RETURN_CODE(0xA0);
|
static constexpr ReturnValue_t INVALID_READ_WRITE_MODE = MAKE_RETURN_CODE(0xA0);
|
||||||
|
static constexpr ReturnValue_t INVALID_POOL_ENTRY = MAKE_RETURN_CODE(0xA1);
|
||||||
|
|
||||||
static constexpr bool VALID = 1;
|
static constexpr bool VALID = 1;
|
||||||
static constexpr bool INVALID = 0;
|
static constexpr bool INVALID = 0;
|
||||||
@ -57,41 +59,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void setValid(bool validity) = 0;
|
virtual void setValid(bool validity) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The commit call shall write back a newly calculated local
|
|
||||||
* value to the data pool.
|
|
||||||
* @details
|
|
||||||
* It is assumed that these calls are implemented in a thread-safe manner!
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t commit(uint32_t lockTimeout) = 0;
|
|
||||||
/**
|
|
||||||
* @brief The read call shall read the value of this parameter from
|
|
||||||
* the data pool and store the content locally.
|
|
||||||
* @details
|
|
||||||
* It is assumbed that these calls are implemented in a thread-safe manner!
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t read(uint32_t lockTimeout) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Same as commit with the difference that comitting will be
|
|
||||||
* performed without a lock
|
|
||||||
* @return
|
|
||||||
* This can be used if the lock protection is handled externally
|
|
||||||
* to avoid the overhead of locking and unlocking consecutively.
|
|
||||||
* Declared protected to avoid free public usage.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t readWithoutLock() = 0;
|
|
||||||
/**
|
|
||||||
* @brief Same as commit with the difference that comitting will be
|
|
||||||
* performed without a lock
|
|
||||||
* @return
|
|
||||||
* This can be used if the lock protection is handled externally
|
|
||||||
* to avoid the overhead of locking and unlocking consecutively.
|
|
||||||
* Declared protected to avoid free public usage.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t commitWithoutLock() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
||||||
|
34
datapool/ReadCommitIF.h
Normal file
34
datapool/ReadCommitIF.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef FSFW_DATAPOOL_READCOMMITIF_H_
|
||||||
|
#define FSFW_DATAPOOL_READCOMMITIF_H_
|
||||||
|
|
||||||
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
|
#include "../ipc/MutexIF.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common interface for all software objects which employ read-commit
|
||||||
|
* semantics.
|
||||||
|
*/
|
||||||
|
class ReadCommitIF {
|
||||||
|
public:
|
||||||
|
virtual ~ReadCommitIF() {}
|
||||||
|
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t timeoutMs) = 0;
|
||||||
|
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t timeoutMs) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Optional and protected because this is interesting for classes grouping
|
||||||
|
//! members with commit and read semantics where the lock is only necessary
|
||||||
|
//! once.
|
||||||
|
virtual ReturnValue_t readWithoutLock() {
|
||||||
|
return read(MutexIF::TimeoutType::WAITING, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ReturnValue_t commitWithoutLock() {
|
||||||
|
return commit(MutexIF::TimeoutType::WAITING, 20);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOL_READCOMMITIF_H_ */
|
27
datapoollocal/AccessLocalPoolF.h
Normal file
27
datapoollocal/AccessLocalPoolF.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
|
||||||
|
|
||||||
|
class LocalDataPoolManager;
|
||||||
|
class MutexIF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Accessor class which can be used by classes which like to use the pool manager.
|
||||||
|
*/
|
||||||
|
class AccessPoolManagerIF {
|
||||||
|
public:
|
||||||
|
virtual ~AccessPoolManagerIF() {};
|
||||||
|
|
||||||
|
virtual MutexIF* getLocalPoolMutex() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to get a handle to the local data pool manager.
|
||||||
|
* This function is protected because it should only be used by the
|
||||||
|
* class imlementing the interface.
|
||||||
|
*/
|
||||||
|
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_ */
|
@ -6,3 +6,5 @@ target_sources(${LIB_FSFW_NAME}
|
|||||||
LocalPoolObjectBase.cpp
|
LocalPoolObjectBase.cpp
|
||||||
SharedLocalDataSet.cpp
|
SharedLocalDataSet.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(internal)
|
@ -1,49 +1,40 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
||||||
#define FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
#define FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
||||||
|
|
||||||
#include "locPoolDefinitions.h"
|
#include "localPoolDefinitions.h"
|
||||||
|
#include "LocalDataPoolManager.h"
|
||||||
|
|
||||||
#include "../datapool/PoolEntryIF.h"
|
#include "../datapool/PoolEntryIF.h"
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
#include "../housekeeping/HousekeepingMessage.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class LocalDataPoolManager;
|
class AccessPoolManagerIF;
|
||||||
|
class ProvidesDataPoolSubscriptionIF;
|
||||||
class LocalPoolDataSetBase;
|
class LocalPoolDataSetBase;
|
||||||
class LocalPoolObjectBase;
|
class LocalPoolObjectBase;
|
||||||
|
|
||||||
using LocalDataPool = std::map<lp_id_t, PoolEntryIF*>;
|
|
||||||
using LocalDataPoolMapIter = LocalDataPool::iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This interface is implemented by classes which posses a local
|
* @brief This interface is implemented by classes which posses a local data pool (not the
|
||||||
* data pool (not the managing class). It defines the relationship
|
* managing class). It defines the relationship between the local data pool owner
|
||||||
* between the local data pool owner and the LocalDataPoolManager.
|
* and the LocalDataPoolManager.
|
||||||
* @details
|
* @details
|
||||||
* Any class implementing this interface shall also have a LocalDataPoolManager
|
* Any class implementing this interface shall also have a LocalDataPoolManager member class which
|
||||||
* member class which contains the actual pool data structure
|
* contains the actual pool data structure and exposes the public interface for it.
|
||||||
* and exposes the public interface for it.
|
* The local data pool can be accessed using helper classes by using the
|
||||||
* This is required because the pool entries are templates, which makes
|
* LocalPoolVariable, LocalPoolVector or LocalDataSet classes. Every local pool variable can
|
||||||
* specifying an interface rather difficult. The local data pool can be
|
* be uniquely identified by a global pool ID (gp_id_t) and every dataset tied
|
||||||
* accessed by using the LocalPoolVariable, LocalPoolVector or LocalDataSet
|
* to a pool manager can be uniqely identified by a global structure ID (sid_t).
|
||||||
* classes.
|
|
||||||
*
|
*
|
||||||
* Architectural Note:
|
|
||||||
* This could be circumvented by using a wrapper/accessor function or
|
|
||||||
* implementing the templated function in this interface..
|
|
||||||
* The first solution sounds better than the second but
|
|
||||||
* the LocalPoolVariable classes are templates as well, so this just shifts
|
|
||||||
* the problem somewhere else. Interfaces are nice, but the most
|
|
||||||
* pragmatic solution I found was to offer the client the full interface
|
|
||||||
* of the LocalDataPoolManager.
|
|
||||||
*/
|
*/
|
||||||
class HasLocalDataPoolIF {
|
class HasLocalDataPoolIF {
|
||||||
|
friend class HasLocalDpIFManagerAttorney;
|
||||||
|
friend class HasLocalDpIFUserAttorney;
|
||||||
public:
|
public:
|
||||||
virtual~ HasLocalDataPoolIF() {};
|
virtual~ HasLocalDataPoolIF() {};
|
||||||
|
|
||||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
|
|
||||||
|
|
||||||
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
||||||
|
|
||||||
virtual object_id_t getObjectId() const = 0;
|
virtual object_id_t getObjectId() const = 0;
|
||||||
@ -56,13 +47,9 @@ public:
|
|||||||
* The manager instance shall also be passed to this function.
|
* The manager instance shall also be passed to this function.
|
||||||
* It can be used to subscribe for periodic packets for for updates.
|
* It can be used to subscribe for periodic packets for for updates.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t initializeLocalDataPool(
|
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPool& localDataPoolMap,
|
|
||||||
LocalDataPoolManager& poolManager) = 0;
|
LocalDataPoolManager& poolManager) = 0;
|
||||||
|
|
||||||
/** Can be used to get a handle to the local data pool manager. */
|
|
||||||
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the minimum sampling frequency in milliseconds, which will
|
* Returns the minimum sampling frequency in milliseconds, which will
|
||||||
* usually be the period the pool owner performs its periodic operation.
|
* usually be the period the pool owner performs its periodic operation.
|
||||||
@ -70,31 +57,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual uint32_t getPeriodicOperationFrequency() const = 0;
|
virtual uint32_t getPeriodicOperationFrequency() const = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is used by the pool manager to get a valid dataset
|
|
||||||
* from a SID
|
|
||||||
* @param sid Corresponding structure ID
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Similar to the function above, but used to get a local pool variable
|
|
||||||
* handle. This is only needed for update notifications, so it is not
|
|
||||||
* defined as abstract.
|
|
||||||
* @param localPoolId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) {
|
|
||||||
sif::warning << "HasLocalDataPoolIF::getPoolObjectHandle: Not overriden"
|
|
||||||
<< ". Returning nullptr!" << std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function will be called by the manager if an update
|
* @brief This function will be called by the manager if an update
|
||||||
* notification is received.
|
* notification is received.
|
||||||
* @details
|
* @details HasLocalDataPoolIF
|
||||||
* Can be overriden by the child class to handle changed datasets.
|
* Can be overriden by the child class to handle changed datasets.
|
||||||
* @param sid
|
* @param sid
|
||||||
* @param storeId If a snapshot was requested, data will be located inside
|
* @param storeId If a snapshot was requested, data will be located inside
|
||||||
@ -119,18 +85,81 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These function can be implemented by pool owner, as they are required
|
/**
|
||||||
* by the housekeeping message interface */
|
* These function can be implemented by pool owner, if they are required
|
||||||
|
* and used by the housekeeping message interface.
|
||||||
|
* */
|
||||||
virtual ReturnValue_t addDataSet(sid_t sid) {
|
virtual ReturnValue_t addDataSet(sid_t sid) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
};
|
};
|
||||||
virtual ReturnValue_t removeDataSet(sid_t sid) {
|
virtual ReturnValue_t removeDataSet(sid_t sid) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
};
|
};
|
||||||
virtual ReturnValue_t changeCollectionInterval(sid_t sid,
|
virtual ReturnValue_t changeCollectionInterval(sid_t sid, float newIntervalSeconds) {
|
||||||
float newIntervalSeconds) {
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function can be used by data pool consumers to retrieve a handle
|
||||||
|
* which allows subscriptions to dataset and variable updates in form of messages.
|
||||||
|
* The consumers can then read the most recent variable value by calling read with
|
||||||
|
* an own pool variable or set instance or using the deserialized snapshot data.
|
||||||
|
* Returns the HK manager casted to the required interface by default.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ProvidesDataPoolSubscriptionIF* getSubscriptionInterface() {
|
||||||
|
return getHkManagerHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every class implementing this interface should have a local data pool manager. This
|
||||||
|
* function will return a reference to the manager.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor handle required for internal handling. Not intended for users and therefore
|
||||||
|
* declared protected. Users should instead use pool variables, sets or the subscription
|
||||||
|
* interface to access pool entries. Returns the HK manager casted to a different interface
|
||||||
|
* by default.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual AccessPoolManagerIF* getAccessorHandle() {
|
||||||
|
return getHkManagerHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used by the pool manager to get a valid dataset
|
||||||
|
* from a SID. This function is protected to prevent users from
|
||||||
|
* using raw data set pointers which could not be thread-safe. Users
|
||||||
|
* should use the #ProvidesDataPoolSubscriptionIF.
|
||||||
|
* @param sid Corresponding structure ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to the function above, but used to get a local pool variable
|
||||||
|
* handle. This is only needed for update notifications, so it is not
|
||||||
|
* defined as abstract. This function is protected to prevent users from
|
||||||
|
* using raw pool variable pointers which could not be thread-safe.
|
||||||
|
* Users should use the #ProvidesDataPoolSubscriptionIF.
|
||||||
|
* @param localPoolId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "HasLocalDataPoolIF::getPoolObjectHandle: Not overriden"
|
||||||
|
<< ". Returning nullptr!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("HasLocalDataPoolIF::getPoolObjectHandle: "
|
||||||
|
"Not overriden. Returning nullptr!\n");
|
||||||
|
#endif
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_ */
|
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_ */
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
|
#include "HasLocalDataPoolIF.h"
|
||||||
#include "LocalDataPoolManager.h"
|
#include "LocalDataPoolManager.h"
|
||||||
#include "LocalPoolObjectBase.h"
|
#include "LocalPoolObjectBase.h"
|
||||||
#include "LocalPoolDataSetBase.h"
|
#include "LocalPoolDataSetBase.h"
|
||||||
|
#include "internal/LocalPoolDataSetAttorney.h"
|
||||||
|
#include "internal/HasLocalDpIFManagerAttorney.h"
|
||||||
|
|
||||||
#include "../housekeeping/HousekeepingPacketUpdate.h"
|
#include "../housekeeping/HousekeepingPacketUpdate.h"
|
||||||
#include "../housekeeping/HousekeepingSetPacket.h"
|
#include "../housekeeping/HousekeepingSetPacket.h"
|
||||||
#include "../housekeeping/AcceptsHkPacketsIF.h"
|
#include "../housekeeping/AcceptsHkPacketsIF.h"
|
||||||
|
|
||||||
#include "../timemanager/CCSDSTime.h"
|
#include "../timemanager/CCSDSTime.h"
|
||||||
#include "../ipc/MutexFactory.h"
|
#include "../ipc/MutexFactory.h"
|
||||||
#include "../ipc/MutexHelper.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
@ -14,22 +16,23 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
object_id_t LocalDataPoolManager::defaultHkDestination =
|
object_id_t LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
|
||||||
objects::PUS_SERVICE_3_HOUSEKEEPING;
|
|
||||||
|
|
||||||
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
|
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||||
MessageQueueIF* queueToUse, bool appendValidityBuffer):
|
bool appendValidityBuffer):
|
||||||
appendValidityBuffer(appendValidityBuffer) {
|
appendValidityBuffer(appendValidityBuffer) {
|
||||||
if(owner == nullptr) {
|
if(owner == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
<< "Invalid supplied owner!" << std::endl;
|
"LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
"Invalid supplied owner");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->owner = owner;
|
this->owner = owner;
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
if(mutex == nullptr) {
|
if(mutex == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
<< "Could not create mutex." << std::endl;
|
"LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
"Could not create mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
hkQueue = queueToUse;
|
hkQueue = queueToUse;
|
||||||
@ -39,17 +42,18 @@ LocalDataPoolManager::~LocalDataPoolManager() {}
|
|||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||||
if(queueToUse == nullptr) {
|
if(queueToUse == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::initialize: "
|
// error, all destinations invalid
|
||||||
<< std::hex << "0x" << owner->getObjectId() << ". Supplied "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
<< "queue invalid!" << std::dec << std::endl;
|
"initialize", QUEUE_OR_DESTINATION_INVALID);
|
||||||
}
|
}
|
||||||
hkQueue = queueToUse;
|
hkQueue = queueToUse;
|
||||||
|
|
||||||
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
if(ipcStore == nullptr) {
|
if(ipcStore == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::initialize: "
|
// error, all destinations invalid
|
||||||
<< std::hex << "0x" << owner->getObjectId() << ": Could not "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
<< "set IPC store." <<std::dec << std::endl;
|
"initialize", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
"Could not set IPC store.");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,9 +65,9 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
|||||||
hkDestinationId = hkPacketReceiver->getHkQueue();
|
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
<< "Default HK destination object is invalid!" << std::endl;
|
"initialize", QUEUE_OR_DESTINATION_INVALID);
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +89,10 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
sif::warning << "HousekeepingManager: The map should only be initialized "
|
|
||||||
<< "once!" << std::endl;
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"initialize", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
"The map should only be initialized once");
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +135,7 @@ ReturnValue_t LocalDataPoolManager::handleHkUpdate(HkReceiver& receiver,
|
|||||||
// Update packets shall only be generated from datasets.
|
// Update packets shall only be generated from datasets.
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner,
|
||||||
receiver.dataId.sid);
|
receiver.dataId.sid);
|
||||||
if(dataSet->hasChanged()) {
|
if(dataSet->hasChanged()) {
|
||||||
// prepare and send update notification
|
// prepare and send update notification
|
||||||
@ -144,20 +150,23 @@ ReturnValue_t LocalDataPoolManager::handleHkUpdate(HkReceiver& receiver,
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(
|
ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receiver,
|
||||||
HkReceiver& receiver, ReturnValue_t& status) {
|
ReturnValue_t& status) {
|
||||||
MarkChangedIF* toReset = nullptr;
|
MarkChangedIF* toReset = nullptr;
|
||||||
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
||||||
LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle(
|
LocalPoolObjectBase* poolObj = HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner,
|
||||||
receiver.dataId.localPoolId);
|
receiver.dataId.localPoolId);
|
||||||
|
//LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle(receiver.dataId.localPoolId);
|
||||||
if(poolObj == nullptr) {
|
if(poolObj == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"handleNotificationUpdate", POOLOBJECT_NOT_FOUND);
|
||||||
|
return POOLOBJECT_NOT_FOUND;
|
||||||
}
|
}
|
||||||
if(poolObj->hasChanged()) {
|
if(poolObj->hasChanged()) {
|
||||||
// prepare and send update notification.
|
// prepare and send update notification.
|
||||||
CommandMessage notification;
|
CommandMessage notification;
|
||||||
HousekeepingMessage::setUpdateNotificationVariableCommand(
|
HousekeepingMessage::setUpdateNotificationVariableCommand(¬ification,
|
||||||
¬ification, receiver.dataId.localPoolId);
|
receiver.dataId.localPoolId);
|
||||||
ReturnValue_t result = hkQueue->sendMessage(
|
ReturnValue_t result = hkQueue->sendMessage(
|
||||||
receiver.destinationQueue, ¬ification);
|
receiver.destinationQueue, ¬ification);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
@ -168,10 +177,12 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(
|
|||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner,
|
||||||
receiver.dataId.sid);
|
receiver.dataId.sid);
|
||||||
if(dataSet == nullptr) {
|
if(dataSet == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"handleNotificationUpdate", DATASET_NOT_FOUND);
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
if(dataSet->hasChanged()) {
|
if(dataSet->hasChanged()) {
|
||||||
// prepare and send update notification
|
// prepare and send update notification
|
||||||
@ -198,10 +209,12 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
|
|||||||
MarkChangedIF* toReset = nullptr;
|
MarkChangedIF* toReset = nullptr;
|
||||||
// check whether data has changed and send messages in case it has.
|
// check whether data has changed and send messages in case it has.
|
||||||
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
||||||
LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle(
|
LocalPoolObjectBase* poolObj = HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner,
|
||||||
receiver.dataId.localPoolId);
|
receiver.dataId.localPoolId);
|
||||||
if(poolObj == nullptr) {
|
if(poolObj == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"handleNotificationSnapshot", POOLOBJECT_NOT_FOUND);
|
||||||
|
return POOLOBJECT_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not poolObj->hasChanged()) {
|
if (not poolObj->hasChanged()) {
|
||||||
@ -214,7 +227,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
|
|||||||
CCSDSTime::CDS_short cds;
|
CCSDSTime::CDS_short cds;
|
||||||
CCSDSTime::convertToCcsds(&cds, &now);
|
CCSDSTime::convertToCcsds(&cds, &now);
|
||||||
HousekeepingPacketUpdate updatePacket(reinterpret_cast<uint8_t*>(&cds),
|
HousekeepingPacketUpdate updatePacket(reinterpret_cast<uint8_t*>(&cds),
|
||||||
sizeof(cds), owner->getPoolObjectHandle(
|
sizeof(cds), HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner,
|
||||||
receiver.dataId.localPoolId));
|
receiver.dataId.localPoolId));
|
||||||
|
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
@ -234,10 +247,12 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
|
|||||||
toReset = poolObj;
|
toReset = poolObj;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner,
|
||||||
receiver.dataId.sid);
|
receiver.dataId.sid);
|
||||||
if(dataSet == nullptr) {
|
if(dataSet == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"handleNotificationSnapshot", DATASET_NOT_FOUND);
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(not dataSet->hasChanged()) {
|
if(not dataSet->hasChanged()) {
|
||||||
@ -250,7 +265,8 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
|
|||||||
CCSDSTime::CDS_short cds;
|
CCSDSTime::CDS_short cds;
|
||||||
CCSDSTime::convertToCcsds(&cds, &now);
|
CCSDSTime::convertToCcsds(&cds, &now);
|
||||||
HousekeepingPacketUpdate updatePacket(reinterpret_cast<uint8_t*>(&cds),
|
HousekeepingPacketUpdate updatePacket(reinterpret_cast<uint8_t*>(&cds),
|
||||||
sizeof(cds), owner->getDataSetHandle(receiver.dataId.sid));
|
sizeof(cds), HasLocalDpIFManagerAttorney::getDataSetHandle(owner,
|
||||||
|
receiver.dataId.sid));
|
||||||
|
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
ReturnValue_t result = addUpdateToStore(updatePacket, storeId);
|
ReturnValue_t result = addUpdateToStore(updatePacket, storeId);
|
||||||
@ -296,8 +312,8 @@ void LocalDataPoolManager::handleChangeResetLogic(
|
|||||||
// config error!
|
// config error!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
HkUpdateResetList& listRef = *hkUpdateResetList;
|
||||||
for(auto& changeInfo: *hkUpdateResetList) {
|
for(auto& changeInfo: listRef) {
|
||||||
if(changeInfo.dataType != type) {
|
if(changeInfo.dataType != type) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -310,12 +326,16 @@ void LocalDataPoolManager::handleChangeResetLogic(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only one update recipient, we can reset changes status immediately.
|
||||||
if(changeInfo.updateCounter <= 1) {
|
if(changeInfo.updateCounter <= 1) {
|
||||||
toReset->setChanged(false);
|
toReset->setChanged(false);
|
||||||
}
|
}
|
||||||
if(changeInfo.currentUpdateCounter == 0) {
|
// All recipients have been notified, reset the changed flag.
|
||||||
|
if(changeInfo.currentUpdateCounter <= 1) {
|
||||||
toReset->setChanged(false);
|
toReset->setChanged(false);
|
||||||
|
changeInfo.currentUpdateCounter = 0;
|
||||||
}
|
}
|
||||||
|
// Not all recipiens have been notified yet, decrement.
|
||||||
else {
|
else {
|
||||||
changeInfo.currentUpdateCounter--;
|
changeInfo.currentUpdateCounter--;
|
||||||
}
|
}
|
||||||
@ -339,9 +359,9 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
|
|||||||
AcceptsHkPacketsIF* hkReceiverObject =
|
AcceptsHkPacketsIF* hkReceiverObject =
|
||||||
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
||||||
if(hkReceiverObject == nullptr) {
|
if(hkReceiverObject == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:"
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
<< " Invalid receiver!"<< std::endl;
|
"subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HkReceiver hkReceiver;
|
struct HkReceiver hkReceiver;
|
||||||
@ -350,11 +370,12 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
|
|||||||
hkReceiver.dataType = DataType::DATA_SET;
|
hkReceiver.dataType = DataType::DATA_SET;
|
||||||
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
||||||
|
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
|
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
if(dataSet != nullptr) {
|
if(dataSet != nullptr) {
|
||||||
dataSet->setReportingEnabled(enableReporting);
|
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting);
|
||||||
dataSet->setDiagnostic(isDiagnostics);
|
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
|
||||||
dataSet->initializePeriodicHelper(collectionInterval,
|
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, collectionInterval,
|
||||||
owner->getPeriodicOperationFrequency(), isDiagnostics);
|
owner->getPeriodicOperationFrequency(), isDiagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,9 +390,9 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePackets(sid_t sid,
|
|||||||
AcceptsHkPacketsIF* hkReceiverObject =
|
AcceptsHkPacketsIF* hkReceiverObject =
|
||||||
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
||||||
if(hkReceiverObject == nullptr) {
|
if(hkReceiverObject == nullptr) {
|
||||||
sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:"
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
<< " Invalid receiver!"<< std::endl;
|
"subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HkReceiver hkReceiver;
|
struct HkReceiver hkReceiver;
|
||||||
@ -380,10 +401,11 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePackets(sid_t sid,
|
|||||||
hkReceiver.dataType = DataType::DATA_SET;
|
hkReceiver.dataType = DataType::DATA_SET;
|
||||||
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
||||||
|
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
|
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
if(dataSet != nullptr) {
|
if(dataSet != nullptr) {
|
||||||
dataSet->setReportingEnabled(true);
|
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
|
||||||
dataSet->setDiagnostic(isDiagnostics);
|
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
hkReceiversMap.push_back(hkReceiver);
|
hkReceiversMap.push_back(hkReceiver);
|
||||||
@ -397,7 +419,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForSetUpdateMessages(
|
|||||||
MessageQueueId_t targetQueueId, bool generateSnapshot) {
|
MessageQueueId_t targetQueueId, bool generateSnapshot) {
|
||||||
struct HkReceiver hkReceiver;
|
struct HkReceiver hkReceiver;
|
||||||
hkReceiver.dataType = DataType::DATA_SET;
|
hkReceiver.dataType = DataType::DATA_SET;
|
||||||
hkReceiver.dataId.sid = sid_t(this->getOwner()->getObjectId(), setId);
|
hkReceiver.dataId.sid = sid_t(owner->getObjectId(), setId);
|
||||||
hkReceiver.destinationQueue = targetQueueId;
|
hkReceiver.destinationQueue = targetQueueId;
|
||||||
hkReceiver.objectId = destinationObject;
|
hkReceiver.objectId = destinationObject;
|
||||||
if(generateSnapshot) {
|
if(generateSnapshot) {
|
||||||
@ -497,10 +519,13 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES):
|
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): {
|
||||||
return generateSetStructurePacket(sid, true);
|
return generateSetStructurePacket(sid, true);
|
||||||
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES):
|
}
|
||||||
|
|
||||||
|
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): {
|
||||||
return generateSetStructurePacket(sid, false);
|
return generateSetStructurePacket(sid, false);
|
||||||
|
}
|
||||||
case(HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL):
|
case(HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL):
|
||||||
case(HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
|
case(HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
|
||||||
float newCollIntvl = 0;
|
float newCollIntvl = 0;
|
||||||
@ -518,13 +543,14 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
|
|||||||
|
|
||||||
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
|
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
|
||||||
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): {
|
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): {
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
LocalPoolDataSetBase* dataSet =HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
|
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
if(command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT
|
if(command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT
|
||||||
and dataSet->isDiagnostics()) {
|
and LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
|
||||||
return WRONG_HK_PACKET_TYPE;
|
return WRONG_HK_PACKET_TYPE;
|
||||||
}
|
}
|
||||||
else if(command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT
|
else if(command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT
|
||||||
and not dataSet->isDiagnostics()) {
|
and not LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
|
||||||
return WRONG_HK_PACKET_TYPE;
|
return WRONG_HK_PACKET_TYPE;
|
||||||
}
|
}
|
||||||
return generateHousekeepingPacket(HousekeepingMessage::getSid(message),
|
return generateHousekeepingPacket(HousekeepingMessage::getSid(message),
|
||||||
@ -575,9 +601,9 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry(
|
|||||||
lp_id_t localPoolId) {
|
lp_id_t localPoolId) {
|
||||||
auto poolIter = localPoolMap.find(localPoolId);
|
auto poolIter = localPoolMap.find(localPoolId);
|
||||||
if (poolIter == localPoolMap.end()) {
|
if (poolIter == localPoolMap.end()) {
|
||||||
sif::debug << "HousekeepingManager::fechPoolEntry:"
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "printPoolEntry",
|
||||||
<< " Pool entry not found." << std::endl;
|
localpool::POOL_ENTRY_NOT_FOUND);
|
||||||
return POOL_ENTRY_NOT_FOUND;
|
return localpool::POOL_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
poolIter->second->print();
|
poolIter->second->print();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@ -596,9 +622,10 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|||||||
MessageQueueId_t destination) {
|
MessageQueueId_t destination) {
|
||||||
if(dataSet == nullptr) {
|
if(dataSet == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
<< " Set ID not found or dataset not assigned!" << std::endl;
|
"generateHousekeepingPacket",
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
DATASET_NOT_FOUND);
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
@ -612,7 +639,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|||||||
|
|
||||||
// and now we set a HK message and send it the HK packet destination.
|
// and now we set a HK message and send it the HK packet destination.
|
||||||
CommandMessage hkMessage;
|
CommandMessage hkMessage;
|
||||||
if(dataSet->isDiagnostics()) {
|
if(LocalPoolDataSetAttorney::isDiagnostics(*dataSet)) {
|
||||||
HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId);
|
HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -620,12 +647,18 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hkQueue == nullptr) {
|
if(hkQueue == nullptr) {
|
||||||
return QUEUE_OR_DESTINATION_NOT_SET;
|
// error, no queue available to send packet with.
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"generateHousekeepingPacket",
|
||||||
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
if(destination == MessageQueueIF::NO_QUEUE) {
|
if(destination == MessageQueueIF::NO_QUEUE) {
|
||||||
if(hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
if(hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
||||||
// error, all destinations invalid
|
// error, all destinations invalid
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"generateHousekeepingPacket",
|
||||||
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
}
|
}
|
||||||
destination = hkDestinationId;
|
destination = hkDestinationId;
|
||||||
}
|
}
|
||||||
@ -660,17 +693,28 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor(
|
|||||||
|
|
||||||
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
||||||
sid_t sid = receiver.dataId.sid;
|
sid_t sid = receiver.dataId.sid;
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
if(not dataSet->getReportingEnabled()) {
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
|
if(dataSet == nullptr) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"performPeriodicHkGeneration",
|
||||||
|
DATASET_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dataSet->periodicHelper == nullptr) {
|
if(not LocalPoolDataSetAttorney::getReportingEnabled(*dataSet)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PeriodicHousekeepingHelper* periodicHelper =
|
||||||
|
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
|
||||||
|
|
||||||
|
if(periodicHelper == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(not dataSet->periodicHelper->checkOpNecessary()) {
|
if(periodicHelper->checkOpNecessary()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,70 +722,80 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
|||||||
sid, dataSet, true);
|
sid, dataSet, true);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
// configuration error
|
// configuration error
|
||||||
sif::debug << "LocalDataPoolManager::performHkOperation:"
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
<< "0x" << std::hex << std::setfill('0') << std::setw(8)
|
sif::warning << "LocalDataPoolManager::performHkOperation: "
|
||||||
<< owner->getObjectId() << " Error generating "
|
<< "HK generation failed." << std::endl;
|
||||||
<< "HK packet" << std::setfill(' ') << std::dec << std::endl;
|
#else
|
||||||
|
sif::printWarning("LocalDataPoolManager::performHkOperation: "
|
||||||
|
"HK generation failed.\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid,
|
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid,
|
||||||
bool enable, bool isDiagnostics) {
|
bool enable, bool isDiagnostics) {
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
if((dataSet->isDiagnostics() and not isDiagnostics) or
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
(not dataSet->isDiagnostics() and isDiagnostics)) {
|
if((LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and not isDiagnostics) or
|
||||||
|
(not LocalPoolDataSetAttorney::isDiagnostics(*dataSet) and isDiagnostics)) {
|
||||||
return WRONG_HK_PACKET_TYPE;
|
return WRONG_HK_PACKET_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((dataSet->getReportingEnabled() and enable) or
|
if((LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and enable) or
|
||||||
(not dataSet->getReportingEnabled() and not enable)) {
|
(not LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and not enable)) {
|
||||||
return REPORTING_STATUS_UNCHANGED;
|
return REPORTING_STATUS_UNCHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataSet->setReportingEnabled(enable);
|
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enable);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
|
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
|
||||||
float newCollectionInterval, bool isDiagnostics) {
|
float newCollectionInterval, bool isDiagnostics) {
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
bool targetIsDiagnostics = dataSet->isDiagnostics();
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
|
bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet);
|
||||||
if((targetIsDiagnostics and not isDiagnostics) or
|
if((targetIsDiagnostics and not isDiagnostics) or
|
||||||
(not targetIsDiagnostics and isDiagnostics)) {
|
(not targetIsDiagnostics and isDiagnostics)) {
|
||||||
return WRONG_HK_PACKET_TYPE;
|
return WRONG_HK_PACKET_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dataSet->periodicHelper == nullptr) {
|
PeriodicHousekeepingHelper* periodicHelper =
|
||||||
|
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
|
||||||
|
|
||||||
|
if(periodicHelper == nullptr) {
|
||||||
// config error
|
// config error
|
||||||
return PERIODIC_HELPER_INVALID;
|
return PERIODIC_HELPER_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataSet->periodicHelper->changeCollectionInterval(newCollectionInterval);
|
periodicHelper->changeCollectionInterval(newCollectionInterval);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
||||||
bool isDiagnostics) {
|
bool isDiagnostics) {
|
||||||
// Get and check dataset first.
|
// Get and check dataset first.
|
||||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
//LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||||
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if(dataSet == nullptr) {
|
if(dataSet == nullptr) {
|
||||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
<< " Set ID not found" << std::endl;
|
"performPeriodicHkGeneration",
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
DATASET_NOT_FOUND);
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool targetIsDiagnostics = dataSet->isDiagnostics();
|
bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet);
|
||||||
if((targetIsDiagnostics and not isDiagnostics) or
|
if((targetIsDiagnostics and not isDiagnostics) or
|
||||||
(not targetIsDiagnostics and isDiagnostics)) {
|
(not targetIsDiagnostics and isDiagnostics)) {
|
||||||
return WRONG_HK_PACKET_TYPE;
|
return WRONG_HK_PACKET_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid = dataSet->isValid();
|
bool valid = dataSet->isValid();
|
||||||
bool reportingEnabled = dataSet->getReportingEnabled();
|
bool reportingEnabled = LocalPoolDataSetAttorney::getReportingEnabled(*dataSet);
|
||||||
float collectionInterval =
|
float collectionInterval = LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet)->
|
||||||
dataSet->periodicHelper->getCollectionIntervalInSeconds();
|
getCollectionIntervalInSeconds();
|
||||||
|
|
||||||
// Generate set packet which can be serialized.
|
// Generate set packet which can be serialized.
|
||||||
HousekeepingSetPacket setPacket(sid,
|
HousekeepingSetPacket setPacket(sid,
|
||||||
@ -752,8 +806,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
|||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
|
||||||
expectedSize,&storePtr);
|
expectedSize,&storePtr);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
<< "Could not get free element from IPC store." << std::endl;
|
"generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
"Could not get free element from IPC store.");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,8 +817,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
|||||||
result = setPacket.serialize(&storePtr, &size, expectedSize,
|
result = setPacket.serialize(&storePtr, &size, expectedSize,
|
||||||
SerializeIF::Endianness::BIG);
|
SerializeIF::Endianness::BIG);
|
||||||
if(expectedSize != size) {
|
if(expectedSize != size) {
|
||||||
sif::error << "HousekeepingManager::generateSetStructurePacket: "
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
<< "Expected size is not equal to serialized size" << std::endl;
|
"generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
"Expected size is not equal to serialized size");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send structure reporting reply.
|
// Send structure reporting reply.
|
||||||
@ -780,3 +836,76 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
|||||||
hkQueue->reply(&reply);
|
hkQueue->reply(&reply);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalDataPoolManager::clearReceiversList() {
|
||||||
|
// clear the vector completely and releases allocated memory.
|
||||||
|
HkReceivers().swap(hkReceiversMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexIF* LocalDataPoolManager::getLocalPoolMutex() {
|
||||||
|
return this->mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_t LocalDataPoolManager::getCreatorObjectId() const {
|
||||||
|
return owner->getObjectId();
|
||||||
|
//return owner->getObjectId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
||||||
|
const char* functionName, ReturnValue_t error, const char* errorPrint) {
|
||||||
|
if(errorPrint == nullptr) {
|
||||||
|
if(error == DATASET_NOT_FOUND) {
|
||||||
|
errorPrint = "Dataset not found";
|
||||||
|
}
|
||||||
|
else if(error == POOLOBJECT_NOT_FOUND) {
|
||||||
|
errorPrint = "Pool Object not found";
|
||||||
|
}
|
||||||
|
else if(error == HasReturnvaluesIF::RETURN_FAILED) {
|
||||||
|
if(outputType == sif::OutputTypes::OUT_WARNING) {
|
||||||
|
errorPrint = "Generic Warning";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorPrint = "Generic error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(error == QUEUE_OR_DESTINATION_INVALID) {
|
||||||
|
errorPrint = "Queue or destination not set";
|
||||||
|
}
|
||||||
|
else if(error == localpool::POOL_ENTRY_TYPE_CONFLICT) {
|
||||||
|
errorPrint = "Pool entry type conflict";
|
||||||
|
}
|
||||||
|
else if(error == localpool::POOL_ENTRY_NOT_FOUND) {
|
||||||
|
errorPrint = "Pool entry not found";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorPrint = "Unknown error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(outputType == sif::OutputTypes::OUT_WARNING) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "LocalDataPoolManager::" << functionName
|
||||||
|
<< ": Object ID " << std::setw(8) << std::setfill('0')
|
||||||
|
<< std::hex << owner->getObjectId() << " | " << errorPrint
|
||||||
|
<< std::dec << std::setfill(' ') << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
|
||||||
|
owner->getObjectId(), errorPrint);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(outputType == sif::OutputTypes::OUT_ERROR) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "LocalDataPoolManager::" << functionName
|
||||||
|
<< ": Object ID " << std::setw(8) << std::setfill('0')
|
||||||
|
<< std::hex << owner->getObjectId() << " | " << errorPrint
|
||||||
|
<< std::dec << std::setfill(' ') << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
|
||||||
|
owner->getObjectId(), errorPrint);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDataPoolManager* LocalDataPoolManager::getHkManagerHandle() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||||
|
|
||||||
#include "HasLocalDataPoolIF.h"
|
#include "ProvidesDataPoolSubscriptionIF.h"
|
||||||
|
#include "AccessLocalPoolF.h"
|
||||||
|
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../housekeeping/HousekeepingPacketDownlink.h"
|
#include "../housekeeping/HousekeepingPacketDownlink.h"
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
#include "../housekeeping/HousekeepingMessage.h"
|
||||||
#include "../housekeeping/PeriodicHousekeepingHelper.h"
|
#include "../housekeeping/PeriodicHousekeepingHelper.h"
|
||||||
@ -15,6 +17,7 @@
|
|||||||
#include "../ipc/MutexHelper.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Factory {
|
namespace Factory {
|
||||||
void setStaticFrameworkObjectIds();
|
void setStaticFrameworkObjectIds();
|
||||||
@ -22,6 +25,8 @@ void setStaticFrameworkObjectIds();
|
|||||||
|
|
||||||
class LocalPoolDataSetBase;
|
class LocalPoolDataSetBase;
|
||||||
class HousekeepingPacketUpdate;
|
class HousekeepingPacketUpdate;
|
||||||
|
class HasLocalDataPoolIF;
|
||||||
|
class LocalDataPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class is the managing instance for the local data pool.
|
* @brief This class is the managing instance for the local data pool.
|
||||||
@ -47,22 +52,23 @@ class HousekeepingPacketUpdate;
|
|||||||
* Each pool entry has a valid state too.
|
* Each pool entry has a valid state too.
|
||||||
* @author R. Mueller
|
* @author R. Mueller
|
||||||
*/
|
*/
|
||||||
class LocalDataPoolManager {
|
class LocalDataPoolManager: public ProvidesDataPoolSubscriptionIF,
|
||||||
template<typename T> friend class LocalPoolVariable;
|
public AccessPoolManagerIF {
|
||||||
template<typename T, uint16_t vecSize> friend class LocalPoolVector;
|
|
||||||
friend class LocalPoolDataSetBase;
|
|
||||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||||
|
//! Some classes using the pool manager directly need to access class internals of the
|
||||||
|
//! manager. The attorney provides granular control of access to these internals.
|
||||||
|
friend class LocalDpManagerAttorney;
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
|
||||||
|
|
||||||
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
|
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_INVALID = MAKE_RETURN_CODE(0);
|
||||||
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
|
|
||||||
|
|
||||||
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x02);
|
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(1);
|
||||||
|
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(2);
|
||||||
|
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(3);
|
||||||
|
static constexpr ReturnValue_t POOLOBJECT_NOT_FOUND = MAKE_RETURN_CODE(4);
|
||||||
|
static constexpr ReturnValue_t DATASET_NOT_FOUND = MAKE_RETURN_CODE(5);
|
||||||
|
|
||||||
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x03);
|
|
||||||
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x04);
|
|
||||||
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x05);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor is used by a class which wants to implement
|
* This constructor is used by a class which wants to implement
|
||||||
@ -119,7 +125,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
|
ReturnValue_t subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
|
||||||
float collectionInterval, bool isDiagnostics,
|
float collectionInterval, bool isDiagnostics,
|
||||||
object_id_t packetDestination = defaultHkDestination);
|
object_id_t packetDestination = defaultHkDestination) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe for the generation of packets if the dataset
|
* @brief Subscribe for the generation of packets if the dataset
|
||||||
@ -133,7 +139,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t subscribeForUpdatePackets(sid_t sid, bool reportingEnabled,
|
ReturnValue_t subscribeForUpdatePackets(sid_t sid, bool reportingEnabled,
|
||||||
bool isDiagnostics,
|
bool isDiagnostics,
|
||||||
object_id_t packetDestination = defaultHkDestination);
|
object_id_t packetDestination = defaultHkDestination) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe for a notification message which will be sent
|
* @brief Subscribe for a notification message which will be sent
|
||||||
@ -152,7 +158,7 @@ public:
|
|||||||
ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId,
|
ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId,
|
||||||
object_id_t destinationObject,
|
object_id_t destinationObject,
|
||||||
MessageQueueId_t targetQueueId,
|
MessageQueueId_t targetQueueId,
|
||||||
bool generateSnapshot);
|
bool generateSnapshot) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe for an notification message which will be sent if a
|
* @brief Subscribe for an notification message which will be sent if a
|
||||||
@ -171,7 +177,9 @@ public:
|
|||||||
ReturnValue_t subscribeForVariableUpdateMessages(const lp_id_t localPoolId,
|
ReturnValue_t subscribeForVariableUpdateMessages(const lp_id_t localPoolId,
|
||||||
object_id_t destinationObject,
|
object_id_t destinationObject,
|
||||||
MessageQueueId_t targetQueueId,
|
MessageQueueId_t targetQueueId,
|
||||||
bool generateSnapshot);
|
bool generateSnapshot) override;
|
||||||
|
|
||||||
|
MutexIF* getLocalPoolMutex() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-Diagnostics packets usually have a lower minimum sampling frequency
|
* Non-Diagnostics packets usually have a lower minimum sampling frequency
|
||||||
@ -250,8 +258,18 @@ public:
|
|||||||
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
|
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
|
||||||
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
|
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function can be used to clear the receivers list. This is
|
||||||
|
* intended for test functions and not for regular operations, because
|
||||||
|
* the insertion operations allocate dynamically.
|
||||||
|
*/
|
||||||
|
void clearReceiversList();
|
||||||
|
|
||||||
|
object_id_t getCreatorObjectId() const;
|
||||||
|
|
||||||
|
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
||||||
private:
|
private:
|
||||||
LocalDataPool localPoolMap;
|
localpool::DataPool localPoolMap;
|
||||||
//! Every housekeeping data manager has a mutex to protect access
|
//! Every housekeeping data manager has a mutex to protect access
|
||||||
//! to it's data pool.
|
//! to it's data pool.
|
||||||
MutexIF* mutex = nullptr;
|
MutexIF* mutex = nullptr;
|
||||||
@ -370,6 +388,11 @@ private:
|
|||||||
ReturnValue_t& status);
|
ReturnValue_t& status);
|
||||||
ReturnValue_t addUpdateToStore(HousekeepingPacketUpdate& updatePacket,
|
ReturnValue_t addUpdateToStore(HousekeepingPacketUpdate& updatePacket,
|
||||||
store_address_t& storeId);
|
store_address_t& storeId);
|
||||||
|
|
||||||
|
void printWarningOrError(sif::OutputTypes outputType,
|
||||||
|
const char* functionName,
|
||||||
|
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
const char* errorPrint = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -378,16 +401,16 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
|||||||
PoolEntry<T> **poolEntry) {
|
PoolEntry<T> **poolEntry) {
|
||||||
auto poolIter = localPoolMap.find(localPoolId);
|
auto poolIter = localPoolMap.find(localPoolId);
|
||||||
if (poolIter == localPoolMap.end()) {
|
if (poolIter == localPoolMap.end()) {
|
||||||
sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "fetchPoolEntry",
|
||||||
"not found." << std::endl;
|
localpool::POOL_ENTRY_NOT_FOUND);
|
||||||
return POOL_ENTRY_NOT_FOUND;
|
return localpool::POOL_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
|
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
|
||||||
if(*poolEntry == nullptr) {
|
if(*poolEntry == nullptr) {
|
||||||
sif::debug << "HousekeepingManager::fetchPoolEntry:"
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "fetchPoolEntry",
|
||||||
" Pool entry not found." << std::endl;
|
localpool::POOL_ENTRY_TYPE_CONFLICT);
|
||||||
return POOL_ENTRY_TYPE_CONFLICT;
|
return localpool::POOL_ENTRY_TYPE_CONFLICT;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
#include "LocalPoolDataSetBase.h"
|
#include "LocalPoolDataSetBase.h"
|
||||||
|
#include "HasLocalDataPoolIF.h"
|
||||||
|
#include "internal/HasLocalDpIFUserAttorney.h"
|
||||||
|
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
#include "../datapoollocal/LocalDataPoolManager.h"
|
||||||
#include "../housekeeping/PeriodicHousekeepingHelper.h"
|
#include "../housekeeping/PeriodicHousekeepingHelper.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
@ -8,22 +12,31 @@
|
|||||||
|
|
||||||
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
||||||
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
||||||
const size_t maxNumberOfVariables, bool noPeriodicHandling):
|
const size_t maxNumberOfVariables, bool periodicHandling):
|
||||||
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
||||||
<< "invalid!" << std::endl;
|
<< "invalid!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
||||||
|
"invalid!\n\r");
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
||||||
|
|
||||||
|
if(accessor != nullptr) {
|
||||||
|
poolManager = accessor->getHkManagerHandle();
|
||||||
|
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
|
||||||
|
}
|
||||||
|
|
||||||
this->sid.objectId = hkOwner->getObjectId();
|
this->sid.objectId = hkOwner->getObjectId();
|
||||||
this->sid.ownerSetId = setId;
|
this->sid.ownerSetId = setId;
|
||||||
|
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
|
||||||
|
|
||||||
// Data creators get a periodic helper for periodic HK data generation.
|
// Data creators get a periodic helper for periodic HK data generation.
|
||||||
if(not noPeriodicHandling) {
|
if(periodicHandling) {
|
||||||
periodicHelper = new PeriodicHousekeepingHelper(this);
|
periodicHelper = new PeriodicHousekeepingHelper(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,24 +47,37 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
|
|||||||
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
||||||
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
|
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
|
||||||
sid.objectId);
|
sid.objectId);
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner != nullptr) {
|
||||||
// Configuration error.
|
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
||||||
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
if(accessor != nullptr) {
|
||||||
<< "invalid!" << std::endl;
|
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
|
||||||
this->sid = sid;
|
|
||||||
|
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
this->sid = sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalPoolDataSetBase::LocalPoolDataSetBase(
|
||||||
|
PoolVariableIF **registeredVariablesArray,
|
||||||
|
const size_t maxNumberOfVariables, bool protectEveryReadCommitCall):
|
||||||
|
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
||||||
|
this->setReadCommitProtectionBehaviour(protectEveryReadCommitCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LocalPoolDataSetBase::~LocalPoolDataSetBase() {
|
LocalPoolDataSetBase::~LocalPoolDataSetBase() {
|
||||||
|
if(periodicHelper != nullptr) {
|
||||||
|
delete periodicHelper;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::lockDataPool(uint32_t timeoutMs) {
|
ReturnValue_t LocalPoolDataSetBase::lockDataPool(
|
||||||
MutexIF* mutex = hkManager->getMutexHandle();
|
MutexIF::TimeoutType timeoutType,
|
||||||
return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs);
|
uint32_t timeoutMs) {
|
||||||
|
if(mutexIfSingleDataCreator != nullptr) {
|
||||||
|
return mutexIfSingleDataCreator->lockMutex(timeoutType, timeoutMs);
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer,
|
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer,
|
||||||
@ -127,8 +153,10 @@ ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
|
ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
|
||||||
MutexIF* mutex = hkManager->getMutexHandle();
|
if(mutexIfSingleDataCreator != nullptr) {
|
||||||
return mutex->unlockMutex();
|
return mutexIfSingleDataCreator->unlockMutex();
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
||||||
@ -145,8 +173,13 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
|||||||
auto result = SerializeAdapter::serialize(¤tPoolId, buffer,
|
auto result = SerializeAdapter::serialize(¤tPoolId, buffer,
|
||||||
size, maxSize, streamEndianness);
|
size, maxSize, streamEndianness);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization"
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
" error!" << std::endl;
|
sif::warning << "LocalPoolDataSetBase::serializeLocalPoolIds: "
|
||||||
|
<< "Serialization error!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("LocalPoolDataSetBase::serializeLocalPoolIds: "
|
||||||
|
"Serialization error!\n\r");
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,8 +237,13 @@ ReturnValue_t LocalPoolDataSetBase::serialize(uint8_t **buffer, size_t *size,
|
|||||||
|
|
||||||
void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const {
|
void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const {
|
||||||
if(position > 7) {
|
if(position > 7) {
|
||||||
sif::debug << "Pool Raw Access: Bit setting invalid position"
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "LocalPoolDataSetBase::bitSetter: Invalid position!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("LocalPoolDataSetBase::bitSetter: "
|
||||||
|
"Invalid position!\n\r");
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||||
@ -236,14 +274,10 @@ void LocalPoolDataSetBase::initializePeriodicHelper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setChanged(bool changed) {
|
void LocalPoolDataSetBase::setChanged(bool changed) {
|
||||||
// TODO: Make this configurable?
|
|
||||||
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
|
||||||
this->changed = changed;
|
this->changed = changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocalPoolDataSetBase::hasChanged() const {
|
bool LocalPoolDataSetBase::hasChanged() const {
|
||||||
// TODO: Make this configurable?
|
|
||||||
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,8 +288,10 @@ sid_t LocalPoolDataSetBase::getSid() const {
|
|||||||
bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
|
bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
|
||||||
uint8_t position) const {
|
uint8_t position) const {
|
||||||
if(position > 7) {
|
if(position > 7) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Pool Raw Access: Bit setting invalid position"
|
sif::debug << "Pool Raw Access: Bit setting invalid position"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||||
@ -263,12 +299,10 @@ bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool LocalPoolDataSetBase::isValid() const {
|
bool LocalPoolDataSetBase::isValid() const {
|
||||||
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 5);
|
|
||||||
return this->valid;
|
return this->valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
|
void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
|
||||||
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, 5);
|
|
||||||
if(setEntriesRecursively) {
|
if(setEntriesRecursively) {
|
||||||
for(size_t idx = 0; idx < this->getFillCount(); idx++) {
|
for(size_t idx = 0; idx < this->getFillCount(); idx++) {
|
||||||
registeredVariables[idx] -> setValid(valid);
|
registeredVariables[idx] -> setValid(valid);
|
||||||
@ -276,3 +310,10 @@ void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
|
|||||||
}
|
}
|
||||||
this->valid = valid;
|
this->valid = valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_id_t LocalPoolDataSetBase::getCreatorObjectId() {
|
||||||
|
if(poolManager != nullptr) {
|
||||||
|
return poolManager->getCreatorObjectId();
|
||||||
|
}
|
||||||
|
return objects::NO_OBJECT;
|
||||||
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
||||||
|
|
||||||
#include "HasLocalDataPoolIF.h"
|
|
||||||
#include "MarkChangedIF.h"
|
#include "MarkChangedIF.h"
|
||||||
|
#include "localPoolDefinitions.h"
|
||||||
|
|
||||||
#include "../datapool/DataSetIF.h"
|
#include "../datapool/DataSetIF.h"
|
||||||
#include "../datapool/PoolDataSetBase.h"
|
#include "../datapool/PoolDataSetBase.h"
|
||||||
#include "../serialize/SerializeIF.h"
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class LocalDataPoolManager;
|
class LocalDataPoolManager;
|
||||||
|
class HasLocalDataPoolIF;
|
||||||
class PeriodicHousekeepingHelper;
|
class PeriodicHousekeepingHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,9 +41,10 @@ class PeriodicHousekeepingHelper;
|
|||||||
*
|
*
|
||||||
* @ingroup data_pool
|
* @ingroup data_pool
|
||||||
*/
|
*/
|
||||||
class LocalPoolDataSetBase: public PoolDataSetBase,
|
class LocalPoolDataSetBase:
|
||||||
|
public PoolDataSetBase,
|
||||||
public MarkChangedIF {
|
public MarkChangedIF {
|
||||||
friend class LocalDataPoolManager;
|
friend class LocalPoolDataSetAttorney;
|
||||||
friend class PeriodicHousekeepingHelper;
|
friend class PeriodicHousekeepingHelper;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -54,11 +55,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
||||||
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
||||||
const size_t maxNumberOfVariables, bool noPeriodicHandling = false);
|
const size_t maxNumberOfVariables, bool periodicHandling = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for users of local pool data.
|
* @brief Constructor for users of the local pool data, which need
|
||||||
|
* to access data created by one (!) HK manager.
|
||||||
* @details
|
* @details
|
||||||
|
* Unlike the first constructor, no component for periodic handling
|
||||||
|
* will be initiated.
|
||||||
* @param sid Unique identifier of dataset consisting of object ID and
|
* @param sid Unique identifier of dataset consisting of object ID and
|
||||||
* set ID.
|
* set ID.
|
||||||
* @param registeredVariablesArray
|
* @param registeredVariablesArray
|
||||||
@ -67,6 +71,28 @@ public:
|
|||||||
LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray,
|
LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray,
|
||||||
const size_t maxNumberOfVariables);
|
const size_t maxNumberOfVariables);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Simple constructor, if the dataset is not the owner by
|
||||||
|
* a class with a HK manager.
|
||||||
|
* @details
|
||||||
|
* This constructor won't create components required for periodic handling
|
||||||
|
* and it also won't try to deduce the HK manager because no SID is
|
||||||
|
* supplied. This function should therefore be called by classes which need
|
||||||
|
* to access pool variables from different creators.
|
||||||
|
*
|
||||||
|
* If the class is intended to access pool variables from different
|
||||||
|
* creators, the third argument should be set to true. The mutex
|
||||||
|
* properties can be set with #setReadCommitProtectionBehaviour .
|
||||||
|
* @param registeredVariablesArray
|
||||||
|
* @param maxNumberOfVariables
|
||||||
|
* @param protectEveryReadCommitCall If the pool variables are created by
|
||||||
|
* multiple creators, this flag can be set to protect all read and
|
||||||
|
* commit calls separately.
|
||||||
|
*/
|
||||||
|
LocalPoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||||
|
const size_t maxNumberOfVariables,
|
||||||
|
bool protectEveryReadCommitCall = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The destructor automatically manages writing the valid
|
* @brief The destructor automatically manages writing the valid
|
||||||
* information of variables.
|
* information of variables.
|
||||||
@ -126,9 +152,11 @@ public:
|
|||||||
void setChanged(bool changed) override;
|
void setChanged(bool changed) override;
|
||||||
bool hasChanged() const override;
|
bool hasChanged() const override;
|
||||||
|
|
||||||
|
object_id_t getCreatorObjectId();
|
||||||
protected:
|
protected:
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
MutexIF* mutex = nullptr;
|
//! This mutex is used if the data is created by one object only.
|
||||||
|
MutexIF* mutexIfSingleDataCreator = nullptr;
|
||||||
|
|
||||||
bool diagnostic = false;
|
bool diagnostic = false;
|
||||||
void setDiagnostic(bool diagnostics);
|
void setDiagnostic(bool diagnostics);
|
||||||
@ -172,7 +200,9 @@ protected:
|
|||||||
* @details
|
* @details
|
||||||
* It makes use of the lockDataPool method offered by the DataPool class.
|
* It makes use of the lockDataPool method offered by the DataPool class.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t lockDataPool(uint32_t timeoutMs) override;
|
ReturnValue_t lockDataPool(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t timeoutMs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a small helper function to facilitate
|
* @brief This is a small helper function to facilitate
|
||||||
* unlocking the global data pool
|
* unlocking the global data pool
|
||||||
@ -181,8 +211,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t unlockDataPool() override;
|
ReturnValue_t unlockDataPool() override;
|
||||||
|
|
||||||
LocalDataPoolManager* hkManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set n-th bit of a byte, with n being the position from 0
|
* Set n-th bit of a byte, with n being the position from 0
|
||||||
* (most significant bit) to 7 (least significant bit)
|
* (most significant bit) to 7 (least significant bit)
|
||||||
@ -191,6 +219,7 @@ protected:
|
|||||||
bool bitGetter(const uint8_t* byte, uint8_t position) const;
|
bool bitGetter(const uint8_t* byte, uint8_t position) const;
|
||||||
|
|
||||||
PeriodicHousekeepingHelper* periodicHelper = nullptr;
|
PeriodicHousekeepingHelper* periodicHelper = nullptr;
|
||||||
|
LocalDataPoolManager* poolManager = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,40 +1,58 @@
|
|||||||
#include "LocalPoolObjectBase.h"
|
#include "LocalPoolObjectBase.h"
|
||||||
|
#include "LocalDataPoolManager.h"
|
||||||
|
#include "internal/HasLocalDpIFUserAttorney.h"
|
||||||
|
#include "HasLocalDataPoolIF.h"
|
||||||
|
|
||||||
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId,
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
|
|
||||||
pool_rwm_t setReadWriteMode): localPoolId(poolId),
|
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
||||||
readWriteMode(setReadWriteMode) {
|
DataSetIF* dataSet, pool_rwm_t setReadWriteMode):
|
||||||
|
localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
||||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
||||||
<< "which is the NO_PARAMETER value!" << std::endl;
|
<< "which is the NO_PARAMETER value!" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool "
|
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool "
|
||||||
<< "owner is a invalid!" << std::endl;
|
<< "owner is a invalid!" << std::endl;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
AccessPoolManagerIF* poolManAccessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
||||||
|
hkManager = poolManAccessor->getHkManagerHandle();
|
||||||
|
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
dataSet->registerVariable(this);
|
dataSet->registerVariable(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF *dataSet,
|
||||||
DataSetIF *dataSet, pool_rwm_t setReadWriteMode): localPoolId(poolId),
|
pool_rwm_t setReadWriteMode):
|
||||||
readWriteMode(setReadWriteMode) {
|
localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
||||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
||||||
<< "which is the NO_PARAMETER value!" << std::endl;
|
<< "which is the NO_PARAMETER value!" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
HasLocalDataPoolIF* hkOwner =
|
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
||||||
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
|
||||||
if(hkOwner == nullptr) {
|
if(hkOwner == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPoolVariable: The supplied pool owner did not "
|
sif::error << "LocalPoolVariable: The supplied pool owner did not "
|
||||||
<< "implement the correct interface"
|
<< "implement the correct interface"
|
||||||
<< " HasLocalDataPoolIF!" << std::endl;
|
<< " HasLocalDataPoolIF!" << std::endl;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hkManager = hkOwner->getHkManagerHandle();
|
|
||||||
|
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
||||||
|
if(accessor != nullptr) {
|
||||||
|
hkManager = accessor->getHkManagerHandle();
|
||||||
|
}
|
||||||
|
|
||||||
if(dataSet != nullptr) {
|
if(dataSet != nullptr) {
|
||||||
dataSet->registerVariable(this);
|
dataSet->registerVariable(this);
|
||||||
}
|
}
|
||||||
@ -71,3 +89,42 @@ bool LocalPoolObjectBase::hasChanged() const {
|
|||||||
void LocalPoolObjectBase::setReadWriteMode(pool_rwm_t newReadWriteMode) {
|
void LocalPoolObjectBase::setReadWriteMode(pool_rwm_t newReadWriteMode) {
|
||||||
this->readWriteMode = newReadWriteMode;
|
this->readWriteMode = newReadWriteMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalPoolObjectBase::reportReadCommitError(const char* variableType,
|
||||||
|
ReturnValue_t error, bool read, object_id_t objectId, lp_id_t lpId) {
|
||||||
|
#if FSFW_DISABLE_PRINTOUT == 0
|
||||||
|
const char* type = nullptr;
|
||||||
|
if(read) {
|
||||||
|
type = "read";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
type = "commit";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* errMsg = nullptr;
|
||||||
|
if(error == localpool::POOL_ENTRY_NOT_FOUND) {
|
||||||
|
errMsg = "Pool entry not found";
|
||||||
|
}
|
||||||
|
else if(error == localpool::POOL_ENTRY_TYPE_CONFLICT) {
|
||||||
|
errMsg = "Pool entry type conflict";
|
||||||
|
}
|
||||||
|
else if(error == PoolVariableIF::INVALID_READ_WRITE_MODE) {
|
||||||
|
errMsg = "Pool variable wrong read-write mode";
|
||||||
|
}
|
||||||
|
else if(error == PoolVariableIF::INVALID_POOL_ENTRY) {
|
||||||
|
errMsg = "Pool entry invalid";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errMsg = "Unknown error code";
|
||||||
|
}
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << variableType << ": " << type << " call | " << errMsg << " | Owner: 0x"
|
||||||
|
<< std::hex << std::setw(8) << std::setfill('0') << objectId << std::dec
|
||||||
|
<< " LPID: " << lpId << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("%s: %s call | %s | Owner: 0x%08x LPID: %lu\n",
|
||||||
|
variableType, type, errMsg, objectId, lpId);
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
#endif /* FSFW_DISABLE_PRINTOUT == 0 */
|
||||||
|
}
|
||||||
|
@ -2,10 +2,20 @@
|
|||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_
|
||||||
|
|
||||||
#include "MarkChangedIF.h"
|
#include "MarkChangedIF.h"
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
#include "localPoolDefinitions.h"
|
||||||
|
|
||||||
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
|
class LocalDataPoolManager;
|
||||||
|
class DataSetIF;
|
||||||
|
class HasLocalDataPoolIF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class serves as a non-template base for pool objects like pool variables
|
||||||
|
* or pool vectors.
|
||||||
|
*/
|
||||||
class LocalPoolObjectBase: public PoolVariableIF,
|
class LocalPoolObjectBase: public PoolVariableIF,
|
||||||
public HasReturnvaluesIF,
|
public HasReturnvaluesIF,
|
||||||
public MarkChangedIF {
|
public MarkChangedIF {
|
||||||
@ -54,10 +64,10 @@ protected:
|
|||||||
ReadWriteMode_t readWriteMode = pool_rwm_t::VAR_READ_WRITE;
|
ReadWriteMode_t readWriteMode = pool_rwm_t::VAR_READ_WRITE;
|
||||||
|
|
||||||
//! @brief Pointer to the class which manages the HK pool.
|
//! @brief Pointer to the class which manages the HK pool.
|
||||||
LocalDataPoolManager* hkManager;
|
LocalDataPoolManager* hkManager = nullptr;
|
||||||
|
|
||||||
|
void reportReadCommitError(const char* variableType,
|
||||||
|
ReturnValue_t error, bool read, object_id_t objectId, lp_id_t lpId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_ */
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_ */
|
||||||
|
@ -4,9 +4,12 @@
|
|||||||
#include "LocalPoolObjectBase.h"
|
#include "LocalPoolObjectBase.h"
|
||||||
#include "HasLocalDataPoolIF.h"
|
#include "HasLocalDataPoolIF.h"
|
||||||
#include "LocalDataPoolManager.h"
|
#include "LocalDataPoolManager.h"
|
||||||
|
#include "AccessLocalPoolF.h"
|
||||||
|
#include "internal/LocalDpManagerAttorney.h"
|
||||||
|
|
||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
#include "../datapool/DataSetIF.h"
|
#include "../datapool/DataSetIF.h"
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
@ -105,7 +108,9 @@ public:
|
|||||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
ReturnValue_t read(dur_millis_t lockTimeout = MutexIF::BLOCKING) override;
|
ReturnValue_t read(MutexIF::TimeoutType timeoutType =
|
||||||
|
MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20) override;
|
||||||
/**
|
/**
|
||||||
* @brief The commit call copies the array values back to the data pool.
|
* @brief The commit call copies the array values back to the data pool.
|
||||||
* @details
|
* @details
|
||||||
@ -115,8 +120,21 @@ public:
|
|||||||
* It is recommended to use DataSets to read and commit multiple variables
|
* It is recommended to use DataSets to read and commit multiple variables
|
||||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t commit(dur_millis_t lockTimeout = MutexIF::BLOCKING) override;
|
ReturnValue_t commit(MutexIF::TimeoutType timeoutType =
|
||||||
|
MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This commit function can be used to set the pool variable valid
|
||||||
|
* as well.
|
||||||
|
* @param setValid
|
||||||
|
* @param timeoutType
|
||||||
|
* @param timeoutMs
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReturnValue_t commit(bool setValid, MutexIF::TimeoutType timeoutType =
|
||||||
|
MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20);
|
||||||
|
|
||||||
LocalPoolVariable<T> &operator=(const T& newValue);
|
LocalPoolVariable<T> &operator=(const T& newValue);
|
||||||
LocalPoolVariable<T> &operator=(const LocalPoolVariable<T>& newPoolVariable);
|
LocalPoolVariable<T> &operator=(const LocalPoolVariable<T>& newPoolVariable);
|
||||||
@ -157,12 +175,12 @@ protected:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t commitWithoutLock() override;
|
ReturnValue_t commitWithoutLock() override;
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// std::ostream is the type for object std::cout
|
// std::ostream is the type for object std::cout
|
||||||
template <typename U>
|
template <typename U>
|
||||||
friend std::ostream& operator<< (std::ostream &out,
|
friend std::ostream& operator<< (std::ostream &out,
|
||||||
const LocalPoolVariable<U> &var);
|
const LocalPoolVariable<U> &var);
|
||||||
|
#endif
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "LocalPoolVariable.tpp"
|
#include "LocalPoolVariable.tpp"
|
||||||
|
@ -11,78 +11,104 @@ inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner,
|
|||||||
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
|
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner,
|
||||||
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||||
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF *dataSet,
|
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId,
|
||||||
pool_rwm_t setReadWriteMode):
|
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||||
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
|
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
|
||||||
dataSet, setReadWriteMode){}
|
dataSet, setReadWriteMode){}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::read(dur_millis_t lockTimeout) {
|
inline ReturnValue_t LocalPoolVariable<T>::read(
|
||||||
MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
lockTimeout);
|
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
||||||
return readWithoutLock();
|
return readWithoutLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
|
inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
|
||||||
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||||
sif::debug << "LocalPoolVar: Invalid read write "
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
"mode for read() call." << std::endl;
|
reportReadCommitError("LocalPoolVector",
|
||||||
|
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
|
||||||
|
localPoolId);
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
|
||||||
if(result != RETURN_OK and poolEntry != nullptr) {
|
&poolEntry);
|
||||||
sif::error << "PoolVector: Read of local pool variable of object "
|
//ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
||||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
if(result != RETURN_OK) {
|
||||||
hkManager->getOwner() << " and lp ID 0x" << localPoolId <<
|
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
|
||||||
std::dec << " failed.\n" << std::flush;
|
reportReadCommitError("LocalPoolVariable", result,
|
||||||
|
false, ownerObjectId, localPoolId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
this->value = *(poolEntry->address);
|
|
||||||
this->valid = poolEntry->valid;
|
// Actually this should never happen..
|
||||||
|
// if(poolEntry->address == nullptr) {
|
||||||
|
// result = PoolVariableIF::INVALID_POOL_ENTRY;
|
||||||
|
// object_id_t ownerObjectId = hkManager->getOwner()->getObjectId();
|
||||||
|
// reportReadCommitError("LocalPoolVariable", result,
|
||||||
|
// false, ownerObjectId, localPoolId);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
this->value = *(poolEntry->getDataPtr());
|
||||||
|
this->valid = poolEntry->getValid();
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::commit(dur_millis_t lockTimeout) {
|
inline ReturnValue_t LocalPoolVariable<T>::commit(bool setValid,
|
||||||
MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
lockTimeout);
|
this->setValid(setValid);
|
||||||
|
return commit(timeoutType, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline ReturnValue_t LocalPoolVariable<T>::commit(
|
||||||
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
|
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
||||||
return commitWithoutLock();
|
return commitWithoutLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
|
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
|
||||||
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
||||||
sif::debug << "LocalPoolVar: Invalid read write "
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
"mode for commit() call." << std::endl;
|
reportReadCommitError("LocalPoolVector",
|
||||||
|
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
|
||||||
|
localPoolId);
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
//ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
||||||
|
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
|
||||||
|
&poolEntry);
|
||||||
if(result != RETURN_OK) {
|
if(result != RETURN_OK) {
|
||||||
sif::error << "PoolVector: Read of local pool variable of object "
|
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
|
||||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
reportReadCommitError("LocalPoolVariable", result,
|
||||||
hkManager->getOwner() << " and lp ID 0x" << localPoolId <<
|
false, ownerObjectId, localPoolId);
|
||||||
std::dec << " failed.\n" << std::flush;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
*(poolEntry->address) = this->value;
|
|
||||||
poolEntry->valid = this->valid;
|
*(poolEntry->getDataPtr()) = this->value;
|
||||||
|
poolEntry->setValid(this->valid);
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::serialize(uint8_t** buffer, size_t* size,
|
inline ReturnValue_t LocalPoolVariable<T>::serialize(uint8_t** buffer,
|
||||||
const size_t max_size, SerializeIF::Endianness streamEndianness) const {
|
size_t* size, const size_t max_size,
|
||||||
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
return SerializeAdapter::serialize(&value,
|
return SerializeAdapter::serialize(&value,
|
||||||
buffer, size ,max_size, streamEndianness);
|
buffer, size ,max_size, streamEndianness);
|
||||||
}
|
}
|
||||||
@ -98,12 +124,14 @@ inline ReturnValue_t LocalPoolVariable<T>::deSerialize(const uint8_t** buffer,
|
|||||||
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::ostream& operator<< (std::ostream &out,
|
inline std::ostream& operator<< (std::ostream &out,
|
||||||
const LocalPoolVariable<T> &var) {
|
const LocalPoolVariable<T> &var) {
|
||||||
out << var.value;
|
out << var.value;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline LocalPoolVariable<T>::operator T() const {
|
inline LocalPoolVariable<T>::operator T() const {
|
||||||
@ -111,7 +139,8 @@ inline LocalPoolVariable<T>::operator T() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline LocalPoolVariable<T> & LocalPoolVariable<T>::operator=(const T& newValue) {
|
inline LocalPoolVariable<T> & LocalPoolVariable<T>::operator=(
|
||||||
|
const T& newValue) {
|
||||||
value = newValue;
|
value = newValue;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -124,7 +153,8 @@ inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator =(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool LocalPoolVariable<T>::operator ==(const LocalPoolVariable<T> &other) const {
|
inline bool LocalPoolVariable<T>::operator ==(
|
||||||
|
const LocalPoolVariable<T> &other) const {
|
||||||
return this->value == other.value;
|
return this->value == other.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +165,8 @@ inline bool LocalPoolVariable<T>::operator ==(const T &other) const {
|
|||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool LocalPoolVariable<T>::operator !=(const LocalPoolVariable<T> &other) const {
|
inline bool LocalPoolVariable<T>::operator !=(
|
||||||
|
const LocalPoolVariable<T> &other) const {
|
||||||
return not (*this == other);
|
return not (*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +177,8 @@ inline bool LocalPoolVariable<T>::operator !=(const T &other) const {
|
|||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool LocalPoolVariable<T>::operator <(const LocalPoolVariable<T> &other) const {
|
inline bool LocalPoolVariable<T>::operator <(
|
||||||
|
const LocalPoolVariable<T> &other) const {
|
||||||
return this->value < other.value;
|
return this->value < other.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +189,8 @@ inline bool LocalPoolVariable<T>::operator <(const T &other) const {
|
|||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool LocalPoolVariable<T>::operator >(const LocalPoolVariable<T> &other) const {
|
inline bool LocalPoolVariable<T>::operator >(
|
||||||
|
const LocalPoolVariable<T> &other) const {
|
||||||
return not (*this < other);
|
return not (*this < other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
|
||||||
|
|
||||||
#include "LocalPoolObjectBase.h"
|
#include "LocalPoolObjectBase.h"
|
||||||
|
#include "internal/LocalDpManagerAttorney.h"
|
||||||
|
|
||||||
#include "../datapool/DataSetIF.h"
|
#include "../datapool/DataSetIF.h"
|
||||||
#include "../datapool/PoolEntry.h"
|
#include "../datapool/PoolEntry.h"
|
||||||
#include "../datapool/PoolVariableIF.h"
|
#include "../datapool/PoolVariableIF.h"
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
#include "../datapoollocal/LocalDataPoolManager.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,8 +102,8 @@ public:
|
|||||||
return vectorSize;
|
return vectorSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator [](int i);
|
T& operator [](size_t i);
|
||||||
const T &operator [](int i) const;
|
const T &operator [](size_t i) const;
|
||||||
|
|
||||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||||
const size_t maxSize,
|
const size_t maxSize,
|
||||||
@ -123,7 +125,10 @@ public:
|
|||||||
* It is recommended to use DataSets to read and commit multiple variables
|
* It is recommended to use DataSets to read and commit multiple variables
|
||||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override;
|
ReturnValue_t read(MutexIF::TimeoutType timeoutType =
|
||||||
|
MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The commit call copies the array values back to the data pool.
|
* @brief The commit call copies the array values back to the data pool.
|
||||||
* @details
|
* @details
|
||||||
@ -133,7 +138,17 @@ public:
|
|||||||
* It is recommended to use DataSets to read and commit multiple variables
|
* It is recommended to use DataSets to read and commit multiple variables
|
||||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
|
ReturnValue_t commit(MutexIF::TimeoutType timeoutType =
|
||||||
|
MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This commit call also sets the validity of the pool entry.
|
||||||
|
* @details
|
||||||
|
*/
|
||||||
|
ReturnValue_t commit(bool valid, MutexIF::TimeoutType timeoutType =
|
||||||
|
MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -157,12 +172,12 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// std::ostream is the type for object std::cout
|
// std::ostream is the type for object std::cout
|
||||||
template <typename U, uint16_t otherSize>
|
template <typename U, uint16_t otherSize>
|
||||||
friend std::ostream& operator<< (std::ostream &out,
|
friend std::ostream& operator<< (std::ostream &out,
|
||||||
const LocalPoolVector<U, otherSize> &var);
|
const LocalPoolVector<U, otherSize> &var);
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,86 +24,106 @@ inline LocalPoolVector<T, vectorSize>::LocalPoolVector(gp_id_t globalPoolId,
|
|||||||
dataSet, setReadWriteMode) {}
|
dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(uint32_t lockTimeout) {
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(
|
||||||
MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
lockTimeout);
|
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
||||||
return readWithoutLock();
|
return readWithoutLock();
|
||||||
}
|
}
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
||||||
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||||
sif::debug << "LocalPoolVar: Invalid read write "
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
"mode for read() call." << std::endl;
|
reportReadCommitError("LocalPoolVector",
|
||||||
|
PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId,
|
||||||
|
localPoolId);
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
|
||||||
|
&poolEntry);
|
||||||
memset(this->value, 0, vectorSize * sizeof(T));
|
memset(this->value, 0, vectorSize * sizeof(T));
|
||||||
|
|
||||||
if(result != RETURN_OK) {
|
if(result != RETURN_OK) {
|
||||||
sif::error << "PoolVector: Read of local pool variable of object "
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
reportReadCommitError("LocalPoolVector", result, true, targetObjectId,
|
||||||
hkManager->getOwner() << "and lp ID 0x" << localPoolId <<
|
localPoolId);
|
||||||
std::dec << " failed." << std::endl;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
std::memcpy(this->value, poolEntry->address, poolEntry->getByteSize());
|
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
|
||||||
this->valid = poolEntry->valid;
|
this->valid = poolEntry->getValid();
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, uint16_t vectorSize>
|
||||||
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(bool valid,
|
||||||
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
|
this->setValid(valid);
|
||||||
|
return commit(timeoutType, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(
|
||||||
uint32_t lockTimeout) {
|
MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
|
MutexHelper(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
||||||
lockTimeout);
|
|
||||||
return commitWithoutLock();
|
return commitWithoutLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
|
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
|
||||||
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
||||||
sif::debug << "LocalPoolVar: Invalid read write "
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
"mode for commit() call." << std::endl;
|
reportReadCommitError("LocalPoolVector",
|
||||||
|
PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId,
|
||||||
|
localPoolId);
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
}
|
}
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId,
|
||||||
|
&poolEntry);
|
||||||
if(result != RETURN_OK) {
|
if(result != RETURN_OK) {
|
||||||
sif::error << "PoolVector: Read of local pool variable of object "
|
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
||||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
reportReadCommitError("LocalPoolVector", result, false, targetObjectId,
|
||||||
hkManager->getOwner() << " and lp ID 0x" << localPoolId <<
|
localPoolId);
|
||||||
std::dec << " failed.\n" << std::flush;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
std::memcpy(poolEntry->address, this->value, poolEntry->getByteSize());
|
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
|
||||||
poolEntry->valid = this->valid;
|
poolEntry->setValid(this->valid);
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline T& LocalPoolVector<T, vectorSize>::operator [](int i) {
|
inline T& LocalPoolVector<T, vectorSize>::operator [](size_t i) {
|
||||||
if(i <= vectorSize) {
|
if(i < vectorSize) {
|
||||||
return value[i];
|
return value[i];
|
||||||
}
|
}
|
||||||
// If this happens, I have to set some value. I consider this
|
// If this happens, I have to set some value. I consider this
|
||||||
// a configuration error, but I wont exit here.
|
// a configuration error, but I wont exit here.
|
||||||
sif::error << "LocalPoolVector: Invalid index. Setting or returning"
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
|
||||||
" last value!" << std::endl;
|
" last value!" << std::endl;
|
||||||
return value[i];
|
#else
|
||||||
|
sif::printWarning("LocalPoolVector: Invalid index. Setting or returning"
|
||||||
|
" last value!\n");
|
||||||
|
#endif
|
||||||
|
return value[vectorSize - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline const T& LocalPoolVector<T, vectorSize>::operator [](int i) const {
|
inline const T& LocalPoolVector<T, vectorSize>::operator [](size_t i) const {
|
||||||
if(i <= vectorSize) {
|
if(i < vectorSize) {
|
||||||
return value[i];
|
return value[i];
|
||||||
}
|
}
|
||||||
// If this happens, I have to set some value. I consider this
|
// If this happens, I have to set some value. I consider this
|
||||||
// a configuration error, but I wont exit here.
|
// a configuration error, but I wont exit here.
|
||||||
sif::error << "LocalPoolVector: Invalid index. Setting or returning"
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
|
||||||
" last value!" << std::endl;
|
" last value!" << std::endl;
|
||||||
return value[i];
|
#else
|
||||||
|
sif::printWarning("LocalPoolVector: Invalid index. Setting or returning"
|
||||||
|
" last value!\n");
|
||||||
|
#endif
|
||||||
|
return value[vectorSize - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
@ -141,6 +161,7 @@ inline ReturnValue_t LocalPoolVector<T, vectorSize>::deSerialize(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
template<typename T, uint16_t vectorSize>
|
template<typename T, uint16_t vectorSize>
|
||||||
inline std::ostream& operator<< (std::ostream &out,
|
inline std::ostream& operator<< (std::ostream &out,
|
||||||
const LocalPoolVector<T, vectorSize> &var) {
|
const LocalPoolVector<T, vectorSize> &var) {
|
||||||
@ -154,5 +175,6 @@ inline std::ostream& operator<< (std::ostream &out,
|
|||||||
out << "]";
|
out << "]";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_TPP_ */
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_TPP_ */
|
||||||
|
83
datapoollocal/ProvidesDataPoolSubscriptionIF.h
Normal file
83
datapoollocal/ProvidesDataPoolSubscriptionIF.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||||
|
|
||||||
|
#include "localPoolDefinitions.h"
|
||||||
|
#include "../ipc/messageQueueDefinitions.h"
|
||||||
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ProvidesDataPoolSubscriptionIF {
|
||||||
|
public:
|
||||||
|
virtual ~ProvidesDataPoolSubscriptionIF(){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Subscribe for the generation of periodic packets.
|
||||||
|
* @details
|
||||||
|
* This subscription mechanism will generally be used by the data creator
|
||||||
|
* to generate housekeeping packets which are downlinked directly.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t subscribeForPeriodicPacket(sid_t sid,
|
||||||
|
bool enableReporting,
|
||||||
|
float collectionInterval, bool isDiagnostics,
|
||||||
|
object_id_t packetDestination) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Subscribe for the generation of packets if the dataset
|
||||||
|
* is marked as changed.
|
||||||
|
* @details
|
||||||
|
* This subscription mechanism will generally be used by the data creator.
|
||||||
|
* @param sid
|
||||||
|
* @param isDiagnostics
|
||||||
|
* @param packetDestination
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t subscribeForUpdatePackets(sid_t sid,
|
||||||
|
bool reportingEnabled,
|
||||||
|
bool isDiagnostics,
|
||||||
|
object_id_t packetDestination) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Subscribe for a notification message which will be sent
|
||||||
|
* if a dataset has changed.
|
||||||
|
* @details
|
||||||
|
* This subscription mechanism will generally be used internally by
|
||||||
|
* other software components.
|
||||||
|
* @param setId Set ID of the set to receive update messages from.
|
||||||
|
* @param destinationObject
|
||||||
|
* @param targetQueueId
|
||||||
|
* @param generateSnapshot If this is set to true, a copy of the current
|
||||||
|
* data with a timestamp will be generated and sent via message.
|
||||||
|
* Otherwise, only an notification message is sent.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t subscribeForSetUpdateMessages(const uint32_t setId,
|
||||||
|
object_id_t destinationObject,
|
||||||
|
MessageQueueId_t targetQueueId,
|
||||||
|
bool generateSnapshot) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Subscribe for an notification message which will be sent if a
|
||||||
|
* pool variable has changed.
|
||||||
|
* @details
|
||||||
|
* This subscription mechanism will generally be used internally by
|
||||||
|
* other software components.
|
||||||
|
* @param localPoolId Pool ID of the pool variable
|
||||||
|
* @param destinationObject
|
||||||
|
* @param targetQueueId
|
||||||
|
* @param generateSnapshot If this is set to true, a copy of the current
|
||||||
|
* data with a timestamp will be generated and sent via message.
|
||||||
|
* Otherwise, only an notification message is sent.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t subscribeForVariableUpdateMessages(
|
||||||
|
const lp_id_t localPoolId,
|
||||||
|
object_id_t destinationObject,
|
||||||
|
MessageQueueId_t targetQueueId,
|
||||||
|
bool generateSnapshot) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_ */
|
@ -6,7 +6,15 @@
|
|||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class SharedLocalDataSet: public SystemObject,
|
/**
|
||||||
|
* This local dataset variation can be used if the dataset is used concurrently across
|
||||||
|
* multiple threads. It provides a lock in addition to all other functionalities provided
|
||||||
|
* by the LocalPoolDataSetBase class.
|
||||||
|
*
|
||||||
|
* TODO: override and protect read, commit and some other calls used by pool manager.
|
||||||
|
*/
|
||||||
|
class SharedLocalDataSet:
|
||||||
|
public SystemObject,
|
||||||
public LocalPoolDataSetBase,
|
public LocalPoolDataSetBase,
|
||||||
public SharedDataSetIF {
|
public SharedDataSetIF {
|
||||||
public:
|
public:
|
||||||
|
@ -27,9 +27,8 @@ public:
|
|||||||
* @param hkOwner
|
* @param hkOwner
|
||||||
* @param setId
|
* @param setId
|
||||||
*/
|
*/
|
||||||
StaticLocalDataSet(HasLocalDataPoolIF* hkOwner,
|
StaticLocalDataSet(HasLocalDataPoolIF* hkOwner, uint32_t setId):
|
||||||
uint32_t setId): LocalPoolDataSetBase(hkOwner, setId, nullptr,
|
LocalPoolDataSetBase(hkOwner, setId, nullptr, NUM_VARIABLES) {
|
||||||
NUM_VARIABLES) {
|
|
||||||
this->setContainer(poolVarList.data());
|
this->setContainer(poolVarList.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +37,7 @@ public:
|
|||||||
* @param hkOwner
|
* @param hkOwner
|
||||||
* @param setId
|
* @param setId
|
||||||
*/
|
*/
|
||||||
StaticLocalDataSet(sid_t sid): LocalPoolDataSetBase(sid, nullptr,
|
StaticLocalDataSet(sid_t sid): LocalPoolDataSetBase(sid, nullptr, NUM_VARIABLES) {
|
||||||
NUM_VARIABLES) {
|
|
||||||
this->setContainer(poolVarList.data());
|
this->setContainer(poolVarList.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
datapoollocal/internal/CMakeLists.txt
Normal file
5
datapoollocal/internal/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
target_sources(${LIB_FSFW_NAME}
|
||||||
|
PRIVATE
|
||||||
|
HasLocalDpIFUserAttorney.cpp
|
||||||
|
HasLocalDpIFManagerAttorney.cpp
|
||||||
|
)
|
18
datapoollocal/internal/HasLocalDpIFManagerAttorney.cpp
Normal file
18
datapoollocal/internal/HasLocalDpIFManagerAttorney.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "HasLocalDpIFManagerAttorney.h"
|
||||||
|
#include "../LocalPoolObjectBase.h"
|
||||||
|
#include "../LocalPoolDataSetBase.h"
|
||||||
|
#include "../HasLocalDataPoolIF.h"
|
||||||
|
|
||||||
|
LocalPoolDataSetBase* HasLocalDpIFManagerAttorney::getDataSetHandle(HasLocalDataPoolIF* clientIF,
|
||||||
|
sid_t sid) {
|
||||||
|
return clientIF->getDataSetHandle(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalPoolObjectBase* HasLocalDpIFManagerAttorney::getPoolObjectHandle(HasLocalDataPoolIF* clientIF,
|
||||||
|
lp_id_t localPoolId) {
|
||||||
|
return clientIF->getPoolObjectHandle(localPoolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_t HasLocalDpIFManagerAttorney::getObjectId(HasLocalDataPoolIF* clientIF) {
|
||||||
|
return clientIF->getObjectId();
|
||||||
|
}
|
22
datapoollocal/internal/HasLocalDpIFManagerAttorney.h
Normal file
22
datapoollocal/internal/HasLocalDpIFManagerAttorney.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_
|
||||||
|
|
||||||
|
#include "../localPoolDefinitions.h"
|
||||||
|
|
||||||
|
class HasLocalDataPoolIF;
|
||||||
|
class LocalPoolDataSetBase;
|
||||||
|
class LocalPoolObjectBase;
|
||||||
|
|
||||||
|
class HasLocalDpIFManagerAttorney {
|
||||||
|
|
||||||
|
static LocalPoolDataSetBase* getDataSetHandle(HasLocalDataPoolIF* clientIF, sid_t sid);
|
||||||
|
|
||||||
|
static LocalPoolObjectBase* getPoolObjectHandle(HasLocalDataPoolIF* clientIF,
|
||||||
|
lp_id_t localPoolId);
|
||||||
|
|
||||||
|
static object_id_t getObjectId(HasLocalDataPoolIF* clientIF);
|
||||||
|
|
||||||
|
friend class LocalDataPoolManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_ */
|
7
datapoollocal/internal/HasLocalDpIFUserAttorney.cpp
Normal file
7
datapoollocal/internal/HasLocalDpIFUserAttorney.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "HasLocalDpIFUserAttorney.h"
|
||||||
|
#include "../AccessLocalPoolF.h"
|
||||||
|
#include "../HasLocalDataPoolIF.h"
|
||||||
|
|
||||||
|
AccessPoolManagerIF* HasLocalDpIFUserAttorney::getAccessorHandle(HasLocalDataPoolIF *clientIF) {
|
||||||
|
return clientIF->getAccessorHandle();
|
||||||
|
}
|
18
datapoollocal/internal/HasLocalDpIFUserAttorney.h
Normal file
18
datapoollocal/internal/HasLocalDpIFUserAttorney.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
|
||||||
|
|
||||||
|
class HasLocalDataPoolIF;
|
||||||
|
class AccessPoolManagerIF;
|
||||||
|
|
||||||
|
class HasLocalDpIFUserAttorney {
|
||||||
|
private:
|
||||||
|
|
||||||
|
static AccessPoolManagerIF* getAccessorHandle(HasLocalDataPoolIF* clientIF);
|
||||||
|
|
||||||
|
friend class LocalPoolObjectBase;
|
||||||
|
friend class LocalPoolDataSetBase;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_ */
|
32
datapoollocal/internal/LocalDpManagerAttorney.h
Normal file
32
datapoollocal/internal/LocalDpManagerAttorney.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
|
||||||
|
|
||||||
|
#include "../LocalDataPoolManager.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is a helper class implements the Attorney-Client idiom for access to
|
||||||
|
* LocalDataPoolManager internals
|
||||||
|
* @details
|
||||||
|
* This helper class provides better control over which classes are allowed to access
|
||||||
|
* LocalDataPoolManager internals in a granular and encapsulated way when compared to
|
||||||
|
* other methods like direct friend declarations. It allows these classes to use
|
||||||
|
* an explicit subset of the pool manager private/protected functions.
|
||||||
|
* See: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Friendship_and_the_Attorney-Client
|
||||||
|
*/
|
||||||
|
class LocalDpManagerAttorney {
|
||||||
|
private:
|
||||||
|
template<typename T> static ReturnValue_t fetchPoolEntry(LocalDataPoolManager& manager,
|
||||||
|
lp_id_t localPoolId, PoolEntry<T> **poolEntry) {
|
||||||
|
return manager.fetchPoolEntry(localPoolId, poolEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MutexIF* getMutexHandle(LocalDataPoolManager& manager) {
|
||||||
|
return manager.getMutexHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T> friend class LocalPoolVariable;
|
||||||
|
template<typename T, uint16_t vecSize> friend class LocalPoolVector;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_ */
|
39
datapoollocal/internal/LocalPoolDataSetAttorney.h
Normal file
39
datapoollocal/internal/LocalPoolDataSetAttorney.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_
|
||||||
|
|
||||||
|
#include "../LocalPoolDataSetBase.h"
|
||||||
|
|
||||||
|
class LocalPoolDataSetAttorney {
|
||||||
|
private:
|
||||||
|
static void setDiagnostic(LocalPoolDataSetBase& set, bool diagnostics) {
|
||||||
|
set.setDiagnostic(diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isDiagnostics(LocalPoolDataSetBase& set) {
|
||||||
|
return set.isDiagnostics();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
|
||||||
|
uint32_t minimumPeriodicIntervalMs,
|
||||||
|
bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5) {
|
||||||
|
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs, isDiagnostics,
|
||||||
|
nonDiagIntervalFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setReportingEnabled(LocalPoolDataSetBase& set, bool enabled) {
|
||||||
|
set.setReportingEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getReportingEnabled(LocalPoolDataSetBase& set) {
|
||||||
|
return set.getReportingEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PeriodicHousekeepingHelper* getPeriodicHelper(LocalPoolDataSetBase& set) {
|
||||||
|
return set.periodicHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class LocalDataPoolManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_ */
|
@ -1,10 +1,13 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCPOOLDEFINITIONS_H_
|
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCPOOLDEFINITIONS_H_
|
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_
|
||||||
|
|
||||||
#include <cstdint>
|
#include "../datapool/PoolEntryIF.h"
|
||||||
#include "../objectmanager/SystemObjectIF.h"
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include "../objectmanager/frameworkObjects.h"
|
#include "../objectmanager/frameworkObjects.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definition for local pool entries.
|
* @brief Type definition for local pool entries.
|
||||||
*/
|
*/
|
||||||
@ -12,10 +15,21 @@ using lp_id_t = uint32_t;
|
|||||||
|
|
||||||
namespace localpool {
|
namespace localpool {
|
||||||
static constexpr uint32_t INVALID_LPID = -1;
|
static constexpr uint32_t INVALID_LPID = -1;
|
||||||
|
|
||||||
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
|
||||||
|
|
||||||
|
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
|
||||||
|
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
|
||||||
|
|
||||||
|
//! This is the core data structure of the local data pools. Users should insert all desired
|
||||||
|
//! pool variables, using the std::map interface.
|
||||||
|
using DataPool = std::map<lp_id_t, PoolEntryIF*>;
|
||||||
|
using DataPoolMapIter = DataPool::iterator;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a unique identifier for data sets.
|
* Used as a unique identifier for data sets. Consists of 4 byte object ID and 4 byte set ID.
|
||||||
*/
|
*/
|
||||||
union sid_t {
|
union sid_t {
|
||||||
static constexpr uint64_t INVALID_SID = -1;
|
static constexpr uint64_t INVALID_SID = -1;
|
||||||
@ -57,7 +71,8 @@ union sid_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a global unique identifier for local pool variables.
|
* Used as a global unique identifier for local pool variables. Consists of 4 byte object ID
|
||||||
|
* and 4 byte local pool ID.
|
||||||
*/
|
*/
|
||||||
union gp_id_t {
|
union gp_id_t {
|
||||||
static constexpr uint64_t INVALID_GPID = -1;
|
static constexpr uint64_t INVALID_GPID = -1;
|
||||||
@ -90,4 +105,4 @@ union gp_id_t {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCPOOLDEFINITIONS_H_ */
|
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_ */
|
@ -1,15 +1,15 @@
|
|||||||
target_sources(${TARGET_NAME}
|
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||||
PRIVATE
|
ipc/missionMessageTypes.cpp
|
||||||
|
objects/FsfwFactory.cpp
|
||||||
|
pollingsequence/PollingSequenceFactory.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add include paths for the executable
|
# Should be added to include path
|
||||||
target_include_directories(${TARGET_NAME}
|
target_include_directories(${TARGET_NAME} PRIVATE
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add include paths for the FSFW library
|
if(NOT FSFW_CONFIG_PATH)
|
||||||
target_include_directories(${LIB_FSFW_NAME}
|
set(FSFW_CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
PUBLIC
|
endif()
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
|
@ -4,16 +4,21 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
//! Used to determine whether C++ ostreams are used
|
//! Used to determine whether C++ ostreams are used which can increase
|
||||||
//! Those can lead to code bloat.
|
//! the binary size significantly. If this is disabled,
|
||||||
|
//! the C stdio functions can be used alternatively
|
||||||
#define FSFW_CPP_OSTREAM_ENABLED 1
|
#define FSFW_CPP_OSTREAM_ENABLED 1
|
||||||
|
|
||||||
//! Reduced printout to further decrease code size
|
//! More FSFW related printouts depending on level. Useful for development.
|
||||||
//! Be careful, this also turns off most diagnostic prinouts!
|
#define FSFW_VERBOSE_LEVEL 1
|
||||||
#define FSFW_ENHANCED_PRINTOUT 0
|
|
||||||
|
|
||||||
//! Can be used to enable additional debugging printouts for developing the FSFW
|
//! Can be used to completely disable printouts, even the C stdio ones.
|
||||||
#define FSFW_PRINT_VERBOSITY_LEVEL 0
|
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0
|
||||||
|
#define FSFW_DISABLE_PRINTOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Can be used to disable the ANSI color sequences for C stdio.
|
||||||
|
#define FSFW_COLORED_OUTPUT 1
|
||||||
|
|
||||||
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
|
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
|
||||||
//! additional output which requires the translation files translateObjects
|
//! additional output which requires the translation files translateObjects
|
||||||
@ -50,6 +55,8 @@ static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
|||||||
//! simulataneously. This will increase the required RAM for
|
//! simulataneously. This will increase the required RAM for
|
||||||
//! each CSB service !
|
//! each CSB service !
|
||||||
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
|
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
|
||||||
|
|
||||||
|
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
#endif /* CONFIG_FSFWCONFIG_H_ */
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
|
|
||||||
#include "OBSWVersion.h"
|
#include "OBSWVersion.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "objects/systemObjectList.h"
|
#include "objects/systemObjectList.h"
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
#include "returnvalues/classIds.h"
|
#include "returnvalues/classIds.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
namespace config {
|
namespace config {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CONFIG_DEVICES_LOGICALADDRESSES_H_
|
#define CONFIG_DEVICES_LOGICALADDRESSES_H_
|
||||||
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
#include "../objects/systemObjectList.h"
|
#include <objects/systemObjectList.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
#include "Factory.h"
|
#include "FsfwFactory.h"
|
||||||
#include "../tmtc/apid.h"
|
#include <OBSWConfig.h>
|
||||||
#include "../tmtc/pusIds.h"
|
|
||||||
#include "../objects/systemObjectList.h"
|
|
||||||
#include "../devices/logicalAddresses.h"
|
|
||||||
#include "../devices/powerSwitcherList.h"
|
|
||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <fsfw/events/EventManager.h>
|
#include <fsfw/events/EventManager.h>
|
||||||
@ -11,24 +7,27 @@
|
|||||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
#include <internalError/InternalErrorReporter.h>
|
#include <fsfw/internalError/InternalErrorReporter.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class should be used to create all system objects required for
|
* This function builds all system objects required for using
|
||||||
* the on-board software, using the object ID list from the configuration
|
* the FSFW. It is recommended to build all other required objects
|
||||||
* folder.
|
* in a function with an identical prototype, call this function in it and
|
||||||
|
* then pass the function to the object manager so it builds all system
|
||||||
|
* objects on software startup.
|
||||||
*
|
*
|
||||||
* The objects are registered in the internal object manager automatically.
|
* All system objects are registered in the internal object manager
|
||||||
* This is used later to add objects to tasks.
|
* automatically. The objects should be added to tasks at a later stage, using
|
||||||
|
* their objects IDs.
|
||||||
*
|
*
|
||||||
* This file also sets static framework IDs.
|
* This function also sets static framework IDs.
|
||||||
*
|
*
|
||||||
* Framework objects are created first.
|
* Framework should be created first before creating mission system objects.
|
||||||
* @ingroup init
|
* @ingroup init
|
||||||
*/
|
*/
|
||||||
void Factory::produce(void) {
|
void Factory::produceFsfwObjects(void) {
|
||||||
setStaticFrameworkObjectIds();
|
setStaticFrameworkObjectIds();
|
||||||
new EventManager(objects::EVENT_MANAGER);
|
new EventManager(objects::EVENT_MANAGER);
|
||||||
new HealthTable(objects::HEALTH_TABLE);
|
new HealthTable(objects::HEALTH_TABLE);
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef FACTORY_H_
|
#ifndef FSFWCONFIG_OBJECTS_FACTORY_H_
|
||||||
#define FACTORY_H_
|
#define FSFWCONFIG_OBJECTS_FACTORY_H_
|
||||||
|
|
||||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@ -9,9 +9,9 @@ namespace Factory {
|
|||||||
* @brief Creates all SystemObject elements which are persistent
|
* @brief Creates all SystemObject elements which are persistent
|
||||||
* during execution.
|
* during execution.
|
||||||
*/
|
*/
|
||||||
void produce();
|
void produceFsfwObjects();
|
||||||
void setStaticFrameworkObjectIds();
|
void setStaticFrameworkObjectIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* FACTORY_H_ */
|
#endif /* FSFWCONFIG_OBJECTS_FACTORY_H_ */
|
@ -15,8 +15,10 @@ ReturnValue_t pst::pollingSequenceInitDefault(
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "pst::pollingSequenceInitDefault: Sequence invalid!"
|
sif::error << "pst::pollingSequenceInitDefault: Sequence invalid!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "AcceptsDeviceResponsesIF.h"
|
#include "AcceptsDeviceResponsesIF.h"
|
||||||
#include "DeviceTmReportingWrapper.h"
|
#include "DeviceTmReportingWrapper.h"
|
||||||
|
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../objectmanager/ObjectManager.h"
|
#include "../objectmanager/ObjectManager.h"
|
||||||
#include "../storagemanager/StorageManagerIF.h"
|
#include "../storagemanager/StorageManagerIF.h"
|
||||||
#include "../thermal/ThermalComponentIF.h"
|
#include "../thermal/ThermalComponentIF.h"
|
||||||
@ -13,9 +13,6 @@
|
|||||||
#include "../subsystem/SubsystemBase.h"
|
#include "../subsystem/SubsystemBase.h"
|
||||||
#include "../datapoollocal/LocalPoolVariable.h"
|
#include "../datapoollocal/LocalPoolVariable.h"
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
|
|
||||||
object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||||
object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
|
object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
|
||||||
object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT;
|
object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT;
|
||||||
@ -27,7 +24,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
|
|||||||
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
||||||
deviceCommunicationId(deviceCommunication), comCookie(comCookie),
|
deviceCommunicationId(deviceCommunication), comCookie(comCookie),
|
||||||
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
|
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
|
||||||
actionHelper(this, nullptr), hkManager(this, nullptr),
|
actionHelper(this, nullptr), poolManager(this, nullptr),
|
||||||
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
|
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
|
||||||
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
|
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
|
||||||
switchOffWasReported(false), childTransitionDelay(5000),
|
switchOffWasReported(false), childTransitionDelay(5000),
|
||||||
@ -39,11 +36,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
|
|||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||||
if (comCookie == nullptr) {
|
if (comCookie == nullptr) {
|
||||||
sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
|
||||||
<< std::setw(8) << std::setfill('0') << this->getObjectId()
|
HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
|
||||||
<< std::dec << ": Do not pass nullptr as a cookie, consider "
|
|
||||||
<< std::setfill(' ') << "passing a dummy cookie instead!"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
if (this->fdirInstance == nullptr) {
|
if (this->fdirInstance == nullptr) {
|
||||||
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
|
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
|
||||||
@ -113,7 +107,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
|
|||||||
doGetRead();
|
doGetRead();
|
||||||
// This will be performed after datasets have been updated by the
|
// This will be performed after datasets have been updated by the
|
||||||
// custom device implementation.
|
// custom device implementation.
|
||||||
hkManager.performHkOperation();
|
poolManager.performHkOperation();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -130,24 +124,24 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
communicationInterface = objectManager->get<DeviceCommunicationIF>(
|
communicationInterface = objectManager->get<DeviceCommunicationIF>(
|
||||||
deviceCommunicationId);
|
deviceCommunicationId);
|
||||||
if (communicationInterface == nullptr) {
|
if (communicationInterface == nullptr) {
|
||||||
sif::error << "DeviceHandlerBase::initialize: Communication interface "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
||||||
"invalid." << std::endl;
|
ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
sif::error << "Make sure it is set up properly and implements"
|
"Passed communication IF invalid");
|
||||||
" DeviceCommunicationIF" << std::endl;
|
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = communicationInterface->initializeInterface(comCookie);
|
result = communicationInterface->initializeInterface(comCookie);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
sif::error << "DeviceHandlerBase::initialize: Initializing "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
||||||
"communication interface failed!" << std::endl;
|
ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
|
"ComIF initialization failed");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
if (IPCStore == nullptr) {
|
if (IPCStore == nullptr) {
|
||||||
sif::error << "DeviceHandlerBase::initialize: IPC store not set up in "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
||||||
"factory." << std::endl;
|
ObjectManagerIF::CHILD_INIT_FAILED, "IPC Store not set up");
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,10 +150,16 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
||||||
|
|
||||||
if (rawReceiver == nullptr) {
|
if (rawReceiver == nullptr) {
|
||||||
sif::error << "DeviceHandlerBase::initialize: Raw receiver object "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
"ID set but no valid object found." << std::endl;
|
"initialize", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
|
"Raw receiver object ID set but no valid object found.");
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Make sure the raw receiver object is set up properly"
|
sif::error << "Make sure the raw receiver object is set up properly"
|
||||||
" and implements AcceptsDeviceResponsesIF" << std::endl;
|
" and implements AcceptsDeviceResponsesIF" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("Make sure the raw receiver object is set up "
|
||||||
|
"properly and implements AcceptsDeviceResponsesIF\n");
|
||||||
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
defaultRawReceiver = rawReceiver->getDeviceQueue();
|
defaultRawReceiver = rawReceiver->getDeviceQueue();
|
||||||
@ -168,10 +168,16 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
if(powerSwitcherId != objects::NO_OBJECT) {
|
if(powerSwitcherId != objects::NO_OBJECT) {
|
||||||
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
|
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
|
||||||
if (powerSwitcher == nullptr) {
|
if (powerSwitcher == nullptr) {
|
||||||
sif::error << "DeviceHandlerBase::initialize: Power switcher "
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
<< "object ID set but no valid object found." << std::endl;
|
"initialize", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
sif::error << "Make sure the raw receiver object is set up properly"
|
"Power switcher set but no valid object found.");
|
||||||
<< " and implements PowerSwitchIF" << std::endl;
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "Make sure the power switcher object is set up "
|
||||||
|
<< "properly and implements PowerSwitchIF" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("Make sure the power switcher object is set up "
|
||||||
|
"properly and implements PowerSwitchIF\n");
|
||||||
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +210,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = hkManager.initialize(commandQueue);
|
result = poolManager.initialize(commandQueue);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -217,7 +223,8 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
thermalSet->heaterRequest.value =
|
thermalSet->heaterRequest.value =
|
||||||
ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||||
thermalSet->commit(PoolVariableIF::VALID);
|
thermalSet->heaterRequest.setValid(true);
|
||||||
|
thermalSet->commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -273,7 +280,7 @@ void DeviceHandlerBase::readCommandQueue() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = hkManager.handleHousekeepingMessage(&command);
|
result = poolManager.handleHousekeepingMessage(&command);
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -543,17 +550,17 @@ void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status,
|
|||||||
|
|
||||||
void DeviceHandlerBase::replyToCommand(ReturnValue_t status,
|
void DeviceHandlerBase::replyToCommand(ReturnValue_t status,
|
||||||
uint32_t parameter) {
|
uint32_t parameter) {
|
||||||
//Check if we reply to a raw command.
|
// Check if we reply to a raw command.
|
||||||
if (cookieInfo.pendingCommand->first == RAW_COMMAND_ID) {
|
if (cookieInfo.pendingCommand->first == RAW_COMMAND_ID) {
|
||||||
if (status == NO_REPLY_EXPECTED) {
|
if (status == NO_REPLY_EXPECTED) {
|
||||||
status = RETURN_OK;
|
status = RETURN_OK;
|
||||||
}
|
}
|
||||||
replyReturnvalueToCommand(status, parameter);
|
replyReturnvalueToCommand(status, parameter);
|
||||||
//Always delete data from a raw command.
|
// Always delete data from a raw command.
|
||||||
IPCStore->deleteData(storedRawData);
|
IPCStore->deleteData(storedRawData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Check if we were externally commanded.
|
// Check if we were externally commanded.
|
||||||
if (cookieInfo.pendingCommand->second.sendReplyTo != NO_COMMANDER) {
|
if (cookieInfo.pendingCommand->second.sendReplyTo != NO_COMMANDER) {
|
||||||
MessageQueueId_t queueId = cookieInfo.pendingCommand->second.sendReplyTo;
|
MessageQueueId_t queueId = cookieInfo.pendingCommand->second.sendReplyTo;
|
||||||
if (status == NO_REPLY_EXPECTED) {
|
if (status == NO_REPLY_EXPECTED) {
|
||||||
@ -568,15 +575,17 @@ void DeviceHandlerBase::replyToCommand(ReturnValue_t status,
|
|||||||
|
|
||||||
void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
|
void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
|
||||||
ReturnValue_t status) {
|
ReturnValue_t status) {
|
||||||
//No need to check if iter exists, as this is checked by callers. If someone else uses the method, add check.
|
// No need to check if iter exists, as this is checked by callers.
|
||||||
|
// If someone else uses the method, add check.
|
||||||
if (iter->second.command == deviceCommandMap.end()) {
|
if (iter->second.command == deviceCommandMap.end()) {
|
||||||
//Is most likely periodic reply. Silent return.
|
//Is most likely periodic reply. Silent return.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Check if more replies are expected. If so, do nothing.
|
// Check if more replies are expected. If so, do nothing.
|
||||||
DeviceCommandInfo* info = &(iter->second.command->second);
|
DeviceCommandInfo* info = &(iter->second.command->second);
|
||||||
if (--info->expectedReplies == 0) {
|
if (--info->expectedReplies == 0) {
|
||||||
//Check if it was transition or internal command. Don't send any replies in that case.
|
// Check if it was transition or internal command.
|
||||||
|
// Don't send any replies in that case.
|
||||||
if (info->sendReplyTo != NO_COMMANDER) {
|
if (info->sendReplyTo != NO_COMMANDER) {
|
||||||
actionHelper.finish(info->sendReplyTo, iter->first, status);
|
actionHelper.finish(info->sendReplyTo, iter->first, status);
|
||||||
}
|
}
|
||||||
@ -593,7 +602,7 @@ void DeviceHandlerBase::doSendWrite() {
|
|||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
cookieInfo.state = COOKIE_WRITE_SENT;
|
cookieInfo.state = COOKIE_WRITE_SENT;
|
||||||
} else {
|
} else {
|
||||||
//always generate a failure event, so that FDIR knows what's up
|
// always generate a failure event, so that FDIR knows what's up
|
||||||
triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result,
|
triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result,
|
||||||
cookieInfo.pendingCommand->first);
|
cookieInfo.pendingCommand->first);
|
||||||
replyToCommand(result);
|
replyToCommand(result);
|
||||||
@ -682,9 +691,11 @@ void DeviceHandlerBase::doGetRead() {
|
|||||||
replyRawData(receivedData, receivedDataLen, requestedRawTraffic);
|
replyRawData(receivedData, receivedDataLen, requestedRawTraffic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == MODE_RAW and defaultRawReceiver != MessageQueueIF::NO_QUEUE) {
|
if (mode == MODE_RAW) {
|
||||||
|
if (defaultRawReceiver != MessageQueueIF::NO_QUEUE) {
|
||||||
replyRawReplyIfnotWiretapped(receivedData, receivedDataLen);
|
replyRawReplyIfnotWiretapped(receivedData, receivedDataLen);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
parseReply(receivedData, receivedDataLen);
|
parseReply(receivedData, receivedDataLen);
|
||||||
}
|
}
|
||||||
@ -706,8 +717,9 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
|
|||||||
case RETURN_OK:
|
case RETURN_OK:
|
||||||
handleReply(receivedData, foundId, foundLen);
|
handleReply(receivedData, foundId, foundLen);
|
||||||
if(foundLen == 0) {
|
if(foundLen == 0) {
|
||||||
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
" Packet parsing will be stuck." << std::endl;
|
"parseReply", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
|
"Found length is one, parsing might be stuck");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case APERIODIC_REPLY: {
|
case APERIODIC_REPLY: {
|
||||||
@ -718,8 +730,13 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
|
|||||||
foundId);
|
foundId);
|
||||||
}
|
}
|
||||||
if(foundLen == 0) {
|
if(foundLen == 0) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_ERROR,
|
||||||
|
"parseReply", ObjectManagerIF::CHILD_INIT_FAILED,
|
||||||
|
"Power switcher set but no valid object found.");
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
|
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
|
||||||
" Packet parsing will be stuck." << std::endl;
|
" Packet parsing will be stuck." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -728,7 +745,8 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
|
|||||||
case IGNORE_FULL_PACKET:
|
case IGNORE_FULL_PACKET:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
//We need to wait for timeout.. don't know what command failed and who sent it.
|
// We need to wait for timeout.. don't know what command failed
|
||||||
|
// and who sent it.
|
||||||
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
||||||
triggerEvent(DEVICE_READING_REPLY_FAILED, result, foundLen);
|
triggerEvent(DEVICE_READING_REPLY_FAILED, result, foundLen);
|
||||||
break;
|
break;
|
||||||
@ -949,7 +967,8 @@ ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mode_t DeviceHandlerBase::getBaseMode(Mode_t transitionMode) {
|
Mode_t DeviceHandlerBase::getBaseMode(Mode_t transitionMode) {
|
||||||
//only child action special modes are handled, as a child should never see any base action modes
|
// only child action special modes are handled, as a child should
|
||||||
|
// never see any base action modes
|
||||||
if (transitionMode == _MODE_START_UP) {
|
if (transitionMode == _MODE_START_UP) {
|
||||||
return _MODE_TO_ON;
|
return _MODE_TO_ON;
|
||||||
}
|
}
|
||||||
@ -1272,10 +1291,11 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
|||||||
if (mode == MODE_NORMAL) {
|
if (mode == MODE_NORMAL) {
|
||||||
result = buildNormalDeviceCommand(&deviceCommandId);
|
result = buildNormalDeviceCommand(&deviceCommandId);
|
||||||
if (result == BUSY) {
|
if (result == BUSY) {
|
||||||
//so we can track misconfigurations
|
// so we can track misconfigurations
|
||||||
sif::debug << std::hex << getObjectId()
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
<< ": DHB::buildInternalCommand: Busy" << std::dec
|
"buildInternalCommand",
|
||||||
<< std::endl;
|
HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
"Busy.");
|
||||||
result = NOTHING_TO_SEND; //no need to report this
|
result = NOTHING_TO_SEND; //no need to report this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1299,11 +1319,16 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
|||||||
if (iter == deviceCommandMap.end()) {
|
if (iter == deviceCommandMap.end()) {
|
||||||
result = COMMAND_NOT_SUPPORTED;
|
result = COMMAND_NOT_SUPPORTED;
|
||||||
} else if (iter->second.isExecuting) {
|
} else if (iter->second.isExecuting) {
|
||||||
//so we can track misconfigurations
|
#if FSFW_DISABLE_PRINTOUT == 0
|
||||||
sif::debug << std::hex << getObjectId()
|
char output[36];
|
||||||
<< ": DHB::buildInternalCommand: Command "
|
sprintf(output, "Command 0x%08x is executing",
|
||||||
<< deviceCommandId << " isExecuting" << std::dec
|
static_cast<unsigned int>(deviceCommandId));
|
||||||
<< std::endl;
|
// so we can track misconfigurations
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||||
|
"buildInternalCommand",
|
||||||
|
HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
output);
|
||||||
|
#endif
|
||||||
// this is an internal command, no need to report a failure here,
|
// this is an internal command, no need to report a failure here,
|
||||||
// missed reply will track if a reply is too late, otherwise, it's ok
|
// missed reply will track if a reply is too late, otherwise, it's ok
|
||||||
return;
|
return;
|
||||||
@ -1396,7 +1421,7 @@ void DeviceHandlerBase::performOperationHook() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(
|
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(
|
||||||
LocalDataPool &localDataPoolMap,
|
localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) {
|
LocalDataPoolManager& poolManager) {
|
||||||
if(thermalSet != nullptr) {
|
if(thermalSet != nullptr) {
|
||||||
localDataPoolMap.emplace(thermalSet->thermalStatePoolId,
|
localDataPoolMap.emplace(thermalSet->thermalStatePoolId,
|
||||||
@ -1407,18 +1432,13 @@ ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(
|
|||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() {
|
|
||||||
return &hkManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
||||||
// In this function, the task handle should be valid if the task
|
// In this function, the task handle should be valid if the task
|
||||||
// was implemented correctly. We still check to be 1000 % sure :-)
|
// was implemented correctly. We still check to be 1000 % sure :-)
|
||||||
if(executingTask != nullptr) {
|
if(executingTask != nullptr) {
|
||||||
pstIntervalMs = executingTask->getPeriodMs();
|
pstIntervalMs = executingTask->getPeriodMs();
|
||||||
}
|
}
|
||||||
this->hkManager.initializeAfterTaskCreation();
|
this->poolManager.initializeAfterTaskCreation();
|
||||||
|
|
||||||
if(setStartupImmediately) {
|
if(setStartupImmediately) {
|
||||||
startTransition(MODE_ON, SUBMODE_NONE);
|
startTransition(MODE_ON, SUBMODE_NONE);
|
||||||
@ -1462,3 +1482,52 @@ void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType,
|
||||||
|
const char *functionName, ReturnValue_t errorCode,
|
||||||
|
const char *errorPrint) {
|
||||||
|
if(errorPrint == nullptr) {
|
||||||
|
if(errorCode == ObjectManagerIF::CHILD_INIT_FAILED) {
|
||||||
|
errorPrint = "Initialization error";
|
||||||
|
}
|
||||||
|
if(errorCode == HasReturnvaluesIF::RETURN_FAILED) {
|
||||||
|
if(errorType == sif::OutputTypes::OUT_WARNING) {
|
||||||
|
errorPrint = "Generic Warning";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorPrint = "Generic Error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorPrint = "Unknown error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errorType == sif::OutputTypes::OUT_WARNING) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "DeviceHandlerBase::" << functionName << ": Object ID "
|
||||||
|
<< std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< this->getObjectId() << " | " << errorPrint << std::dec
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n",
|
||||||
|
this->getObjectId(), errorPrint);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(errorType == sif::OutputTypes::OUT_ERROR) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "DeviceHandlerBase::" << functionName << ": Object ID "
|
||||||
|
<< std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< this->getObjectId() << " | " << errorPrint << std::dec
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n",
|
||||||
|
this->getObjectId(), errorPrint);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() {
|
||||||
|
return &poolManager;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "DeviceHandlerFailureIsolation.h"
|
#include "DeviceHandlerFailureIsolation.h"
|
||||||
#include "DeviceHandlerThermalSet.h"
|
#include "DeviceHandlerThermalSet.h"
|
||||||
|
|
||||||
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
|
#include "../serviceinterface/serviceInterfaceDefintions.h"
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "../objectmanager/SystemObject.h"
|
||||||
#include "../tasks/ExecutableObjectIF.h"
|
#include "../tasks/ExecutableObjectIF.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
@ -512,11 +514,14 @@ protected:
|
|||||||
* @param localDataPoolMap
|
* @param localDataPoolMap
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t initializeLocalDataPool(LocalDataPool& localDataPoolMap,
|
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
|
|
||||||
/** Get the HK manager object handle */
|
/**
|
||||||
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
* Required for HasLocalDataPoolIF, return a handle to the local pool manager.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalDataPoolManager* getHkManagerHandle() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Hook function for child handlers which is called once per
|
* @brief Hook function for child handlers which is called once per
|
||||||
@ -646,7 +651,7 @@ protected:
|
|||||||
/** Action helper for HasActionsIF */
|
/** Action helper for HasActionsIF */
|
||||||
ActionHelper actionHelper;
|
ActionHelper actionHelper;
|
||||||
/** Housekeeping Manager */
|
/** Housekeeping Manager */
|
||||||
LocalDataPoolManager hkManager;
|
LocalDataPoolManager poolManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Information about commands
|
* @brief Information about commands
|
||||||
@ -1111,7 +1116,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* @brief The mode the current transition originated from
|
* @brief The mode the current transition originated from
|
||||||
*
|
*
|
||||||
* This is private so the child can not change it and fuck up the timeouts
|
* This is private so the child can not change it and mess up the timeouts
|
||||||
*
|
*
|
||||||
* IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!!
|
* IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!!
|
||||||
* (it is _MODE_POWER_DOWN during this modes)
|
* (it is _MODE_POWER_DOWN during this modes)
|
||||||
@ -1190,7 +1195,8 @@ private:
|
|||||||
* Check if the RMAP sendWrite action was successful.
|
* Check if the RMAP sendWrite action was successful.
|
||||||
*
|
*
|
||||||
* Depending on the result, the following is done
|
* Depending on the result, the following is done
|
||||||
* - if the device command was external commanded, a reply is sent indicating the result
|
* - if the device command was external commanded, a reply is sent
|
||||||
|
* indicating the result
|
||||||
* - if the action was successful, the reply timout counter is initialized
|
* - if the action was successful, the reply timout counter is initialized
|
||||||
*/
|
*/
|
||||||
void doGetWrite(void);
|
void doGetWrite(void);
|
||||||
@ -1206,9 +1212,9 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Check the getRead reply and the contained data.
|
* Check the getRead reply and the contained data.
|
||||||
*
|
*
|
||||||
* If data was received scanForReply() and, if successful, handleReply() are called.
|
* If data was received scanForReply() and, if successful, handleReply()
|
||||||
* If the current mode is @c MODE_RAW, the received packet is sent to the commanding object
|
* are called. If the current mode is @c MODE_RAW, the received packet
|
||||||
* via commandQueue.
|
* is sent to the commanding object via commandQueue.
|
||||||
*/
|
*/
|
||||||
void doGetRead(void);
|
void doGetRead(void);
|
||||||
|
|
||||||
@ -1227,7 +1233,7 @@ private:
|
|||||||
uint32_t *len);
|
uint32_t *len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!!
|
* @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW, nothing else!
|
||||||
*/
|
*/
|
||||||
void setTransition(Mode_t modeTo, Submode_t submodeTo);
|
void setTransition(Mode_t modeTo, Submode_t submodeTo);
|
||||||
|
|
||||||
@ -1247,6 +1253,11 @@ private:
|
|||||||
|
|
||||||
void handleTransitionToOnMode(Mode_t commandedMode,
|
void handleTransitionToOnMode(Mode_t commandedMode,
|
||||||
Submode_t commandedSubmode);
|
Submode_t commandedSubmode);
|
||||||
|
|
||||||
|
void printWarningOrError(sif::OutputTypes errorType,
|
||||||
|
const char* functionName,
|
||||||
|
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
||||||
|
const char* errorPrint = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||||
|
@ -169,8 +169,10 @@ void DeviceHandlerFailureIsolation::clearFaultCounters() {
|
|||||||
ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
|
ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
|
||||||
ReturnValue_t result = FailureIsolationBase::initialize();
|
ReturnValue_t result = FailureIsolationBase::initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DeviceHandlerFailureIsolation::initialize: Could not"
|
sif::error << "DeviceHandlerFailureIsolation::initialize: Could not"
|
||||||
" initialize FailureIsolationBase." << std::endl;
|
" initialize FailureIsolationBase." << std::endl;
|
||||||
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
ConfirmsFailuresIF* power = objectManager->get<ConfirmsFailuresIF>(
|
ConfirmsFailuresIF* power = objectManager->get<ConfirmsFailuresIF>(
|
||||||
@ -250,8 +252,10 @@ bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty(
|
|||||||
|
|
||||||
if (owner == nullptr) {
|
if (owner == nullptr) {
|
||||||
// Configuration error.
|
// Configuration error.
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "DeviceHandlerFailureIsolation::"
|
sif::error << "DeviceHandlerFailureIsolation::"
|
||||||
<< "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl;
|
<< "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl;
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "DeviceHandlerMessage.h"
|
#include "DeviceHandlerMessage.h"
|
||||||
|
|
||||||
|
#include "../datapoollocal/localPoolDefinitions.h"
|
||||||
#include "../action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
#include "../datapoollocal/locPoolDefinitions.h"
|
|
||||||
#include "../events/Event.h"
|
#include "../events/Event.h"
|
||||||
#include "../modes/HasModesIF.h"
|
#include "../modes/HasModesIF.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
|
1
doc/README-controllers.md
Normal file
1
doc/README-controllers.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
## Controllers
|
@ -16,9 +16,8 @@ Flight Software Framework
|
|||||||
* A reference to an object can be get by calling the following function. T must be the specific Interface you want to call.
|
* A reference to an object can be get by calling the following function. T must be the specific Interface you want to call.
|
||||||
A nullptr check of the returning Pointer must be done. This function is based on Run-time type information.
|
A nullptr check of the returning Pointer must be done. This function is based on Run-time type information.
|
||||||
|
|
||||||
``` c++
|
```cpp
|
||||||
template <typename T> T* ObjectManagerIF::get( object_id_t id )
|
template <typename T> 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.
|
* 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.
|
By calling objectManager->initialize() the produce function will be called and all SystemObjects will be initialized afterwards.
|
||||||
|
@ -1 +1 @@
|
|||||||
## FSFW DeviceHandlers
|
## Device Handlers
|
||||||
|
99
doc/README-highlevel.md
Normal file
99
doc/README-highlevel.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# High-level overview
|
||||||
|
|
||||||
|
## 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 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.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
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
|
||||||
|
|
||||||
|
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()".
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### Internal Communication
|
||||||
|
|
||||||
|
Components communicate mostly over Message through Queues.
|
||||||
|
Those queues are created by calling the singleton QueueFactory::instance()->create().
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
#### 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).
|
||||||
|
|
||||||
|
#### Modes, Health
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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 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)
|
3
doc/README-localpools.md
Normal file
3
doc/README-localpools.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
## Local Data Pools
|
||||||
|
|
||||||
|
|
32
doc/README-osal.md
Normal file
32
doc/README-osal.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Operating System Abstraction Layer (OSAL)
|
||||||
|
|
||||||
|
Some specific information on the provided OSALs are provided.
|
||||||
|
|
||||||
|
## Linux OSAL
|
||||||
|
|
||||||
|
This OSAL can be used to compile for Linux host systems like Ubuntu 20.04 or for
|
||||||
|
embedded Linux targets like the Raspberry Pi. This OSAL generally requires threading support
|
||||||
|
and real-time functionalities. For most UNIX systems, this is done by adding `-lrt` and `-lpthread` to the linked libraries in the compilation process. The CMake build support provided will do this automatically for the `fsfw` target. It should be noted that most UNIX systems need to be configured specifically to allow the real-time functionalities required by the FSFW.
|
||||||
|
|
||||||
|
More information on how to set up a Linux system accordingly can be found in the
|
||||||
|
[Linux README of the FSFW example application](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example/src/branch/master/doc/README-linux.md#top)
|
||||||
|
|
||||||
|
## Hosted OSAL
|
||||||
|
|
||||||
|
This is the newest OSAL. Support for Semaphores has not been implemented yet and will propably be implemented as soon as C++20 with Semaphore support has matured. This OSAL can be used to run the FSFW on any host system, but currently has only been tested on Windows 10 and Ubuntu 20.04. Unlike the other OSALs, it uses dynamic memory allocation (e.g. for the message queue implementation). Cross-platform serial port (USB) support might be added soon.
|
||||||
|
|
||||||
|
## FreeRTOS OSAL
|
||||||
|
|
||||||
|
FreeRTOS is not included and the developer needs to take care of compiling the FreeRTOS sources and adding the `FreeRTOSConfig.h` file location to the include path. This OSAL has only been tested extensively with the pre-emptive scheduler configuration so far but it should in principle also be possible to use a cooperative scheduler. It is recommended to use the `heap_4` allocation scheme. When using newlib (nano), it is also recommended to add `#define configUSE_NEWLIB_REENTRANT` to the FreeRTOS configuration file to ensure thread-safety.
|
||||||
|
|
||||||
|
When using this OSAL, developers also need to provide an implementation for the `vRequestContextSwitchFromISR` function. This has been done because the call to request a context switch from an ISR is generally located in the `portmacro.h` header and is different depending on the target architecture or device.
|
||||||
|
|
||||||
|
## RTEMS OSAL
|
||||||
|
|
||||||
|
The RTEMS OSAL was the first implemented OSAL which is also used on the active satellite Flying Laptop.
|
||||||
|
|
||||||
|
## TCP/IP socket abstraction
|
||||||
|
|
||||||
|
The Linux and Host OSAL provide abstraction layers for the socket API. Currently, only UDP sockets have been imlemented. This is very useful to test TMTC handling either on the host computer directly (targeting localhost with a TMTC application) or on embedded Linux devices, sending TMTC packets via Ethernet.
|
||||||
|
|
||||||
|
|
1
doc/README-pus.md
Normal file
1
doc/README-pus.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
## PUS Services
|
@ -122,6 +122,7 @@ void EventManager::printEvent(EventMessage* message) {
|
|||||||
case severity::INFO:
|
case severity::INFO:
|
||||||
#if DEBUG_INFO_EVENT == 1
|
#if DEBUG_INFO_EVENT == 1
|
||||||
string = translateObject(message->getReporter());
|
string = translateObject(message->getReporter());
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "EVENT: ";
|
sif::info << "EVENT: ";
|
||||||
if (string != 0) {
|
if (string != 0) {
|
||||||
sif::info << string;
|
sif::info << string;
|
||||||
@ -132,10 +133,12 @@ void EventManager::printEvent(EventMessage* message) {
|
|||||||
<< std::dec << message->getEventId() << std::hex << ") P1: 0x"
|
<< std::dec << message->getEventId() << std::hex << ") P1: 0x"
|
||||||
<< message->getParameter1() << " P2: 0x"
|
<< message->getParameter1() << " P2: 0x"
|
||||||
<< message->getParameter2() << std::dec << std::endl;
|
<< message->getParameter2() << std::dec << std::endl;
|
||||||
#endif
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
#endif /* DEBUG_INFO_EVENT == 1 */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
string = translateObject(message->getReporter());
|
string = translateObject(message->getReporter());
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "EventManager: ";
|
sif::debug << "EventManager: ";
|
||||||
if (string != 0) {
|
if (string != 0) {
|
||||||
sif::debug << string;
|
sif::debug << string;
|
||||||
@ -146,22 +149,28 @@ void EventManager::printEvent(EventMessage* message) {
|
|||||||
sif::debug << " reported " << translateEvents(message->getEvent())
|
sif::debug << " reported " << translateEvents(message->getEvent())
|
||||||
<< " (" << std::dec << message->getEventId() << ") "
|
<< " (" << std::dec << message->getEventId() << ") "
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
sif::debug << std::hex << "P1 Hex: 0x" << message->getParameter1()
|
sif::debug << std::hex << "P1 Hex: 0x" << message->getParameter1()
|
||||||
<< ", P1 Dec: " << std::dec << message->getParameter1()
|
<< ", P1 Dec: " << std::dec << message->getParameter1()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
sif::debug << std::hex << "P2 Hex: 0x" << message->getParameter2()
|
sif::debug << std::hex << "P2 Hex: 0x" << message->getParameter2()
|
||||||
<< ", P2 Dec: " << std::dec << message->getParameter2()
|
<< ", P2 Dec: " << std::dec << message->getParameter2()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void EventManager::lockMutex() {
|
void EventManager::lockMutex() {
|
||||||
mutex->lockMutex(MutexIF::BLOCKING);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::unlockMutex() {
|
void EventManager::unlockMutex() {
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventManager::setMutexTimeout(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t timeoutMs) {
|
||||||
|
this->timeoutType = timeoutType;
|
||||||
|
this->timeoutMs = timeoutMs;
|
||||||
|
}
|
||||||
|
@ -29,6 +29,8 @@ public:
|
|||||||
EventManager(object_id_t setObjectId);
|
EventManager(object_id_t setObjectId);
|
||||||
virtual ~EventManager();
|
virtual ~EventManager();
|
||||||
|
|
||||||
|
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
||||||
|
|
||||||
MessageQueueId_t getEventReportQueue();
|
MessageQueueId_t getEventReportQueue();
|
||||||
|
|
||||||
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
|
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
|
||||||
@ -51,6 +53,8 @@ protected:
|
|||||||
std::map<MessageQueueId_t, EventMatchTree> listenerList;
|
std::map<MessageQueueId_t, EventMatchTree> listenerList;
|
||||||
|
|
||||||
MutexIF* mutex = nullptr;
|
MutexIF* mutex = nullptr;
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t timeoutMs = 20;
|
||||||
|
|
||||||
static const uint8_t N_POOLS = 3;
|
static const uint8_t N_POOLS = 3;
|
||||||
LocalPool factoryBackend;
|
LocalPool factoryBackend;
|
||||||
|
@ -21,8 +21,10 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
|||||||
EventManagerIF* manager = objectManager->get<EventManagerIF>(
|
EventManagerIF* manager = objectManager->get<EventManagerIF>(
|
||||||
objects::EVENT_MANAGER);
|
objects::EVENT_MANAGER);
|
||||||
if (manager == nullptr) {
|
if (manager == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FailureIsolationBase::initialize: Event Manager has not"
|
sif::error << "FailureIsolationBase::initialize: Event Manager has not"
|
||||||
" been initialized!" << std::endl;
|
" been initialized!" << std::endl;
|
||||||
|
#endif
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = manager->registerListener(eventQueue->getId());
|
ReturnValue_t result = manager->registerListener(eventQueue->getId());
|
||||||
@ -36,8 +38,10 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
|||||||
}
|
}
|
||||||
owner = objectManager->get<HasHealthIF>(ownerId);
|
owner = objectManager->get<HasHealthIF>(ownerId);
|
||||||
if (owner == nullptr) {
|
if (owner == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FailureIsolationBase::intialize: Owner object "
|
sif::error << "FailureIsolationBase::intialize: Owner object "
|
||||||
"invalid. Make sure it implements HasHealthIF" << std::endl;
|
"invalid. Make sure it implements HasHealthIF" << std::endl;
|
||||||
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,10 +49,14 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
|||||||
ConfirmsFailuresIF* parentIF = objectManager->get<ConfirmsFailuresIF>(
|
ConfirmsFailuresIF* parentIF = objectManager->get<ConfirmsFailuresIF>(
|
||||||
faultTreeParent);
|
faultTreeParent);
|
||||||
if (parentIF == nullptr) {
|
if (parentIF == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FailureIsolationBase::intialize: Parent object"
|
sif::error << "FailureIsolationBase::intialize: Parent object"
|
||||||
<< "invalid." << std::endl;
|
<< "invalid." << std::endl;
|
||||||
|
#endif
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Make sure it implements ConfirmsFailuresIF."
|
sif::error << "Make sure it implements ConfirmsFailuresIF."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
1
fsfw.mk
1
fsfw.mk
@ -10,6 +10,7 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/coordinates/*.cpp)
|
|||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datalinklayer/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datalinklayer/*.cpp)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapool/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapool/*.cpp)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapoollocal/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapoollocal/*.cpp)
|
||||||
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapoollocal/internal/*.cpp)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/housekeeping/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/housekeeping/*.cpp)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/devicehandlers/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/devicehandlers/*.cpp)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/*.cpp)
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
#include "arrayprinter.h"
|
#include "arrayprinter.h"
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type,
|
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type,
|
||||||
bool printInfo, size_t maxCharPerLine) {
|
bool printInfo, size_t maxCharPerLine) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
if(printInfo) {
|
if(printInfo) {
|
||||||
sif::info << "Printing data with size " << size << ": ";
|
sif::info << "Printing data with size " << size << ": ";
|
||||||
}
|
}
|
||||||
sif::info << "[";
|
sif::info << "[";
|
||||||
|
#else
|
||||||
|
sif::printInfo("Printing data with size %zu: [", size);
|
||||||
|
#endif
|
||||||
if(type == OutputType::HEX) {
|
if(type == OutputType::HEX) {
|
||||||
arrayprinter::printHex(data, size, maxCharPerLine);
|
arrayprinter::printHex(data, size, maxCharPerLine);
|
||||||
}
|
}
|
||||||
@ -21,6 +25,7 @@ void arrayprinter::print(const uint8_t *data, size_t size, OutputType type,
|
|||||||
|
|
||||||
void arrayprinter::printHex(const uint8_t *data, size_t size,
|
void arrayprinter::printHex(const uint8_t *data, size_t size,
|
||||||
size_t maxCharPerLine) {
|
size_t maxCharPerLine) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << std::hex;
|
sif::info << std::hex;
|
||||||
for(size_t i = 0; i < size; i++) {
|
for(size_t i = 0; i < size; i++) {
|
||||||
sif::info << "0x" << static_cast<int>(data[i]);
|
sif::info << "0x" << static_cast<int>(data[i]);
|
||||||
@ -28,16 +33,20 @@ void arrayprinter::printHex(const uint8_t *data, size_t size,
|
|||||||
sif::info << " , ";
|
sif::info << " , ";
|
||||||
if(i > 0 and i % maxCharPerLine == 0) {
|
if(i > 0 and i % maxCharPerLine == 0) {
|
||||||
sif::info << std::endl;
|
sif::info << std::endl;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
sif::info << std::dec;
|
sif::info << std::dec;
|
||||||
sif::info << "]" << std::endl;
|
sif::info << "]" << std::endl;
|
||||||
|
#else
|
||||||
|
// how much memory to reserve for printout?
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrayprinter::printDec(const uint8_t *data, size_t size,
|
void arrayprinter::printDec(const uint8_t *data, size_t size,
|
||||||
size_t maxCharPerLine) {
|
size_t maxCharPerLine) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << std::dec;
|
sif::info << std::dec;
|
||||||
for(size_t i = 0; i < size; i++) {
|
for(size_t i = 0; i < size; i++) {
|
||||||
sif::info << static_cast<int>(data[i]);
|
sif::info << static_cast<int>(data[i]);
|
||||||
@ -49,13 +58,20 @@ void arrayprinter::printDec(const uint8_t *data, size_t size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sif::info << "]" << std::endl;
|
sif::info << "]" << std::endl;
|
||||||
|
#else
|
||||||
|
// how much memory to reserve for printout?
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrayprinter::printBin(const uint8_t *data, size_t size) {
|
void arrayprinter::printBin(const uint8_t *data, size_t size) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "\n" << std::flush;
|
sif::info << "\n" << std::flush;
|
||||||
for(size_t i = 0; i < size; i++) {
|
for(size_t i = 0; i < size; i++) {
|
||||||
sif::info << "Byte " << i + 1 << ": 0b"<<
|
sif::info << "Byte " << i + 1 << ": 0b"<<
|
||||||
std::bitset<8>(data[i]) << ",\n" << std::flush;
|
std::bitset<8>(data[i]) << ",\n" << std::flush;
|
||||||
}
|
}
|
||||||
sif::info << "]" << std::endl;
|
sif::info << "]" << std::endl;
|
||||||
|
#else
|
||||||
|
// how much memory to reserve for printout?
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -41,14 +41,18 @@ ReturnValue_t HealthHelper::initialize() {
|
|||||||
eventSender = objectManager->get<EventReportingProxyIF>(objectId);
|
eventSender = objectManager->get<EventReportingProxyIF>(objectId);
|
||||||
|
|
||||||
if (healthTable == nullptr) {
|
if (healthTable == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "HealthHelper::initialize: Health table object needs"
|
sif::error << "HealthHelper::initialize: Health table object needs"
|
||||||
"to be created in factory." << std::endl;
|
"to be created in factory." << std::endl;
|
||||||
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eventSender == nullptr) {
|
if(eventSender == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "HealthHelper::initialize: Owner has to implement "
|
sif::error << "HealthHelper::initialize: Owner has to implement "
|
||||||
"ReportingProxyIF." << std::endl;
|
"ReportingProxyIF." << std::endl;
|
||||||
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,8 +83,10 @@ void HealthHelper::informParent(HasHealthIF::HealthState health,
|
|||||||
health, oldHealth);
|
health, oldHealth);
|
||||||
if (MessageQueueSenderIF::sendMessage(parentQueue, &information,
|
if (MessageQueueSenderIF::sendMessage(parentQueue, &information,
|
||||||
owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) {
|
owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "HealthHelper::informParent: sending health reply failed."
|
sif::debug << "HealthHelper::informParent: sending health reply failed."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,8 +104,10 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* command) {
|
|||||||
}
|
}
|
||||||
if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply,
|
if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply,
|
||||||
owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) {
|
owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "HealthHelper::handleHealthCommand: sending health "
|
sif::debug << "HealthHelper::handleHealthCommand: sending health "
|
||||||
"reply failed." << std::endl;
|
"reply failed." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
class HealthTableIF: public ManagesHealthIF {
|
class HealthTableIF: public ManagesHealthIF {
|
||||||
public:
|
public:
|
||||||
virtual ~HealthTableIF() {}
|
virtual ~HealthTableIF() {}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
||||||
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
||||||
|
|
||||||
#include "../datapoollocal/locPoolDefinitions.h"
|
#include "../datapoollocal/localPoolDefinitions.h"
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "../ipc/CommandMessage.h"
|
||||||
#include "../ipc/FwMessageTypes.h"
|
#include "../ipc/FwMessageTypes.h"
|
||||||
#include "../objectmanager/frameworkObjects.h"
|
#include "../objectmanager/frameworkObjects.h"
|
||||||
|
@ -21,11 +21,11 @@ public:
|
|||||||
InternalErrorDataset(object_id_t objectId):
|
InternalErrorDataset(object_id_t objectId):
|
||||||
StaticLocalDataSet(sid_t(objectId , ERROR_SET_ID)) {}
|
StaticLocalDataSet(sid_t(objectId , ERROR_SET_ID)) {}
|
||||||
|
|
||||||
lp_var_t<uint32_t> tmHits = lp_var_t<uint32_t>(hkManager->getOwner(),
|
lp_var_t<uint32_t> tmHits = lp_var_t<uint32_t>(sid.objectId,
|
||||||
TM_HITS, this);
|
TM_HITS, this);
|
||||||
lp_var_t<uint32_t> queueHits = lp_var_t<uint32_t>(hkManager->getOwner(),
|
lp_var_t<uint32_t> queueHits = lp_var_t<uint32_t>(sid.objectId,
|
||||||
QUEUE_HITS, this);
|
QUEUE_HITS, this);
|
||||||
lp_var_t<uint32_t> storeHits = lp_var_t<uint32_t>(hkManager->getOwner(),
|
lp_var_t<uint32_t> storeHits = lp_var_t<uint32_t>(sid.objectId,
|
||||||
STORE_HITS, this);
|
STORE_HITS, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
#include "../ipc/MutexFactory.h"
|
#include "../ipc/MutexFactory.h"
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId,
|
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId,
|
||||||
uint32_t messageQueueDepth): SystemObject(setObjectId),
|
uint32_t messageQueueDepth): SystemObject(setObjectId),
|
||||||
@ -23,20 +23,27 @@ void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
||||||
internalErrorDataset.read(INTERNAL_ERROR_MUTEX_TIMEOUT);
|
internalErrorDataset.read(timeoutType, timeoutMs);
|
||||||
|
|
||||||
uint32_t newQueueHits = getAndResetQueueHits();
|
uint32_t newQueueHits = getAndResetQueueHits();
|
||||||
uint32_t newTmHits = getAndResetTmHits();
|
uint32_t newTmHits = getAndResetTmHits();
|
||||||
uint32_t newStoreHits = getAndResetStoreHits();
|
uint32_t newStoreHits = getAndResetStoreHits();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if FSFW_VERBOSE_LEVEL == 1
|
||||||
if(diagnosticPrintout) {
|
if(diagnosticPrintout) {
|
||||||
if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
||||||
<< "occured!" << std::endl;
|
<< "occured!" << std::endl;
|
||||||
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
||||||
sif::debug << "TM errors: " << newTmHits << std::endl;
|
sif::debug << "TM errors: " << newTmHits << std::endl;
|
||||||
sif::debug << "Store errors: " << newStoreHits << std::endl;
|
sif::debug << "Store errors: " << newStoreHits << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
|
||||||
|
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
|
||||||
|
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
|
||||||
|
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -44,8 +51,8 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
|||||||
internalErrorDataset.queueHits.value += newQueueHits;
|
internalErrorDataset.queueHits.value += newQueueHits;
|
||||||
internalErrorDataset.storeHits.value += newStoreHits;
|
internalErrorDataset.storeHits.value += newStoreHits;
|
||||||
internalErrorDataset.tmHits.value += newTmHits;
|
internalErrorDataset.tmHits.value += newTmHits;
|
||||||
|
internalErrorDataset.setValidity(true, true);
|
||||||
internalErrorDataset.commit(INTERNAL_ERROR_MUTEX_TIMEOUT);
|
internalErrorDataset.commit(timeoutType, timeoutMs);
|
||||||
|
|
||||||
poolManager.performHkOperation();
|
poolManager.performHkOperation();
|
||||||
|
|
||||||
@ -67,7 +74,7 @@ void InternalErrorReporter::lostTm() {
|
|||||||
|
|
||||||
uint32_t InternalErrorReporter::getAndResetQueueHits() {
|
uint32_t InternalErrorReporter::getAndResetQueueHits() {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
value = queueHits;
|
value = queueHits;
|
||||||
queueHits = 0;
|
queueHits = 0;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
@ -76,21 +83,21 @@ uint32_t InternalErrorReporter::getAndResetQueueHits() {
|
|||||||
|
|
||||||
uint32_t InternalErrorReporter::getQueueHits() {
|
uint32_t InternalErrorReporter::getQueueHits() {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
value = queueHits;
|
value = queueHits;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InternalErrorReporter::incrementQueueHits() {
|
void InternalErrorReporter::incrementQueueHits() {
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
queueHits++;
|
queueHits++;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t InternalErrorReporter::getAndResetTmHits() {
|
uint32_t InternalErrorReporter::getAndResetTmHits() {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
value = tmHits;
|
value = tmHits;
|
||||||
tmHits = 0;
|
tmHits = 0;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
@ -99,14 +106,14 @@ uint32_t InternalErrorReporter::getAndResetTmHits() {
|
|||||||
|
|
||||||
uint32_t InternalErrorReporter::getTmHits() {
|
uint32_t InternalErrorReporter::getTmHits() {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
value = tmHits;
|
value = tmHits;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InternalErrorReporter::incrementTmHits() {
|
void InternalErrorReporter::incrementTmHits() {
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
tmHits++;
|
tmHits++;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
}
|
}
|
||||||
@ -117,7 +124,7 @@ void InternalErrorReporter::storeFull() {
|
|||||||
|
|
||||||
uint32_t InternalErrorReporter::getAndResetStoreHits() {
|
uint32_t InternalErrorReporter::getAndResetStoreHits() {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
value = storeHits;
|
value = storeHits;
|
||||||
storeHits = 0;
|
storeHits = 0;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
@ -126,14 +133,14 @@ uint32_t InternalErrorReporter::getAndResetStoreHits() {
|
|||||||
|
|
||||||
uint32_t InternalErrorReporter::getStoreHits() {
|
uint32_t InternalErrorReporter::getStoreHits() {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
value = storeHits;
|
value = storeHits;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InternalErrorReporter::incrementStoreHits() {
|
void InternalErrorReporter::incrementStoreHits() {
|
||||||
mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
|
mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
storeHits++;
|
storeHits++;
|
||||||
mutex->unlockMutex();
|
mutex->unlockMutex();
|
||||||
}
|
}
|
||||||
@ -147,7 +154,7 @@ MessageQueueId_t InternalErrorReporter::getCommandQueue() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t InternalErrorReporter::initializeLocalDataPool(
|
ReturnValue_t InternalErrorReporter::initializeLocalDataPool(
|
||||||
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
|
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
|
||||||
localDataPoolMap.emplace(errorPoolIds::TM_HITS,
|
localDataPoolMap.emplace(errorPoolIds::TM_HITS,
|
||||||
new PoolEntry<uint32_t>());
|
new PoolEntry<uint32_t>());
|
||||||
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS,
|
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS,
|
||||||
@ -160,10 +167,6 @@ ReturnValue_t InternalErrorReporter::initializeLocalDataPool(
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDataPoolManager* InternalErrorReporter::getHkManagerHandle() {
|
|
||||||
return &poolManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const {
|
dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const {
|
||||||
return this->executingTask->getPeriodMs();
|
return this->executingTask->getPeriodMs();
|
||||||
}
|
}
|
||||||
@ -188,3 +191,12 @@ ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() {
|
|||||||
return poolManager.initializeAfterTaskCreation();
|
return poolManager.initializeAfterTaskCreation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InternalErrorReporter::setMutexTimeout(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t timeoutMs) {
|
||||||
|
this->timeoutType = timeoutType;
|
||||||
|
this->timeoutMs = timeoutMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDataPoolManager* InternalErrorReporter::getHkManagerHandle() {
|
||||||
|
return &poolManager;
|
||||||
|
}
|
||||||
|
@ -22,7 +22,6 @@ class InternalErrorReporter: public SystemObject,
|
|||||||
public InternalErrorReporterIF,
|
public InternalErrorReporterIF,
|
||||||
public HasLocalDataPoolIF {
|
public HasLocalDataPoolIF {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t INTERNAL_ERROR_MUTEX_TIMEOUT = 20;
|
|
||||||
|
|
||||||
InternalErrorReporter(object_id_t setObjectId,
|
InternalErrorReporter(object_id_t setObjectId,
|
||||||
uint32_t messageQueueDepth = 5);
|
uint32_t messageQueueDepth = 5);
|
||||||
@ -34,16 +33,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setDiagnosticPrintout(bool enable);
|
void setDiagnosticPrintout(bool enable);
|
||||||
|
|
||||||
|
void setMutexTimeout(MutexIF::TimeoutType timeoutType,
|
||||||
|
uint32_t timeoutMs);
|
||||||
|
|
||||||
virtual ~InternalErrorReporter();
|
virtual ~InternalErrorReporter();
|
||||||
|
|
||||||
virtual object_id_t getObjectId() const override;
|
virtual object_id_t getObjectId() const override;
|
||||||
virtual MessageQueueId_t getCommandQueue() const override;
|
virtual MessageQueueId_t getCommandQueue() const override;
|
||||||
virtual ReturnValue_t initializeLocalDataPool(
|
virtual ReturnValue_t initializeLocalDataPool(
|
||||||
LocalDataPool& localDataPoolMap,
|
localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
|
||||||
virtual dur_millis_t getPeriodicOperationFrequency() const override;
|
virtual dur_millis_t getPeriodicOperationFrequency() const override;
|
||||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
|
LocalDataPoolManager* getHkManagerHandle() override;
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
virtual ReturnValue_t initialize() override;
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
@ -61,7 +63,11 @@ protected:
|
|||||||
LocalDataPoolManager poolManager;
|
LocalDataPoolManager poolManager;
|
||||||
|
|
||||||
PeriodicTaskIF* executingTask = nullptr;
|
PeriodicTaskIF* executingTask = nullptr;
|
||||||
|
|
||||||
MutexIF* mutex = nullptr;
|
MutexIF* mutex = nullptr;
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t timeoutMs = 20;
|
||||||
|
|
||||||
sid_t internalErrorSid;
|
sid_t internalErrorSid;
|
||||||
InternalErrorDataset internalErrorDataset;
|
InternalErrorDataset internalErrorDataset;
|
||||||
|
|
||||||
|
@ -15,8 +15,10 @@ MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size) :
|
|||||||
this->messageSize = this->HEADER_SIZE + size;
|
this->messageSize = this->HEADER_SIZE + size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "MessageQueueMessage: Passed size larger than maximum"
|
sif::warning << "MessageQueueMessage: Passed size larger than maximum"
|
||||||
"allowed size! Setting content to 0" << std::endl;
|
"allowed size! Setting content to 0" << std::endl;
|
||||||
|
#endif
|
||||||
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
||||||
this->messageSize = this->HEADER_SIZE;
|
this->messageSize = this->HEADER_SIZE;
|
||||||
}
|
}
|
||||||
@ -52,7 +54,9 @@ void MessageQueueMessage::setSender(MessageQueueId_t setId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessageQueueMessage::print(bool printWholeMessage) {
|
void MessageQueueMessage::print(bool printWholeMessage) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "MessageQueueMessage content: " << std::endl;
|
sif::debug << "MessageQueueMessage content: " << std::endl;
|
||||||
|
#endif
|
||||||
if(printWholeMessage) {
|
if(printWholeMessage) {
|
||||||
arrayprinter::print(getData(), getMaximumMessageSize());
|
arrayprinter::print(getData(), getMaximumMessageSize());
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,16 @@ public:
|
|||||||
ReturnValue_t status = mutex->lockMutex(timeoutType,
|
ReturnValue_t status = mutex->lockMutex(timeoutType,
|
||||||
timeoutMs);
|
timeoutMs);
|
||||||
if(status == MutexIF::MUTEX_TIMEOUT) {
|
if(status == MutexIF::MUTEX_TIMEOUT) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MutexHelper: Lock of mutex failed with timeout of "
|
sif::error << "MutexHelper: Lock of mutex failed with timeout of "
|
||||||
<< timeoutMs << " milliseconds!" << std::endl;
|
<< timeoutMs << " milliseconds!" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if(status != HasReturnvaluesIF::RETURN_OK){
|
else if(status != HasReturnvaluesIF::RETURN_OK){
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MutexHelper: Lock of Mutex failed with code "
|
sif::error << "MutexHelper: Lock of Mutex failed with code "
|
||||||
<< status << std::endl;
|
<< status << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Different types of timeout for the mutex lock.
|
* Different types of timeout for the mutex lock.
|
||||||
*/
|
*/
|
||||||
enum TimeoutType {
|
enum class TimeoutType {
|
||||||
POLLING, //!< If mutex is not available, return immediately
|
POLLING, //!< If mutex is not available, return immediately
|
||||||
WAITING, //!< Wait a specified time for the mutex to become available
|
WAITING, //!< Wait a specified time for the mutex to become available
|
||||||
BLOCKING //!< Block indefinitely until the mutex becomes available.
|
BLOCKING //!< Block indefinitely until the mutex becomes available.
|
||||||
|
@ -16,7 +16,9 @@ ReturnValue_t MemoryHelper::handleMemoryCommand(CommandMessage* message) {
|
|||||||
lastSender = message->getSender();
|
lastSender = message->getSender();
|
||||||
lastCommand = message->getCommand();
|
lastCommand = message->getCommand();
|
||||||
if (busy) {
|
if (busy) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "MemHelper: Busy!" << std::endl;
|
sif::debug << "MemHelper: Busy!" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
switch (lastCommand) {
|
switch (lastCommand) {
|
||||||
case MemoryMessage::CMD_MEMORY_DUMP:
|
case MemoryMessage::CMD_MEMORY_DUMP:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "MonitoringIF.h"
|
#include "MonitoringIF.h"
|
||||||
#include "MonitoringMessageContent.h"
|
#include "MonitoringMessageContent.h"
|
||||||
|
|
||||||
#include "../datapoollocal/locPoolDefinitions.h"
|
#include "../datapoollocal/localPoolDefinitions.h"
|
||||||
#include "../events/EventManagerIF.h"
|
#include "../events/EventManagerIF.h"
|
||||||
#include "../parameters/HasParametersIF.h"
|
#include "../parameters/HasParametersIF.h"
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#ifndef MONITORINGMESSAGECONTENT_H_
|
#ifndef FSFW_MONITORING_MONITORINGMESSAGECONTENT_H_
|
||||||
#define MONITORINGMESSAGECONTENT_H_
|
#define FSFW_MONITORING_MONITORINGMESSAGECONTENT_H_
|
||||||
|
|
||||||
#include "HasMonitorsIF.h"
|
#include "HasMonitorsIF.h"
|
||||||
#include "MonitoringIF.h"
|
#include "MonitoringIF.h"
|
||||||
#include "../datapoollocal/locPoolDefinitions.h"
|
|
||||||
|
#include "../datapoollocal/localPoolDefinitions.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
#include "../serialize/SerialBufferAdapter.h"
|
#include "../serialize/SerialBufferAdapter.h"
|
||||||
#include "../serialize/SerialFixedArrayListAdapter.h"
|
#include "../serialize/SerialFixedArrayListAdapter.h"
|
||||||
@ -72,8 +73,10 @@ private:
|
|||||||
if (timeStamper == nullptr) {
|
if (timeStamper == nullptr) {
|
||||||
timeStamper = objectManager->get<TimeStamperIF>( timeStamperId );
|
timeStamper = objectManager->get<TimeStamperIF>( timeStamperId );
|
||||||
if ( timeStamper == nullptr ) {
|
if ( timeStamper == nullptr ) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MonitoringReportContent::checkAndSetStamper: "
|
sif::error << "MonitoringReportContent::checkAndSetStamper: "
|
||||||
"Stamper not found!" << std::endl;
|
"Stamper not found!" << std::endl;
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,4 +86,4 @@ private:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
object_id_t MonitoringReportContent<T>::timeStamperId = 0;
|
object_id_t MonitoringReportContent<T>::timeStamperId = 0;
|
||||||
|
|
||||||
#endif /* MONITORINGMESSAGECONTENT_H_ */
|
#endif /* FSFW_MONITORING_MONITORINGMESSAGECONTENT_H_ */
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#include "ObjectManager.h"
|
#include "ObjectManager.h"
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#endif
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
ObjectManager::ObjectManager( void (*setProducer)() ):
|
ObjectManager::ObjectManager( void (*setProducer)() ):
|
||||||
@ -18,13 +21,18 @@ ObjectManager::~ObjectManager() {
|
|||||||
ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) {
|
ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) {
|
||||||
auto returnPair = objectList.emplace(id, object);
|
auto returnPair = objectList.emplace(id, object);
|
||||||
if (returnPair.second) {
|
if (returnPair.second) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// sif::debug << "ObjectManager::insert: Object " << std::hex
|
// sif::debug << "ObjectManager::insert: Object " << std::hex
|
||||||
// << (int)id << std::dec << " inserted." << std::endl;
|
// << (int)id << std::dec << " inserted." << std::endl;
|
||||||
|
#endif
|
||||||
return this->RETURN_OK;
|
return this->RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "ObjectManager::insert: Object id " << std::hex
|
sif::error << "ObjectManager::insert: Object id " << std::hex
|
||||||
<< (int)id << std::dec << " is already in use!" << std::endl;
|
<< static_cast<uint32_t>(id) << std::dec
|
||||||
|
<< " is already in use!" << std::endl;
|
||||||
sif::error << "Terminating program." << std::endl;
|
sif::error << "Terminating program." << std::endl;
|
||||||
|
#endif
|
||||||
//This is very severe and difficult to handle in other places.
|
//This is very severe and difficult to handle in other places.
|
||||||
std::exit(INSERTION_FAILED);
|
std::exit(INSERTION_FAILED);
|
||||||
}
|
}
|
||||||
@ -33,12 +41,16 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) {
|
|||||||
ReturnValue_t ObjectManager::remove( object_id_t id ) {
|
ReturnValue_t ObjectManager::remove( object_id_t id ) {
|
||||||
if ( this->getSystemObject(id) != NULL ) {
|
if ( this->getSystemObject(id) != NULL ) {
|
||||||
this->objectList.erase( id );
|
this->objectList.erase( id );
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
//sif::debug << "ObjectManager::removeObject: Object " << std::hex
|
//sif::debug << "ObjectManager::removeObject: Object " << std::hex
|
||||||
// << (int)id << std::dec << " removed." << std::endl;
|
// << (int)id << std::dec << " removed." << std::endl;
|
||||||
|
#endif
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "ObjectManager::removeObject: Requested object "
|
sif::error << "ObjectManager::removeObject: Requested object "
|
||||||
<< std::hex << (int)id << std::dec << " not found." << std::endl;
|
<< std::hex << (int)id << std::dec << " not found." << std::endl;
|
||||||
|
#endif
|
||||||
return NOT_FOUND;
|
return NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,8 +72,10 @@ ObjectManager::ObjectManager() : produceObjects(nullptr) {
|
|||||||
|
|
||||||
void ObjectManager::initialize() {
|
void ObjectManager::initialize() {
|
||||||
if(produceObjects == nullptr) {
|
if(produceObjects == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "ObjectManager::initialize: Passed produceObjects "
|
sif::error << "ObjectManager::initialize: Passed produceObjects "
|
||||||
"functions is nullptr!" << std::endl;
|
"functions is nullptr!" << std::endl;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->produceObjects();
|
this->produceObjects();
|
||||||
@ -70,38 +84,49 @@ void ObjectManager::initialize() {
|
|||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
result = it.second->initialize();
|
result = it.second->initialize();
|
||||||
if ( result != RETURN_OK ) {
|
if ( result != RETURN_OK ) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
object_id_t var = it.first;
|
object_id_t var = it.first;
|
||||||
sif::error << "ObjectManager::initialize: Object 0x" << std::hex <<
|
sif::error << "ObjectManager::initialize: Object 0x" << std::hex <<
|
||||||
std::setw(8) << std::setfill('0')<< var << " failed to "
|
std::setw(8) << std::setfill('0')<< var << " failed to "
|
||||||
"initialize with code 0x" << result << std::dec <<
|
"initialize with code 0x" << result << std::dec <<
|
||||||
std::setfill(' ') << std::endl;
|
std::setfill(' ') << std::endl;
|
||||||
|
#endif
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errorCount > 0) {
|
if (errorCount > 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
||||||
<< " failed initializations." << std::endl;
|
<< " failed initializations." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
//Init was successful. Now check successful interconnections.
|
//Init was successful. Now check successful interconnections.
|
||||||
errorCount = 0;
|
errorCount = 0;
|
||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
result = it.second->checkObjectConnections();
|
result = it.second->checkObjectConnections();
|
||||||
if ( result != RETURN_OK ) {
|
if ( result != RETURN_OK ) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "ObjectManager::ObjectManager: Object " << std::hex <<
|
sif::error << "ObjectManager::ObjectManager: Object " << std::hex <<
|
||||||
(int) it.first << " connection check failed with code 0x"
|
(int) it.first << " connection check failed with code 0x"
|
||||||
<< result << std::dec << std::endl;
|
<< result << std::dec << std::endl;
|
||||||
|
#endif
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errorCount > 0) {
|
if (errorCount > 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
||||||
<< " failed connection checks." << std::endl;
|
<< " failed connection checks." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::printList() {
|
void ObjectManager::printList() {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "ObjectManager: Object List contains:" << std::endl;
|
sif::debug << "ObjectManager: Object List contains:" << std::endl;
|
||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
sif::debug << std::hex << it.first << " | " << it.second << std::endl;
|
sif::debug << std::hex << it.first << " | " << it.second << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,10 @@ extern ObjectManagerIF *objectManager;
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T* ObjectManagerIF::get( object_id_t id ) {
|
T* ObjectManagerIF::get( object_id_t id ) {
|
||||||
if(objectManager == nullptr) {
|
if(objectManager == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "ObjectManagerIF: Global object manager has not "
|
sif::error << "ObjectManagerIF: Global object manager has not "
|
||||||
"been initialized yet!" << std::endl;
|
"been initialized yet!" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
SystemObjectIF* temp = this->getSystemObject(id);
|
SystemObjectIF* temp = this->getSystemObject(id);
|
||||||
return dynamic_cast<T*>(temp);
|
return dynamic_cast<T*>(temp);
|
||||||
|
@ -8,8 +8,10 @@
|
|||||||
BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() {
|
BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() {
|
||||||
handle = TaskManagement::getCurrentTaskHandle();
|
handle = TaskManagement::getCurrentTaskHandle();
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Could not retrieve task handle. Please ensure the"
|
sif::error << "Could not retrieve task handle. Please ensure the"
|
||||||
"constructor was called inside a task." << std::endl;
|
"constructor was called inside a task." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
xTaskNotifyGive(handle);
|
xTaskNotifyGive(handle);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
BinarySemaphore::BinarySemaphore() {
|
BinarySemaphore::BinarySemaphore() {
|
||||||
handle = xSemaphoreCreateBinary();
|
handle = xSemaphoreCreateBinary();
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Semaphore: Binary semaph creation failure" << std::endl;
|
sif::error << "Semaphore: Binary semaph creation failure" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// Initiated semaphore must be given before it can be taken.
|
// Initiated semaphore must be given before it can be taken.
|
||||||
xSemaphoreGive(handle);
|
xSemaphoreGive(handle);
|
||||||
@ -18,7 +20,9 @@ BinarySemaphore::~BinarySemaphore() {
|
|||||||
BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) {
|
BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) {
|
||||||
handle = xSemaphoreCreateBinary();
|
handle = xSemaphoreCreateBinary();
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Binary semaphore creation failure" << std::endl;
|
sif::error << "Binary semaphore creation failure" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
xSemaphoreGive(handle);
|
xSemaphoreGive(handle);
|
||||||
}
|
}
|
||||||
@ -28,7 +32,9 @@ BinarySemaphore& BinarySemaphore::operator =(
|
|||||||
if(&s != this) {
|
if(&s != this) {
|
||||||
handle = xSemaphoreCreateBinary();
|
handle = xSemaphoreCreateBinary();
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Binary semaphore creation failure" << std::endl;
|
sif::error << "Binary semaphore creation failure" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
xSemaphoreGive(handle);
|
xSemaphoreGive(handle);
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
|
|||||||
if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) {
|
if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
|
ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
|||||||
if (timeMutex == NULL) {
|
if (timeMutex == NULL) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
|
ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -9,25 +9,31 @@
|
|||||||
CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount,
|
CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount,
|
||||||
uint8_t initCount): maxCount(maxCount) {
|
uint8_t initCount): maxCount(maxCount) {
|
||||||
if(initCount > maxCount) {
|
if(initCount > maxCount) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
|
sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
|
||||||
"intial cout. Setting initial count to max count." << std::endl;
|
"intial cout. Setting initial count to max count." << std::endl;
|
||||||
|
#endif
|
||||||
initCount = maxCount;
|
initCount = maxCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = TaskManagement::getCurrentTaskHandle();
|
handle = TaskManagement::getCurrentTaskHandle();
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CountingSemaphoreUsingTask: Could not retrieve task "
|
sif::error << "CountingSemaphoreUsingTask: Could not retrieve task "
|
||||||
"handle. Please ensure the constructor was called inside a "
|
"handle. Please ensure the constructor was called inside a "
|
||||||
"task." << std::endl;
|
"task." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t oldNotificationValue;
|
uint32_t oldNotificationValue;
|
||||||
xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite,
|
xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite,
|
||||||
&oldNotificationValue);
|
&oldNotificationValue);
|
||||||
if(oldNotificationValue != 0) {
|
if(oldNotificationValue != 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "CountinSemaphoreUsingTask: Semaphore initiated but "
|
sif::warning << "CountinSemaphoreUsingTask: Semaphore initiated but "
|
||||||
"current notification value is not 0. Please ensure the "
|
"current notification value is not 0. Please ensure the "
|
||||||
"notification value is not used for other purposes!" << std::endl;
|
"notification value is not used for other purposes!" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
for(int i = 0; i < initCount; i++) {
|
for(int i = 0; i < initCount; i++) {
|
||||||
xTaskNotifyGive(handle);
|
xTaskNotifyGive(handle);
|
||||||
|
@ -10,14 +10,18 @@
|
|||||||
CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount):
|
CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount):
|
||||||
maxCount(maxCount), initCount(initCount) {
|
maxCount(maxCount), initCount(initCount) {
|
||||||
if(initCount > maxCount) {
|
if(initCount > maxCount) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
|
sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
|
||||||
"intial cout. Setting initial count to max count." << std::endl;
|
"intial cout. Setting initial count to max count." << std::endl;
|
||||||
|
#endif
|
||||||
initCount = maxCount;
|
initCount = maxCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = xSemaphoreCreateCounting(maxCount, initCount);
|
handle = xSemaphoreCreateCounting(maxCount, initCount);
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CountingSemaphore: Creation failure" << std::endl;
|
sif::error << "CountingSemaphore: Creation failure" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +29,9 @@ CountingSemaphore::CountingSemaphore(CountingSemaphore&& other):
|
|||||||
maxCount(other.maxCount), initCount(other.initCount) {
|
maxCount(other.maxCount), initCount(other.initCount) {
|
||||||
handle = xSemaphoreCreateCounting(other.maxCount, other.initCount);
|
handle = xSemaphoreCreateCounting(other.maxCount, other.initCount);
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CountingSemaphore: Creation failure" << std::endl;
|
sif::error << "CountingSemaphore: Creation failure" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +39,9 @@ CountingSemaphore& CountingSemaphore::operator =(
|
|||||||
CountingSemaphore&& other) {
|
CountingSemaphore&& other) {
|
||||||
handle = xSemaphoreCreateCounting(other.maxCount, other.initCount);
|
handle = xSemaphoreCreateCounting(other.maxCount, other.initCount);
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CountingSemaphore: Creation failure" << std::endl;
|
sif::error << "CountingSemaphore: Creation failure" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return * this;
|
return * this;
|
||||||
}
|
}
|
||||||
|
@ -37,15 +37,19 @@ void FixedTimeslotTask::taskEntryPoint(void* argument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
originalTask->taskFunctionality();
|
originalTask->taskFunctionality();
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Polling task " << originalTask->handle
|
sif::debug << "Polling task " << originalTask->handle
|
||||||
<< " returned from taskFunctionality." << std::endl;
|
<< " returned from taskFunctionality." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedTimeslotTask::missedDeadlineCounter() {
|
void FixedTimeslotTask::missedDeadlineCounter() {
|
||||||
FixedTimeslotTask::deadlineMissedCount++;
|
FixedTimeslotTask::deadlineMissedCount++;
|
||||||
if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) {
|
if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount
|
sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount
|
||||||
<< " deadlines." << std::endl;
|
<< " deadlines." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,8 +73,10 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Component " << std::hex << componentId <<
|
sif::error << "Component " << std::hex << componentId <<
|
||||||
" not found, not adding it to pst" << std::endl;
|
" not found, not adding it to pst" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
|
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
|
||||||
maxMessageSize(maxMessageSize) {
|
maxMessageSize(maxMessageSize) {
|
||||||
handle = xQueueCreate(messageDepth, maxMessageSize);
|
handle = xQueueCreate(messageDepth, maxMessageSize);
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
sif::error << "MessageQueue::MessageQueue:"
|
sif::error << "MessageQueue::MessageQueue:"
|
||||||
<< " Creation failed." << std::endl;
|
<< " Creation failed." << std::endl;
|
||||||
@ -17,7 +18,9 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
sif::error << "Specified Maximum Message Size: "
|
sif::error << "Specified Maximum Message Size: "
|
||||||
<< maxMessageSize << std::endl;
|
<< maxMessageSize << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue::~MessageQueue() {
|
MessageQueue::~MessageQueue() {
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
Mutex::Mutex() {
|
Mutex::Mutex() {
|
||||||
handle = xSemaphoreCreateMutex();
|
handle = xSemaphoreCreateMutex();
|
||||||
if(handle == nullptr) {
|
if(handle == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Mutex::Mutex(FreeRTOS): Creation failure" << std::endl;
|
sif::error << "Mutex::Mutex(FreeRTOS): Creation failure" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,10 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
|
|||||||
BaseType_t status = xTaskCreate(taskEntryPoint, name,
|
BaseType_t status = xTaskCreate(taskEntryPoint, name,
|
||||||
stackSize, this, setPriority, &handle);
|
stackSize, this, setPriority, &handle);
|
||||||
if(status != pdPASS){
|
if(status != pdPASS){
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "PeriodicTask Insufficient heap memory remaining. "
|
sif::debug << "PeriodicTask Insufficient heap memory remaining. "
|
||||||
"Status: " << status << std::endl;
|
"Status: " << status << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -41,8 +43,10 @@ void PeriodicTask::taskEntryPoint(void* argument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
originalTask->taskFunctionality();
|
originalTask->taskFunctionality();
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Polling task " << originalTask->handle
|
sif::debug << "Polling task " << originalTask->handle
|
||||||
<< " returned from taskFunctionality." << std::endl;
|
<< " returned from taskFunctionality." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PeriodicTask::startTask() {
|
ReturnValue_t PeriodicTask::startTask() {
|
||||||
@ -99,8 +103,10 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
|
|||||||
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
|
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
|
||||||
object);
|
object);
|
||||||
if (newObject == nullptr) {
|
if (newObject == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
|
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
|
||||||
"it implement ExecutableObjectIF" << std::endl;
|
"it implement ExecutableObjectIF" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
objectList.push_back(newObject);
|
objectList.push_back(newObject);
|
||||||
|
@ -32,8 +32,10 @@ SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) {
|
|||||||
return new BinarySemaphoreUsingTask();
|
return new BinarySemaphoreUsingTask();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SemaphoreFactory: Invalid argument, return regular"
|
sif::warning << "SemaphoreFactory: Invalid argument, return regular"
|
||||||
"binary semaphore" << std::endl;
|
"binary semaphore" << std::endl;
|
||||||
|
#endif
|
||||||
return new BinarySemaphore();
|
return new BinarySemaphore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,8 +49,10 @@ SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount,
|
|||||||
return new CountingSemaphoreUsingTask(maxCount, initCount);
|
return new CountingSemaphoreUsingTask(maxCount, initCount);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SemaphoreFactory: Invalid argument, return regular"
|
sif::warning << "SemaphoreFactory: Invalid argument, return regular"
|
||||||
"binary semaphore" << std::endl;
|
"binary semaphore" << std::endl;
|
||||||
|
#endif
|
||||||
return new CountingSemaphore(maxCount, initCount);
|
return new CountingSemaphore(maxCount, initCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,11 @@ target_sources(${LIB_FSFW_NAME}
|
|||||||
)
|
)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
target_link_libraries(${LIB_FSFW_NAME}
|
target_link_libraries(${LIB_FSFW_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
rt
|
rt
|
||||||
pthread
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
@ -14,7 +14,9 @@ MutexIF* Clock::timeMutex = NULL;
|
|||||||
using SystemClock = std::chrono::system_clock;
|
using SystemClock = std::chrono::system_clock;
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void){
|
uint32_t Clock::getTicksPerSecond(void){
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::getTicksPerSecond: not implemented yet" << std::endl;
|
sif::warning << "Clock::getTicksPerSecond: not implemented yet" << std::endl;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
//return CLOCKS_PER_SEC;
|
//return CLOCKS_PER_SEC;
|
||||||
//uint32_t ticks = sysconf(_SC_CLK_TCK);
|
//uint32_t ticks = sysconf(_SC_CLK_TCK);
|
||||||
@ -23,7 +25,9 @@ uint32_t Clock::getTicksPerSecond(void){
|
|||||||
|
|
||||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||||
// do some magic with chrono
|
// do some magic with chrono
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::setClock: not implemented yet" << std::endl;
|
sif::warning << "Clock::setClock: not implemented yet" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +40,9 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +66,9 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||||||
time->tv_usec = timeUnix.tv_nsec / 1000.0;
|
time->tv_usec = timeUnix.tv_nsec / 1000.0;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
#else
|
#else
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -68,7 +76,9 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||||||
|
|
||||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||||
// do some magic with chrono
|
// do some magic with chrono
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::gerClock_usecs: not implemented yet" << std::endl;
|
sif::warning << "Clock::gerClock_usecs: not implemented yet" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +100,9 @@ timeval Clock::getUptime() {
|
|||||||
timeval.tv_usec = uptimeSeconds *(double) 1e6 - (timeval.tv_sec *1e6);
|
timeval.tv_usec = uptimeSeconds *(double) 1e6 - (timeval.tv_sec *1e6);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return timeval;
|
return timeval;
|
||||||
}
|
}
|
||||||
@ -126,7 +138,9 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
|||||||
auto usecond = std::chrono::duration_cast<std::chrono::microseconds>(fraction);
|
auto usecond = std::chrono::duration_cast<std::chrono::microseconds>(fraction);
|
||||||
time->usecond = usecond.count();
|
time->usecond = usecond.count();
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
//sif::warning << "Clock::getDateAndTime: not implemented yet" << std::endl;
|
//sif::warning << "Clock::getDateAndTime: not implemented yet" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +162,9 @@ ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from,
|
|||||||
to->tv_usec = from->usecond;
|
to->tv_usec = from->usecond;
|
||||||
//Fails in 2038..
|
//Fails in 2038..
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Clock::convertTimeBla: not implemented yet" << std::endl;
|
sif::warning << "Clock::convertTimeBla: not implemented yet" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +202,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
|
|||||||
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
|
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
|
ReturnValue_t result = timeMutex->lockMutex();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -201,7 +217,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
|||||||
if(timeMutex == nullptr){
|
if(timeMutex == nullptr){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
|
ReturnValue_t result = timeMutex->lockMutex();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,19 @@ FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority,
|
|||||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||||
ABOVE_NORMAL_PRIORITY_CLASS);
|
ABOVE_NORMAL_PRIORITY_CLASS);
|
||||||
if(result != 0) {
|
if(result != 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
|
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
|
||||||
<< GetLastError() << std::endl;
|
<< GetLastError() << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
result = SetThreadPriority(
|
result = SetThreadPriority(
|
||||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||||
THREAD_PRIORITY_NORMAL);
|
THREAD_PRIORITY_NORMAL);
|
||||||
if(result != 0) {
|
if(result != 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
|
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
|
||||||
<< GetLastError() << std::endl;
|
<< GetLastError() << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#elif defined(LINUX)
|
#elif defined(LINUX)
|
||||||
// TODO: we can just copy and paste the code from the linux OSAL here.
|
// TODO: we can just copy and paste the code from the linux OSAL here.
|
||||||
@ -70,8 +74,10 @@ void FixedTimeslotTask::taskEntryPoint(void* argument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->taskFunctionality();
|
this->taskFunctionality();
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "FixedTimeslotTask::taskEntryPoint: "
|
sif::debug << "FixedTimeslotTask::taskEntryPoint: "
|
||||||
"Returned from taskFunctionality." << std::endl;
|
"Returned from taskFunctionality." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t FixedTimeslotTask::startTask() {
|
ReturnValue_t FixedTimeslotTask::startTask() {
|
||||||
@ -134,8 +140,10 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Component " << std::hex << componentId <<
|
sif::error << "Component " << std::hex << componentId <<
|
||||||
" not found, not adding it to pst" << std::endl;
|
" not found, not adding it to pst" << std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,8 +10,10 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
|
|||||||
queueLock = MutexFactory::instance()->createMutex();
|
queueLock = MutexFactory::instance()->createMutex();
|
||||||
auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId);
|
auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MessageQueue::MessageQueue:"
|
sif::error << "MessageQueue::MessageQueue:"
|
||||||
<< " Could not be created" << std::endl;
|
<< " Could not be created" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,8 +139,10 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
targetQueue->messageQueue.push(*mqmMessage);
|
targetQueue->messageQueue.push(*mqmMessage);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message"
|
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message"
|
||||||
"is not MessageQueueMessage!" << std::endl;
|
"is not MessageQueueMessage!" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,16 @@
|
|||||||
Mutex::Mutex() {}
|
Mutex::Mutex() {}
|
||||||
|
|
||||||
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
|
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
if(timeoutType == MutexIF::BLOCKING) {
|
if(timeoutType == TimeoutType::BLOCKING) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
else if(timeoutType == MutexIF::POLLING) {
|
else if(timeoutType == TimeoutType::POLLING) {
|
||||||
if(mutex.try_lock()) {
|
if(mutex.try_lock()) {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(timeoutMs > MutexIF::POLLING){
|
else if(timeoutType == TimeoutType::WAITING){
|
||||||
auto chronoMs = std::chrono::milliseconds(timeoutMs);
|
auto chronoMs = std::chrono::milliseconds(timeoutMs);
|
||||||
if(mutex.try_lock_for(chronoMs)) {
|
if(mutex.try_lock_for(chronoMs)) {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
@ -22,7 +22,6 @@ public:
|
|||||||
|
|
||||||
std::timed_mutex* getMutexHandle();
|
std::timed_mutex* getMutexHandle();
|
||||||
private:
|
private:
|
||||||
//bool locked = false;
|
|
||||||
std::timed_mutex mutex;
|
std::timed_mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,15 +33,19 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
|
|||||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||||
ABOVE_NORMAL_PRIORITY_CLASS);
|
ABOVE_NORMAL_PRIORITY_CLASS);
|
||||||
if(result != 0) {
|
if(result != 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
||||||
<< GetLastError() << std::endl;
|
<< GetLastError() << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
result = SetThreadPriority(
|
result = SetThreadPriority(
|
||||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||||
THREAD_PRIORITY_NORMAL);
|
THREAD_PRIORITY_NORMAL);
|
||||||
if(result != 0) {
|
if(result != 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
|
||||||
<< GetLastError() << std::endl;
|
<< GetLastError() << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#elif defined(LINUX)
|
#elif defined(LINUX)
|
||||||
// we can just copy and paste the code from linux here.
|
// we can just copy and paste the code from linux here.
|
||||||
@ -69,8 +73,10 @@ void PeriodicTask::taskEntryPoint(void* argument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->taskFunctionality();
|
this->taskFunctionality();
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "PeriodicTask::taskEntryPoint: "
|
sif::debug << "PeriodicTask::taskEntryPoint: "
|
||||||
"Returned from taskFunctionality." << std::endl;
|
"Returned from taskFunctionality." << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PeriodicTask::startTask() {
|
ReturnValue_t PeriodicTask::startTask() {
|
||||||
|
@ -26,8 +26,10 @@ ReturnValue_t QueueMapManager::addMessageQueue(
|
|||||||
auto returnPair = queueMap.emplace(currentId, queueToInsert);
|
auto returnPair = queueMap.emplace(currentId, queueToInsert);
|
||||||
if(not returnPair.second) {
|
if(not returnPair.second) {
|
||||||
// this should never happen for the atomic variable.
|
// this should never happen for the atomic variable.
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "QueueMapManager: This ID is already inside the map!"
|
sif::error << "QueueMapManager: This ID is already inside the map!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if (id != nullptr) {
|
if (id != nullptr) {
|
||||||
@ -44,8 +46,10 @@ MessageQueueIF* QueueMapManager::getMessageQueue(
|
|||||||
return queueIter->second;
|
return queueIter->second;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "QueueMapManager::getQueueHandle: The ID " <<
|
sif::warning << "QueueMapManager::getQueueHandle: The ID " <<
|
||||||
messageQueueId << " does not exists in the map" << std::endl;
|
messageQueueId << " does not exists in the map" << std::endl;
|
||||||
|
#endif
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user