Update HK and datapool handling #45
14
CHANGELOG.md
14
CHANGELOG.md
@ -34,6 +34,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
|
- Complete overhaul of HK subsystem. Replaced local data pool manager by periodic HK
|
||||||
|
helper. The shared pool and the periodic HK generation are now distinct concepts.
|
||||||
|
- The local HK manager was replaced by a periodic HK helper which has reduced responsibilities.
|
||||||
|
It takes care of tracking the HK generation using a set specification provided by the user.n
|
||||||
|
However, it leaves serialization of the HK data completely to the developer. This removes a major
|
||||||
|
constraint on the format of the HK data, which was previously constrained to implementors of a
|
||||||
|
certain base class.
|
||||||
|
- The former set classes and pool objects are still available for HK set specification and
|
||||||
|
generation. The API has changed, but the general usage and their architecture has not.
|
||||||
|
- A new set of set classes and helper objects to specify HK sets and data which does not need to be
|
||||||
|
shared was added as well. The majority of datasets do not need to be shared anyway.
|
||||||
|
- The non-shared API retain the capability of appending of a validity blob for each piece of set
|
||||||
|
data at the end of the HK data. For both non-shared and shared data, this capability can be
|
||||||
|
specified in the constructor, and defaults to true.
|
||||||
- Improved File System Abstraction to be more in line with normal filesystems.
|
- Improved File System Abstraction to be more in line with normal filesystems.
|
||||||
- CFDP implementation was improved, has now even less dependencies on other FSFW components
|
- CFDP implementation was improved, has now even less dependencies on other FSFW components
|
||||||
and allows one inserted packet per state machine call.
|
and allows one inserted packet per state machine call.
|
||||||
|
@ -142,7 +142,7 @@ if(FSFW_BUILD_TESTS)
|
|||||||
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
||||||
|
|
||||||
project(${FSFW_TEST_TGT} CXX C)
|
project(${FSFW_TEST_TGT} CXX C)
|
||||||
add_executable(${FSFW_TEST_TGT})
|
add_executable(${FSFW_TEST_TGT} unittests/datapool/testDataset.cpp)
|
||||||
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
||||||
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
||||||
TRUE)
|
TRUE)
|
||||||
|
@ -8,7 +8,8 @@ GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceC
|
|||||||
CookieIF *comCookie, uint32_t transitionDelayMs)
|
CookieIF *comCookie, uint32_t transitionDelayMs)
|
||||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
transitionDelayMs(transitionDelayMs),
|
transitionDelayMs(transitionDelayMs),
|
||||||
dataset(this) {}
|
sharedPool(DeviceHandlerBase::getObjectId()),
|
||||||
|
dataset(sharedPool) {}
|
||||||
|
|
||||||
GyroHandlerL3GD20H::~GyroHandlerL3GD20H() {}
|
GyroHandlerL3GD20H::~GyroHandlerL3GD20H() {}
|
||||||
|
|
||||||
@ -210,27 +211,27 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
if (readSet.getReadResult() == returnvalue::OK) {
|
if (readSet.getReadResult() == returnvalue::OK) {
|
||||||
if (std::abs(angVelocX) < this->absLimitX) {
|
if (std::abs(angVelocX) < this->absLimitX) {
|
||||||
dataset.angVelocX = angVelocX;
|
dataset.angVelocX = angVelocX;
|
||||||
dataset.angVelocX.setValid(true);
|
// dataset.angVelocX.setValid(true);
|
||||||
} else {
|
} else {
|
||||||
dataset.angVelocX.setValid(false);
|
// dataset.angVelocX.setValid(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::abs(angVelocY) < this->absLimitY) {
|
if (std::abs(angVelocY) < this->absLimitY) {
|
||||||
dataset.angVelocY = angVelocY;
|
dataset.angVelocY = angVelocY;
|
||||||
dataset.angVelocY.setValid(true);
|
// dataset.angVelocY.setValid(true);
|
||||||
} else {
|
} else {
|
||||||
dataset.angVelocY.setValid(false);
|
// dataset.angVelocY.setValid(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::abs(angVelocZ) < this->absLimitZ) {
|
if (std::abs(angVelocZ) < this->absLimitZ) {
|
||||||
dataset.angVelocZ = angVelocZ;
|
dataset.angVelocZ = angVelocZ;
|
||||||
dataset.angVelocZ.setValid(true);
|
// dataset.angVelocZ.setValid(true);
|
||||||
} else {
|
} else {
|
||||||
dataset.angVelocZ.setValid(false);
|
// dataset.angVelocZ.setValid(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
dataset.temperature = temperature;
|
dataset.temperature = temperature;
|
||||||
dataset.temperature.setValid(true);
|
// dataset.temperature.setValid(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -246,16 +247,19 @@ uint32_t GyroHandlerL3GD20H::getTransitionDelayMs(Mode_t from, Mode_t to) {
|
|||||||
|
|
||||||
void GyroHandlerL3GD20H::setToGoToNormalMode(bool enable) { this->goNormalModeImmediately = true; }
|
void GyroHandlerL3GD20H::setToGoToNormalMode(bool enable) { this->goNormalModeImmediately = true; }
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
/*
|
||||||
ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) {
|
PeriodicHkGenerationHelper &hkGenHelper) {
|
||||||
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_X, new PoolEntry<float>({0.0}));
|
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_X, new PoolEntry<float>({0.0}));
|
||||||
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
||||||
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
||||||
localDataPoolMap.emplace(l3gd20h::TEMPERATURE, new PoolEntry<float>({0.0}));
|
localDataPoolMap.emplace(l3gd20h::TEMPERATURE, new PoolEntry<float>({0.0}));
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
hkGenHelper.enableRegularPeriodicPacket(
|
||||||
subdp::RegularHkPeriodicParams(dataset.getSid(), false, 10.0));
|
subdp::RegularHkPeriodicParams(dataset.getSid(), false, 10.0));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void GyroHandlerL3GD20H::fillCommandAndReplyMap() {
|
void GyroHandlerL3GD20H::fillCommandAndReplyMap() {
|
||||||
insertInCommandAndReplyMap(l3gd20h::READ_REGS, 1, &dataset);
|
insertInCommandAndReplyMap(l3gd20h::READ_REGS, 1, &dataset);
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
#ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
||||||
#define MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
#define MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||||
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
|
#include "gyroL3gHelpers.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device Handler for the L3GD20H gyroscope sensor
|
* @brief Device Handler for the L3GD20H gyroscope sensor
|
||||||
@ -51,11 +51,12 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase {
|
|||||||
void fillCommandAndReplyMap() override;
|
void fillCommandAndReplyMap() override;
|
||||||
void modeChanged() override;
|
void modeChanged() override;
|
||||||
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
// ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) override;
|
// PeriodicHkGenerationHelper &hkGenHelper) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t transitionDelayMs = 0;
|
uint32_t transitionDelayMs = 0;
|
||||||
|
localpool::SharedPool sharedPool;
|
||||||
GyroPrimaryDataset dataset;
|
GyroPrimaryDataset dataset;
|
||||||
|
|
||||||
float absLimitX = l3gd20h::RANGE_DPS_00;
|
float absLimitX = l3gd20h::RANGE_DPS_00;
|
13
misc/archive/HasLocalDpIFManagerAttorney.cpp
Normal file
13
misc/archive/HasLocalDpIFManagerAttorney.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "HasLocalDpIFManagerAttorney.h"
|
||||||
|
|
||||||
|
#include "fsfw/datapool/LocalPoolObjectBase.h"
|
||||||
|
#include "fsfw/housekeeping/GeneratesPeriodicHkIF.h"
|
||||||
|
|
||||||
|
LocalPoolObjectBase* HasLocalDpIFManagerAttorney::getPoolObjectHandle(
|
||||||
|
PeriodicHkGenerationIF* clientIF, dp::lp_id_t localPoolId) {
|
||||||
|
return clientIF->getPoolObjectHandle(localPoolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_t HasLocalDpIFManagerAttorney::getObjectId(PeriodicHkGenerationIF* clientIF) {
|
||||||
|
return clientIF->getObjectId();
|
||||||
|
}
|
17
misc/archive/HasLocalDpIFManagerAttorney.h
Normal file
17
misc/archive/HasLocalDpIFManagerAttorney.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <fsfw/housekeeping/PeriodicHkHelper.h>
|
||||||
|
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
|
||||||
|
class PeriodicHkGenerationIF;
|
||||||
|
class LocalPoolDataSetBase;
|
||||||
|
class LocalPoolObjectBase;
|
||||||
|
|
||||||
|
class HasLocalDpIFManagerAttorney {
|
||||||
|
static LocalPoolObjectBase* getPoolObjectHandle(PeriodicHkGenerationIF* clientIF,
|
||||||
|
dp::id_t localPoolId);
|
||||||
|
|
||||||
|
static object_id_t getObjectId(PeriodicHkGenerationIF* clientIF);
|
||||||
|
|
||||||
|
friend class hk::PeriodicHelper;
|
||||||
|
};
|
1
misc/archive/HasLocalDpIFUserAttorney.cpp
Normal file
1
misc/archive/HasLocalDpIFUserAttorney.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "HasLocalDpIFUserAttorney.h"
|
@ -1,12 +1,12 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
|
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
|
||||||
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
|
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
|
||||||
|
|
||||||
class HasLocalDataPoolIF;
|
class PeriodicHkGenerationIF;
|
||||||
class AccessPoolManagerIF;
|
class AccessPoolManagerIF;
|
||||||
|
|
||||||
class HasLocalDpIFUserAttorney {
|
class HasLocalDpIFUserAttorney {
|
||||||
private:
|
private:
|
||||||
static AccessPoolManagerIF* getAccessorHandle(HasLocalDataPoolIF* clientIF);
|
// static AccessPoolManagerIF* getAccessorHandle(PeriodicHkGenerationIF* clientIF);
|
||||||
|
|
||||||
friend class LocalPoolObjectBase;
|
friend class LocalPoolObjectBase;
|
||||||
friend class LocalPoolDataSetBase;
|
friend class LocalPoolDataSetBase;
|
@ -273,7 +273,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
|||||||
if (readHelper.getReadResult() == returnvalue::OK) {
|
if (readHelper.getReadResult() == returnvalue::OK) {
|
||||||
if (std::abs(mgmX) > absLimitX or std::abs(mgmY) > absLimitY or
|
if (std::abs(mgmX) > absLimitX or std::abs(mgmY) > absLimitY or
|
||||||
std::abs(mgmZ) > absLimitZ) {
|
std::abs(mgmZ) > absLimitZ) {
|
||||||
dataset.fieldStrengths.setValid(false);
|
dataset.setIsValid = false;
|
||||||
}
|
}
|
||||||
if (std::abs(mgmX) < absLimitX) {
|
if (std::abs(mgmX) < absLimitX) {
|
||||||
dataset.fieldStrengths[0] = mgmX;
|
dataset.fieldStrengths[0] = mgmX;
|
||||||
@ -286,7 +286,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
|||||||
if (std::abs(mgmZ) < absLimitZ) {
|
if (std::abs(mgmZ) < absLimitZ) {
|
||||||
dataset.fieldStrengths[2] = mgmZ;
|
dataset.fieldStrengths[2] = mgmZ;
|
||||||
}
|
}
|
||||||
dataset.fieldStrengths.setValid(true);
|
dataset.setIsValid = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -415,13 +415,15 @@ uint32_t MgmLIS3MDLHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { retur
|
|||||||
|
|
||||||
void MgmLIS3MDLHandler::modeChanged(void) { internalState = InternalState::STATE_NONE; }
|
void MgmLIS3MDLHandler::modeChanged(void) { internalState = InternalState::STATE_NONE; }
|
||||||
|
|
||||||
|
/*
|
||||||
ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) {
|
PeriodicHkGenerationHelper &poolManager) {
|
||||||
localDataPoolMap.emplace(mgmLis3::FIELD_STRENGTHS, &mgmXYZ);
|
localDataPoolMap.emplace(mgmLis3::FIELD_STRENGTHS, &mgmXYZ);
|
||||||
localDataPoolMap.emplace(mgmLis3::TEMPERATURE_CELCIUS, &temperature);
|
localDataPoolMap.emplace(mgmLis3::TEMPERATURE_CELCIUS, &temperature);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({dataset.getSid(), false, 10.0});
|
poolManager.setPeriodicFrequency(dataset.getSid(), 10'000);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void MgmLIS3MDLHandler::setAbsoluteLimits(float xLimit, float yLimit, float zLimit) {
|
void MgmLIS3MDLHandler::setAbsoluteLimits(float xLimit, float yLimit, float zLimit) {
|
||||||
this->absLimitX = xLimit;
|
this->absLimitX = xLimit;
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
#ifndef MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
||||||
#define MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
#define MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
||||||
|
|
||||||
#include <fsfw_hal/devicehandlers/devicedefinitions/mgmLis3Helpers.h>
|
#include "mgmLis3Helpers.h"
|
||||||
|
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||||
@ -63,8 +63,8 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
|||||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
||||||
void fillCommandAndReplyMap() override;
|
void fillCommandAndReplyMap() override;
|
||||||
void modeChanged(void) override;
|
void modeChanged(void) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
// ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) override;
|
// PeriodicHkGenerationHelper &poolManager) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mgmLis3::MgmPrimaryDataset dataset;
|
mgmLis3::MgmPrimaryDataset dataset;
|
@ -9,7 +9,7 @@
|
|||||||
MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommunication,
|
MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommunication,
|
||||||
CookieIF *comCookie, uint32_t transitionDelay)
|
CookieIF *comCookie, uint32_t transitionDelay)
|
||||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
primaryDataset(this),
|
primaryDataset(sharedPool),
|
||||||
transitionDelay(transitionDelay) {}
|
transitionDelay(transitionDelay) {}
|
||||||
|
|
||||||
MgmRM3100Handler::~MgmRM3100Handler() {}
|
MgmRM3100Handler::~MgmRM3100Handler() {}
|
||||||
@ -307,12 +307,15 @@ void MgmRM3100Handler::fillCommandAndReplyMap() {
|
|||||||
|
|
||||||
void MgmRM3100Handler::modeChanged() { internalState = InternalState::NONE; }
|
void MgmRM3100Handler::modeChanged() { internalState = InternalState::NONE; }
|
||||||
|
|
||||||
|
// TODO: Fix
|
||||||
|
/*
|
||||||
ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) {
|
PeriodicHkGenerationHelper &poolManager) {
|
||||||
localDataPoolMap.emplace(mgmRm3100::FIELD_STRENGTHS, &mgmXYZ);
|
localDataPoolMap.emplace(mgmRm3100::FIELD_STRENGTHS, &mgmXYZ);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({primaryDataset.getSid(), false, 10.0});
|
poolManager.setPeriodicFrequency(primaryDataset.getSid(), 10'000);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
uint32_t MgmRM3100Handler::getTransitionDelayMs(Mode_t from, Mode_t to) {
|
uint32_t MgmRM3100Handler::getTransitionDelayMs(Mode_t from, Mode_t to) {
|
||||||
return this->transitionDelay;
|
return this->transitionDelay;
|
||||||
@ -356,7 +359,7 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
|
|||||||
primaryDataset.fieldStrengths[0] = fieldStrengthX;
|
primaryDataset.fieldStrengths[0] = fieldStrengthX;
|
||||||
primaryDataset.fieldStrengths[1] = fieldStrengthY;
|
primaryDataset.fieldStrengths[1] = fieldStrengthY;
|
||||||
primaryDataset.fieldStrengths[2] = fieldStrengthZ;
|
primaryDataset.fieldStrengths[2] = fieldStrengthZ;
|
||||||
primaryDataset.setValidity(true, true);
|
primaryDataset.valid = true;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef MISSION_DEVICES_MGMRM3100HANDLER_H_
|
#ifndef MISSION_DEVICES_MGMRM3100HANDLER_H_
|
||||||
#define MISSION_DEVICES_MGMRM3100HANDLER_H_
|
#define MISSION_DEVICES_MGMRM3100HANDLER_H_
|
||||||
|
|
||||||
#include <fsfw_hal/devicehandlers/devicedefinitions/mgmRm3100Helpers.h>
|
#include "mgmRm3100Helpers.h"
|
||||||
|
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||||
@ -52,8 +52,8 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
|||||||
void fillCommandAndReplyMap() override;
|
void fillCommandAndReplyMap() override;
|
||||||
void modeChanged(void) override;
|
void modeChanged(void) override;
|
||||||
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
// ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) override;
|
// PeriodicHkGenerationHelper &poolManager) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class InternalState {
|
enum class InternalState {
|
46
misc/archive/ProvidesDataPoolSubscriptionIF.h
Normal file
46
misc/archive/ProvidesDataPoolSubscriptionIF.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||||
|
|
||||||
|
#include <fsfw/timemanager/clockDefinitions.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
|
#include "fsfw/ipc/messageQueueDefinitions.h"
|
||||||
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
#include "localPoolDefinitions.h"
|
||||||
|
|
||||||
|
namespace subdp {
|
||||||
|
|
||||||
|
struct ParamsBase {
|
||||||
|
ParamsBase(sid_t sid, bool enableReporting, dur_millis_t collectionIntervalMs)
|
||||||
|
: sid(sid), enableReporting(enableReporting), collectionIntervalMs(collectionIntervalMs) {}
|
||||||
|
|
||||||
|
[[nodiscard]] bool isDiagnostics() const { return diagnostics; }
|
||||||
|
|
||||||
|
sid_t sid;
|
||||||
|
bool enableReporting;
|
||||||
|
dur_millis_t collectionIntervalMs;
|
||||||
|
MessageQueueId_t receiver = MessageQueueIF::NO_QUEUE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegularHkPeriodicParams : public ParamsBase {
|
||||||
|
RegularHkPeriodicParams(sid_t sid, bool enableReporting, dur_millis_t collectionIntervalMs)
|
||||||
|
: ParamsBase(sid, enableReporting, collectionIntervalMs) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegularHkUpdateParams : public ParamsBase {
|
||||||
|
RegularHkUpdateParams(sid_t sid, bool enableReporting) : ParamsBase(sid, enableReporting, 0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiagnosticsHkUpdateParams : public ParamsBase {
|
||||||
|
DiagnosticsHkUpdateParams(sid_t sid, bool enableReporting)
|
||||||
|
: ParamsBase(sid, enableReporting, 0) {}
|
||||||
|
};
|
||||||
|
} // namespace subdp
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_ */
|
@ -1,21 +1,23 @@
|
|||||||
#include "fsfw/datapoollocal/SharedLocalDataSet.h"
|
#include "fsfw/datapool/SharedLocalDataset.h"
|
||||||
|
|
||||||
SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize)
|
SharedLocalDataset::SharedLocalDataset(object_id_t objectId, structure_id_t sid, const size_t maxSize)
|
||||||
: SystemObject(objectId), LocalPoolDataSetBase(sid, nullptr, maxSize), poolVarVector(maxSize) {
|
: SystemObject(objectId), SharedDatasetBase(sid, nullptr, maxSize), poolVarVector(maxSize) {
|
||||||
this->setContainer(poolVarVector.data());
|
this->setContainer(poolVarVector.data());
|
||||||
datasetLock = MutexFactory::instance()->createMutex();
|
datasetLock = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, HasLocalDataPoolIF *owner,
|
SharedLocalDataset::SharedLocalDataset(object_id_t objectId, localpool::SharedPool& sharedPool,
|
||||||
uint32_t setId, const size_t maxSize)
|
uint32_t setId, const size_t maxSize)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
LocalPoolDataSetBase(owner, setId, nullptr, maxSize),
|
SharedDatasetBase(sharedPool, setId, nullptr, maxSize),
|
||||||
poolVarVector(maxSize) {
|
poolVarVector(maxSize) {
|
||||||
this->setContainer(poolVarVector.data());
|
this->setContainer(poolVarVector.data());
|
||||||
datasetLock = MutexFactory::instance()->createMutex();
|
datasetLock = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SharedLocalDataSet::lockDataset(MutexIF::TimeoutType timeoutType,
|
SharedLocalDataset::~SharedLocalDataset() { MutexFactory::instance()->deleteMutex(datasetLock); }
|
||||||
|
|
||||||
|
ReturnValue_t SharedLocalDataset::lockDataset(MutexIF::TimeoutType timeoutType,
|
||||||
dur_millis_t mutexTimeout) {
|
dur_millis_t mutexTimeout) {
|
||||||
if (datasetLock != nullptr) {
|
if (datasetLock != nullptr) {
|
||||||
return datasetLock->lockMutex(timeoutType, mutexTimeout);
|
return datasetLock->lockMutex(timeoutType, mutexTimeout);
|
||||||
@ -23,9 +25,7 @@ ReturnValue_t SharedLocalDataSet::lockDataset(MutexIF::TimeoutType timeoutType,
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedLocalDataSet::~SharedLocalDataSet() { MutexFactory::instance()->deleteMutex(datasetLock); }
|
ReturnValue_t SharedLocalDataset::unlockDataset() {
|
||||||
|
|
||||||
ReturnValue_t SharedLocalDataSet::unlockDataset() {
|
|
||||||
if (datasetLock != nullptr) {
|
if (datasetLock != nullptr) {
|
||||||
return datasetLock->unlockMutex();
|
return datasetLock->unlockMutex();
|
||||||
}
|
}
|
37
misc/archive/SharedLocalDataset.h
Normal file
37
misc/archive/SharedLocalDataset.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fsfw/datapool/SharedDataSetIF.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
#include "SharedSetBase.h"
|
||||||
|
#include "SharedPool.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* The user is completely responsible for locking and unlocking the dataset when using the
|
||||||
|
* shared dataset.
|
||||||
|
*/
|
||||||
|
class SharedLocalDataset : public SystemObject, public SharedSetBase, public SharedDataSetIF {
|
||||||
|
public:
|
||||||
|
SharedLocalDataset(object_id_t objectId, SharedPool& sharedPool, uint32_t setId,
|
||||||
|
size_t maxSize);
|
||||||
|
SharedLocalDataset(object_id_t objectId, sid_t sid, size_t maxSize);
|
||||||
|
|
||||||
|
~SharedLocalDataset() override;
|
||||||
|
|
||||||
|
ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
dur_millis_t mutexTimeout = 20) override;
|
||||||
|
ReturnValue_t unlockDataset() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MutexIF* datasetLock = nullptr;
|
||||||
|
std::vector<PoolVariableIF*> poolVarVector;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
|
#include "gyroL3gHelpers.h"
|
||||||
|
|
||||||
float l3gd20h::ctrlReg4ToSensitivity(uint8_t reg) {
|
float l3gd20h::ctrlReg4ToSensitivity(uint8_t reg) {
|
||||||
bool fsH = reg & l3gd20h::SET_FS_1;
|
bool fsH = reg & l3gd20h::SET_FS_1;
|
@ -1,8 +1,8 @@
|
|||||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_
|
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_
|
||||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_
|
#define MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_
|
||||||
|
|
||||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
#include "fsfw/datapoollocal/StaticLocalDataSet.h"
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -124,8 +124,8 @@ class GyroPrimaryDataset : public StaticLocalDataSet<5> {
|
|||||||
setAllVariablesReadOnly();
|
setAllVariablesReadOnly();
|
||||||
}
|
}
|
||||||
/** Constructor for the data creator */
|
/** Constructor for the data creator */
|
||||||
GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner)
|
GyroPrimaryDataset(localpool::SharedPool& sharedPool)
|
||||||
: StaticLocalDataSet(hkOwner, l3gd20h::GYRO_DATASET_ID) {}
|
: StaticLocalDataSet(sharedPool, l3gd20h::GYRO_DATASET_ID) {}
|
||||||
|
|
||||||
/* Angular velocities in degrees per second (DPS) */
|
/* Angular velocities in degrees per second (DPS) */
|
||||||
lp_var_t<float> angVelocX = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_X, this);
|
lp_var_t<float> angVelocX = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_X, this);
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_
|
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_
|
||||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_
|
#define MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_
|
||||||
|
|
||||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
||||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
#include "fsfw/datapoollocal/StaticLocalDataSet.h"
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -169,11 +169,12 @@ static const uint8_t CTRL_REG5_DEFAULT = 0;
|
|||||||
|
|
||||||
static const uint32_t MGM_DATA_SET_ID = READ_CONFIG_AND_DATA;
|
static const uint32_t MGM_DATA_SET_ID = READ_CONFIG_AND_DATA;
|
||||||
|
|
||||||
enum MgmPoolIds : lp_id_t { FIELD_STRENGTHS, TEMPERATURE_CELCIUS };
|
enum MgmPoolIds : lp_id_t { FIELD_STRENGTHS = 0, TEMPERATURE_CELCIUS = 1, SET_IS_VALID = 2 };
|
||||||
|
|
||||||
class MgmPrimaryDataset : public StaticLocalDataSet<4> {
|
class MgmPrimaryDataset : public StaticLocalDataSet<4> {
|
||||||
public:
|
public:
|
||||||
MgmPrimaryDataset(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, MGM_DATA_SET_ID) {}
|
MgmPrimaryDataset(localpool::SharedPool& sharedPool)
|
||||||
|
: StaticLocalDataSet(sharedPool, MGM_DATA_SET_ID) {}
|
||||||
|
|
||||||
MgmPrimaryDataset(object_id_t mgmId) : StaticLocalDataSet(sid_t(mgmId, MGM_DATA_SET_ID)) {}
|
MgmPrimaryDataset(object_id_t mgmId) : StaticLocalDataSet(sid_t(mgmId, MGM_DATA_SET_ID)) {}
|
||||||
|
|
||||||
@ -182,6 +183,7 @@ class MgmPrimaryDataset : public StaticLocalDataSet<4> {
|
|||||||
*/
|
*/
|
||||||
lp_vec_t<float, 3> fieldStrengths = lp_vec_t<float, 3>(sid.objectId, FIELD_STRENGTHS, this);
|
lp_vec_t<float, 3> fieldStrengths = lp_vec_t<float, 3>(sid.objectId, FIELD_STRENGTHS, this);
|
||||||
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, TEMPERATURE_CELCIUS, this);
|
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, TEMPERATURE_CELCIUS, this);
|
||||||
|
lp_var_t<uint8_t> setIsValid = lp_var_t<uint8_t>(sid.objectId, SET_IS_VALID, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mgmLis3
|
} // namespace mgmLis3
|
@ -1,13 +1,13 @@
|
|||||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_
|
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_
|
||||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_
|
#define MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_
|
||||||
|
|
||||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
|
||||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
|
||||||
#include <fsfw/serialize/SerialLinkedListAdapter.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
||||||
|
#include "fsfw/datapoollocal/StaticLocalDataSet.h"
|
||||||
|
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||||
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||||
|
|
||||||
namespace mgmRm3100 {
|
namespace mgmRm3100 {
|
||||||
|
|
||||||
/* Actually 10, we round up a little bit */
|
/* Actually 10, we round up a little bit */
|
||||||
@ -101,11 +101,12 @@ class CycleCountCommand : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
|
|
||||||
static constexpr uint32_t MGM_DATASET_ID = READ_DATA;
|
static constexpr uint32_t MGM_DATASET_ID = READ_DATA;
|
||||||
|
|
||||||
enum MgmPoolIds : lp_id_t { FIELD_STRENGTHS };
|
enum MgmPoolIds : lp_id_t { FIELD_STRENGTHS = 0, VALID = 1 };
|
||||||
|
|
||||||
class Rm3100PrimaryDataset : public StaticLocalDataSet<3> {
|
class Rm3100PrimaryDataset : public StaticLocalDataSet<3> {
|
||||||
public:
|
public:
|
||||||
Rm3100PrimaryDataset(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, MGM_DATASET_ID) {}
|
Rm3100PrimaryDataset(localpool::SharedPool& sharedPool)
|
||||||
|
: StaticLocalDataSet(sharedPool, MGM_DATASET_ID) {}
|
||||||
|
|
||||||
Rm3100PrimaryDataset(object_id_t mgmId) : StaticLocalDataSet(sid_t(mgmId, MGM_DATASET_ID)) {}
|
Rm3100PrimaryDataset(object_id_t mgmId) : StaticLocalDataSet(sid_t(mgmId, MGM_DATASET_ID)) {}
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ class Rm3100PrimaryDataset : public StaticLocalDataSet<3> {
|
|||||||
* Field strenghts in uT
|
* Field strenghts in uT
|
||||||
*/
|
*/
|
||||||
lp_vec_t<float, 3> fieldStrengths = lp_vec_t<float, 3>(sid.objectId, FIELD_STRENGTHS, this);
|
lp_vec_t<float, 3> fieldStrengths = lp_vec_t<float, 3>(sid.objectId, FIELD_STRENGTHS, this);
|
||||||
|
lp_var_t<uint8_t> valid = lp_var_t<uint8_t>(sid.objectId, VALID, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mgmRm3100
|
} // namespace mgmRm3100
|
@ -7,7 +7,6 @@ add_subdirectory(cfdp)
|
|||||||
add_subdirectory(container)
|
add_subdirectory(container)
|
||||||
add_subdirectory(controller)
|
add_subdirectory(controller)
|
||||||
add_subdirectory(datapool)
|
add_subdirectory(datapool)
|
||||||
add_subdirectory(datapoollocal)
|
|
||||||
add_subdirectory(devicehandlers)
|
add_subdirectory(devicehandlers)
|
||||||
add_subdirectory(events)
|
add_subdirectory(events)
|
||||||
add_subdirectory(fdir)
|
add_subdirectory(fdir)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth)
|
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth)
|
||||||
: ControllerBase(objectId, commandQueueDepth),
|
: ControllerBase(objectId, commandQueueDepth),
|
||||||
poolManager(this, commandQueue),
|
hkHelper(this, commandQueue),
|
||||||
actionHelper(this, commandQueue) {}
|
actionHelper(this, commandQueue) {}
|
||||||
|
|
||||||
ExtendedControllerBase::~ExtendedControllerBase() = default;
|
ExtendedControllerBase::~ExtendedControllerBase() = default;
|
||||||
@ -10,22 +10,18 @@ ExtendedControllerBase::~ExtendedControllerBase() = default;
|
|||||||
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
||||||
MessageQueueId_t commandedBy,
|
MessageQueueId_t commandedBy,
|
||||||
const uint8_t *data, size_t size) {
|
const uint8_t *data, size_t size) {
|
||||||
/* Needs to be overriden and implemented by child class. */
|
// Needs to be overriden and implemented by child class.
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
object_id_t ExtendedControllerBase::getObjectId() const { return SystemObject::getObjectId(); }
|
object_id_t ExtendedControllerBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const {
|
|
||||||
return this->executingTask->getPeriodMs();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::handleCommandMessage(CommandMessage *message) {
|
ReturnValue_t ExtendedControllerBase::handleCommandMessage(CommandMessage *message) {
|
||||||
ReturnValue_t result = actionHelper.handleActionMessage(message);
|
ReturnValue_t result = actionHelper.handleActionMessage(message);
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return poolManager.handleHousekeepingMessage(message);
|
return hkHelper.handleHousekeepingMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtendedControllerBase::handleQueue() {
|
void ExtendedControllerBase::handleQueue() {
|
||||||
@ -48,7 +44,7 @@ void ExtendedControllerBase::handleQueue() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = poolManager.handleHousekeepingMessage(&command);
|
result = hkHelper.handleHousekeepingMessage(&command);
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -72,22 +68,18 @@ ReturnValue_t ExtendedControllerBase::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return poolManager.initialize(commandQueue);
|
return hkHelper.initialize(commandQueue);
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
|
|
||||||
return poolManager.initializeAfterTaskCreation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
|
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
|
||||||
handleQueue();
|
handleQueue();
|
||||||
performControlOperation(opCode);
|
performControlOperation(opCode);
|
||||||
/* We do this after performing control operation because variables will be set changed
|
// We do this after performing control operation because variables will be set changed
|
||||||
in this function. */
|
// in this function.
|
||||||
poolManager.performHkOperation();
|
hkHelper.performHkOperation();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t ExtendedControllerBase::getCommandQueue() const { return commandQueue->getId(); }
|
MessageQueueId_t ExtendedControllerBase::getCommandQueue() const { return commandQueue->getId(); }
|
||||||
|
|
||||||
LocalDataPoolManager *ExtendedControllerBase::getHkManagerHandle() { return &poolManager; }
|
datapool::SharedPool *ExtendedControllerBase::getOptionalSharedPool() { return nullptr; }
|
@ -1,10 +1,11 @@
|
|||||||
#ifndef FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_
|
#ifndef FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_
|
||||||
#define FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_
|
#define FSFW_CONTROLLER_EXTENDEDCONTROLLERBASE_H_
|
||||||
|
|
||||||
|
#include <fsfw/housekeeping/GeneratesPeriodicHkIF.h>
|
||||||
|
|
||||||
#include "ControllerBase.h"
|
#include "ControllerBase.h"
|
||||||
#include "fsfw/action.h"
|
#include "fsfw/action.h"
|
||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
#include "fsfw/housekeeping/PeriodicHkHelper.h"
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extends the basic ControllerBase with commonly used components
|
* @brief Extends the basic ControllerBase with commonly used components
|
||||||
@ -15,9 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
class ExtendedControllerBase : public ControllerBase,
|
class ExtendedControllerBase : public ControllerBase,
|
||||||
public HasActionsIF,
|
public HasActionsIF,
|
||||||
public HasLocalDataPoolIF {
|
public hk::GeneratesPeriodicHkIF {
|
||||||
public:
|
public:
|
||||||
ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth = 3);
|
explicit ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth = 3);
|
||||||
~ExtendedControllerBase() override;
|
~ExtendedControllerBase() override;
|
||||||
|
|
||||||
/* SystemObjectIF overrides */
|
/* SystemObjectIF overrides */
|
||||||
@ -27,12 +28,19 @@ class ExtendedControllerBase : public ControllerBase,
|
|||||||
|
|
||||||
/* ExecutableObjectIF overrides */
|
/* ExecutableObjectIF overrides */
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
ReturnValue_t initializeAfterTaskCreation() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LocalDataPoolManager poolManager;
|
hk::PeriodicHelper hkHelper;
|
||||||
ActionHelper actionHelper;
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
|
// Periodic HK methods, default method assumes that no shared pool is required.
|
||||||
|
datapool::SharedPool* getOptionalSharedPool() override = 0;
|
||||||
|
|
||||||
|
// Periodic HK abstract methods.
|
||||||
|
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf,
|
||||||
|
size_t maxSize) override = 0;
|
||||||
|
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implemented by child class. Handle all command messages which are
|
* Implemented by child class. Handle all command messages which are
|
||||||
* not health, mode, action or housekeeping messages.
|
* not health, mode, action or housekeeping messages.
|
||||||
@ -49,18 +57,12 @@ class ExtendedControllerBase : public ControllerBase,
|
|||||||
// Handle the four messages mentioned above
|
// Handle the four messages mentioned above
|
||||||
void handleQueue() override;
|
void handleQueue() override;
|
||||||
|
|
||||||
/* HasActionsIF overrides */
|
// HasActionsIF overrides
|
||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) override;
|
const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
/* HasLocalDatapoolIF overrides */
|
// HasLocalDatapoolIF overrides
|
||||||
LocalDataPoolManager* getHkManagerHandle() override;
|
|
||||||
[[nodiscard]] object_id_t getObjectId() const override;
|
[[nodiscard]] object_id_t getObjectId() const override;
|
||||||
[[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
|
|
||||||
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
|
||||||
LocalDataPoolManager& poolManager) override = 0;
|
|
||||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
|
||||||
|
|
||||||
// Mode abstract functions
|
// Mode abstract functions
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
|
11
src/fsfw/datapool.h
Normal file
11
src/fsfw/datapool.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_
|
||||||
|
#define FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_
|
||||||
|
|
||||||
|
// Collected related headers
|
||||||
|
#include "fsfw/datapool/LocalPoolVector.h"
|
||||||
|
#include "fsfw/datapool/PoolVariable.h"
|
||||||
|
#include "fsfw/datapool/SharedPool.h"
|
||||||
|
#include "fsfw/datapool/SharedSet.h"
|
||||||
|
#include "fsfw/datapool/StaticSharedSet.h"
|
||||||
|
|
||||||
|
#endif /* FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_ */
|
@ -1 +1,6 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE PoolDataSetBase.cpp PoolEntry.cpp)
|
target_sources(
|
||||||
|
${LIB_FSFW_NAME}
|
||||||
|
PRIVATE PoolDataSetBase.cpp PoolEntry.cpp SharedPool.cpp SharedSet.cpp
|
||||||
|
SharedSetBase.cpp LocalPoolObjectBase.cpp)
|
||||||
|
|
||||||
|
add_subdirectory(internal)
|
||||||
|
@ -1,36 +1,25 @@
|
|||||||
#include "fsfw/datapoollocal/LocalPoolObjectBase.h"
|
#include "fsfw/datapool/LocalPoolObjectBase.h"
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/AccessLocalPoolF.h"
|
#include "fsfw/housekeeping/PeriodicHkHelper.h"
|
||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "internal/HasLocalDpIFUserAttorney.h"
|
|
||||||
|
|
||||||
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
using namespace dp;
|
||||||
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
|
PoolObjectBase::PoolObjectBase(SharedPool& sharedPool, dp::id_t poolId, DataSetIF* dataSet,
|
||||||
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
pool_rwm_t setReadWriteMode)
|
||||||
|
: localPoolId(poolId), readWriteMode(setReadWriteMode), sharedPool(&sharedPool) {
|
||||||
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
if (hkOwner == nullptr) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool "
|
|
||||||
<< "owner is a invalid!" << std::endl;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AccessPoolManagerIF* poolManAccessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
|
||||||
hkManager = poolManAccessor->getPoolManagerHandle();
|
|
||||||
|
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
dataSet->registerVariable(this);
|
dataSet->registerVariable(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet,
|
PoolObjectBase::PoolObjectBase(object_id_t poolOwner, id_t poolId, DataSetIF* dataSet,
|
||||||
pool_rwm_t setReadWriteMode)
|
pool_rwm_t setReadWriteMode)
|
||||||
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
|
||||||
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
if (poolId == PoolVariableIF::NO_PARAMETER) {
|
||||||
@ -44,7 +33,7 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
|||||||
"which is the NO_PARAMETER value!\n");
|
"which is the NO_PARAMETER value!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
|
auto* hkOwner = ObjectManager::instance()->get<hk::GeneratesPeriodicHkIF>(poolOwner);
|
||||||
if (hkOwner == nullptr) {
|
if (hkOwner == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
|
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
|
||||||
@ -58,10 +47,14 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
sharedPool = hkOwner->getOptionalSharedPool();
|
||||||
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
if (sharedPool == nullptr) {
|
||||||
if (accessor != nullptr) {
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
hkManager = accessor->getPoolManagerHandle();
|
sif::error << "PoolObjectBase: HK owner 0x" << std::hex << poolOwner << std::dec
|
||||||
|
<< "does not have a shared pool " << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("PoolObjectBase: HK owner 0x%08x does not have a shared pool\n", poolOwner);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
@ -69,26 +62,22 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pool_rwm_t LocalPoolObjectBase::getReadWriteMode() const { return readWriteMode; }
|
pool_rwm_t PoolObjectBase ::getReadWriteMode() const { return readWriteMode; }
|
||||||
|
|
||||||
bool LocalPoolObjectBase::isValid() const { return valid; }
|
id_t PoolObjectBase ::getDataPoolId() const { return localPoolId; }
|
||||||
|
|
||||||
void LocalPoolObjectBase::setValid(bool valid) { this->valid = valid; }
|
void PoolObjectBase::setDataPoolId(id_t poolId) { this->localPoolId = poolId; }
|
||||||
|
|
||||||
lp_id_t LocalPoolObjectBase::getDataPoolId() const { return localPoolId; }
|
void PoolObjectBase::setReadWriteMode(pool_rwm_t newReadWriteMode) {
|
||||||
|
|
||||||
void LocalPoolObjectBase::setDataPoolId(lp_id_t poolId) { this->localPoolId = poolId; }
|
|
||||||
|
|
||||||
void LocalPoolObjectBase::setChanged(bool changed) { this->changed = changed; }
|
|
||||||
|
|
||||||
bool LocalPoolObjectBase::hasChanged() const { return changed; }
|
|
||||||
|
|
||||||
void LocalPoolObjectBase::setReadWriteMode(pool_rwm_t newReadWriteMode) {
|
|
||||||
this->readWriteMode = newReadWriteMode;
|
this->readWriteMode = newReadWriteMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalPoolObjectBase::reportReadCommitError(const char* variableType, ReturnValue_t error,
|
[[nodiscard]] bool PoolObjectBase::isValid() const { return valid; }
|
||||||
bool read, object_id_t objectId, lp_id_t lpId) {
|
|
||||||
|
void PoolObjectBase::setValid(bool valid) { this->valid = valid; }
|
||||||
|
|
||||||
|
void PoolObjectBase::reportReadCommitError(const char* variableType, ReturnValue_t error, bool read,
|
||||||
|
object_id_t objectId, id_t lpId) {
|
||||||
#if FSFW_DISABLE_PRINTOUT == 0
|
#if FSFW_DISABLE_PRINTOUT == 0
|
||||||
const char* variablePrintout = variableType;
|
const char* variablePrintout = variableType;
|
||||||
if (variablePrintout == nullptr) {
|
if (variablePrintout == nullptr) {
|
||||||
@ -102,9 +91,9 @@ void LocalPoolObjectBase::reportReadCommitError(const char* variableType, Return
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* errMsg = nullptr;
|
const char* errMsg = nullptr;
|
||||||
if (error == localpool::POOL_ENTRY_NOT_FOUND) {
|
if (error == POOL_ENTRY_NOT_FOUND) {
|
||||||
errMsg = "Pool entry not found";
|
errMsg = "Pool entry not found";
|
||||||
} else if (error == localpool::POOL_ENTRY_TYPE_CONFLICT) {
|
} else if (error == POOL_ENTRY_TYPE_CONFLICT) {
|
||||||
errMsg = "Pool entry type conflict";
|
errMsg = "Pool entry type conflict";
|
||||||
} else if (error == PoolVariableIF::INVALID_READ_WRITE_MODE) {
|
} else if (error == PoolVariableIF::INVALID_READ_WRITE_MODE) {
|
||||||
errMsg = "Pool variable wrong read-write mode";
|
errMsg = "Pool variable wrong read-write mode";
|
55
src/fsfw/datapool/LocalPoolObjectBase.h
Normal file
55
src/fsfw/datapool/LocalPoolObjectBase.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SharedPool.h"
|
||||||
|
#include "fsfw/datapool/PoolVariableIF.h"
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||||
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
class DataSetIF;
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
/**
|
||||||
|
* @brief This class serves as a non-template base for pool objects like pool variables
|
||||||
|
* or pool vectors.
|
||||||
|
*/
|
||||||
|
class PoolObjectBase : public PoolVariableIF {
|
||||||
|
public:
|
||||||
|
PoolObjectBase(dp::SharedPool& sharedPool, dp::id_t poolId, DataSetIF* dataSet,
|
||||||
|
pool_rwm_t setReadWriteMode);
|
||||||
|
|
||||||
|
PoolObjectBase(object_id_t poolOwner, dp::id_t poolId, DataSetIF* dataSet = nullptr,
|
||||||
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||||
|
|
||||||
|
void setReadWriteMode(pool_rwm_t newReadWriteMode) override;
|
||||||
|
[[nodiscard]] pool_rwm_t getReadWriteMode() const override;
|
||||||
|
|
||||||
|
[[nodiscard]] dp::id_t getDataPoolId() const override;
|
||||||
|
void setDataPoolId(dp::id_t poolId);
|
||||||
|
|
||||||
|
[[nodiscard]] bool isValid() const;
|
||||||
|
void setValid(bool valid);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @brief To access the correct data pool entry on read and commit calls,
|
||||||
|
* the data pool id is stored.
|
||||||
|
*/
|
||||||
|
uint32_t localPoolId = PoolVariableIF::NO_PARAMETER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The information whether the class is read-write or
|
||||||
|
* read-only is stored here.
|
||||||
|
*/
|
||||||
|
ReadWriteMode_t readWriteMode = pool_rwm_t::VAR_READ_WRITE;
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
//! @brief Pointer to the class which manages the HK pool.
|
||||||
|
dp::SharedPool* sharedPool = nullptr;
|
||||||
|
|
||||||
|
void reportReadCommitError(const char* variableType, ReturnValue_t error, bool read,
|
||||||
|
object_id_t objectId, dp::id_t lpId);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace datapool
|
@ -1,14 +1,15 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
|
#pragma once
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
|
|
||||||
|
#include <fsfw/ipc/MutexGuard.h>
|
||||||
|
|
||||||
#include "../datapool/DataSetIF.h"
|
|
||||||
#include "../datapool/PoolEntry.h"
|
|
||||||
#include "../datapool/PoolVariableIF.h"
|
|
||||||
#include "../datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "../serialize/SerializeAdapter.h"
|
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "LocalPoolObjectBase.h"
|
#include "LocalPoolObjectBase.h"
|
||||||
#include "internal/LocalDpManagerAttorney.h"
|
#include "fsfw/datapool/DataSetIF.h"
|
||||||
|
#include "fsfw/datapool/PoolEntry.h"
|
||||||
|
#include "fsfw/datapool/PoolVariableIF.h"
|
||||||
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the access class for array-type data pool entries.
|
* @brief This is the access class for array-type data pool entries.
|
||||||
@ -24,16 +25,16 @@
|
|||||||
* @tparam T
|
* @tparam T
|
||||||
* This template parameter specifies the data type of an array entry. Currently,
|
* This template parameter specifies the data type of an array entry. Currently,
|
||||||
* all plain data types are supported, but in principle any type is possible.
|
* all plain data types are supported, but in principle any type is possible.
|
||||||
* @tparam vector_size
|
* @tparam N
|
||||||
* This template parameter specifies the vector size of this entry. Using a
|
* This template parameter specifies the vector size of this entry. Using a
|
||||||
* template parameter for this is not perfect, but avoids
|
* template parameter for this is not perfect, but avoids
|
||||||
* dynamic memory allocation.
|
* dynamic memory allocation.
|
||||||
* @ingroup data_pool
|
* @ingroup data_pool
|
||||||
*/
|
*/
|
||||||
template <typename T, uint16_t vectorSize>
|
template <typename T, size_t N>
|
||||||
class LocalPoolVector : public LocalPoolObjectBase {
|
class PoolVector : public PoolObjectBase {
|
||||||
public:
|
public:
|
||||||
LocalPoolVector() = delete;
|
PoolVector() = delete;
|
||||||
/**
|
/**
|
||||||
* This constructor is used by the data creators to have pool variable
|
* This constructor is used by the data creators to have pool variable
|
||||||
* instances which can also be stored in datasets.
|
* instances which can also be stored in datasets.
|
||||||
@ -47,8 +48,9 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* @param dataSet The data set in which the variable shall register itself.
|
* @param dataSet The data set in which the variable shall register itself.
|
||||||
* If nullptr, the variable is not registered.
|
* If nullptr, the variable is not registered.
|
||||||
*/
|
*/
|
||||||
LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
|
PoolVector(SharedPool& sharedPool, id_t poolId, DataSetIF* dataSet = nullptr,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE)
|
||||||
|
: PoolObjectBase(sharedPool, poolId, dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor is used by data users like controllers to have
|
* This constructor is used by data users like controllers to have
|
||||||
@ -57,15 +59,15 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* It does not fetch the current value from the data pool. This is performed
|
* It does not fetch the current value from the data pool. This is performed
|
||||||
* by the read() operation (which is not thread-safe).
|
* by the read() operation (which is not thread-safe).
|
||||||
* Datasets can be used to access local pool entires in a thread-safe way.
|
* Datasets can be used to access local pool entires in a thread-safe way.
|
||||||
|
* @param poolOwner Owner of the shared pool.
|
||||||
* @param poolId ID of the local pool entry.
|
* @param poolId ID of the local pool entry.
|
||||||
* @param hkOwner Pointer of the owner. This will generally be the calling
|
|
||||||
* class itself which passes "this".
|
|
||||||
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
||||||
* @param dataSet The data set in which the variable shall register itself.
|
* @param dataSet The data set in which the variable shall register itself.
|
||||||
* If nullptr, the variable is not registered.
|
* If nullptr, the variable is not registered.
|
||||||
*/
|
*/
|
||||||
LocalPoolVector(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
|
PoolVector(object_id_t poolOwner, id_t poolId, DataSetIF* dataSet = nullptr,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE)
|
||||||
|
: PoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
||||||
/**
|
/**
|
||||||
* Variation which takes the unique global identifier of a local pool
|
* Variation which takes the unique global identifier of a local pool
|
||||||
* vector.
|
* vector.
|
||||||
@ -73,8 +75,10 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* @param dataSet
|
* @param dataSet
|
||||||
* @param setReadWriteMode
|
* @param setReadWriteMode
|
||||||
*/
|
*/
|
||||||
LocalPoolVector(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr,
|
PoolVector(g_id_t globalPoolId, DataSetIF* dataSet = nullptr,
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE)
|
||||||
|
: PoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet, setReadWriteMode) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the local copy of the data pool entry.
|
* @brief This is the local copy of the data pool entry.
|
||||||
@ -82,27 +86,80 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* The user can work on this attribute just like he would on a local
|
* The user can work on this attribute just like he would on a local
|
||||||
* array of this type.
|
* array of this type.
|
||||||
*/
|
*/
|
||||||
T value[vectorSize] = {};
|
T value[N] = {};
|
||||||
/**
|
/**
|
||||||
* @brief The classes destructor is empty.
|
* @brief The classes destructor is empty.
|
||||||
* @details If commit() was not called, the local value is
|
* @details If commit() was not called, the local value is
|
||||||
* discarded and not written back to the data pool.
|
* discarded and not written back to the data pool.
|
||||||
*/
|
*/
|
||||||
~LocalPoolVector() {};
|
~PoolVector() override {};
|
||||||
/**
|
/**
|
||||||
* @brief The operation returns the number of array entries
|
* @brief The operation returns the number of array entries
|
||||||
* in this variable.
|
* in this variable.
|
||||||
*/
|
*/
|
||||||
uint8_t getSize() { return vectorSize; }
|
size_t getSize() { return N; }
|
||||||
|
|
||||||
T& operator[](size_t i);
|
T& operator[](size_t i) {
|
||||||
const T& operator[](size_t i) const;
|
if (i < N) {
|
||||||
|
return value[i];
|
||||||
|
}
|
||||||
|
// If this happens, I have to set some value. I consider this
|
||||||
|
// a configuration error, but I wont exit here.
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "PoolVector: Invalid index. Setting or returning"
|
||||||
|
" last value!"
|
||||||
|
<< std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning(
|
||||||
|
"PoolVector: Invalid index. Setting or returning"
|
||||||
|
" last value!\n");
|
||||||
|
#endif
|
||||||
|
return value[N - 1];
|
||||||
|
}
|
||||||
|
const T& operator[](size_t i) const {
|
||||||
|
if (i < N) {
|
||||||
|
return value[i];
|
||||||
|
}
|
||||||
|
// If this happens, I have to set some value. I consider this
|
||||||
|
// a configuration error, but I wont exit here.
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "PoolVector: Invalid index. Setting or returning"
|
||||||
|
" last value!"
|
||||||
|
<< std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning(
|
||||||
|
"PoolVector: Invalid index. Setting or returning"
|
||||||
|
" last value!\n");
|
||||||
|
#endif
|
||||||
|
return value[N - 1];
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndiannes) const override;
|
SerializeIF::Endianness streamEndianness) const override {
|
||||||
size_t getSerializedSize() const override;
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
|
for (uint16_t i = 0; i < N; i++) {
|
||||||
|
result = SerializeAdapter::serialize(&(value[i]), buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getSerializedSize() const override {
|
||||||
|
return N * SerializeAdapter::getSerializedSize(value);
|
||||||
|
}
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
SerializeIF::Endianness streamEndianness) override;
|
SerializeIF::Endianness streamEndianness) override {
|
||||||
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
|
for (uint16_t i = 0; i < N; i++) {
|
||||||
|
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a call to read the array's values
|
* @brief This is a call to read the array's values
|
||||||
@ -118,7 +175,10 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* 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(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
uint32_t timeoutMs = 20) override;
|
uint32_t timeoutMs = 20) override {
|
||||||
|
MutexGuard mg(sharedPool->getPoolMutex(), timeoutType, timeoutMs);
|
||||||
|
return readWithoutLock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
@ -129,15 +189,11 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* 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(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
ReturnValue_t commit(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) override {
|
||||||
uint32_t timeoutMs = 20) override;
|
MutexGuard mg(sharedPool->getPoolMutex(), timeoutType, timeoutMs);
|
||||||
|
return commitWithoutLock();
|
||||||
/**
|
}
|
||||||
* @brief This commit call also sets the validity of the pool entry.
|
ReturnValue_t commit() { return commit(MutexIF::TimeoutType::WAITING, 20); }
|
||||||
* @details
|
|
||||||
*/
|
|
||||||
ReturnValue_t commit(bool valid, MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
|
||||||
uint32_t timeoutMs = 20);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -148,7 +204,23 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* of consecutive lock und unlock operations.
|
* of consecutive lock und unlock operations.
|
||||||
* Declared protected to discourage free public usage.
|
* Declared protected to discourage free public usage.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t readWithoutLock() override;
|
ReturnValue_t readWithoutLock() override {
|
||||||
|
if (readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||||
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
|
ReturnValue_t result = sharedPool->fetchPoolEntry(localPoolId, &poolEntry);
|
||||||
|
memset(this->value, 0, N * sizeof(T));
|
||||||
|
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
this->valid = poolEntry->getValid();
|
||||||
|
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Like #commit, but without a lock protection of the global pool.
|
* @brief Like #commit, but without a lock protection of the global pool.
|
||||||
* @details
|
* @details
|
||||||
@ -157,19 +229,37 @@ class LocalPoolVector : public LocalPoolObjectBase {
|
|||||||
* of consecutive lock und unlock operations.
|
* of consecutive lock und unlock operations.
|
||||||
* Declared protected to discourage free public usage.
|
* Declared protected to discourage free public usage.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t commitWithoutLock() override;
|
ReturnValue_t commitWithoutLock() override {
|
||||||
|
if (readWriteMode == pool_rwm_t::VAR_READ) {
|
||||||
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
|
}
|
||||||
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
|
ReturnValue_t result = sharedPool->fetchPoolEntry(localPoolId, &poolEntry);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
poolEntry->setValid(this->valid);
|
||||||
|
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// std::ostream is the type for object std::cout
|
std::ostream& operator<<(std::ostream& out, const PoolVector<T, N>& var) {
|
||||||
template <typename U, uint16_t otherSize>
|
out << "Vector: [";
|
||||||
friend std::ostream& operator<<(std::ostream& out, const LocalPoolVector<U, otherSize>& var);
|
for (int i = 0; i < N; i++) {
|
||||||
|
out << var.value[i];
|
||||||
|
if (i < N - 1) {
|
||||||
|
out << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << "]";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "LocalPoolVector.tpp"
|
template <typename T, size_t N>
|
||||||
|
using vec_t = PoolVector<T, N>;
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
} // namespace datapool
|
||||||
using lp_vec_t = LocalPoolVector<T, vectorSize>;
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ */
|
|
0
src/fsfw/datapool/LocalPoolVector.tpp
Normal file
0
src/fsfw/datapool/LocalPoolVector.tpp
Normal file
@ -1,15 +1,19 @@
|
|||||||
#include "fsfw/datapool/PoolDataSetBase.h"
|
#include "fsfw/datapool/PoolDataSetBase.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/datapool/ReadCommitIFAttorney.h"
|
#include "fsfw/datapool/ReadCommitIFAttorney.h"
|
||||||
|
#include "fsfw/globalfunctions/bitutility.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||||
const size_t maxFillCount)
|
const size_t maxFillCount, bool serializeWithValidityBlob)
|
||||||
: registeredVariables(registeredVariablesArray), maxFillCount(maxFillCount) {}
|
: serializeWithValidityBlob(serializeWithValidityBlob),
|
||||||
|
registeredVariables(registeredVariablesArray),
|
||||||
|
maxFillCount(maxFillCount) {}
|
||||||
|
|
||||||
PoolDataSetBase::~PoolDataSetBase() {}
|
PoolDataSetBase::~PoolDataSetBase() = default;
|
||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::registerVariable(PoolVariableIF* variable) {
|
ReturnValue_t PoolDataSetBase::registerVariable(PoolVariableIF* variable) {
|
||||||
if (registeredVariables == nullptr) {
|
if (registeredVariables == nullptr) {
|
||||||
@ -82,19 +86,19 @@ uint16_t PoolDataSetBase::getFillCount() const { return fillCount; }
|
|||||||
ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
if (registeredVariables[count] == nullptr) {
|
if (registeredVariables[count] == nullptr) {
|
||||||
/* Configuration error. */
|
// Configuration error.
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These checks are often performed by the respective variable implementation too, but I guess
|
// These checks are often performed by the respective variable implementation too, but I guess
|
||||||
a double check does not hurt. */
|
// a double check does not hurt.
|
||||||
if (registeredVariables[count]->getReadWriteMode() != PoolVariableIF::VAR_WRITE and
|
if (registeredVariables[count]->getReadWriteMode() != PoolVariableIF::VAR_WRITE and
|
||||||
registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) {
|
registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) {
|
||||||
if (protectEveryReadCommitCall) {
|
if (protectEveryReadCommitCall) {
|
||||||
result =
|
result =
|
||||||
registeredVariables[count]->read(timeoutTypeForSingleVars, mutexTimeoutForSingleVars);
|
registeredVariables[count]->read(timeoutTypeForSingleVars, mutexTimeoutForSingleVars);
|
||||||
} else {
|
} else {
|
||||||
/* The readWithoutLock function is protected, so we use the attorney here */
|
// The readWithoutLock function is protected, so we use the attorney here
|
||||||
result = ReadCommitIFAttorney::readWithoutLock(registeredVariables[count]);
|
result = ReadCommitIFAttorney::readWithoutLock(registeredVariables[count]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +176,9 @@ ReturnValue_t PoolDataSetBase::unlockDataPool() { return returnvalue::OK; }
|
|||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
|
if (this->serializeWithValidityBlob) {
|
||||||
|
return doSerializeWithValidityBlob(buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
ReturnValue_t result = returnvalue::FAILED;
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
result = registeredVariables[count]->serialize(buffer, size, maxSize, streamEndianness);
|
result = registeredVariables[count]->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
@ -182,6 +189,51 @@ ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size, const s
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PoolDataSetBase::doSerializeWithValidityBlob(
|
||||||
|
uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||||
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
|
const uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount) / 8.0);
|
||||||
|
uint8_t* validityPtr = nullptr;
|
||||||
|
#if defined(_MSC_VER) || defined(__clang__)
|
||||||
|
// Use a std::vector here because MSVC will (rightly) not create a fixed size array
|
||||||
|
// with a non constant size specifier. The Apple compiler (LLVM) will not accept
|
||||||
|
// the initialization of a variable sized array
|
||||||
|
std::vector<uint8_t> validityMask(validityMaskSize, 0);
|
||||||
|
validityPtr = validityMask.data();
|
||||||
|
#else
|
||||||
|
uint8_t validityMask[validityMaskSize] = {};
|
||||||
|
validityPtr = validityMask;
|
||||||
|
#endif
|
||||||
|
uint8_t validBufferIndex = 0;
|
||||||
|
uint8_t validBufferIndexBit = 0;
|
||||||
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
|
if (registeredVariables[count]->isValid()) {
|
||||||
|
// Set bit at correct position
|
||||||
|
bitutil::set(validityPtr + validBufferIndex, validBufferIndexBit);
|
||||||
|
}
|
||||||
|
if (validBufferIndexBit == 7) {
|
||||||
|
validBufferIndex++;
|
||||||
|
validBufferIndexBit = 0;
|
||||||
|
} else {
|
||||||
|
validBufferIndexBit++;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = registeredVariables[count]->serialize(buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*size + validityMaskSize > maxSize) {
|
||||||
|
return SerializeIF::BUFFER_TOO_SHORT;
|
||||||
|
}
|
||||||
|
// copy validity buffer to end
|
||||||
|
std::memcpy(*buffer, validityPtr, validityMaskSize);
|
||||||
|
*size += validityMaskSize;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t PoolDataSetBase::deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t PoolDataSetBase::deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
SerializeIF::Endianness streamEndianness) {
|
SerializeIF::Endianness streamEndianness) {
|
||||||
ReturnValue_t result = returnvalue::FAILED;
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
@ -199,6 +251,9 @@ size_t PoolDataSetBase::getSerializedSize() const {
|
|||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
size += registeredVariables[count]->getSerializedSize();
|
size += registeredVariables[count]->getSerializedSize();
|
||||||
}
|
}
|
||||||
|
if (serializeWithValidityBlob) {
|
||||||
|
size += std::ceil(static_cast<float>(fillCount) / 8.0);
|
||||||
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,3 +270,9 @@ void PoolDataSetBase::setReadCommitProtectionBehaviour(bool protectEveryReadComm
|
|||||||
this->timeoutTypeForSingleVars = timeoutType;
|
this->timeoutTypeForSingleVars = timeoutType;
|
||||||
this->mutexTimeoutForSingleVars = mutexTimeout;
|
this->mutexTimeoutForSingleVars = mutexTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PoolDataSetBase::setChildrenValidity(bool valid) {
|
||||||
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
|
registeredVariables[count]->setValid(valid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#ifndef FSFW_DATAPOOL_POOLDATASETBASE_H_
|
#pragma once
|
||||||
#define FSFW_DATAPOOL_POOLDATASETBASE_H_
|
|
||||||
|
|
||||||
#include "PoolDataSetIF.h"
|
#include "PoolDataSetIF.h"
|
||||||
#include "PoolVariableIF.h"
|
#include "PoolVariableIF.h"
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
#include "fsfw/serialize/SerializeIF.h"
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
class SharedSetBase;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The DataSetBase class manages a set of locally checked out variables.
|
* @brief The DataSetBase class manages a set of locally checked out variables.
|
||||||
* @details
|
* @details
|
||||||
@ -30,13 +33,16 @@
|
|||||||
* @ingroup data_pool
|
* @ingroup data_pool
|
||||||
*/
|
*/
|
||||||
class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
||||||
|
friend class datapool::SharedSetBase;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Creates an empty dataset. Use registerVariable or
|
* @brief Creates an empty dataset. Use registerVariable or
|
||||||
* supply a pointer to this dataset to PoolVariable
|
* supply a pointer to this dataset to PoolVariable
|
||||||
* initializations to register pool variables.
|
* initializations to register pool variables.
|
||||||
*/
|
*/
|
||||||
PoolDataSetBase(PoolVariableIF** registeredVariablesArray, size_t maxFillCount);
|
PoolDataSetBase(PoolVariableIF** registeredVariablesArray, size_t maxFillCount,
|
||||||
|
bool serializeWithValidityBlob = true);
|
||||||
|
|
||||||
/* Forbidden for now */
|
/* Forbidden for now */
|
||||||
PoolDataSetBase(const PoolDataSetBase& otherSet) = delete;
|
PoolDataSetBase(const PoolDataSetBase& otherSet) = delete;
|
||||||
@ -99,25 +105,26 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
|||||||
* thread-safety. Default implementation is empty
|
* thread-safety. Default implementation is empty
|
||||||
* @return Always returns -@c returnvalue::OK
|
* @return Always returns -@c returnvalue::OK
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t lockDataPool(
|
ReturnValue_t lockDataPool(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
|
||||||
uint32_t timeoutMs = 20) override;
|
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
|
||||||
* @return Always returns -@c returnvalue::OK
|
* @return Always returns -@c returnvalue::OK
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t unlockDataPool() override;
|
ReturnValue_t unlockDataPool() override;
|
||||||
|
|
||||||
virtual uint16_t getFillCount() const override;
|
[[nodiscard]] uint16_t getFillCount() const override;
|
||||||
|
|
||||||
/* SerializeIF implementations */
|
// SerializeIF implementations
|
||||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness) const override;
|
SerializeIF::Endianness streamEndianness) const override;
|
||||||
virtual size_t getSerializedSize() const override;
|
[[nodiscard]] size_t getSerializedSize() const override;
|
||||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
SerializeIF::Endianness streamEndianness) override;
|
SerializeIF::Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
ReturnValue_t doSerializeWithValidityBlob(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||||
|
SerializeIF::Endianness streamEndianness) const;
|
||||||
/**
|
/**
|
||||||
* Can be used to individually protect every read and commit call.
|
* Can be used to individually protect every read and commit call.
|
||||||
* @param protectEveryReadCommit
|
* @param protectEveryReadCommit
|
||||||
@ -127,6 +134,13 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
|||||||
bool protectEveryReadCommit, MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
bool protectEveryReadCommit, MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
uint32_t mutexTimeout = 20);
|
uint32_t mutexTimeout = 20);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the validity of all children
|
||||||
|
*/
|
||||||
|
void setChildrenValidity(bool valid);
|
||||||
|
|
||||||
|
bool serializeWithValidityBlob = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief The fill_count attribute ensures that the variables
|
* @brief The fill_count attribute ensures that the variables
|
||||||
@ -169,5 +183,3 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
|||||||
ReturnValue_t handleUnreadDatasetCommit(
|
ReturnValue_t handleUnreadDatasetCommit(
|
||||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING, uint32_t timeoutMs = 20);
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING, uint32_t timeoutMs = 20);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOL_POOLDATASETBASE_H_ */
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
class PoolDataSetIF : virtual public DataSetIF, virtual public ReadCommitIF {
|
class PoolDataSetIF : virtual public DataSetIF, virtual public ReadCommitIF {
|
||||||
public:
|
public:
|
||||||
virtual ~PoolDataSetIF() {};
|
~PoolDataSetIF() override = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Most underlying data structures will have a pool like structure
|
* @brief Most underlying data structures will have a pool like structure
|
||||||
@ -18,17 +18,13 @@ class PoolDataSetIF : virtual public DataSetIF, virtual public ReadCommitIF {
|
|||||||
* thread-safety
|
* thread-safety
|
||||||
* @return Lock operation result
|
* @return Lock operation result
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t lockDataPool(
|
virtual ReturnValue_t lockDataPool(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) = 0;
|
||||||
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
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t unlockDataPool() = 0;
|
virtual ReturnValue_t unlockDataPool() = 0;
|
||||||
|
|
||||||
virtual bool isValid() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOL_POOLDATASETIF_H_ */
|
#endif /* FSFW_DATAPOOL_POOLDATASETIF_H_ */
|
||||||
|
@ -104,16 +104,18 @@ class PoolEntry : public PoolEntryIF {
|
|||||||
* @brief This operation returns a the address pointer casted to void*.
|
* @brief This operation returns a the address pointer casted to void*.
|
||||||
*/
|
*/
|
||||||
void* getRawData();
|
void* getRawData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This method allows to set the valid information
|
* @brief This method allows to set the valid information
|
||||||
* of the pool entry.
|
* of the pool entry.
|
||||||
*/
|
*/
|
||||||
void setValid(bool isValid);
|
void setValid(bool isValid) override;
|
||||||
/**
|
/**
|
||||||
* @brief This method allows to get the valid information
|
* @brief This method allows to get the valid information
|
||||||
* of the pool entry.
|
* of the pool entry.
|
||||||
*/
|
*/
|
||||||
bool getValid();
|
bool getValid() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a debug method that prints all values and the valid
|
* @brief This is a debug method that prints all values and the valid
|
||||||
* information to the screen. It prints all array entries in a row.
|
* information to the screen. It prints all array entries in a row.
|
||||||
|
@ -39,14 +39,7 @@ class PoolEntryIF {
|
|||||||
* @brief This operation returns a the address pointer casted to void*.
|
* @brief This operation returns a the address pointer casted to void*.
|
||||||
*/
|
*/
|
||||||
virtual void* getRawData() = 0;
|
virtual void* getRawData() = 0;
|
||||||
/**
|
|
||||||
* @brief This method allows to set the valid information of the pool entry.
|
|
||||||
*/
|
|
||||||
virtual void setValid(bool isValid) = 0;
|
|
||||||
/**
|
|
||||||
* @brief This method allows to set the valid information of the pool entry.
|
|
||||||
*/
|
|
||||||
virtual bool getValid() = 0;
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a debug method that prints all values and the valid
|
* @brief This is a debug method that prints all values and the valid
|
||||||
* information to the screen. It prints all array entries in a row.
|
* information to the screen. It prints all array entries in a row.
|
||||||
@ -58,6 +51,15 @@ class PoolEntryIF {
|
|||||||
* Returns the type of the entry.
|
* Returns the type of the entry.
|
||||||
*/
|
*/
|
||||||
virtual Type getType() = 0;
|
virtual Type getType() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This method allows to set the valid information of the pool entry.
|
||||||
|
*/
|
||||||
|
virtual void setValid(bool isValid) = 0;
|
||||||
|
/**
|
||||||
|
* @brief This method allows to set the valid information of the pool entry.
|
||||||
|
*/
|
||||||
|
virtual bool getValid() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOL_POOLENTRYIF_H_ */
|
#endif /* FSFW_DATAPOOL_POOLENTRYIF_H_ */
|
||||||
|
@ -20,9 +20,9 @@ class PoolReadGuard {
|
|||||||
if (readResult != returnvalue::OK) {
|
if (readResult != returnvalue::OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL == 1
|
#if FSFW_VERBOSE_LEVEL == 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PoolReadHelper: Read failed!" << std::endl;
|
sif::error << "PoolReaGuard: Read failed!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("PoolReadHelper: Read failed!\n");
|
sif::printError("PoolReadGuard: Read failed!\n");
|
||||||
#endif /* FSFW_PRINT_VERBOSITY_LEVEL == 1 */
|
#endif /* FSFW_PRINT_VERBOSITY_LEVEL == 1 */
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
}
|
}
|
||||||
|
348
src/fsfw/datapool/PoolVariable.h
Normal file
348
src/fsfw/datapool/PoolVariable.h
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/datapool/internal/SharedPoolAttorney.h>
|
||||||
|
|
||||||
|
#include "FSFWConfig.h"
|
||||||
|
#include "LocalPoolObjectBase.h"
|
||||||
|
#include "fsfw/datapool/DataSetIF.h"
|
||||||
|
#include "fsfw/datapool/PoolVariableIF.h"
|
||||||
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Local Pool Variable class which is used to access the local pools.
|
||||||
|
* @details
|
||||||
|
* This class is not stored in the map. Instead, it is used to access
|
||||||
|
* the pool entries by using a pointer to the map storing the pool
|
||||||
|
* entries. It can also be used to organize these pool entries into data sets.
|
||||||
|
*
|
||||||
|
* @tparam T The template parameter sets the type of the variable. Currently,
|
||||||
|
* all plain data types are supported, but in principle any type is possible.
|
||||||
|
* @ingroup data_pool
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class PoolVariable : public PoolObjectBase {
|
||||||
|
public:
|
||||||
|
//! Default ctor is forbidden.
|
||||||
|
PoolVariable() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is used by the data creators to have pool variable
|
||||||
|
* instances which can also be stored in datasets.
|
||||||
|
*
|
||||||
|
* It does not fetch the current value from the data pool, which
|
||||||
|
* has to be done by calling the read() operation.
|
||||||
|
* Datasets can be used to access multiple local pool entries in an
|
||||||
|
* efficient way. A pointer to a dataset can be passed to register
|
||||||
|
* the pool variable in that dataset directly.
|
||||||
|
* @param poolId ID of the local pool entry.
|
||||||
|
* @param hkOwner Pointer of the owner. This will generally be the calling
|
||||||
|
* class itself which passes "this".
|
||||||
|
* @param dataSet The data set in which the variable shall register itself.
|
||||||
|
* If nullptr, the variable is not registered.
|
||||||
|
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
||||||
|
*/
|
||||||
|
PoolVariable(SharedPool& sharedPool, dp::id_t poolId, DataSetIF* dataSet = nullptr,
|
||||||
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is used by data users like controllers to have
|
||||||
|
* access to the local pool variables of data creators by supplying
|
||||||
|
* the respective creator object ID.
|
||||||
|
*
|
||||||
|
* It does not fetch the current value from the data pool, which
|
||||||
|
* has to be done by calling the read() operation.
|
||||||
|
* Datasets can be used to access multiple local pool entries in an
|
||||||
|
* efficient way. A pointer to a dataset can be passed to register
|
||||||
|
* the pool variable in that dataset directly.
|
||||||
|
* @param poolId ID of the local pool entry.
|
||||||
|
* @param hkOwner object ID of the pool owner.
|
||||||
|
* @param dataSet The data set in which the variable shall register itself.
|
||||||
|
* If nullptr, the variable is not registered.
|
||||||
|
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
PoolVariable(object_id_t poolOwner, dp::id_t poolId, DataSetIF* dataSet = nullptr,
|
||||||
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||||
|
/**
|
||||||
|
* Variation which takes the global unique identifier of a pool variable.
|
||||||
|
* @param globalPoolId
|
||||||
|
* @param dataSet
|
||||||
|
* @param setReadWriteMode
|
||||||
|
*/
|
||||||
|
PoolVariable(g_id_t globalPoolId, DataSetIF* dataSet = nullptr,
|
||||||
|
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||||
|
|
||||||
|
virtual ~PoolVariable() {};
|
||||||
|
|
||||||
|
T get() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is the local copy of the data pool entry.
|
||||||
|
* @details The user can work on this attribute
|
||||||
|
* just like he would on a simple local variable.
|
||||||
|
*/
|
||||||
|
T value = 0;
|
||||||
|
|
||||||
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
|
SerializeIF::Endianness streamEndianness) const override;
|
||||||
|
size_t getSerializedSize() const override;
|
||||||
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
|
SerializeIF::Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is a call to read the array's values
|
||||||
|
* from the global data pool.
|
||||||
|
* @details
|
||||||
|
* When executed, this operation tries to fetch the pool entry with matching
|
||||||
|
* data pool id from the data pool and copies all array values and the valid
|
||||||
|
* information to its local attributes.
|
||||||
|
* In case of a failure (wrong type, size or pool id not found), the
|
||||||
|
* variable is set to zero and invalid.
|
||||||
|
* The read call is protected with a lock.
|
||||||
|
* It is recommended to use DataSets to read and commit multiple variables
|
||||||
|
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
* @details
|
||||||
|
* It checks type and size, as well as if the variable is writable. If so,
|
||||||
|
* the value is copied and the local valid flag is written back as well.
|
||||||
|
* The read call is protected with a lock.
|
||||||
|
* It is recommended to use DataSets to read and commit multiple variables
|
||||||
|
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||||
|
*/
|
||||||
|
ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||||
|
uint32_t timeoutMs = 20) override;
|
||||||
|
|
||||||
|
PoolVariable<T>& operator=(const T& newValue);
|
||||||
|
PoolVariable<T>& operator=(const PoolVariable<T>& newPoolVariable);
|
||||||
|
|
||||||
|
//! Explicit type conversion operator. Allows casting the class to
|
||||||
|
//! its template type to perform operations on value.
|
||||||
|
explicit operator T() const;
|
||||||
|
|
||||||
|
bool operator==(const PoolVariable<T>& other) const;
|
||||||
|
bool operator==(const T& other) const;
|
||||||
|
|
||||||
|
bool operator!=(const PoolVariable<T>& other) const;
|
||||||
|
bool operator!=(const T& other) const;
|
||||||
|
|
||||||
|
bool operator<(const PoolVariable<T>& other) const;
|
||||||
|
bool operator<(const T& other) const;
|
||||||
|
|
||||||
|
bool operator>(const PoolVariable<T>& other) const;
|
||||||
|
bool operator>(const T& other) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @brief Like #read, but without a lock protection of the global pool.
|
||||||
|
* @details
|
||||||
|
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||||
|
* This can be used if the lock is handled externally to avoid the overhead
|
||||||
|
* of consecutive lock und unlock operations.
|
||||||
|
* Declared protected to discourage free public usage.
|
||||||
|
*/
|
||||||
|
ReturnValue_t readWithoutLock() override;
|
||||||
|
/**
|
||||||
|
* @brief Like #commit, but without a lock protection of the global pool.
|
||||||
|
* @details
|
||||||
|
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||||
|
* This can be used if the lock is handled externally to avoid the overhead
|
||||||
|
* of consecutive lock und unlock operations.
|
||||||
|
* Declared protected to discourage free public usage.
|
||||||
|
*/
|
||||||
|
ReturnValue_t commitWithoutLock() override;
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
// std::ostream is the type for object std::cout
|
||||||
|
template <typename U>
|
||||||
|
friend std::ostream& operator<<(std::ostream& out, const LocalPoolVariable<U>& var);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PoolVariable<T>::PoolVariable(SharedPool& sharedPool, dp::id_t poolId, DataSetIF* dataSet,
|
||||||
|
pool_rwm_t setReadWriteMode)
|
||||||
|
: PoolObjectBase(sharedPool, poolId, dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PoolVariable<T>::PoolVariable(object_id_t poolOwner, dp::id_t poolId, DataSetIF* dataSet,
|
||||||
|
pool_rwm_t setReadWriteMode)
|
||||||
|
: PoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PoolVariable<T>::PoolVariable(g_id_t globalPoolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
|
||||||
|
: PoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet, setReadWriteMode) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ReturnValue_t PoolVariable<T>::read(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
|
if (sharedPool == nullptr) {
|
||||||
|
return readWithoutLock();
|
||||||
|
}
|
||||||
|
MutexIF* mutex = sharedPool->getPoolMutex();
|
||||||
|
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = readWithoutLock();
|
||||||
|
mutex->unlockMutex();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline ReturnValue_t PoolVariable<T>::readWithoutLock() {
|
||||||
|
if (sharedPool == nullptr) {
|
||||||
|
return PoolVariableIF::INVALID_SHARED_POOL;
|
||||||
|
}
|
||||||
|
if (readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||||
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
|
if (ReturnValue_t result = sharedPool->fetchPoolEntry(localPoolId, &poolEntry);
|
||||||
|
result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->value = *(poolEntry->getDataPtr());
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline ReturnValue_t PoolVariable<T>::commit(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
|
if (sharedPool == nullptr) {
|
||||||
|
return commitWithoutLock();
|
||||||
|
}
|
||||||
|
MutexIF* mutex = sharedPool->getPoolMutex();
|
||||||
|
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = commitWithoutLock();
|
||||||
|
mutex->unlockMutex();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ReturnValue_t PoolVariable<T>::commitWithoutLock() {
|
||||||
|
if (readWriteMode == pool_rwm_t::VAR_READ) {
|
||||||
|
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolEntry<T>* poolEntry = nullptr;
|
||||||
|
ReturnValue_t result = sharedPool->fetchPoolEntry(localPoolId, &poolEntry);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(poolEntry->getDataPtr()) = this->value;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ReturnValue_t PoolVariable<T>::serialize(uint8_t** buffer, size_t* size, const size_t max_size,
|
||||||
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
|
return SerializeAdapter::serialize(&value, buffer, size, max_size, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t PoolVariable<T>::getSerializedSize() const {
|
||||||
|
return SerializeAdapter::getSerializedSize(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ReturnValue_t PoolVariable<T>::deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
|
SerializeIF::Endianness streamEndianness) {
|
||||||
|
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
T PoolVariable<T>::get() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
template <typename T>
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, const PoolVariable<T>& var) {
|
||||||
|
out << var.value;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PoolVariable<T>::operator T() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PoolVariable<T>& PoolVariable<T>::operator=(const T& newValue) {
|
||||||
|
value = newValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PoolVariable<T>& PoolVariable<T>::operator=(const PoolVariable<T>& newPoolVariable) {
|
||||||
|
value = newPoolVariable.value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator==(const PoolVariable<T>& other) const {
|
||||||
|
return this->value == other.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator==(const T& other) const {
|
||||||
|
return this->value == other;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator!=(const PoolVariable& other) const {
|
||||||
|
return not(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator!=(const T& other) const {
|
||||||
|
return not(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator<(const PoolVariable<T>& other) const {
|
||||||
|
return this->value < other.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator<(const T& other) const {
|
||||||
|
return this->value < other;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator>(const PoolVariable<T>& other) const {
|
||||||
|
return not(*this < other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool PoolVariable<T>::operator>(const T& other) const {
|
||||||
|
return not(*this < other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using var_t = PoolVariable<T>;
|
||||||
|
|
||||||
|
using bool_t = PoolVariable<uint8_t>;
|
||||||
|
using u8_t = PoolVariable<uint8_t>;
|
||||||
|
using u16_t = PoolVariable<uint16_t>;
|
||||||
|
using u32_t = PoolVariable<uint32_t>;
|
||||||
|
using u64_t = PoolVariable<uint64_t>;
|
||||||
|
using i8_t = PoolVariable<int8_t>;
|
||||||
|
using i16_t = PoolVariable<int16_t>;
|
||||||
|
using i32_t = PoolVariable<int32_t>;
|
||||||
|
using i64_t = PoolVariable<int64_t>;
|
||||||
|
using f32_t = PoolVariable<float>;
|
||||||
|
using f64_t = PoolVariable<double>;
|
||||||
|
|
||||||
|
} // namespace datapool
|
1
src/fsfw/datapool/PoolVariable.tpp
Normal file
1
src/fsfw/datapool/PoolVariable.tpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#pragma once
|
@ -23,6 +23,7 @@ class PoolVariableIF : public SerializeIF, public ReadCommitIF {
|
|||||||
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 ReturnValue_t INVALID_POOL_ENTRY = MAKE_RETURN_CODE(0xA1);
|
||||||
|
static constexpr ReturnValue_t INVALID_SHARED_POOL = MAKE_RETURN_CODE(0xA2);
|
||||||
|
|
||||||
static constexpr bool VALID = 1;
|
static constexpr bool VALID = 1;
|
||||||
static constexpr bool INVALID = 0;
|
static constexpr bool INVALID = 0;
|
||||||
@ -46,15 +47,9 @@ class PoolVariableIF : public SerializeIF, public ReadCommitIF {
|
|||||||
* @brief This operation shall return the data pool id of the variable.
|
* @brief This operation shall return the data pool id of the variable.
|
||||||
*/
|
*/
|
||||||
virtual uint32_t getDataPoolId() const = 0;
|
virtual uint32_t getDataPoolId() const = 0;
|
||||||
/**
|
|
||||||
* @brief With this call, the valid information of the
|
|
||||||
* variable is returned.
|
|
||||||
*/
|
|
||||||
virtual bool isValid() const = 0;
|
virtual bool isValid() const = 0;
|
||||||
/**
|
virtual void setValid(bool valid) = 0;
|
||||||
* @brief With this call, the valid information of the variable is set.
|
|
||||||
*/
|
|
||||||
virtual void setValid(bool validity) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
||||||
|
36
src/fsfw/datapool/SharedPool.cpp
Normal file
36
src/fsfw/datapool/SharedPool.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "SharedPool.h"
|
||||||
|
|
||||||
|
#include "FSFWConfig.h"
|
||||||
|
#include "fsfw/ipc/MutexFactory.h"
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
|
using namespace dp;
|
||||||
|
SharedPool::SharedPool(object_id_t ownerId) : ownerId(ownerId) {
|
||||||
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
|
if (mutex == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "localpool::Manager: Mutex creation failed" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("localpool::Manager: Mutex creation failed");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPool::~SharedPool() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
|
|
||||||
|
object_id_t SharedPool::getOwnerId() const { return ownerId; }
|
||||||
|
|
||||||
|
void SharedPool::addPoolEntry(id_t poolId, PoolEntryIF* entry) {
|
||||||
|
localPoolMap.emplace(poolId, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexIF* SharedPool::getPoolMutex() { return mutex; }
|
||||||
|
|
||||||
|
ReturnValue_t SharedPool::printPoolEntry(id_t localPoolId) {
|
||||||
|
auto poolIter = localPoolMap.find(localPoolId);
|
||||||
|
if (poolIter == localPoolMap.end()) {
|
||||||
|
return POOL_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
poolIter->second->print();
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
62
src/fsfw/datapool/SharedPool.h
Normal file
62
src/fsfw/datapool/SharedPool.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fsfw/datapool/PoolEntry.h"
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
|
||||||
|
class SharedPool {
|
||||||
|
public:
|
||||||
|
explicit SharedPool(object_id_t ownerId);
|
||||||
|
~SharedPool();
|
||||||
|
|
||||||
|
[[nodiscard]] object_id_t getOwnerId() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a variable by supplying its local pool ID and assign the pool
|
||||||
|
* entry to the supplied PoolEntry pointer. The type of the pool entry
|
||||||
|
* is deduced automatically. This call is not thread-safe!
|
||||||
|
* For now, only classes designated by the LocalDpManagerAttorney may use this function.
|
||||||
|
* @tparam T Type of the pool entry
|
||||||
|
* @param localPoolId Pool ID of the variable to read
|
||||||
|
* @param poolVar [out] Corresponding pool entry will be assigned to the
|
||||||
|
* supplied pointer.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
ReturnValue_t fetchPoolEntry(id_t localPoolId, PoolEntry<T>** poolEntry);
|
||||||
|
ReturnValue_t printPoolEntry(id_t localPoolId);
|
||||||
|
void addPoolEntry(id_t poolId, PoolEntryIF* entry);
|
||||||
|
MutexIF* getPoolMutex();
|
||||||
|
|
||||||
|
private:
|
||||||
|
object_id_t ownerId;
|
||||||
|
|
||||||
|
// Core data structure for the actual pool data
|
||||||
|
DataPool localPoolMap{};
|
||||||
|
// Every housekeeping data manager has a mutex to protect access
|
||||||
|
// to it's data pool.
|
||||||
|
MutexIF* mutex = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline ReturnValue_t datapool::SharedPool::fetchPoolEntry(id_t localPoolId,
|
||||||
|
PoolEntry<T>** poolEntry) {
|
||||||
|
if (poolEntry == nullptr) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto poolIter = localPoolMap.find(localPoolId);
|
||||||
|
if (poolIter == localPoolMap.end()) {
|
||||||
|
return POOL_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
*poolEntry = dynamic_cast<PoolEntry<T>*>(poolIter->second);
|
||||||
|
if (*poolEntry == nullptr) {
|
||||||
|
return POOL_ENTRY_TYPE_CONFLICT;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace datapool
|
19
src/fsfw/datapool/SharedSet.cpp
Normal file
19
src/fsfw/datapool/SharedSet.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "SharedSet.h"
|
||||||
|
|
||||||
|
using namespace dp;
|
||||||
|
|
||||||
|
SharedSet::SharedSet(dp::SharedPool& sharedPool, uint32_t setId, const size_t maxNumberOfVariables,
|
||||||
|
bool serializeWithValidityBlob)
|
||||||
|
: SharedSetBase(sharedPool, setId, nullptr, maxNumberOfVariables, serializeWithValidityBlob),
|
||||||
|
poolVarList(maxNumberOfVariables) {
|
||||||
|
this->setContainer(poolVarList.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedSet::SharedSet(dp::structure_id_t sid, const size_t maxNumberOfVariables,
|
||||||
|
bool serializeWithValidityBlob)
|
||||||
|
: SharedSetBase(sid, nullptr, maxNumberOfVariables, serializeWithValidityBlob),
|
||||||
|
poolVarList(maxNumberOfVariables) {
|
||||||
|
this->setContainer(poolVarList.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedSet::~SharedSet() = default;
|
@ -1,10 +1,11 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALDATASET_H_
|
#pragma once
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALDATASET_H_
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "LocalPoolDataSetBase.h"
|
#include "SharedPool.h"
|
||||||
|
#include "SharedSetBase.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
/**
|
/**
|
||||||
* @brief This dataset type can be used to group related pool variables if the number of
|
* @brief This dataset type can be used to group related pool variables if the number of
|
||||||
* variables should not be fixed.
|
* variables should not be fixed.
|
||||||
@ -18,20 +19,21 @@
|
|||||||
* @tparam capacity Capacity of the static dataset, which is usually known
|
* @tparam capacity Capacity of the static dataset, which is usually known
|
||||||
* beforehand.
|
* beforehand.
|
||||||
*/
|
*/
|
||||||
class LocalDataSet : public LocalPoolDataSetBase {
|
class SharedSet : public SharedSetBase {
|
||||||
public:
|
public:
|
||||||
LocalDataSet(HasLocalDataPoolIF* hkOwner, uint32_t setId, const size_t maxSize);
|
SharedSet(SharedPool& sharedPool, uint32_t setId, size_t maxSize,
|
||||||
|
bool serializeWithValidityBlob = true);
|
||||||
|
|
||||||
LocalDataSet(sid_t sid, const size_t maxSize);
|
SharedSet(sid_t sid, size_t maxSize, bool serializeWithValidityBlob = true);
|
||||||
|
|
||||||
virtual ~LocalDataSet();
|
~SharedSet() override;
|
||||||
|
|
||||||
//! Copying forbidden for now.
|
//! Copying forbidden for now.
|
||||||
LocalDataSet(const LocalDataSet&) = delete;
|
SharedSet(const SharedSet&) = delete;
|
||||||
LocalDataSet& operator=(const LocalDataSet&) = delete;
|
SharedSet& operator=(const SharedSet&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<PoolVariableIF*> poolVarList;
|
std::vector<PoolVariableIF*> poolVarList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALDATASET_H_ */
|
} // namespace datapool
|
169
src/fsfw/datapool/SharedSetBase.cpp
Normal file
169
src/fsfw/datapool/SharedSetBase.cpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#include "SharedSetBase.h"
|
||||||
|
|
||||||
|
#include <fsfw/housekeeping/GeneratesPeriodicHkIF.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "fsfw/datapool.h"
|
||||||
|
#include "fsfw/globalfunctions/bitutility.h"
|
||||||
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
|
using namespace datapool;
|
||||||
|
|
||||||
|
SharedSetBase::SharedSetBase(SharedPool &sharedPool, uint32_t setId,
|
||||||
|
PoolVariableIF **registeredVariablesArray,
|
||||||
|
const size_t maxNumberOfVariables, bool serializeWithValidityBlob)
|
||||||
|
: base(registeredVariablesArray, maxNumberOfVariables, serializeWithValidityBlob),
|
||||||
|
sharedPool(&sharedPool) {
|
||||||
|
mutexIfSingleDataCreator = sharedPool.getPoolMutex();
|
||||||
|
|
||||||
|
this->sid.objectId = sharedPool.getOwnerId();
|
||||||
|
this->sid.ownerSetId = setId;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedSetBase::SharedSetBase(structure_id_t sid, PoolVariableIF **registeredVariablesArray,
|
||||||
|
const size_t maxNumberOfVariables, bool serializeWithValidityBlob)
|
||||||
|
: base(registeredVariablesArray, maxNumberOfVariables, serializeWithValidityBlob) {
|
||||||
|
auto *hkOwner = ObjectManager::instance()->get<hk::GeneratesPeriodicHkIF>(sid.objectId);
|
||||||
|
if (hkOwner != nullptr) {
|
||||||
|
sharedPool = hkOwner->getOptionalSharedPool();
|
||||||
|
if (sharedPool != nullptr) {
|
||||||
|
mutexIfSingleDataCreator = sharedPool->getPoolMutex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->sid = sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedSetBase::SharedSetBase(PoolVariableIF **registeredVariablesArray,
|
||||||
|
const size_t maxNumberOfVariables, bool protectEveryReadCommitCall,
|
||||||
|
bool serializeWithValidityBlob)
|
||||||
|
: base(registeredVariablesArray, maxNumberOfVariables, serializeWithValidityBlob) {
|
||||||
|
base.setReadCommitProtectionBehaviour(protectEveryReadCommitCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedSetBase::~SharedSetBase() {
|
||||||
|
// In case set was read but not comitted, we commit all variables with an invalid state
|
||||||
|
if (base.state == PoolDataSetBase::States::STATE_SET_WAS_READ) {
|
||||||
|
for (uint16_t count = 0; count < base.getFillCount(); count++) {
|
||||||
|
if (base.registeredVariables[count] != nullptr) {
|
||||||
|
base.registeredVariables[count]->commit(MutexIF::TimeoutType::WAITING, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::lockDataPool(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
|
if (mutexIfSingleDataCreator != nullptr) {
|
||||||
|
return mutexIfSingleDataCreator->lockMutex(timeoutType, timeoutMs);
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::unlockDataPool() {
|
||||||
|
if (mutexIfSingleDataCreator != nullptr) {
|
||||||
|
return mutexIfSingleDataCreator->unlockMutex();
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::serializeLocalPoolIds(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
|
/* Serialize fill count as uint8_t */
|
||||||
|
auto fillCount = this->getFillCount();
|
||||||
|
for (uint16_t count = 0; count < fillCount; count++) {
|
||||||
|
id_t currentPoolId = base.registeredVariables[count]->getDataPoolId();
|
||||||
|
auto result =
|
||||||
|
SerializeAdapter::serialize(¤tPoolId, buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
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 returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SharedSetBase::getLocalPoolIdsSerializedSize() const {
|
||||||
|
return base.getFillCount() * sizeof(id_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SharedSetBase::getSerializedSize() const { return base.getSerializedSize(); }
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
|
SerializeIF::Endianness streamEndianness) {
|
||||||
|
return base.deSerialize(buffer, size, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
|
return base.serialize(buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ReturnValue_t SharedSetBase::serialize(
|
||||||
|
uint8_t *buffer, size_t &serLen, size_t maxSize,
|
||||||
|
SerializeIF::Endianness streamEndianness) const {
|
||||||
|
return SerializeIF::serialize(buffer, serLen, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharedSetBase::setReportingEnabled(bool reportingEnabled) {
|
||||||
|
this->reportingEnabled = reportingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SharedSetBase::getReportingEnabled() const { return reportingEnabled; }
|
||||||
|
|
||||||
|
structure_id_t SharedSetBase::getStructureId() const { return sid; }
|
||||||
|
|
||||||
|
void SharedSetBase::setChildrenValidity(bool valid) { return base.setChildrenValidity(valid); }
|
||||||
|
|
||||||
|
object_id_t SharedSetBase::getCreatorObjectId() {
|
||||||
|
if (sharedPool != nullptr) {
|
||||||
|
return sharedPool->getOwnerId();
|
||||||
|
}
|
||||||
|
return objects::NO_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharedSetBase::setAllVariablesReadOnly() {
|
||||||
|
for (size_t idx = 0; idx < this->getFillCount(); idx++) {
|
||||||
|
base.registeredVariables[idx]->setReadWriteMode(pool_rwm_t::VAR_READ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharedSetBase::printSet() { return; }
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::read(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
|
lockDataPool(timeoutType, timeoutMs);
|
||||||
|
ReturnValue_t result = base.read(timeoutType, timeoutMs);
|
||||||
|
unlockDataPool();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::commit(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
|
lockDataPool(timeoutType, timeoutMs);
|
||||||
|
ReturnValue_t result = base.commit(timeoutType, timeoutMs);
|
||||||
|
unlockDataPool();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
uint16_t SharedSetBase::getFillCount() const { return base.getFillCount(); }
|
||||||
|
|
||||||
|
ReturnValue_t SharedSetBase::registerVariable(PoolVariableIF *variable) {
|
||||||
|
return base.registerVariable(variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharedSetBase::setContainer(PoolVariableIF **variablesContainer) {
|
||||||
|
return base.setContainer(variablesContainer);
|
||||||
|
}
|
||||||
|
PoolVariableIF **SharedSetBase::getContainer() const { return base.getContainer(); }
|
||||||
|
|
||||||
|
void SharedSetBase::updateValidityBlobSerialization(bool enable) {
|
||||||
|
base.serializeWithValidityBlob = enable;
|
||||||
|
}
|
||||||
|
bool SharedSetBase::getValidityBlobSerialization() const { return base.serializeWithValidityBlob; }
|
@ -1,17 +1,16 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
#pragma once
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_
|
|
||||||
|
|
||||||
#include <vector>
|
#include "SharedPool.h"
|
||||||
|
#include "definitions.h"
|
||||||
#include "MarkChangedIF.h"
|
|
||||||
#include "fsfw/datapool/DataSetIF.h"
|
#include "fsfw/datapool/DataSetIF.h"
|
||||||
#include "fsfw/datapool/PoolDataSetBase.h"
|
#include "fsfw/datapool/PoolDataSetBase.h"
|
||||||
#include "localPoolDefinitions.h"
|
|
||||||
|
|
||||||
class LocalDataPoolManager;
|
class PeriodicHkGenerationHelper;
|
||||||
class HasLocalDataPoolIF;
|
class PeriodicHkGenerationIF;
|
||||||
class PeriodicHousekeepingHelper;
|
class PeriodicHousekeepingHelper;
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The LocalDataSet class manages a set of locally checked out
|
* @brief The LocalDataSet class manages a set of locally checked out
|
||||||
* variables for local data pools
|
* variables for local data pools
|
||||||
@ -40,10 +39,7 @@ class PeriodicHousekeepingHelper;
|
|||||||
*
|
*
|
||||||
* @ingroup data_pool
|
* @ingroup data_pool
|
||||||
*/
|
*/
|
||||||
class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
class SharedSetBase : public SerializeIF, public PoolDataSetIF {
|
||||||
friend class LocalPoolDataSetAttorney;
|
|
||||||
friend class PeriodicHousekeepingHelper;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for the creator of local pool data.
|
* @brief Constructor for the creator of local pool data.
|
||||||
@ -51,9 +47,8 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* This constructor also initializes the components required for
|
* This constructor also initializes the components required for
|
||||||
* periodic handling.
|
* periodic handling.
|
||||||
*/
|
*/
|
||||||
LocalPoolDataSetBase(HasLocalDataPoolIF* hkOwner, uint32_t setId,
|
SharedSetBase(SharedPool& sharedPool, uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
||||||
PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables,
|
size_t maxNumberOfVariables, bool serializeWithValidityBlob = true);
|
||||||
bool periodicHandling = true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for users of the local pool data, which need
|
* @brief Constructor for users of the local pool data, which need
|
||||||
@ -66,8 +61,8 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* @param registeredVariablesArray
|
* @param registeredVariablesArray
|
||||||
* @param maxNumberOfVariables
|
* @param maxNumberOfVariables
|
||||||
*/
|
*/
|
||||||
LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray,
|
SharedSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray, size_t maxNumberOfVariables,
|
||||||
const size_t maxNumberOfVariables);
|
bool serializeWithValidityBlob = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Simple constructor, if the dataset is not the owner by
|
* @brief Simple constructor, if the dataset is not the owner by
|
||||||
@ -87,8 +82,8 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* multiple creators, this flag can be set to protect all read and
|
* multiple creators, this flag can be set to protect all read and
|
||||||
* commit calls separately.
|
* commit calls separately.
|
||||||
*/
|
*/
|
||||||
LocalPoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables,
|
SharedSetBase(PoolVariableIF** registeredVariablesArray, size_t maxNumberOfVariables,
|
||||||
bool protectEveryReadCommitCall = true);
|
bool serializeWithValidityBlob, bool protectEveryReadCommitCall = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The destructor automatically manages writing the valid
|
* @brief The destructor automatically manages writing the valid
|
||||||
@ -98,13 +93,13 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* the destructor parses all variables that are still registered to the set.
|
* the destructor parses all variables that are still registered to the set.
|
||||||
* For each, the valid flag in the data pool is set to "invalid".
|
* For each, the valid flag in the data pool is set to "invalid".
|
||||||
*/
|
*/
|
||||||
~LocalPoolDataSetBase();
|
~SharedSetBase() override;
|
||||||
|
|
||||||
/* The copy constructor and assingment constructor are forbidden for now.
|
/* The copy constructor and assingment constructor are forbidden for now.
|
||||||
The use-cases are limited and the first step would be to implement them properly for the
|
The use-cases are limited and the first step would be to implement them properly for the
|
||||||
base class */
|
base class */
|
||||||
LocalPoolDataSetBase(const LocalPoolDataSetBase& otherSet) = delete;
|
SharedSetBase(const SharedSetBase& otherSet) = delete;
|
||||||
const LocalPoolDataSetBase& operator=(const LocalPoolDataSetBase& otherSet) = delete;
|
const SharedSetBase& operator=(const SharedSetBase& otherSet) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper functions used to set all currently contained variables to read-only.
|
* Helper functions used to set all currently contained variables to read-only.
|
||||||
@ -112,56 +107,27 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* by data consumers to prevent accidentally changing pool data.
|
* by data consumers to prevent accidentally changing pool data.
|
||||||
*/
|
*/
|
||||||
void setAllVariablesReadOnly();
|
void setAllVariablesReadOnly();
|
||||||
void setValidityBufferGeneration(bool withValidityBuffer);
|
|
||||||
|
|
||||||
sid_t getSid() const;
|
[[nodiscard]] virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const override;
|
||||||
|
|
||||||
/** SerializeIF overrides */
|
[[nodiscard]] ReturnValue_t serialize(uint8_t* buffer, size_t& serLen, size_t maxSize,
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const override;
|
SerializeIF::Endianness streamEndianness) const override;
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
|
||||||
SerializeIF::Endianness streamEndianness) override;
|
|
||||||
size_t getSerializedSize() const override;
|
|
||||||
|
|
||||||
/**
|
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
* Special version of the serilization function which appends a
|
Endianness streamEndianness) override;
|
||||||
* validity buffer at the end. Each bit of this validity buffer
|
|
||||||
* denotes whether the container data set entries are valid from left
|
[[nodiscard]] dp::sid_t getStructureId() const;
|
||||||
* to right, MSB first. (length = ceil(N/8), N = number of pool variables)
|
|
||||||
* @param buffer
|
[[nodiscard]] size_t getSerializedSize() const override;
|
||||||
* @param size
|
|
||||||
* @param maxSize
|
|
||||||
* @param bigEndian
|
|
||||||
* @param withValidityBuffer
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer, size_t* size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const;
|
|
||||||
ReturnValue_t deSerializeWithValidityBuffer(const uint8_t** buffer, size_t* size,
|
|
||||||
SerializeIF::Endianness streamEndianness);
|
|
||||||
ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
SerializeIF::Endianness streamEndianness,
|
SerializeIF::Endianness streamEndianness) const;
|
||||||
bool serializeFillCount = true) const;
|
[[nodiscard]] size_t getLocalPoolIdsSerializedSize() const;
|
||||||
uint8_t getLocalPoolIdsSerializedSize(bool serializeFillCount = true) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the dataset valid or invalid. These calls are mutex protected.
|
|
||||||
* @param setEntriesRecursively
|
|
||||||
* If this is true, all contained datasets will also be set recursively.
|
|
||||||
*/
|
|
||||||
void setValidity(bool valid, bool setEntriesRecursively);
|
|
||||||
bool isValid() const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* These calls are mutex protected.
|
|
||||||
* @param changed
|
|
||||||
*/
|
|
||||||
void setChanged(bool changed) override;
|
|
||||||
bool hasChanged() const override;
|
|
||||||
|
|
||||||
object_id_t getCreatorObjectId();
|
object_id_t getCreatorObjectId();
|
||||||
|
|
||||||
bool getReportingEnabled() const;
|
[[nodiscard]] bool getReportingEnabled() const;
|
||||||
void setReportingEnabled(bool enabled);
|
void setReportingEnabled(bool enabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,14 +136,35 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* returns 0.0
|
* returns 0.0
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
float getCollectionInterval() const;
|
[[nodiscard]] float getCollectionInterval() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Can be overwritten by a specific implementation of a dataset to print the set.
|
* @brief Can be overwritten by a specific implementation of a dataset to print the set.
|
||||||
*/
|
*/
|
||||||
virtual void printSet();
|
virtual void printSet();
|
||||||
|
|
||||||
|
ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::BLOCKING,
|
||||||
|
dur_millis_t timeoutMs = 0) override;
|
||||||
|
ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::BLOCKING,
|
||||||
|
dur_millis_t timeoutMs = 0) override;
|
||||||
|
uint16_t getFillCount() const override;
|
||||||
|
|
||||||
|
ReturnValue_t registerVariable(PoolVariableIF* variable) override;
|
||||||
|
|
||||||
|
void setContainer(PoolVariableIF** variablesContainer);
|
||||||
|
PoolVariableIF** getContainer() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the validity of all children
|
||||||
|
*/
|
||||||
|
void setChildrenValidity(bool valid);
|
||||||
|
|
||||||
|
void updateValidityBlobSerialization(bool enable);
|
||||||
|
bool getValidityBlobSerialization() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PoolDataSetBase base;
|
||||||
|
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
//! This mutex is used if the data is created by one object only.
|
//! This mutex is used if the data is created by one object only.
|
||||||
MutexIF* mutexIfSingleDataCreator = nullptr;
|
MutexIF* mutexIfSingleDataCreator = nullptr;
|
||||||
@ -189,27 +176,6 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
|
|
||||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval);
|
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval);
|
||||||
|
|
||||||
/**
|
|
||||||
* If the valid state of a dataset is always relevant to the whole
|
|
||||||
* data set we can use this flag.
|
|
||||||
*/
|
|
||||||
bool valid = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can be used to mark the dataset as changed, which is used
|
|
||||||
* by the LocalDataPoolManager to send out update messages.
|
|
||||||
*/
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify whether the validity buffer is serialized too when serializing
|
|
||||||
* or deserializing the packet. Each bit of the validity buffer will
|
|
||||||
* contain the validity state of the pool variables from left to right.
|
|
||||||
* The size of validity buffer thus will be ceil(N / 8) with N = number of
|
|
||||||
* pool variables.
|
|
||||||
*/
|
|
||||||
bool withValidityBuffer = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a small helper function to facilitate locking
|
* @brief This is a small helper function to facilitate locking
|
||||||
* the global data pool.
|
* the global data pool.
|
||||||
@ -226,8 +192,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t unlockDataPool() override;
|
ReturnValue_t unlockDataPool() override;
|
||||||
|
|
||||||
PeriodicHousekeepingHelper* periodicHelper = nullptr;
|
dp::SharedPool* sharedPool = nullptr;
|
||||||
LocalDataPoolManager* poolManager = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ */
|
} // namespace datapool
|
@ -1,13 +1,10 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_
|
#pragma once
|
||||||
#define FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "../objectmanager/SystemObjectIF.h"
|
#include "SharedSetBase.h"
|
||||||
#include "LocalPoolDataSetBase.h"
|
|
||||||
#include "LocalPoolVariable.h"
|
|
||||||
#include "LocalPoolVector.h"
|
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
/**
|
/**
|
||||||
* @brief This dataset type can be used to group related pool variables if the number of
|
* @brief This dataset type can be used to group related pool variables if the number of
|
||||||
* variables is fixed.
|
* variables is fixed.
|
||||||
@ -18,30 +15,31 @@
|
|||||||
*
|
*
|
||||||
* It is recommended to read the documentation of the LocalPoolDataSetBase
|
* It is recommended to read the documentation of the LocalPoolDataSetBase
|
||||||
* class for more information on how this class works and how to use it.
|
* class for more information on how this class works and how to use it.
|
||||||
* @tparam capacity Capacity of the static dataset, which is usually known
|
* @tparam NUM_VARIABLES Capacity of the static dataset, which is usually known
|
||||||
* beforehand.
|
* beforehand.
|
||||||
*/
|
*/
|
||||||
template <uint8_t NUM_VARIABLES>
|
template <size_t NUM_VARIABLES>
|
||||||
class StaticLocalDataSet : public LocalPoolDataSetBase {
|
class StaticSharedSet : public datapool::SharedSetBase {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor used by data owner and creator like device handlers.
|
* Constructor used by data owner and creator like device handlers.
|
||||||
* This constructor also initialized the components required for
|
* This constructor also initialized the components required for
|
||||||
* periodic handling.
|
* periodic handling.
|
||||||
* @param hkOwner
|
* @param sharedPool Shared pool this dataset will read from or write to.
|
||||||
* @param setId
|
* @param setId
|
||||||
*/
|
*/
|
||||||
StaticLocalDataSet(HasLocalDataPoolIF* hkOwner, uint32_t setId)
|
StaticSharedSet(SharedPool& sharedPool, const uint32_t setId,
|
||||||
: LocalPoolDataSetBase(hkOwner, setId, nullptr, NUM_VARIABLES) {
|
bool serializeWithValidityBlob = true)
|
||||||
|
: SharedSetBase(sharedPool, setId, nullptr, NUM_VARIABLES, serializeWithValidityBlob) {
|
||||||
this->setContainer(poolVarList.data());
|
this->setContainer(poolVarList.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used by data users like controllers.
|
* Constructor used by data users like controllers.
|
||||||
* @param hkOwner
|
* @param sid
|
||||||
* @param setId
|
|
||||||
*/
|
*/
|
||||||
StaticLocalDataSet(sid_t sid) : LocalPoolDataSetBase(sid, nullptr, NUM_VARIABLES) {
|
explicit StaticSharedSet(const structure_id_t sid, bool serializeWithValidityBlob = true)
|
||||||
|
: SharedSetBase(sid, nullptr, NUM_VARIABLES, serializeWithValidityBlob) {
|
||||||
this->setContainer(poolVarList.data());
|
this->setContainer(poolVarList.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,4 +47,4 @@ class StaticLocalDataSet : public LocalPoolDataSetBase {
|
|||||||
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList = {};
|
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */
|
} // namespace datapool
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_
|
#pragma once
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -8,44 +7,44 @@
|
|||||||
#include "../objectmanager/SystemObjectIF.h"
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include "../objectmanager/frameworkObjects.h"
|
#include "../objectmanager/frameworkObjects.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definition for local pool entries.
|
* @brief Type definition for local pool entries.
|
||||||
*/
|
*/
|
||||||
using lp_id_t = uint32_t;
|
using id_t = uint32_t;
|
||||||
|
|
||||||
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 uint8_t INTERFACE_ID = CLASS_ID::DATAPOOL_IF;
|
||||||
|
|
||||||
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
|
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
|
||||||
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
|
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
|
/** This is the core data structure of the local data pools. Users should insert all desired
|
||||||
pool variables, using the std::map interface. */
|
pool variables, using the std::map interface. */
|
||||||
using DataPool = std::map<lp_id_t, PoolEntryIF*>;
|
using DataPool = std::map<id_t, PoolEntryIF*>;
|
||||||
using DataPoolMapIter = DataPool::iterator;
|
|
||||||
|
|
||||||
} // namespace localpool
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a unique identifier for data sets. Consists of 4 byte object ID and 4 byte set ID.
|
* Used as a unique identifier for data sets. Consists of 4 byte object ID and 4 byte set ID.
|
||||||
*/
|
*/
|
||||||
union sid_t {
|
union structure_id_t {
|
||||||
|
static constexpr size_t SIZE = sizeof(object_id_t) + sizeof(uint32_t);
|
||||||
|
|
||||||
static constexpr uint64_t INVALID_SID = -1;
|
static constexpr uint64_t INVALID_SID = -1;
|
||||||
static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT;
|
static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT;
|
||||||
static constexpr uint32_t INVALID_SET_ID = -1;
|
static constexpr uint32_t INVALID_SET_ID = -1;
|
||||||
|
|
||||||
sid_t() : raw(INVALID_SID) {}
|
constexpr structure_id_t() : raw(INVALID_SID) {}
|
||||||
|
|
||||||
sid_t(object_id_t objectId, uint32_t setId) : objectId(objectId), ownerSetId(setId) {}
|
constexpr structure_id_t(object_id_t objectId, uint32_t setId)
|
||||||
|
: objectId(objectId), ownerSetId(setId) {}
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
object_id_t objectId;
|
object_id_t objectId;
|
||||||
/**
|
/**
|
||||||
* A generic 32 bit ID to identify unique HK packets for a single
|
* A generic 32 bit ID to identify unique HK set packets for a single
|
||||||
* object. For example, the DeviceCommandId_t is used for
|
* object.
|
||||||
* DeviceHandlers
|
|
||||||
*/
|
*/
|
||||||
uint32_t ownerSetId;
|
uint32_t ownerSetId;
|
||||||
};
|
};
|
||||||
@ -54,39 +53,41 @@ union sid_t {
|
|||||||
*/
|
*/
|
||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
|
|
||||||
bool notSet() const { return raw == INVALID_SID; }
|
[[nodiscard]] bool notSet() const { return raw == INVALID_SID; }
|
||||||
|
|
||||||
bool operator==(const sid_t& other) const { return raw == other.raw; }
|
bool operator==(const structure_id_t& other) const { return raw == other.raw; }
|
||||||
|
|
||||||
bool operator!=(const sid_t& other) const { return not(raw == other.raw); }
|
bool operator!=(const structure_id_t& other) const { return not(raw == other.raw); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using sid_t = structure_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a global unique identifier for local pool variables. Consists of 4 byte object ID
|
* Used as a global unique identifier for local pool variables. Consists of 4 byte object ID
|
||||||
* and 4 byte local pool ID.
|
* and 4 byte local pool ID.
|
||||||
*/
|
*/
|
||||||
union gp_id_t {
|
union g_id_t {
|
||||||
static constexpr uint64_t INVALID_GPID = -1;
|
static constexpr uint64_t INVALID_GPID = -1;
|
||||||
static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT;
|
static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT;
|
||||||
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
|
||||||
|
|
||||||
gp_id_t() : raw(INVALID_GPID) {}
|
g_id_t() : raw(INVALID_GPID) {}
|
||||||
|
|
||||||
gp_id_t(object_id_t objectId, lp_id_t localPoolId)
|
g_id_t(object_id_t objectId, id_t localPoolId) : objectId(objectId), localPoolId(localPoolId) {}
|
||||||
: objectId(objectId), localPoolId(localPoolId) {}
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
object_id_t objectId;
|
object_id_t objectId;
|
||||||
lp_id_t localPoolId;
|
id_t localPoolId;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
|
|
||||||
bool notSet() const { return raw == INVALID_GPID; }
|
bool notSet() const { return raw == INVALID_GPID; }
|
||||||
|
|
||||||
bool operator==(const gp_id_t& other) const { return raw == other.raw; }
|
bool operator==(const g_id_t& other) const { return raw == other.raw; }
|
||||||
|
|
||||||
bool operator!=(const gp_id_t& other) const { return not(raw == other.raw); }
|
bool operator!=(const g_id_t& other) const { return not(raw == other.raw); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDEFINITIONS_H_ */
|
} // namespace datapool
|
||||||
|
|
||||||
|
namespace dp = datapool;
|
1
src/fsfw/datapool/internal/CMakeLists.txt
Normal file
1
src/fsfw/datapool/internal/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
target_sources(${LIB_FSFW_NAME} PRIVATE)
|
11
src/fsfw/datapool/internal/LocalPoolDataSetAttorney.h
Normal file
11
src/fsfw/datapool/internal/LocalPoolDataSetAttorney.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fsfw/datapool/SharedSetBase.h"
|
||||||
|
|
||||||
|
class LocalPoolDataSetAttorney {
|
||||||
|
static void setReportingEnabled(SharedDatasetBase& set, bool enabled) {
|
||||||
|
set.setReportingEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getReportingEnabled(SharedDatasetBase& set) { return set.getReportingEnabled(); }
|
||||||
|
};
|
@ -1,8 +1,8 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
|
#pragma once
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
|
|
||||||
|
|
||||||
#include "../LocalDataPoolManager.h"
|
#include "fsfw/datapool/SharedPool.h"
|
||||||
|
|
||||||
|
namespace datapool {
|
||||||
/**
|
/**
|
||||||
* @brief This is a helper class implements the Attorney-Client idiom for access to
|
* @brief This is a helper class implements the Attorney-Client idiom for access to
|
||||||
* LocalDataPoolManager internals
|
* LocalDataPoolManager internals
|
||||||
@ -13,15 +13,15 @@
|
|||||||
* an explicit subset of the pool manager private/protected functions.
|
* 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
|
* See: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Friendship_and_the_Attorney-Client
|
||||||
*/
|
*/
|
||||||
class LocalDpManagerAttorney {
|
class SharedPoolAttorney {
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static ReturnValue_t fetchPoolEntry(LocalDataPoolManager& manager, lp_id_t localPoolId,
|
static ReturnValue_t fetchPoolEntry(SharedPool& manager, dp::id_t localPoolId,
|
||||||
PoolEntry<T>** poolEntry) {
|
PoolEntry<T>** poolEntry) {
|
||||||
return manager.fetchPoolEntry(localPoolId, poolEntry);
|
return manager.fetchPoolEntry(localPoolId, poolEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MutexIF* getMutexHandle(LocalDataPoolManager& manager) { return manager.getMutexHandle(); }
|
static MutexIF* getMutexHandle(SharedPool& manager) { return manager.getPoolMutex(); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
friend class LocalPoolVariable;
|
friend class LocalPoolVariable;
|
||||||
@ -29,4 +29,4 @@ class LocalDpManagerAttorney {
|
|||||||
friend class LocalPoolVector;
|
friend class LocalPoolVector;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_ */
|
} // namespace datapool
|
@ -1,11 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_
|
|
||||||
|
|
||||||
/* Collected related headers */
|
|
||||||
#include "fsfw/datapoollocal/LocalDataSet.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalPoolVector.h"
|
|
||||||
#include "fsfw/datapoollocal/SharedLocalDataSet.h"
|
|
||||||
#include "fsfw/datapoollocal/StaticLocalDataSet.h"
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_DATAPOOLLOCAL_H_ */
|
|
@ -1,26 +0,0 @@
|
|||||||
#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* getPoolManagerHandle() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_ */
|
|
@ -1,6 +0,0 @@
|
|||||||
target_sources(
|
|
||||||
${LIB_FSFW_NAME}
|
|
||||||
PRIVATE LocalDataPoolManager.cpp LocalDataSet.cpp LocalPoolDataSetBase.cpp
|
|
||||||
LocalPoolObjectBase.cpp SharedLocalDataSet.cpp)
|
|
||||||
|
|
||||||
add_subdirectory(internal)
|
|
@ -1,181 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "LocalDataPoolManager.h"
|
|
||||||
#include "fsfw/datapool/PoolEntryIF.h"
|
|
||||||
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
|
||||||
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
|
||||||
#include "fsfw/serviceinterface.h"
|
|
||||||
#include "localPoolDefinitions.h"
|
|
||||||
|
|
||||||
class AccessPoolManagerIF;
|
|
||||||
class ProvidesDataPoolSubscriptionIF;
|
|
||||||
class LocalPoolDataSetBase;
|
|
||||||
class LocalPoolObjectBase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This interface is implemented by classes which posses a local data pool (not
|
|
||||||
* the managing class). It defines the relationship between the local data pool owner and the
|
|
||||||
* LocalDataPoolManager.
|
|
||||||
* @details
|
|
||||||
* Any class implementing this interface shall also have a LocalDataPoolManager member class which
|
|
||||||
* contains the actual pool data structure and exposes the public interface for it.
|
|
||||||
*
|
|
||||||
* The local data pool can be accessed using helper classes by using the
|
|
||||||
* LocalPoolVariable, LocalPoolVector or LocalDataSet classes. Every local pool variable can
|
|
||||||
* be uniquely identified by a global pool ID (gp_id_t) and every dataset tied
|
|
||||||
* to a pool manager can be uniqely identified by a global structure ID (sid_t).
|
|
||||||
*
|
|
||||||
* All software objects which want to use the local pool of another object shall also use this
|
|
||||||
* interface, for example to get a handle to the subscription interface. The interface
|
|
||||||
* can be retrieved using the object manager, provided the target object is a SystemObject.
|
|
||||||
* For example, the following line of code can be used to retrieve the interface
|
|
||||||
*
|
|
||||||
* HasLocalDataPoolIF* poolIF = ObjectManager::instance()->
|
|
||||||
* get<HasLocalDataPoolIF>(objects::SOME_OBJECT);
|
|
||||||
* if(poolIF != nullptr) {
|
|
||||||
* doSomething()
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
class HasLocalDataPoolIF {
|
|
||||||
friend class HasLocalDpIFManagerAttorney;
|
|
||||||
friend class HasLocalDpIFUserAttorney;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~HasLocalDataPoolIF() {};
|
|
||||||
|
|
||||||
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
|
||||||
|
|
||||||
virtual object_id_t getObjectId() const = 0;
|
|
||||||
|
|
||||||
/** Command queue for housekeeping messages. */
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is used by pool owner to initialize the pool map once
|
|
||||||
* The manager instance shall also be passed to this function.
|
|
||||||
* It can be used to subscribe for periodic packets for for updates.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
|
||||||
LocalDataPoolManager& poolManager) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the minimum sampling frequency in milliseconds, which will
|
|
||||||
* usually be the period the pool owner performs its periodic operation.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual dur_millis_t getPeriodicOperationFrequency() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function will be called by the manager if an update
|
|
||||||
* notification is received.
|
|
||||||
* @details HasLocalDataPoolIF
|
|
||||||
* Can be overriden by the child class to handle changed datasets.
|
|
||||||
* @param sid SID of the updated set
|
|
||||||
* @param storeId If a snapshot was requested, data will be located inside
|
|
||||||
* the IPC store with this store ID.
|
|
||||||
* @param clearMessage If this is set to true, the pool manager will take care of
|
|
||||||
* clearing the store automatically
|
|
||||||
*/
|
|
||||||
virtual void handleChangedDataset(sid_t sid, store_address_t storeId = store_address_t::invalid(),
|
|
||||||
bool* clearMessage = nullptr) {
|
|
||||||
if (clearMessage != nullptr) {
|
|
||||||
*clearMessage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function will be called by the manager if an update
|
|
||||||
* notification is received.
|
|
||||||
* @details
|
|
||||||
* Can be overriden by the child class to handle changed pool variables.
|
|
||||||
* @param gpid GPID of the updated variable.
|
|
||||||
* @param storeId If a snapshot was requested, data will be located inside
|
|
||||||
* the IPC store with this store ID.
|
|
||||||
* @param clearMessage Relevant for snapshots. If the boolean this points to is set to true,
|
|
||||||
* the pool manager will take care of clearing the store automatically
|
|
||||||
* after the callback.
|
|
||||||
*/
|
|
||||||
virtual void handleChangedPoolVariable(gp_id_t gpid,
|
|
||||||
store_address_t storeId = store_address_t::invalid(),
|
|
||||||
bool* clearMessage = nullptr) {
|
|
||||||
if (clearMessage != nullptr) {
|
|
||||||
*clearMessage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) { return returnvalue::FAILED; };
|
|
||||||
virtual ReturnValue_t removeDataSet(sid_t sid) { return returnvalue::FAILED; };
|
|
||||||
virtual ReturnValue_t changeCollectionInterval(sid_t sid, float newIntervalSeconds) {
|
|
||||||
return returnvalue::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_ */
|
|
@ -1,817 +0,0 @@
|
|||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal.h"
|
|
||||||
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
|
||||||
#include "fsfw/housekeeping/HousekeepingSetPacket.h"
|
|
||||||
#include "fsfw/housekeeping/HousekeepingSnapshot.h"
|
|
||||||
#include "fsfw/ipc/MutexFactory.h"
|
|
||||||
#include "fsfw/ipc/MutexGuard.h"
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
|
||||||
#include "fsfw/timemanager/CCSDSTime.h"
|
|
||||||
#include "internal/HasLocalDpIFManagerAttorney.h"
|
|
||||||
#include "internal/LocalPoolDataSetAttorney.h"
|
|
||||||
|
|
||||||
// TODO: Get rid of this. This should be a constructor argument, not something hardcoded in any way
|
|
||||||
object_id_t LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
|
|
||||||
|
|
||||||
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
|
||||||
bool appendValidityBuffer)
|
|
||||||
: appendValidityBuffer(appendValidityBuffer) {
|
|
||||||
if (owner == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "LocalDataPoolManager", returnvalue::FAILED,
|
|
||||||
"Invalid supplied owner");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->owner = owner;
|
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
|
||||||
if (mutex == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "LocalDataPoolManager", returnvalue::FAILED,
|
|
||||||
"Could not create mutex");
|
|
||||||
}
|
|
||||||
|
|
||||||
hkQueue = queueToUse;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDataPoolManager::~LocalDataPoolManager() {
|
|
||||||
if (mutex != nullptr) {
|
|
||||||
MutexFactory::instance()->deleteMutex(mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
|
||||||
if (queueToUse == nullptr) {
|
|
||||||
/* Error, all destinations invalid */
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
|
||||||
}
|
|
||||||
hkQueue = queueToUse;
|
|
||||||
|
|
||||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
|
||||||
if (ipcStore == nullptr) {
|
|
||||||
/* Error, all destinations invalid */
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", returnvalue::FAILED,
|
|
||||||
"Could not set IPC store.");
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defaultHkDestination != objects::NO_OBJECT) {
|
|
||||||
auto* hkPacketReceiver =
|
|
||||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
|
||||||
if (hkPacketReceiver != nullptr) {
|
|
||||||
hkDestinationId = hkPacketReceiver->getHkQueue();
|
|
||||||
} else {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation() {
|
|
||||||
return initializeHousekeepingPoolEntriesOnce();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
|
|
||||||
if (not mapInitialized) {
|
|
||||||
ReturnValue_t result = owner->initializeLocalDataPool(localPoolMap, *this);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
mapInitialized = true;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "initializeHousekeepingPoolEntriesOnce",
|
|
||||||
returnvalue::FAILED, "The map should only be initialized once");
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::performHkOperation() {
|
|
||||||
ReturnValue_t status = returnvalue::OK;
|
|
||||||
for (auto& receiver : hkReceivers) {
|
|
||||||
switch (receiver.reportingType) {
|
|
||||||
case (ReportingType::PERIODIC): {
|
|
||||||
if (receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
|
||||||
/* Periodic packets shall only be generated from datasets */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
performPeriodicHkGeneration(receiver);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ReportingType::UPDATE_HK): {
|
|
||||||
handleHkUpdate(receiver, status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ReportingType::UPDATE_NOTIFICATION): {
|
|
||||||
handleNotificationUpdate(receiver, status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (ReportingType::UPDATE_SNAPSHOT): {
|
|
||||||
handleNotificationSnapshot(receiver, status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// This should never happen.
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resetHkUpdateResetHelper();
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::handleHkUpdate(HkReceiver& receiver, ReturnValue_t& status) {
|
|
||||||
if (receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
|
||||||
/* Update packets shall only be generated from datasets. */
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
LocalPoolDataSetBase* dataSet =
|
|
||||||
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
if (dataSet->hasChanged()) {
|
|
||||||
/* Prepare and send update notification */
|
|
||||||
ReturnValue_t result = generateHousekeepingPacket(receiver.dataId.sid, dataSet, true);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleChangeResetLogic(receiver.dataType, receiver.dataId, dataSet);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(HkReceiver& receiver,
|
|
||||||
ReturnValue_t& status) {
|
|
||||||
MarkChangedIF* toReset = nullptr;
|
|
||||||
if (receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
|
||||||
LocalPoolObjectBase* poolObj =
|
|
||||||
HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, receiver.dataId.localPoolId);
|
|
||||||
if (poolObj == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationUpdate",
|
|
||||||
POOLOBJECT_NOT_FOUND);
|
|
||||||
return POOLOBJECT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
if (poolObj->hasChanged()) {
|
|
||||||
/* Prepare and send update notification. */
|
|
||||||
CommandMessage notification;
|
|
||||||
HousekeepingMessage::setUpdateNotificationVariableCommand(
|
|
||||||
¬ification, gp_id_t(owner->getObjectId(), receiver.dataId.localPoolId));
|
|
||||||
ReturnValue_t result = hkQueue->sendMessage(receiver.destinationQueue, ¬ification);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
toReset = poolObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
LocalPoolDataSetBase* dataSet =
|
|
||||||
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationUpdate",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
if (dataSet->hasChanged()) {
|
|
||||||
/* Prepare and send update notification */
|
|
||||||
CommandMessage notification;
|
|
||||||
HousekeepingMessage::setUpdateNotificationSetCommand(¬ification, receiver.dataId.sid);
|
|
||||||
ReturnValue_t result = hkQueue->sendMessage(receiver.destinationQueue, ¬ification);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
toReset = dataSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (toReset != nullptr) {
|
|
||||||
handleChangeResetLogic(receiver.dataType, receiver.dataId, toReset);
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& receiver,
|
|
||||||
ReturnValue_t& status) {
|
|
||||||
MarkChangedIF* toReset = nullptr;
|
|
||||||
/* Check whether data has changed and send messages in case it has */
|
|
||||||
if (receiver.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
|
||||||
LocalPoolObjectBase* poolObj =
|
|
||||||
HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, receiver.dataId.localPoolId);
|
|
||||||
if (poolObj == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationSnapshot",
|
|
||||||
POOLOBJECT_NOT_FOUND);
|
|
||||||
return POOLOBJECT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not poolObj->hasChanged()) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare and send update snapshot */
|
|
||||||
timeval now{};
|
|
||||||
Clock::getClock_timeval(&now);
|
|
||||||
CCSDSTime::CDS_short cds{};
|
|
||||||
CCSDSTime::convertToCcsds(&cds, &now);
|
|
||||||
HousekeepingSnapshot updatePacket(
|
|
||||||
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
|
||||||
HasLocalDpIFManagerAttorney::getPoolObjectHandle(owner, receiver.dataId.localPoolId));
|
|
||||||
|
|
||||||
store_address_t storeId;
|
|
||||||
ReturnValue_t result = addUpdateToStore(updatePacket, storeId);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandMessage notification;
|
|
||||||
HousekeepingMessage::setUpdateSnapshotVariableCommand(
|
|
||||||
¬ification, gp_id_t(owner->getObjectId(), receiver.dataId.localPoolId), storeId);
|
|
||||||
result = hkQueue->sendMessage(receiver.destinationQueue, ¬ification);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
toReset = poolObj;
|
|
||||||
} else {
|
|
||||||
LocalPoolDataSetBase* dataSet =
|
|
||||||
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleNotificationSnapshot",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not dataSet->hasChanged()) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare and send update snapshot */
|
|
||||||
timeval now{};
|
|
||||||
Clock::getClock_timeval(&now);
|
|
||||||
CCSDSTime::CDS_short cds{};
|
|
||||||
CCSDSTime::convertToCcsds(&cds, &now);
|
|
||||||
HousekeepingSnapshot updatePacket(
|
|
||||||
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
|
||||||
HasLocalDpIFManagerAttorney::getDataSetHandle(owner, receiver.dataId.sid));
|
|
||||||
|
|
||||||
store_address_t storeId;
|
|
||||||
ReturnValue_t result = addUpdateToStore(updatePacket, storeId);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandMessage notification;
|
|
||||||
HousekeepingMessage::setUpdateSnapshotSetCommand(¬ification, receiver.dataId.sid, storeId);
|
|
||||||
result = hkQueue->sendMessage(receiver.destinationQueue, ¬ification);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
toReset = dataSet;
|
|
||||||
}
|
|
||||||
if (toReset != nullptr) {
|
|
||||||
handleChangeResetLogic(receiver.dataType, receiver.dataId, toReset);
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::addUpdateToStore(HousekeepingSnapshot& updatePacket,
|
|
||||||
store_address_t& storeId) {
|
|
||||||
size_t updatePacketSize = updatePacket.getSerializedSize();
|
|
||||||
uint8_t* storePtr = nullptr;
|
|
||||||
ReturnValue_t result =
|
|
||||||
ipcStore->getFreeElement(&storeId, updatePacket.getSerializedSize(), &storePtr);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
size_t serializedSize = 0;
|
|
||||||
result = updatePacket.serialize(&storePtr, &serializedSize, updatePacketSize,
|
|
||||||
SerializeIF::Endianness::MACHINE);
|
|
||||||
return result;
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalDataPoolManager::handleChangeResetLogic(DataType type, DataId dataId,
|
|
||||||
MarkChangedIF* toReset) {
|
|
||||||
for (auto& changeInfo : hkUpdateResetList) {
|
|
||||||
if (changeInfo.dataType != type) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((changeInfo.dataType == DataType::DATA_SET) and (changeInfo.dataId.sid != dataId.sid)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((changeInfo.dataType == DataType::LOCAL_POOL_VARIABLE) and
|
|
||||||
(changeInfo.dataId.localPoolId != dataId.localPoolId)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only one update recipient, we can reset changes status immediately */
|
|
||||||
if (changeInfo.updateCounter <= 1) {
|
|
||||||
toReset->setChanged(false);
|
|
||||||
}
|
|
||||||
/* All recipients have been notified, reset the changed flag */
|
|
||||||
else if (changeInfo.currentUpdateCounter <= 1) {
|
|
||||||
toReset->setChanged(false);
|
|
||||||
changeInfo.currentUpdateCounter = 0;
|
|
||||||
}
|
|
||||||
/* Not all recipiens have been notified yet, decrement */
|
|
||||||
else {
|
|
||||||
changeInfo.currentUpdateCounter--;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalDataPoolManager::resetHkUpdateResetHelper() {
|
|
||||||
for (auto& changeInfo : hkUpdateResetList) {
|
|
||||||
changeInfo.currentUpdateCounter = changeInfo.updateCounter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForRegularPeriodicPacket(
|
|
||||||
subdp::RegularHkPeriodicParams params) {
|
|
||||||
return subscribeForPeriodicPacket(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForDiagPeriodicPacket(
|
|
||||||
subdp::DiagnosticsHkPeriodicParams params) {
|
|
||||||
return subscribeForPeriodicPacket(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(subdp::ParamsBase& params) {
|
|
||||||
struct HkReceiver hkReceiver;
|
|
||||||
hkReceiver.dataId.sid = params.sid;
|
|
||||||
hkReceiver.reportingType = ReportingType::PERIODIC;
|
|
||||||
hkReceiver.dataType = DataType::DATA_SET;
|
|
||||||
if (params.receiver == MessageQueueIF::NO_QUEUE) {
|
|
||||||
hkReceiver.destinationQueue = hkDestinationId;
|
|
||||||
} else {
|
|
||||||
hkReceiver.destinationQueue = params.receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
|
||||||
if (dataSet != nullptr) {
|
|
||||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, params.enableReporting);
|
|
||||||
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, params.collectionInterval,
|
|
||||||
owner->getPeriodicOperationFrequency());
|
|
||||||
}
|
|
||||||
|
|
||||||
hkReceivers.push_back(hkReceiver);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForRegularUpdatePacket(
|
|
||||||
subdp::RegularHkUpdateParams params) {
|
|
||||||
return subscribeForUpdatePacket(params);
|
|
||||||
}
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForDiagUpdatePacket(
|
|
||||||
subdp::DiagnosticsHkUpdateParams params) {
|
|
||||||
return subscribeForUpdatePacket(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(subdp::ParamsBase& params) {
|
|
||||||
struct HkReceiver hkReceiver;
|
|
||||||
hkReceiver.dataId.sid = params.sid;
|
|
||||||
hkReceiver.reportingType = ReportingType::UPDATE_HK;
|
|
||||||
hkReceiver.dataType = DataType::DATA_SET;
|
|
||||||
if (params.receiver == MessageQueueIF::NO_QUEUE) {
|
|
||||||
hkReceiver.destinationQueue = hkDestinationId;
|
|
||||||
} else {
|
|
||||||
hkReceiver.destinationQueue = params.receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
|
||||||
if (dataSet != nullptr) {
|
|
||||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
hkReceivers.push_back(hkReceiver);
|
|
||||||
|
|
||||||
handleHkUpdateResetListInsertion(hkReceiver.dataType, hkReceiver.dataId);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForSetUpdateMessage(const uint32_t setId,
|
|
||||||
object_id_t destinationObject,
|
|
||||||
MessageQueueId_t targetQueueId,
|
|
||||||
bool generateSnapshot) {
|
|
||||||
struct HkReceiver hkReceiver;
|
|
||||||
hkReceiver.dataType = DataType::DATA_SET;
|
|
||||||
hkReceiver.dataId.sid = sid_t(owner->getObjectId(), setId);
|
|
||||||
hkReceiver.destinationQueue = targetQueueId;
|
|
||||||
hkReceiver.objectId = destinationObject;
|
|
||||||
if (generateSnapshot) {
|
|
||||||
hkReceiver.reportingType = ReportingType::UPDATE_SNAPSHOT;
|
|
||||||
} else {
|
|
||||||
hkReceiver.reportingType = ReportingType::UPDATE_NOTIFICATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
hkReceivers.push_back(hkReceiver);
|
|
||||||
|
|
||||||
handleHkUpdateResetListInsertion(hkReceiver.dataType, hkReceiver.dataId);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForVariableUpdateMessage(
|
|
||||||
const lp_id_t localPoolId, object_id_t destinationObject, MessageQueueId_t targetQueueId,
|
|
||||||
bool generateSnapshot) {
|
|
||||||
struct HkReceiver hkReceiver;
|
|
||||||
hkReceiver.dataType = DataType::LOCAL_POOL_VARIABLE;
|
|
||||||
hkReceiver.dataId.localPoolId = localPoolId;
|
|
||||||
hkReceiver.destinationQueue = targetQueueId;
|
|
||||||
hkReceiver.objectId = destinationObject;
|
|
||||||
if (generateSnapshot) {
|
|
||||||
hkReceiver.reportingType = ReportingType::UPDATE_SNAPSHOT;
|
|
||||||
} else {
|
|
||||||
hkReceiver.reportingType = ReportingType::UPDATE_NOTIFICATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
hkReceivers.push_back(hkReceiver);
|
|
||||||
|
|
||||||
handleHkUpdateResetListInsertion(hkReceiver.dataType, hkReceiver.dataId);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalDataPoolManager::handleHkUpdateResetListInsertion(DataType dataType, DataId dataId) {
|
|
||||||
for (auto& updateResetStruct : hkUpdateResetList) {
|
|
||||||
if (dataType == DataType::DATA_SET) {
|
|
||||||
if (updateResetStruct.dataId.sid == dataId.sid) {
|
|
||||||
updateResetStruct.updateCounter++;
|
|
||||||
updateResetStruct.currentUpdateCounter++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (updateResetStruct.dataId.localPoolId == dataId.localPoolId) {
|
|
||||||
updateResetStruct.updateCounter++;
|
|
||||||
updateResetStruct.currentUpdateCounter++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HkUpdateResetHelper hkUpdateResetHelper;
|
|
||||||
hkUpdateResetHelper.currentUpdateCounter = 1;
|
|
||||||
hkUpdateResetHelper.updateCounter = 1;
|
|
||||||
hkUpdateResetHelper.dataType = dataType;
|
|
||||||
if (dataType == DataType::DATA_SET) {
|
|
||||||
hkUpdateResetHelper.dataId.sid = dataId.sid;
|
|
||||||
} else {
|
|
||||||
hkUpdateResetHelper.dataId.localPoolId = dataId.localPoolId;
|
|
||||||
}
|
|
||||||
hkUpdateResetList.push_back(hkUpdateResetHelper);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* message) {
|
|
||||||
Command_t command = message->getCommand();
|
|
||||||
sid_t sid = HousekeepingMessage::getSid(message);
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
switch (command) {
|
|
||||||
// Houskeeping interface handling.
|
|
||||||
case (HousekeepingMessage::ENABLE_PERIODIC_HK_REPORT_GENERATION): {
|
|
||||||
result = togglePeriodicGeneration(sid, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (HousekeepingMessage::DISABLE_PERIODIC_HK_REPORT_GENERATION): {
|
|
||||||
result = togglePeriodicGeneration(sid, false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): {
|
|
||||||
result = generateSetStructurePacket(sid);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
|
|
||||||
float newCollIntvl = 0;
|
|
||||||
HousekeepingMessage::getCollectionIntervalModificationCommand(message, &newCollIntvl);
|
|
||||||
result = changeCollectionInterval(sid, newCollIntvl);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): {
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
return generateHousekeepingPacket(HousekeepingMessage::getSid(message), dataSet, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Notification handling */
|
|
||||||
case (HousekeepingMessage::UPDATE_NOTIFICATION_SET): {
|
|
||||||
owner->handleChangedDataset(sid);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
case (HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE): {
|
|
||||||
gp_id_t globPoolId = HousekeepingMessage::getUpdateNotificationVariableCommand(message);
|
|
||||||
owner->handleChangedPoolVariable(globPoolId);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
case (HousekeepingMessage::UPDATE_SNAPSHOT_SET): {
|
|
||||||
store_address_t storeId;
|
|
||||||
HousekeepingMessage::getUpdateSnapshotSetCommand(message, &storeId);
|
|
||||||
bool clearMessage = true;
|
|
||||||
owner->handleChangedDataset(sid, storeId, &clearMessage);
|
|
||||||
if (clearMessage) {
|
|
||||||
message->clear();
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
case (HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE): {
|
|
||||||
store_address_t storeId;
|
|
||||||
gp_id_t globPoolId = HousekeepingMessage::getUpdateSnapshotVariableCommand(message, &storeId);
|
|
||||||
bool clearMessage = true;
|
|
||||||
owner->handleChangedPoolVariable(globPoolId, storeId, &clearMessage);
|
|
||||||
if (clearMessage) {
|
|
||||||
message->clear();
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return CommandMessageIF::UNKNOWN_COMMAND;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandMessage reply;
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
if (result == WRONG_HK_PACKET_TYPE) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
|
||||||
WRONG_HK_PACKET_TYPE);
|
|
||||||
}
|
|
||||||
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
|
||||||
} else {
|
|
||||||
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
|
||||||
}
|
|
||||||
hkQueue->sendMessage(hkDestinationId, &reply);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::printPoolEntry(lp_id_t localPoolId) {
|
|
||||||
auto poolIter = localPoolMap.find(localPoolId);
|
|
||||||
if (poolIter == localPoolMap.end()) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "printPoolEntry",
|
|
||||||
localpool::POOL_ENTRY_NOT_FOUND);
|
|
||||||
return localpool::POOL_ENTRY_NOT_FOUND;
|
|
||||||
}
|
|
||||||
poolIter->second->print();
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
MutexIF* LocalDataPoolManager::getMutexHandle() { return mutex; }
|
|
||||||
|
|
||||||
HasLocalDataPoolIF* LocalDataPoolManager::getOwner() { return owner; }
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|
||||||
LocalPoolDataSetBase* dataSet,
|
|
||||||
bool forDownlink,
|
|
||||||
MessageQueueId_t destination) {
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
/* Configuration error. */
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
store_address_t storeId;
|
|
||||||
HousekeepingPacketDownlink hkPacket(sid, dataSet);
|
|
||||||
size_t serializedSize = 0;
|
|
||||||
ReturnValue_t result =
|
|
||||||
serializeHkPacketIntoStore(hkPacket, storeId, forDownlink, &serializedSize);
|
|
||||||
if (result != returnvalue::OK or serializedSize == 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we set a HK message and send it the HK packet destination. */
|
|
||||||
CommandMessage hkMessage;
|
|
||||||
HousekeepingMessage::setHkReportReply(&hkMessage, sid, storeId);
|
|
||||||
|
|
||||||
if (hkQueue == nullptr) {
|
|
||||||
/* 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 (hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
|
||||||
/* Error, all destinations invalid */
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
|
||||||
}
|
|
||||||
destination = hkDestinationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hkQueue->sendMessage(destination, &hkMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(HousekeepingPacketDownlink& hkPacket,
|
|
||||||
store_address_t& storeId,
|
|
||||||
bool forDownlink,
|
|
||||||
size_t* serializedSize) {
|
|
||||||
uint8_t* dataPtr = nullptr;
|
|
||||||
const size_t maxSize = hkPacket.getSerializedSize();
|
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &dataPtr);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (forDownlink) {
|
|
||||||
return hkPacket.serialize(&dataPtr, serializedSize, maxSize, SerializeIF::Endianness::BIG);
|
|
||||||
}
|
|
||||||
return hkPacket.serialize(&dataPtr, serializedSize, maxSize, SerializeIF::Endianness::MACHINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
|
||||||
sid_t sid = receiver.dataId.sid;
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not LocalPoolDataSetAttorney::getReportingEnabled(*dataSet)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeriodicHousekeepingHelper* periodicHelper =
|
|
||||||
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
|
|
||||||
|
|
||||||
if (periodicHelper == nullptr) {
|
|
||||||
/* Configuration error */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not periodicHelper->checkOpNecessary()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t result = generateHousekeepingPacket(sid, dataSet, true);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
/* Configuration error */
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed."
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool enable) {
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and enable) or
|
|
||||||
(not LocalPoolDataSetAttorney::getReportingEnabled(*dataSet) and not enable)) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enable);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
|
|
||||||
float newCollectionInterval) {
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeriodicHousekeepingHelper* periodicHelper =
|
|
||||||
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
|
|
||||||
|
|
||||||
if (periodicHelper == nullptr) {
|
|
||||||
/* Configuration error, set might not have a corresponding pool manager */
|
|
||||||
return PERIODIC_HELPER_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
periodicHelper->changeCollectionInterval(newCollectionInterval);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
|
|
||||||
/* Get and check dataset first. */
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
|
||||||
if (dataSet == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration",
|
|
||||||
DATASET_NOT_FOUND);
|
|
||||||
return DATASET_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid = dataSet->isValid();
|
|
||||||
bool reportingEnabled = LocalPoolDataSetAttorney::getReportingEnabled(*dataSet);
|
|
||||||
float collectionInterval =
|
|
||||||
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet)->getCollectionIntervalInSeconds();
|
|
||||||
|
|
||||||
// Generate set packet which can be serialized.
|
|
||||||
HousekeepingSetPacket setPacket(sid, reportingEnabled, valid, collectionInterval, dataSet);
|
|
||||||
size_t expectedSize = setPacket.getSerializedSize();
|
|
||||||
uint8_t* storePtr = nullptr;
|
|
||||||
store_address_t storeId;
|
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, expectedSize, &storePtr);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "generateSetStructurePacket",
|
|
||||||
returnvalue::FAILED, "Could not get free element from IPC store.");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize set packet into store.
|
|
||||||
size_t size = 0;
|
|
||||||
result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
ipcStore->deleteData(storeId);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (expectedSize != size) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket",
|
|
||||||
returnvalue::FAILED, "Expected size is not equal to serialized size");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send structure reporting reply.
|
|
||||||
CommandMessage reply;
|
|
||||||
HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId);
|
|
||||||
|
|
||||||
result = hkQueue->reply(&reply);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
ipcStore->deleteData(storeId);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalDataPoolManager::clearReceiversList() {
|
|
||||||
/* Clear the vector completely and releases allocated memory. */
|
|
||||||
HkReceivers().swap(hkReceivers);
|
|
||||||
/* Also clear the reset helper if it exists */
|
|
||||||
HkUpdateResetList().swap(hkUpdateResetList);
|
|
||||||
}
|
|
||||||
|
|
||||||
MutexIF* LocalDataPoolManager::getLocalPoolMutex() { return this->mutex; }
|
|
||||||
|
|
||||||
object_id_t LocalDataPoolManager::getCreatorObjectId() const { return owner->getObjectId(); }
|
|
||||||
|
|
||||||
void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
|
||||||
const char* functionName, ReturnValue_t error,
|
|
||||||
const char* errorPrint) {
|
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
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 == WRONG_HK_PACKET_TYPE) {
|
|
||||||
errorPrint = "Wrong Packet Type";
|
|
||||||
} else if (error == returnvalue::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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
object_id_t objectId = 0xffffffff;
|
|
||||||
if (owner != nullptr) {
|
|
||||||
objectId = owner->getObjectId();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8)
|
|
||||||
<< std::setfill('0') << std::hex << objectId << " | " << errorPrint << std::dec
|
|
||||||
<< std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, objectId,
|
|
||||||
errorPrint);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
} else if (outputType == sif::OutputTypes::OUT_ERROR) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8)
|
|
||||||
<< std::setfill('0') << std::hex << objectId << " | " << errorPrint << std::dec
|
|
||||||
<< std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, objectId,
|
|
||||||
errorPrint);
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
}
|
|
||||||
#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDataPoolManager* LocalDataPoolManager::getPoolManagerHandle() { return this; }
|
|
||||||
|
|
||||||
void LocalDataPoolManager::setHkDestinationId(MessageQueueId_t hkDestId) {
|
|
||||||
hkDestinationId = hkDestId;
|
|
||||||
}
|
|
@ -1,380 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "AccessLocalPoolF.h"
|
|
||||||
#include "ProvidesDataPoolSubscriptionIF.h"
|
|
||||||
#include "fsfw/datapool/DataSetIF.h"
|
|
||||||
#include "fsfw/datapool/PoolEntry.h"
|
|
||||||
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
|
||||||
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
|
||||||
#include "fsfw/housekeeping/HousekeepingPacketDownlink.h"
|
|
||||||
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
|
||||||
#include "fsfw/ipc/CommandMessage.h"
|
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
|
||||||
#include "fsfw/ipc/MutexGuard.h"
|
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
|
||||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
|
|
||||||
namespace Factory {
|
|
||||||
void setStaticFrameworkObjectIds();
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalPoolDataSetBase;
|
|
||||||
class HousekeepingSnapshot;
|
|
||||||
class HasLocalDataPoolIF;
|
|
||||||
class LocalDataPool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This class is the managing instance for the local data pool.
|
|
||||||
* @details
|
|
||||||
* The actual data pool structure is a member of this class. Any class which
|
|
||||||
* has a local data pool shall have this manager class as a member and implement
|
|
||||||
* the HasLocalDataPoolIF.
|
|
||||||
*
|
|
||||||
* The manager offers some adaption points and functions which can be used
|
|
||||||
* by the owning class to simplify data handling significantly.
|
|
||||||
*
|
|
||||||
* Please ensure that both initialize and initializeAfterTaskCreation are
|
|
||||||
* called at some point by the owning class in the respective functions of the
|
|
||||||
* same name!
|
|
||||||
*
|
|
||||||
* Users of the data pool use the helper classes LocalDataSet,
|
|
||||||
* LocalPoolVariable and LocalPoolVector to access pool entries in
|
|
||||||
* a thread-safe and efficient way.
|
|
||||||
*
|
|
||||||
* The local data pools employ a blackboard logic: Only the most recent
|
|
||||||
* value is stored. The helper classes offer a read() and commit() interface
|
|
||||||
* through the PoolVariableIF which is used to read and update values.
|
|
||||||
* Each pool entry has a valid state too.
|
|
||||||
* @author R. Mueller
|
|
||||||
*/
|
|
||||||
class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public AccessPoolManagerIF {
|
|
||||||
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:
|
|
||||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
|
|
||||||
|
|
||||||
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_INVALID = MAKE_RETURN_CODE(0);
|
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constructor is used by a class which wants to implement
|
|
||||||
* a personal local data pool. The queueToUse can be supplied if it
|
|
||||||
* is already known.
|
|
||||||
*
|
|
||||||
* initialize() has to be called in any case before using the object!
|
|
||||||
* @param owner
|
|
||||||
* @param queueToUse
|
|
||||||
* @param appendValidityBuffer Specify whether a buffer containing the
|
|
||||||
* validity state is generated when serializing or deserializing packets.
|
|
||||||
*/
|
|
||||||
LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
|
||||||
bool appendValidityBuffer = true);
|
|
||||||
~LocalDataPoolManager() override;
|
|
||||||
|
|
||||||
void setHkDestinationId(MessageQueueId_t hkDestId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assigns the queue to use. Make sure to call this in the #initialize
|
|
||||||
* function of the owner.
|
|
||||||
* @param queueToUse
|
|
||||||
* @param nonDiagInvlFactor See #setNonDiagnosticIntervalFactor doc
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t initialize(MessageQueueIF* queueToUse);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the map by calling the map initialization function and
|
|
||||||
* setting the periodic factor for non-diagnostic packets.
|
|
||||||
* Don't forget to call this in the #initializeAfterTaskCreation call of
|
|
||||||
* the owner, otherwise the map will be invalid!
|
|
||||||
* @param nonDiagInvlFactor
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t initializeAfterTaskCreation();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This should be called in the periodic handler of the owner.
|
|
||||||
* @details
|
|
||||||
* This in generally called in the #performOperation function of the owner.
|
|
||||||
* It performs all the periodic functionalities of the data pool manager,
|
|
||||||
* for example generating periodic HK packets.
|
|
||||||
* Marked virtual as an adaption point for custom data pool managers.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t performHkOperation();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
ReturnValue_t subscribeForSetUpdateMessage(uint32_t setId, object_id_t destinationObject,
|
|
||||||
MessageQueueId_t targetQueueId,
|
|
||||||
bool generateSnapshot) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
ReturnValue_t subscribeForVariableUpdateMessage(lp_id_t localPoolId,
|
|
||||||
object_id_t destinationObject,
|
|
||||||
MessageQueueId_t targetQueueId,
|
|
||||||
bool generateSnapshot) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The manager is also able to handle housekeeping messages.
|
|
||||||
* @details
|
|
||||||
* This most commonly is used to handle messages for the housekeeping
|
|
||||||
* interface, but the manager is also able to handle update notifications
|
|
||||||
* and calls a special function which can be overriden by a child class
|
|
||||||
* to handle data set or pool variable updates. This is relevant
|
|
||||||
* for classes like controllers which have their own local datapool
|
|
||||||
* but pull their data from other local datapools.
|
|
||||||
* @param message
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a housekeeping packet with a given SID.
|
|
||||||
* @param sid
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t generateHousekeepingPacket(sid_t sid, LocalPoolDataSetBase* dataSet,
|
|
||||||
bool forDownlink,
|
|
||||||
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
|
||||||
ReturnValue_t changeCollectionInterval(sid_t sid, float newCollectionInterval);
|
|
||||||
|
|
||||||
HasLocalDataPoolIF* getOwner();
|
|
||||||
|
|
||||||
ReturnValue_t printPoolEntry(lp_id_t localPoolId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Different types of housekeeping reporting are possible.
|
|
||||||
* 1. PERIODIC:
|
|
||||||
* HK packets are generated in fixed intervals and sent to
|
|
||||||
* destination. Fromat will be raw.
|
|
||||||
* 2. UPDATE_NOTIFICATION:
|
|
||||||
* Notification will be sent out if HK data has changed.
|
|
||||||
* 3. UPDATE_SNAPSHOT:
|
|
||||||
* HK packets are only generated if explicitely requested.
|
|
||||||
* Propably not necessary, just use multiple local data sets or
|
|
||||||
* shared datasets.
|
|
||||||
*/
|
|
||||||
enum class ReportingType : uint8_t {
|
|
||||||
//! Periodic generation of HK packets.
|
|
||||||
PERIODIC,
|
|
||||||
//! Housekeeping packet will be generated if values have changed.
|
|
||||||
UPDATE_HK,
|
|
||||||
//! Update notification will be sent out as message.
|
|
||||||
UPDATE_NOTIFICATION,
|
|
||||||
//! Notification will be sent out as message and a snapshot of the
|
|
||||||
//! current data will be generated.
|
|
||||||
UPDATE_SNAPSHOT,
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Different data types are possible in the HK receiver map. For example, updates can be
|
|
||||||
requested for full datasets or for single pool variables. Periodic reporting is only possible
|
|
||||||
for data sets. */
|
|
||||||
enum class DataType : uint8_t { LOCAL_POOL_VARIABLE, DATA_SET };
|
|
||||||
|
|
||||||
/* Copying forbidden */
|
|
||||||
LocalDataPoolManager(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();
|
|
||||||
|
|
||||||
[[nodiscard]] object_id_t getCreatorObjectId() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the pointer to the mutex. Can be used to lock the data pool
|
|
||||||
* externally. Use with care and don't forget to unlock locked mutexes!
|
|
||||||
* For now, only friend classes can accss this function.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
MutexIF* getMutexHandle();
|
|
||||||
|
|
||||||
LocalDataPoolManager* getPoolManagerHandle() override;
|
|
||||||
ReturnValue_t subscribeForRegularPeriodicPacket(subdp::RegularHkPeriodicParams params) override;
|
|
||||||
ReturnValue_t subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams params) override;
|
|
||||||
|
|
||||||
ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) override;
|
|
||||||
ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params);
|
|
||||||
ReturnValue_t subscribeForUpdatePacket(subdp::ParamsBase& params);
|
|
||||||
|
|
||||||
/** Core data structure for the actual pool data */
|
|
||||||
localpool::DataPool localPoolMap;
|
|
||||||
/** Every housekeeping data manager has a mutex to protect access
|
|
||||||
to it's data pool. */
|
|
||||||
MutexIF* mutex = nullptr;
|
|
||||||
|
|
||||||
/** The class which actually owns the manager (and its datapool). */
|
|
||||||
HasLocalDataPoolIF* owner = nullptr;
|
|
||||||
|
|
||||||
uint8_t nonDiagnosticIntervalFactor = 0;
|
|
||||||
|
|
||||||
/** Default receiver for periodic HK packets */
|
|
||||||
static object_id_t defaultHkDestination;
|
|
||||||
MessageQueueId_t hkDestinationId = MessageQueueIF::NO_QUEUE;
|
|
||||||
|
|
||||||
union DataId {
|
|
||||||
DataId() : sid() {};
|
|
||||||
sid_t sid;
|
|
||||||
lp_id_t localPoolId;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** The data pool manager will keep an internal map of HK receivers. */
|
|
||||||
struct HkReceiver {
|
|
||||||
/** Object ID of receiver */
|
|
||||||
object_id_t objectId = objects::NO_OBJECT;
|
|
||||||
|
|
||||||
DataType dataType = DataType::DATA_SET;
|
|
||||||
DataId dataId;
|
|
||||||
|
|
||||||
ReportingType reportingType = ReportingType::PERIODIC;
|
|
||||||
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** This vector will contain the list of HK receivers. */
|
|
||||||
using HkReceivers = std::vector<struct HkReceiver>;
|
|
||||||
|
|
||||||
HkReceivers hkReceivers;
|
|
||||||
|
|
||||||
struct HkUpdateResetHelper {
|
|
||||||
DataType dataType = DataType::DATA_SET;
|
|
||||||
DataId dataId;
|
|
||||||
uint8_t updateCounter;
|
|
||||||
uint8_t currentUpdateCounter;
|
|
||||||
};
|
|
||||||
|
|
||||||
using HkUpdateResetList = std::vector<struct HkUpdateResetHelper>;
|
|
||||||
/** This list is used to manage creating multiple update packets and only resetting
|
|
||||||
the update flag if all of them were created. */
|
|
||||||
HkUpdateResetList hkUpdateResetList = HkUpdateResetList();
|
|
||||||
|
|
||||||
/** This is the map holding the actual data. Should only be initialized
|
|
||||||
* once ! */
|
|
||||||
bool mapInitialized = false;
|
|
||||||
/** This specifies whether a validity buffer is appended at the end
|
|
||||||
* of generated housekeeping packets. */
|
|
||||||
bool appendValidityBuffer = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Queue used for communication, for example commands.
|
|
||||||
* Is also used to send messages. Can be set either in the constructor
|
|
||||||
* or in the initialize() function.
|
|
||||||
*/
|
|
||||||
MessageQueueIF* hkQueue = nullptr;
|
|
||||||
|
|
||||||
/** Global IPC store is used to store all packets. */
|
|
||||||
StorageManagerIF* ipcStore = nullptr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a variable by supplying its local pool ID and assign the pool
|
|
||||||
* entry to the supplied PoolEntry pointer. The type of the pool entry
|
|
||||||
* is deduced automatically. This call is not thread-safe!
|
|
||||||
* For now, only classes designated by the LocalDpManagerAttorney may use this function.
|
|
||||||
* @tparam T Type of the pool entry
|
|
||||||
* @param localPoolId Pool ID of the variable to read
|
|
||||||
* @param poolVar [out] Corresponding pool entry will be assigned to the
|
|
||||||
* supplied pointer.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
ReturnValue_t fetchPoolEntry(lp_id_t localPoolId, PoolEntry<T>** poolEntry);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is used to fill the local data pool map with pool
|
|
||||||
* entries. It should only be called once by the pool owner.
|
|
||||||
* @param localDataPoolMap
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t initializeHousekeepingPoolEntriesOnce();
|
|
||||||
|
|
||||||
MutexIF* getLocalPoolMutex() override;
|
|
||||||
|
|
||||||
ReturnValue_t serializeHkPacketIntoStore(HousekeepingPacketDownlink& hkPacket,
|
|
||||||
store_address_t& storeId, bool forDownlink,
|
|
||||||
size_t* serializedSize);
|
|
||||||
|
|
||||||
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
|
|
||||||
ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable);
|
|
||||||
ReturnValue_t generateSetStructurePacket(sid_t sid);
|
|
||||||
|
|
||||||
void handleHkUpdateResetListInsertion(DataType dataType, DataId dataId);
|
|
||||||
void handleChangeResetLogic(DataType type, DataId dataId, MarkChangedIF* toReset);
|
|
||||||
void resetHkUpdateResetHelper();
|
|
||||||
|
|
||||||
ReturnValue_t handleHkUpdate(HkReceiver& hkReceiver, ReturnValue_t& status);
|
|
||||||
ReturnValue_t handleNotificationUpdate(HkReceiver& hkReceiver, ReturnValue_t& status);
|
|
||||||
ReturnValue_t handleNotificationSnapshot(HkReceiver& hkReceiver, ReturnValue_t& status);
|
|
||||||
ReturnValue_t addUpdateToStore(HousekeepingSnapshot& updatePacket, store_address_t& storeId);
|
|
||||||
|
|
||||||
void printWarningOrError(sif::OutputTypes outputType, const char* functionName,
|
|
||||||
ReturnValue_t errorCode = returnvalue::FAILED,
|
|
||||||
const char* errorPrint = nullptr);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
|
||||||
PoolEntry<T>** poolEntry) {
|
|
||||||
if (poolEntry == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto poolIter = localPoolMap.find(localPoolId);
|
|
||||||
if (poolIter == localPoolMap.end()) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "fetchPoolEntry",
|
|
||||||
localpool::POOL_ENTRY_NOT_FOUND);
|
|
||||||
return localpool::POOL_ENTRY_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
*poolEntry = dynamic_cast<PoolEntry<T>*>(poolIter->second);
|
|
||||||
if (*poolEntry == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "fetchPoolEntry",
|
|
||||||
localpool::POOL_ENTRY_TYPE_CONFLICT);
|
|
||||||
return localpool::POOL_ENTRY_TYPE_CONFLICT;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */
|
|
@ -1,21 +0,0 @@
|
|||||||
#include "fsfw/datapoollocal/LocalDataSet.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
|
||||||
|
|
||||||
LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, uint32_t setId,
|
|
||||||
const size_t maxNumberOfVariables)
|
|
||||||
: LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables),
|
|
||||||
poolVarList(maxNumberOfVariables) {
|
|
||||||
this->setContainer(poolVarList.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDataSet::LocalDataSet(sid_t sid, const size_t maxNumberOfVariables)
|
|
||||||
: LocalPoolDataSetBase(sid, nullptr, maxNumberOfVariables), poolVarList(maxNumberOfVariables) {
|
|
||||||
this->setContainer(poolVarList.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDataSet::~LocalDataSet() {}
|
|
@ -1,291 +0,0 @@
|
|||||||
#include <cmath>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "fsfw/globalfunctions/bitutility.h"
|
|
||||||
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
#include "internal/HasLocalDpIFUserAttorney.h"
|
|
||||||
|
|
||||||
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId,
|
|
||||||
PoolVariableIF **registeredVariablesArray,
|
|
||||||
const size_t maxNumberOfVariables, bool periodicHandling)
|
|
||||||
: PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
|
||||||
if (hkOwner == nullptr) {
|
|
||||||
// Configuration error.
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
|
||||||
<< "invalid!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError(
|
|
||||||
"LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
|
||||||
"invalid!\n\r");
|
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AccessPoolManagerIF *accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
|
||||||
|
|
||||||
if (accessor != nullptr) {
|
|
||||||
poolManager = accessor->getPoolManagerHandle();
|
|
||||||
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->sid.objectId = hkOwner->getObjectId();
|
|
||||||
this->sid.ownerSetId = setId;
|
|
||||||
|
|
||||||
/* Data creators get a periodic helper for periodic HK data generation. */
|
|
||||||
if (periodicHandling) {
|
|
||||||
periodicHelper = new PeriodicHousekeepingHelper(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, PoolVariableIF **registeredVariablesArray,
|
|
||||||
const size_t maxNumberOfVariables)
|
|
||||||
: PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
|
||||||
HasLocalDataPoolIF *hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(sid.objectId);
|
|
||||||
if (hkOwner != nullptr) {
|
|
||||||
AccessPoolManagerIF *accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
|
|
||||||
if (accessor != nullptr) {
|
|
||||||
mutexIfSingleDataCreator = accessor->getLocalPoolMutex();
|
|
||||||
poolManager = accessor->getPoolManagerHandle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->sid = sid;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoolDataSetBase::LocalPoolDataSetBase(PoolVariableIF **registeredVariablesArray,
|
|
||||||
const size_t maxNumberOfVariables,
|
|
||||||
bool protectEveryReadCommitCall)
|
|
||||||
: PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
|
||||||
this->setReadCommitProtectionBehaviour(protectEveryReadCommitCall);
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoolDataSetBase::~LocalPoolDataSetBase() {
|
|
||||||
/* We only delete objects which were created in the class constructor */
|
|
||||||
if (periodicHelper != nullptr) {
|
|
||||||
delete periodicHelper;
|
|
||||||
}
|
|
||||||
/* In case set was read but not comitted, we commit all variables with an invalid state */
|
|
||||||
if (state == States::STATE_SET_WAS_READ) {
|
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
|
||||||
if (registeredVariables[count] != nullptr) {
|
|
||||||
registeredVariables[count]->setValid(false);
|
|
||||||
registeredVariables[count]->commit(MutexIF::TimeoutType::WAITING, 20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::lockDataPool(MutexIF::TimeoutType timeoutType,
|
|
||||||
uint32_t timeoutMs) {
|
|
||||||
if (mutexIfSingleDataCreator != nullptr) {
|
|
||||||
return mutexIfSingleDataCreator->lockMutex(timeoutType, timeoutMs);
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(
|
|
||||||
uint8_t **buffer, size_t *size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
const uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount) / 8.0);
|
|
||||||
uint8_t *validityPtr = nullptr;
|
|
||||||
#if defined(_MSC_VER) || defined(__clang__)
|
|
||||||
// Use a std::vector here because MSVC will (rightly) not create a fixed size array
|
|
||||||
// with a non constant size specifier. The Apple compiler (LLVM) will not accept
|
|
||||||
// the initialization of a variable sized array
|
|
||||||
std::vector<uint8_t> validityMask(validityMaskSize, 0);
|
|
||||||
validityPtr = validityMask.data();
|
|
||||||
#else
|
|
||||||
uint8_t validityMask[validityMaskSize] = {};
|
|
||||||
validityPtr = validityMask;
|
|
||||||
#endif
|
|
||||||
uint8_t validBufferIndex = 0;
|
|
||||||
uint8_t validBufferIndexBit = 0;
|
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
|
||||||
if (registeredVariables[count]->isValid()) {
|
|
||||||
/* Set bit at correct position */
|
|
||||||
bitutil::set(validityPtr + validBufferIndex, validBufferIndexBit);
|
|
||||||
}
|
|
||||||
if (validBufferIndexBit == 7) {
|
|
||||||
validBufferIndex++;
|
|
||||||
validBufferIndexBit = 0;
|
|
||||||
} else {
|
|
||||||
validBufferIndexBit++;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = registeredVariables[count]->serialize(buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*size + validityMaskSize > maxSize) {
|
|
||||||
return SerializeIF::BUFFER_TOO_SHORT;
|
|
||||||
}
|
|
||||||
// copy validity buffer to end
|
|
||||||
std::memcpy(*buffer, validityPtr, validityMaskSize);
|
|
||||||
*size += validityMaskSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer(
|
|
||||||
const uint8_t **buffer, size_t *size, SerializeIF::Endianness streamEndianness) {
|
|
||||||
ReturnValue_t result = returnvalue::FAILED;
|
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
|
||||||
result = registeredVariables[count]->deSerialize(buffer, size, streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*size < std::ceil(static_cast<float>(fillCount) / 8.0)) {
|
|
||||||
return SerializeIF::STREAM_TOO_SHORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t validBufferIndex = 0;
|
|
||||||
uint8_t validBufferIndexBit = 0;
|
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
|
||||||
// set validity buffer here.
|
|
||||||
bool nextVarValid = false;
|
|
||||||
bitutil::get(*buffer + validBufferIndex, validBufferIndexBit, nextVarValid);
|
|
||||||
registeredVariables[count]->setValid(nextVarValid);
|
|
||||||
|
|
||||||
if (validBufferIndexBit == 7) {
|
|
||||||
validBufferIndex++;
|
|
||||||
validBufferIndexBit = 0;
|
|
||||||
} else {
|
|
||||||
validBufferIndexBit++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
|
|
||||||
if (mutexIfSingleDataCreator != nullptr) {
|
|
||||||
return mutexIfSingleDataCreator->unlockMutex();
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t **buffer, size_t *size,
|
|
||||||
size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness,
|
|
||||||
bool serializeFillCount) const {
|
|
||||||
/* Serialize fill count as uint8_t */
|
|
||||||
uint8_t fillCount = this->fillCount;
|
|
||||||
if (serializeFillCount) {
|
|
||||||
SerializeAdapter::serialize(&fillCount, buffer, size, maxSize, streamEndianness);
|
|
||||||
}
|
|
||||||
for (uint16_t count = 0; count < fillCount; count++) {
|
|
||||||
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
|
|
||||||
auto result =
|
|
||||||
SerializeAdapter::serialize(¤tPoolId, buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
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 returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t LocalPoolDataSetBase::getLocalPoolIdsSerializedSize(bool serializeFillCount) const {
|
|
||||||
if (serializeFillCount) {
|
|
||||||
return fillCount * sizeof(lp_id_t) + sizeof(uint8_t);
|
|
||||||
} else {
|
|
||||||
return fillCount * sizeof(lp_id_t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t LocalPoolDataSetBase::getSerializedSize() const {
|
|
||||||
if (withValidityBuffer) {
|
|
||||||
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount) / 8.0);
|
|
||||||
return validityMaskSize + PoolDataSetBase::getSerializedSize();
|
|
||||||
} else {
|
|
||||||
return PoolDataSetBase::getSerializedSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setValidityBufferGeneration(bool withValidityBuffer) {
|
|
||||||
this->withValidityBuffer = withValidityBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::deSerialize(const uint8_t **buffer, size_t *size,
|
|
||||||
SerializeIF::Endianness streamEndianness) {
|
|
||||||
if (withValidityBuffer) {
|
|
||||||
return this->deSerializeWithValidityBuffer(buffer, size, streamEndianness);
|
|
||||||
} else {
|
|
||||||
return PoolDataSetBase::deSerialize(buffer, size, streamEndianness);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolDataSetBase::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
|
||||||
if (withValidityBuffer) {
|
|
||||||
return this->serializeWithValidityBuffer(buffer, size, maxSize, streamEndianness);
|
|
||||||
} else {
|
|
||||||
return PoolDataSetBase::serialize(buffer, size, maxSize, streamEndianness);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) {
|
|
||||||
this->reportingEnabled = reportingEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LocalPoolDataSetBase::getReportingEnabled() const { return reportingEnabled; }
|
|
||||||
|
|
||||||
void LocalPoolDataSetBase::initializePeriodicHelper(float collectionInterval,
|
|
||||||
dur_millis_t minimumPeriodicInterval) {
|
|
||||||
periodicHelper->initialize(collectionInterval, minimumPeriodicInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setChanged(bool changed) { this->changed = changed; }
|
|
||||||
|
|
||||||
bool LocalPoolDataSetBase::hasChanged() const { return changed; }
|
|
||||||
|
|
||||||
sid_t LocalPoolDataSetBase::getSid() const { return sid; }
|
|
||||||
|
|
||||||
bool LocalPoolDataSetBase::isValid() const { return this->valid; }
|
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
|
|
||||||
if (setEntriesRecursively) {
|
|
||||||
for (size_t idx = 0; idx < this->getFillCount(); idx++) {
|
|
||||||
registeredVariables[idx]->setValid(valid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->valid = valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
object_id_t LocalPoolDataSetBase::getCreatorObjectId() {
|
|
||||||
if (poolManager != nullptr) {
|
|
||||||
return poolManager->getCreatorObjectId();
|
|
||||||
}
|
|
||||||
return objects::NO_OBJECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPoolDataSetBase::setAllVariablesReadOnly() {
|
|
||||||
for (size_t idx = 0; idx < this->getFillCount(); idx++) {
|
|
||||||
registeredVariables[idx]->setReadWriteMode(pool_rwm_t::VAR_READ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float LocalPoolDataSetBase::getCollectionInterval() const {
|
|
||||||
if (periodicHelper != nullptr) {
|
|
||||||
return periodicHelper->getCollectionIntervalInSeconds();
|
|
||||||
} else {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPoolDataSetBase::printSet() { return; }
|
|
@ -1,68 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLOBJECTBASE_H_
|
|
||||||
|
|
||||||
#include "MarkChangedIF.h"
|
|
||||||
#include "fsfw/datapool/PoolVariableIF.h"
|
|
||||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
|
||||||
#include "localPoolDefinitions.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, public MarkChangedIF {
|
|
||||||
public:
|
|
||||||
LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
|
|
||||||
pool_rwm_t setReadWriteMode);
|
|
||||||
|
|
||||||
LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
|
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
|
||||||
|
|
||||||
void setReadWriteMode(pool_rwm_t newReadWriteMode) override;
|
|
||||||
pool_rwm_t getReadWriteMode() const override;
|
|
||||||
|
|
||||||
bool isValid() const override;
|
|
||||||
void setValid(bool valid) override;
|
|
||||||
|
|
||||||
void setChanged(bool changed) override;
|
|
||||||
bool hasChanged() const override;
|
|
||||||
|
|
||||||
lp_id_t getDataPoolId() const override;
|
|
||||||
void setDataPoolId(lp_id_t poolId);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* @brief To access the correct data pool entry on read and commit calls,
|
|
||||||
* the data pool id is stored.
|
|
||||||
*/
|
|
||||||
uint32_t localPoolId = PoolVariableIF::NO_PARAMETER;
|
|
||||||
/**
|
|
||||||
* @brief The valid information as it was stored in the data pool
|
|
||||||
* is copied to this attribute.
|
|
||||||
*/
|
|
||||||
bool valid = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A local pool variable can be marked as changed.
|
|
||||||
*/
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The information whether the class is read-write or
|
|
||||||
* read-only is stored here.
|
|
||||||
*/
|
|
||||||
ReadWriteMode_t readWriteMode = pool_rwm_t::VAR_READ_WRITE;
|
|
||||||
|
|
||||||
//! @brief Pointer to the class which manages the HK pool.
|
|
||||||
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_ */
|
|
@ -1,197 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
|
||||||
|
|
||||||
#include "../datapool/DataSetIF.h"
|
|
||||||
#include "../datapool/PoolVariableIF.h"
|
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
|
||||||
#include "../serialize/SerializeAdapter.h"
|
|
||||||
#include "../serviceinterface/ServiceInterface.h"
|
|
||||||
#include "AccessLocalPoolF.h"
|
|
||||||
#include "HasLocalDataPoolIF.h"
|
|
||||||
#include "LocalDataPoolManager.h"
|
|
||||||
#include "LocalPoolObjectBase.h"
|
|
||||||
#include "internal/LocalDpManagerAttorney.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Local Pool Variable class which is used to access the local pools.
|
|
||||||
* @details
|
|
||||||
* This class is not stored in the map. Instead, it is used to access
|
|
||||||
* the pool entries by using a pointer to the map storing the pool
|
|
||||||
* entries. It can also be used to organize these pool entries into data sets.
|
|
||||||
*
|
|
||||||
* @tparam T The template parameter sets the type of the variable. Currently,
|
|
||||||
* all plain data types are supported, but in principle any type is possible.
|
|
||||||
* @ingroup data_pool
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class LocalPoolVariable : public LocalPoolObjectBase {
|
|
||||||
public:
|
|
||||||
//! Default ctor is forbidden.
|
|
||||||
LocalPoolVariable() = delete;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constructor is used by the data creators to have pool variable
|
|
||||||
* instances which can also be stored in datasets.
|
|
||||||
*
|
|
||||||
* It does not fetch the current value from the data pool, which
|
|
||||||
* has to be done by calling the read() operation.
|
|
||||||
* Datasets can be used to access multiple local pool entries in an
|
|
||||||
* efficient way. A pointer to a dataset can be passed to register
|
|
||||||
* the pool variable in that dataset directly.
|
|
||||||
* @param poolId ID of the local pool entry.
|
|
||||||
* @param hkOwner Pointer of the owner. This will generally be the calling
|
|
||||||
* class itself which passes "this".
|
|
||||||
* @param dataSet The data set in which the variable shall register itself.
|
|
||||||
* If nullptr, the variable is not registered.
|
|
||||||
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
|
||||||
*/
|
|
||||||
LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
|
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constructor is used by data users like controllers to have
|
|
||||||
* access to the local pool variables of data creators by supplying
|
|
||||||
* the respective creator object ID.
|
|
||||||
*
|
|
||||||
* It does not fetch the current value from the data pool, which
|
|
||||||
* has to be done by calling the read() operation.
|
|
||||||
* Datasets can be used to access multiple local pool entries in an
|
|
||||||
* efficient way. A pointer to a dataset can be passed to register
|
|
||||||
* the pool variable in that dataset directly.
|
|
||||||
* @param poolId ID of the local pool entry.
|
|
||||||
* @param hkOwner object ID of the pool owner.
|
|
||||||
* @param dataSet The data set in which the variable shall register itself.
|
|
||||||
* If nullptr, the variable is not registered.
|
|
||||||
* @param setReadWriteMode Specify the read-write mode of the pool variable.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
|
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
|
||||||
/**
|
|
||||||
* Variation which takes the global unique identifier of a pool variable.
|
|
||||||
* @param globalPoolId
|
|
||||||
* @param dataSet
|
|
||||||
* @param setReadWriteMode
|
|
||||||
*/
|
|
||||||
LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr,
|
|
||||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
|
||||||
|
|
||||||
virtual ~LocalPoolVariable() {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This is the local copy of the data pool entry.
|
|
||||||
* @details The user can work on this attribute
|
|
||||||
* just like he would on a simple local variable.
|
|
||||||
*/
|
|
||||||
T value = 0;
|
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const override;
|
|
||||||
size_t getSerializedSize() const override;
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
|
||||||
SerializeIF::Endianness streamEndianness) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This is a call to read the array's values
|
|
||||||
* from the global data pool.
|
|
||||||
* @details
|
|
||||||
* When executed, this operation tries to fetch the pool entry with matching
|
|
||||||
* data pool id from the data pool and copies all array values and the valid
|
|
||||||
* information to its local attributes.
|
|
||||||
* In case of a failure (wrong type, size or pool id not found), the
|
|
||||||
* variable is set to zero and invalid.
|
|
||||||
* The read call is protected with a lock.
|
|
||||||
* It is recommended to use DataSets to read and commit multiple variables
|
|
||||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
* @details
|
|
||||||
* It checks type and size, as well as if the variable is writable. If so,
|
|
||||||
* the value is copied and the local valid flag is written back as well.
|
|
||||||
* The read call is protected with a lock.
|
|
||||||
* It is recommended to use DataSets to read and commit multiple variables
|
|
||||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
|
||||||
*/
|
|
||||||
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 LocalPoolVariable<T>& newPoolVariable);
|
|
||||||
|
|
||||||
//! Explicit type conversion operator. Allows casting the class to
|
|
||||||
//! its template type to perform operations on value.
|
|
||||||
explicit operator T() const;
|
|
||||||
|
|
||||||
bool operator==(const LocalPoolVariable<T>& other) const;
|
|
||||||
bool operator==(const T& other) const;
|
|
||||||
|
|
||||||
bool operator!=(const LocalPoolVariable<T>& other) const;
|
|
||||||
bool operator!=(const T& other) const;
|
|
||||||
|
|
||||||
bool operator<(const LocalPoolVariable<T>& other) const;
|
|
||||||
bool operator<(const T& other) const;
|
|
||||||
|
|
||||||
bool operator>(const LocalPoolVariable<T>& other) const;
|
|
||||||
bool operator>(const T& other) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* @brief Like #read, but without a lock protection of the global pool.
|
|
||||||
* @details
|
|
||||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
|
||||||
* This can be used if the lock is handled externally to avoid the overhead
|
|
||||||
* of consecutive lock und unlock operations.
|
|
||||||
* Declared protected to discourage free public usage.
|
|
||||||
*/
|
|
||||||
ReturnValue_t readWithoutLock() override;
|
|
||||||
/**
|
|
||||||
* @brief Like #commit, but without a lock protection of the global pool.
|
|
||||||
* @details
|
|
||||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
|
||||||
* This can be used if the lock is handled externally to avoid the overhead
|
|
||||||
* of consecutive lock und unlock operations.
|
|
||||||
* Declared protected to discourage free public usage.
|
|
||||||
*/
|
|
||||||
ReturnValue_t commitWithoutLock() override;
|
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
// std::ostream is the type for object std::cout
|
|
||||||
template <typename U>
|
|
||||||
friend std::ostream& operator<<(std::ostream& out, const LocalPoolVariable<U>& var);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "LocalPoolVariable.tpp"
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
using lp_var_t = LocalPoolVariable<T>;
|
|
||||||
|
|
||||||
using lp_bool_t = LocalPoolVariable<uint8_t>;
|
|
||||||
using lp_uint8_t = LocalPoolVariable<uint8_t>;
|
|
||||||
using lp_uint16_t = LocalPoolVariable<uint16_t>;
|
|
||||||
using lp_uint32_t = LocalPoolVariable<uint32_t>;
|
|
||||||
using lp_uint64_t = LocalPoolVariable<uint64_t>;
|
|
||||||
using lp_int8_t = LocalPoolVariable<int8_t>;
|
|
||||||
using lp_int16_t = LocalPoolVariable<int16_t>;
|
|
||||||
using lp_int32_t = LocalPoolVariable<int32_t>;
|
|
||||||
using lp_int64_t = LocalPoolVariable<int64_t>;
|
|
||||||
using lp_float_t = LocalPoolVariable<float>;
|
|
||||||
using lp_double_t = LocalPoolVariable<double>;
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ */
|
|
@ -1,193 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_
|
|
||||||
|
|
||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_
|
|
||||||
#error Include LocalPoolVariable.h before LocalPoolVariable.tpp!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
|
|
||||||
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
|
|
||||||
: LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
|
|
||||||
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
|
|
||||||
: LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet,
|
|
||||||
pool_rwm_t setReadWriteMode)
|
|
||||||
: LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet,
|
|
||||||
setReadWriteMode) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::read(MutexIF::TimeoutType timeoutType,
|
|
||||||
uint32_t timeoutMs) {
|
|
||||||
if (hkManager == nullptr) {
|
|
||||||
return readWithoutLock();
|
|
||||||
}
|
|
||||||
MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager);
|
|
||||||
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = readWithoutLock();
|
|
||||||
mutex->unlockMutex();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
|
|
||||||
if (readWriteMode == pool_rwm_t::VAR_WRITE) {
|
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, true,
|
|
||||||
targetObjectId, localPoolId);
|
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
|
||||||
ReturnValue_t result =
|
|
||||||
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVariable", result, false, ownerObjectId, localPoolId);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->value = *(poolEntry->getDataPtr());
|
|
||||||
this->valid = poolEntry->getValid();
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::commit(bool setValid, MutexIF::TimeoutType timeoutType,
|
|
||||||
uint32_t timeoutMs) {
|
|
||||||
this->setValid(setValid);
|
|
||||||
return commit(timeoutType, timeoutMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::commit(MutexIF::TimeoutType timeoutType,
|
|
||||||
uint32_t timeoutMs) {
|
|
||||||
if (hkManager == nullptr) {
|
|
||||||
return commitWithoutLock();
|
|
||||||
}
|
|
||||||
MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager);
|
|
||||||
ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = commitWithoutLock();
|
|
||||||
mutex->unlockMutex();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
|
|
||||||
if (readWriteMode == pool_rwm_t::VAR_READ) {
|
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, false,
|
|
||||||
targetObjectId, localPoolId);
|
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
|
||||||
ReturnValue_t result =
|
|
||||||
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
object_id_t ownerObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVariable", result, false, ownerObjectId, localPoolId);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(poolEntry->getDataPtr()) = this->value;
|
|
||||||
poolEntry->setValid(this->valid);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::serialize(
|
|
||||||
uint8_t** buffer, size_t* size, const size_t max_size,
|
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
|
||||||
return SerializeAdapter::serialize(&value, buffer, size, max_size, streamEndianness);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline size_t LocalPoolVariable<T>::getSerializedSize() const {
|
|
||||||
return SerializeAdapter::getSerializedSize(&value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline ReturnValue_t LocalPoolVariable<T>::deSerialize(const uint8_t** buffer, size_t* size,
|
|
||||||
SerializeIF::Endianness streamEndianness) {
|
|
||||||
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
template <typename T>
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const LocalPoolVariable<T>& var) {
|
|
||||||
out << var.value;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline LocalPoolVariable<T>::operator T() const {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator=(const T& newValue) {
|
|
||||||
value = newValue;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator=(
|
|
||||||
const LocalPoolVariable<T>& newPoolVariable) {
|
|
||||||
value = newPoolVariable.value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator==(const LocalPoolVariable<T>& other) const {
|
|
||||||
return this->value == other.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator==(const T& other) const {
|
|
||||||
return this->value == other;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator!=(const LocalPoolVariable<T>& other) const {
|
|
||||||
return not(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator!=(const T& other) const {
|
|
||||||
return not(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator<(const LocalPoolVariable<T>& other) const {
|
|
||||||
return this->value < other.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator<(const T& other) const {
|
|
||||||
return this->value < other;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator>(const LocalPoolVariable<T>& other) const {
|
|
||||||
return not(*this < other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool LocalPoolVariable<T>::operator>(const T& other) const {
|
|
||||||
return not(*this < other);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ */
|
|
@ -1,177 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_TPP_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_TPP_
|
|
||||||
|
|
||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_
|
|
||||||
#error Include LocalPoolVector.h before LocalPoolVector.tpp!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
|
|
||||||
DataSetIF* dataSet,
|
|
||||||
pool_rwm_t setReadWriteMode)
|
|
||||||
: LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(object_id_t poolOwner, lp_id_t poolId,
|
|
||||||
DataSetIF* dataSet,
|
|
||||||
pool_rwm_t setReadWriteMode)
|
|
||||||
: LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(gp_id_t globalPoolId, DataSetIF* dataSet,
|
|
||||||
pool_rwm_t setReadWriteMode)
|
|
||||||
: LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet,
|
|
||||||
setReadWriteMode) {}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(MutexIF::TimeoutType timeoutType,
|
|
||||||
uint32_t timeoutMs) {
|
|
||||||
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
|
||||||
return readWithoutLock();
|
|
||||||
}
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
|
||||||
if (readWriteMode == pool_rwm_t::VAR_WRITE) {
|
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, true,
|
|
||||||
targetObjectId, localPoolId);
|
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
|
||||||
ReturnValue_t result =
|
|
||||||
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
|
|
||||||
memset(this->value, 0, vectorSize * sizeof(T));
|
|
||||||
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVector", result, true, targetObjectId, localPoolId);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
|
|
||||||
this->valid = poolEntry->getValid();
|
|
||||||
return returnvalue::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>
|
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(MutexIF::TimeoutType timeoutType,
|
|
||||||
uint32_t timeoutMs) {
|
|
||||||
MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
|
|
||||||
return commitWithoutLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
|
|
||||||
if (readWriteMode == pool_rwm_t::VAR_READ) {
|
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, false,
|
|
||||||
targetObjectId, localPoolId);
|
|
||||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
|
||||||
}
|
|
||||||
PoolEntry<T>* poolEntry = nullptr;
|
|
||||||
ReturnValue_t result =
|
|
||||||
LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
object_id_t targetObjectId = hkManager->getCreatorObjectId();
|
|
||||||
reportReadCommitError("LocalPoolVector", result, false, targetObjectId, localPoolId);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
|
|
||||||
poolEntry->setValid(this->valid);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline T& LocalPoolVector<T, vectorSize>::operator[](size_t i) {
|
|
||||||
if (i < vectorSize) {
|
|
||||||
return value[i];
|
|
||||||
}
|
|
||||||
// If this happens, I have to set some value. I consider this
|
|
||||||
// a configuration error, but I wont exit here.
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!\n");
|
|
||||||
#endif
|
|
||||||
return value[vectorSize - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline const T& LocalPoolVector<T, vectorSize>::operator[](size_t i) const {
|
|
||||||
if (i < vectorSize) {
|
|
||||||
return value[i];
|
|
||||||
}
|
|
||||||
// If this happens, I have to set some value. I consider this
|
|
||||||
// a configuration error, but I wont exit here.
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printWarning(
|
|
||||||
"LocalPoolVector: Invalid index. Setting or returning"
|
|
||||||
" last value!\n");
|
|
||||||
#endif
|
|
||||||
return value[vectorSize - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::serialize(
|
|
||||||
uint8_t** buffer, size_t* size, size_t maxSize,
|
|
||||||
SerializeIF::Endianness streamEndianness) const {
|
|
||||||
ReturnValue_t result = returnvalue::FAILED;
|
|
||||||
for (uint16_t i = 0; i < vectorSize; i++) {
|
|
||||||
result = SerializeAdapter::serialize(&(value[i]), buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline size_t LocalPoolVector<T, vectorSize>::getSerializedSize() const {
|
|
||||||
return vectorSize * SerializeAdapter::getSerializedSize(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::deSerialize(
|
|
||||||
const uint8_t** buffer, size_t* size, SerializeIF::Endianness streamEndianness) {
|
|
||||||
ReturnValue_t result = returnvalue::FAILED;
|
|
||||||
for (uint16_t i = 0; i < vectorSize; i++) {
|
|
||||||
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
template <typename T, uint16_t vectorSize>
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const LocalPoolVector<T, vectorSize>& var) {
|
|
||||||
out << "Vector: [";
|
|
||||||
for (int i = 0; i < vectorSize; i++) {
|
|
||||||
out << var.value[i];
|
|
||||||
if (i < vectorSize - 1) {
|
|
||||||
out << ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << "]";
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVECTOR_TPP_ */
|
|
@ -1,152 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
|
||||||
|
|
||||||
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
|
||||||
#include "fsfw/ipc/messageQueueDefinitions.h"
|
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
|
||||||
#include "localPoolDefinitions.h"
|
|
||||||
|
|
||||||
namespace subdp {
|
|
||||||
|
|
||||||
struct ParamsBase {
|
|
||||||
ParamsBase(sid_t sid, bool enableReporting, float collectionInterval, bool diagnostics)
|
|
||||||
: sid(sid),
|
|
||||||
enableReporting(enableReporting),
|
|
||||||
collectionInterval(collectionInterval),
|
|
||||||
diagnostics(diagnostics) {}
|
|
||||||
|
|
||||||
[[nodiscard]] bool isDiagnostics() const { return diagnostics; }
|
|
||||||
|
|
||||||
sid_t sid;
|
|
||||||
bool enableReporting;
|
|
||||||
float collectionInterval;
|
|
||||||
MessageQueueId_t receiver = MessageQueueIF::NO_QUEUE;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool diagnostics;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RegularHkPeriodicParams : public ParamsBase {
|
|
||||||
RegularHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
|
|
||||||
: ParamsBase(sid, enableReporting, collectionInterval, false) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiagnosticsHkPeriodicParams : public ParamsBase {
|
|
||||||
DiagnosticsHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
|
|
||||||
: ParamsBase(sid, enableReporting, collectionInterval, true) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RegularHkUpdateParams : public ParamsBase {
|
|
||||||
RegularHkUpdateParams(sid_t sid, bool enableReporting)
|
|
||||||
: ParamsBase(sid, enableReporting, 0.0, false) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiagnosticsHkUpdateParams : public ParamsBase {
|
|
||||||
DiagnosticsHkUpdateParams(sid_t sid, bool enableReporting)
|
|
||||||
: ParamsBase(sid, enableReporting, 0.0, true) {}
|
|
||||||
};
|
|
||||||
} // namespace subdp
|
|
||||||
|
|
||||||
class ProvidesDataPoolSubscriptionIF {
|
|
||||||
public:
|
|
||||||
virtual ~ProvidesDataPoolSubscriptionIF() = default;
|
|
||||||
/**
|
|
||||||
* @brief Subscribe for the generation of periodic packets. Used for regular HK 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 subscribeForRegularPeriodicPacket(
|
|
||||||
subdp::RegularHkPeriodicParams params) = 0;
|
|
||||||
/**
|
|
||||||
* @brief Subscribe for the generation of periodic packets. Used for diagnostic 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 subscribeForDiagPeriodicPacket(
|
|
||||||
subdp::DiagnosticsHkPeriodicParams params) = 0;
|
|
||||||
|
|
||||||
[[deprecated(
|
|
||||||
"Please use the new API which takes all arguments as one wrapper "
|
|
||||||
"struct")]] virtual ReturnValue_t
|
|
||||||
subscribeForPeriodicPacket(sid_t sid, bool enableReporting, float collectionInterval,
|
|
||||||
bool isDiagnostics,
|
|
||||||
object_id_t packetDestination = objects::NO_OBJECT) {
|
|
||||||
if (isDiagnostics) {
|
|
||||||
subdp::DiagnosticsHkPeriodicParams params(sid, enableReporting, collectionInterval);
|
|
||||||
return subscribeForDiagPeriodicPacket(params);
|
|
||||||
} else {
|
|
||||||
subdp::RegularHkPeriodicParams params(sid, enableReporting, collectionInterval);
|
|
||||||
return subscribeForRegularPeriodicPacket(params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) = 0;
|
|
||||||
virtual ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) = 0;
|
|
||||||
|
|
||||||
[[deprecated(
|
|
||||||
"Please use the new API which takes all arguments as one wrapper "
|
|
||||||
"struct")]] virtual ReturnValue_t
|
|
||||||
subscribeForUpdatePacket(sid_t sid, bool reportingEnabled, bool isDiagnostics,
|
|
||||||
object_id_t packetDestination = objects::NO_OBJECT) {
|
|
||||||
if (isDiagnostics) {
|
|
||||||
subdp::DiagnosticsHkUpdateParams params(sid, reportingEnabled);
|
|
||||||
return subscribeForDiagUpdatePacket(params);
|
|
||||||
} else {
|
|
||||||
subdp::RegularHkUpdateParams params(sid, reportingEnabled);
|
|
||||||
return subscribeForRegularUpdatePacket(params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 Object ID of the receiver.
|
|
||||||
* @param targetQueueId Receiver queue ID
|
|
||||||
* @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 subscribeForSetUpdateMessage(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 Object ID of the receiver
|
|
||||||
* @param targetQueueId Receiver queue ID
|
|
||||||
* @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 subscribeForVariableUpdateMessage(lp_id_t localPoolId,
|
|
||||||
object_id_t destinationObject,
|
|
||||||
MessageQueueId_t targetQueueId,
|
|
||||||
bool generateSnapshot) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_ */
|
|
@ -1,37 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "../datapool/SharedDataSetIF.h"
|
|
||||||
#include "../objectmanager/SystemObject.h"
|
|
||||||
#include "LocalPoolDataSetBase.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* The user is completely responsible for lockingand unlocking the dataset when using the
|
|
||||||
* shared dataset.
|
|
||||||
*/
|
|
||||||
class SharedLocalDataSet : public SystemObject,
|
|
||||||
public LocalPoolDataSetBase,
|
|
||||||
public SharedDataSetIF {
|
|
||||||
public:
|
|
||||||
SharedLocalDataSet(object_id_t objectId, HasLocalDataPoolIF* owner, uint32_t setId,
|
|
||||||
const size_t maxSize);
|
|
||||||
SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize);
|
|
||||||
|
|
||||||
virtual ~SharedLocalDataSet();
|
|
||||||
|
|
||||||
ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
|
||||||
dur_millis_t mutexTimeout = 20) override;
|
|
||||||
ReturnValue_t unlockDataset() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
MutexIF* datasetLock = nullptr;
|
|
||||||
std::vector<PoolVariableIF*> poolVarVector;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_DATAPOOLLOCAL_SHAREDLOCALDATASET_H_ */
|
|
@ -1,2 +0,0 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE HasLocalDpIFUserAttorney.cpp
|
|
||||||
HasLocalDpIFManagerAttorney.cpp)
|
|
@ -1,19 +0,0 @@
|
|||||||
#include "HasLocalDpIFManagerAttorney.h"
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalPoolDataSetBase.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalPoolObjectBase.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();
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/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_ */
|
|
@ -1,8 +0,0 @@
|
|||||||
#include "HasLocalDpIFUserAttorney.h"
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/AccessLocalPoolF.h"
|
|
||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
|
|
||||||
AccessPoolManagerIF* HasLocalDpIFUserAttorney::getAccessorHandle(HasLocalDataPoolIF* clientIF) {
|
|
||||||
return clientIF->getAccessorHandle();
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_
|
|
||||||
#define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/LocalPoolDataSetBase.h"
|
|
||||||
|
|
||||||
class LocalPoolDataSetAttorney {
|
|
||||||
private:
|
|
||||||
static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
|
|
||||||
uint32_t minimumPeriodicIntervalMs) {
|
|
||||||
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
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,11 +1,10 @@
|
|||||||
#include "DeviceHandlerBase.h"
|
#include "DeviceHandlerBase.h"
|
||||||
|
|
||||||
#include "fsfw/datapool/PoolReadGuard.h"
|
#include "fsfw/datapool/PoolReadGuard.h"
|
||||||
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
#include "fsfw/datapool/PoolVariable.h"
|
||||||
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
||||||
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
||||||
#include "fsfw/globalfunctions/CRC.h"
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
@ -28,11 +27,12 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
||||||
deviceCommunicationId(deviceCommunication),
|
deviceCommunicationId(deviceCommunication),
|
||||||
comCookie(comCookie),
|
comCookie(comCookie),
|
||||||
|
sharedPool(DeviceHandlerBase::getObjectId()),
|
||||||
healthHelper(this, setObjectId),
|
healthHelper(this, setObjectId),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
parameterHelper(this),
|
parameterHelper(this),
|
||||||
actionHelper(this, nullptr),
|
actionHelper(this, nullptr),
|
||||||
poolManager(this, nullptr),
|
hkHelper(this, nullptr),
|
||||||
childTransitionFailure(returnvalue::OK),
|
childTransitionFailure(returnvalue::OK),
|
||||||
fdirInstance(fdirInstance),
|
fdirInstance(fdirInstance),
|
||||||
defaultFDIRUsed(fdirInstance == nullptr),
|
defaultFDIRUsed(fdirInstance == nullptr),
|
||||||
@ -111,7 +111,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. */
|
||||||
poolManager.performHkOperation();
|
hkHelper.performHkOperation();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -152,8 +152,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rawDataReceiverId != objects::NO_OBJECT) {
|
if (rawDataReceiverId != objects::NO_OBJECT) {
|
||||||
AcceptsDeviceResponsesIF* rawReceiver =
|
auto* rawReceiver = ObjectManager::instance()->get<AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
||||||
ObjectManager::instance()->get<AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
|
||||||
|
|
||||||
if (rawReceiver == nullptr) {
|
if (rawReceiver == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
|
||||||
@ -214,7 +213,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = poolManager.initialize(commandQueue);
|
result = hkHelper.initialize(commandQueue);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -226,7 +225,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
// Set temperature target state to NON_OP.
|
// Set temperature target state to NON_OP.
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||||
thermalSet->heaterRequest.setValid(true);
|
// thermalSet->heaterRequest.setValid(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +287,7 @@ void DeviceHandlerBase::readCommandQueue() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = poolManager.handleHousekeepingMessage(&command);
|
result = hkHelper.handleHousekeepingMessage(&command);
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -413,7 +412,7 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, Submode_t s
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
||||||
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet,
|
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, dp::SharedSetBase* replyDataSet,
|
||||||
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId,
|
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId,
|
||||||
Countdown* countdown) {
|
Countdown* countdown) {
|
||||||
// No need to check, as we may try to insert multiple times.
|
// No need to check, as we may try to insert multiple times.
|
||||||
@ -428,7 +427,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
|||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
||||||
uint16_t maxDelayCycles,
|
uint16_t maxDelayCycles,
|
||||||
LocalPoolDataSetBase* dataSet, size_t replyLen,
|
dp::SharedSetBase* dataSet, size_t replyLen,
|
||||||
bool periodic, Countdown* countdown) {
|
bool periodic, Countdown* countdown) {
|
||||||
DeviceReplyInfo info;
|
DeviceReplyInfo info;
|
||||||
info.maxDelayCycles = maxDelayCycles;
|
info.maxDelayCycles = maxDelayCycles;
|
||||||
@ -529,7 +528,7 @@ ReturnValue_t DeviceHandlerBase::updatePeriodicReply(bool enable, DeviceCommandI
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId,
|
ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId,
|
||||||
LocalPoolDataSetBase* dataSet) {
|
dp::SharedSetBase* dataSet) {
|
||||||
auto replyIter = deviceReplyMap.find(replyId);
|
auto replyIter = deviceReplyMap.find(replyId);
|
||||||
if (replyIter == deviceReplyMap.end()) {
|
if (replyIter == deviceReplyMap.end()) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
@ -593,7 +592,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
|||||||
if (thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
if (thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||||
}
|
}
|
||||||
thermalSet->heaterRequest.setValid(true);
|
// thermalSet->heaterRequest.setValid(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
||||||
@ -1468,8 +1467,9 @@ Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
|
|||||||
|
|
||||||
void DeviceHandlerBase::performOperationHook() {}
|
void DeviceHandlerBase::performOperationHook() {}
|
||||||
|
|
||||||
|
/*
|
||||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) {
|
PeriodicHkGenerationHelper& poolManager) {
|
||||||
if (thermalStateCfg.has_value()) {
|
if (thermalStateCfg.has_value()) {
|
||||||
localDataPoolMap.emplace(thermalStateCfg.value().thermalStatePoolId,
|
localDataPoolMap.emplace(thermalStateCfg.value().thermalStatePoolId,
|
||||||
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>());
|
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>());
|
||||||
@ -1478,6 +1478,7 @@ ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& lo
|
|||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
||||||
@ -1485,7 +1486,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
|||||||
if (executingTask != nullptr) {
|
if (executingTask != nullptr) {
|
||||||
pstIntervalMs = executingTask->getPeriodMs();
|
pstIntervalMs = executingTask->getPeriodMs();
|
||||||
}
|
}
|
||||||
this->poolManager.initializeAfterTaskCreation();
|
// this->poolManager.initializeAfterTaskCreation();
|
||||||
|
|
||||||
if (thermalStateCfg.has_value()) {
|
if (thermalStateCfg.has_value()) {
|
||||||
ThermalStateCfg& cfg = thermalStateCfg.value();
|
ThermalStateCfg& cfg = thermalStateCfg.value();
|
||||||
@ -1497,20 +1498,11 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) {
|
|
||||||
auto iter = deviceReplyMap.find(sid.ownerSetId);
|
|
||||||
if (iter != deviceReplyMap.end()) {
|
|
||||||
return iter->second.dataSet;
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object_id_t DeviceHandlerBase::getObjectId() const { return SystemObject::getObjectId(); }
|
object_id_t DeviceHandlerBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
void DeviceHandlerBase::setStartUpImmediately() { this->setStartupImmediately = true; }
|
void DeviceHandlerBase::setStartUpImmediately() { this->setStartupImmediately = true; }
|
||||||
|
|
||||||
dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { return pstIntervalMs; }
|
// dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { return pstIntervalMs; }
|
||||||
|
|
||||||
DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
||||||
if (cookieInfo.pendingCommand != deviceCommandMap.end()) {
|
if (cookieInfo.pendingCommand != deviceCommandMap.end()) {
|
||||||
@ -1519,17 +1511,6 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
|||||||
return DeviceHandlerIF::NO_COMMAND_ID;
|
return DeviceHandlerIF::NO_COMMAND_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
|
||||||
for (const auto& reply : deviceReplyMap) {
|
|
||||||
if (reply.second.dataSet != nullptr) {
|
|
||||||
PoolReadGuard pg(reply.second.dataSet);
|
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
|
||||||
reply.second.dataSet->setValidity(false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const char* functionName,
|
void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const char* functionName,
|
||||||
ReturnValue_t errorCode, const char* errorPrint) {
|
ReturnValue_t errorCode, const char* errorPrint) {
|
||||||
if (errorPrint == nullptr) {
|
if (errorPrint == nullptr) {
|
||||||
@ -1570,8 +1551,6 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() { return &poolManager; }
|
|
||||||
|
|
||||||
MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyId) const {
|
MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyId) const {
|
||||||
auto commandIter = deviceCommandMap.find(replyId);
|
auto commandIter = deviceCommandMap.find(replyId);
|
||||||
if (commandIter == deviceCommandMap.end()) {
|
if (commandIter == deviceCommandMap.end()) {
|
||||||
@ -1628,3 +1607,7 @@ ReturnValue_t DeviceHandlerBase::finishAction(bool success, DeviceCommandId_t ac
|
|||||||
actionHelper.finish(success, commandIter->second.sendReplyTo, action, result);
|
actionHelper.finish(success, commandIter->second.sendReplyTo, action, result);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() { return; }
|
||||||
|
|
||||||
|
hk::PeriodicHelper& DeviceHandlerBase::getHkHelper() { return hkHelper; }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
#pragma once
|
||||||
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
|
||||||
|
#include <fsfw/housekeeping/PeriodicHkHelper.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@ -10,9 +11,6 @@
|
|||||||
#include "DeviceHandlerThermalSet.h"
|
#include "DeviceHandlerThermalSet.h"
|
||||||
#include "fsfw/action/ActionHelper.h"
|
#include "fsfw/action/ActionHelper.h"
|
||||||
#include "fsfw/action/HasActionsIF.h"
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
#include "fsfw/datapool/PoolVariableIF.h"
|
|
||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "fsfw/health/HealthHelper.h"
|
#include "fsfw/health/HealthHelper.h"
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/modes/HasModesIF.h"
|
#include "fsfw/modes/HasModesIF.h"
|
||||||
@ -20,7 +18,6 @@
|
|||||||
#include "fsfw/parameters/ParameterHelper.h"
|
#include "fsfw/parameters/ParameterHelper.h"
|
||||||
#include "fsfw/power/PowerSwitchIF.h"
|
#include "fsfw/power/PowerSwitchIF.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||||
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
@ -88,7 +85,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
public ModeTreeChildIF,
|
public ModeTreeChildIF,
|
||||||
public ModeTreeConnectionIF,
|
public ModeTreeConnectionIF,
|
||||||
public ReceivesParameterMessagesIF,
|
public ReceivesParameterMessagesIF,
|
||||||
public HasLocalDataPoolIF {
|
public hk::GeneratesPeriodicHkIF {
|
||||||
friend void(Factory::setStaticFrameworkObjectIds)();
|
friend void(Factory::setStaticFrameworkObjectIds)();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -96,7 +93,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* The constructor passes the objectId to the SystemObject().
|
* The constructor passes the objectId to the SystemObject().
|
||||||
*
|
*
|
||||||
* @param setObjectId the ObjectId to pass to the SystemObject() Constructor
|
* @param setObjectId the ObjectId to pass to the SystemObject() Constructor
|
||||||
* @param deviceCommuncation Communcation Interface object which is used
|
* @param deviceCommunication Communication Interface object which is used
|
||||||
* to implement communication functions
|
* to implement communication functions
|
||||||
* @param comCookie This object will be passed to the communication inter-
|
* @param comCookie This object will be passed to the communication inter-
|
||||||
* face and can contain user-defined information about the communication.
|
* face and can contain user-defined information about the communication.
|
||||||
@ -109,6 +106,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
void setCustomFdir(FailureIsolationBase *fdir);
|
void setCustomFdir(FailureIsolationBase *fdir);
|
||||||
void setPowerSwitcher(PowerSwitchIF *switcher);
|
void setPowerSwitcher(PowerSwitchIF *switcher);
|
||||||
|
|
||||||
|
hk::PeriodicHelper &getHkHelper();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* extending the modes of DeviceHandler IF for internal state machine
|
* extending the modes of DeviceHandler IF for internal state machine
|
||||||
*/
|
*/
|
||||||
@ -230,7 +229,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
ReturnValue_t initializeAfterTaskCreation() override;
|
ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
virtual ~DeviceHandlerBase();
|
~DeviceHandlerBase() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ExecutableObjectIF function
|
* Implementation of ExecutableObjectIF function
|
||||||
@ -238,7 +237,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @param task_ Pointer to the taskIF of this task
|
* @param task_ Pointer to the taskIF of this task
|
||||||
*/
|
*/
|
||||||
virtual void setTaskIF(PeriodicTaskIF *task_) override;
|
virtual void setTaskIF(PeriodicTaskIF *task_) override;
|
||||||
virtual MessageQueueId_t getCommandQueue(void) const override;
|
virtual MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
/** Explicit interface implementation of getObjectId */
|
/** Explicit interface implementation of getObjectId */
|
||||||
virtual object_id_t getObjectId() const override;
|
virtual object_id_t getObjectId() const override;
|
||||||
@ -506,7 +505,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* - @c returnvalue::FAILED else.
|
* - @c returnvalue::FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
||||||
LocalPoolDataSetBase *replyDataSet = nullptr,
|
dp::SharedSetBase *replyDataSet = nullptr,
|
||||||
size_t replyLen = 0, bool periodic = false,
|
size_t replyLen = 0, bool periodic = false,
|
||||||
bool hasDifferentReplyId = false,
|
bool hasDifferentReplyId = false,
|
||||||
DeviceCommandId_t replyId = 0,
|
DeviceCommandId_t replyId = 0,
|
||||||
@ -527,7 +526,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* - @c returnvalue::FAILED else.
|
* - @c returnvalue::FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
||||||
LocalPoolDataSetBase *dataSet = nullptr, size_t replyLen = 0,
|
dp::SharedSetBase *dataSet = nullptr, size_t replyLen = 0,
|
||||||
bool periodic = false, Countdown *countdown = nullptr);
|
bool periodic = false, Countdown *countdown = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -580,7 +579,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @details
|
* @details
|
||||||
* Used by the local data pool manager.
|
* Used by the local data pool manager.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, LocalPoolDataSetBase *dataset);
|
ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, dp::SharedSetBase *dataset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the time needed to transit from modeFrom to modeTo.
|
* Get the time needed to transit from modeFrom to modeTo.
|
||||||
@ -607,8 +606,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @param localDataPoolMap
|
* @param localDataPoolMap
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
// virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) override;
|
// PeriodicHkGenerationHelper &poolManager) override;
|
||||||
/**
|
/**
|
||||||
* @brief Set all datapool variables that are update periodically in
|
* @brief Set all datapool variables that are update periodically in
|
||||||
* normal mode invalid
|
* normal mode invalid
|
||||||
@ -619,15 +618,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* method optionally.
|
* method optionally.
|
||||||
*/
|
*/
|
||||||
virtual void setNormalDatapoolEntriesInvalid();
|
virtual void setNormalDatapoolEntriesInvalid();
|
||||||
/**
|
|
||||||
* @brief Get the dataset handle for a given SID.
|
|
||||||
* @details
|
|
||||||
* The default implementation will use the deviceCommandMap to look for the corresponding
|
|
||||||
* dataset handle. The user can override this function if this is not desired.
|
|
||||||
* @param sid
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
|
|
||||||
|
|
||||||
/* HasModesIF overrides */
|
/* HasModesIF overrides */
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode) override;
|
virtual void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
@ -797,6 +787,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
/** Cookie used for communication */
|
/** Cookie used for communication */
|
||||||
CookieIF *comCookie;
|
CookieIF *comCookie;
|
||||||
|
|
||||||
|
dp::SharedPool sharedPool;
|
||||||
|
|
||||||
/* Health helper for HasHealthIF */
|
/* Health helper for HasHealthIF */
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
/* Mode helper for HasModesIF */
|
/* Mode helper for HasModesIF */
|
||||||
@ -806,7 +798,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
/* Action helper for HasActionsIF */
|
/* Action helper for HasActionsIF */
|
||||||
ActionHelper actionHelper;
|
ActionHelper actionHelper;
|
||||||
/* Housekeeping Manager */
|
/* Housekeeping Manager */
|
||||||
LocalDataPoolManager poolManager;
|
hk::PeriodicHelper hkHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Information about commands
|
* @brief Information about commands
|
||||||
@ -854,7 +846,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
//! The dataset used to access housekeeping data related to the
|
//! The dataset used to access housekeeping data related to the
|
||||||
//! respective device reply. Will point to a dataset held by
|
//! respective device reply. Will point to a dataset held by
|
||||||
//! the child handler (if one is specified)
|
//! the child handler (if one is specified)
|
||||||
LocalPoolDataSetBase *dataSet = nullptr;
|
dp::SharedSetBase *dataSet = nullptr;
|
||||||
//! The command that expects this reply.
|
//! The command that expects this reply.
|
||||||
DeviceCommandMap::iterator command;
|
DeviceCommandMap::iterator command;
|
||||||
//! Instead of using delayCycles to specify the maximum time to wait for the device reply, it
|
//! Instead of using delayCycles to specify the maximum time to wait for the device reply, it
|
||||||
@ -1006,12 +998,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
virtual void doOnActivity();
|
virtual void doOnActivity();
|
||||||
|
|
||||||
/**
|
|
||||||
* Required for HasLocalDataPoolIF, return a handle to the local pool manager.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
LocalDataPoolManager *getHkManagerHandle() override;
|
|
||||||
|
|
||||||
const HasHealthIF *getOptHealthIF() const override;
|
const HasHealthIF *getOptHealthIF() const override;
|
||||||
const HasModesIF &getModeIF() const override;
|
const HasModesIF &getModeIF() const override;
|
||||||
|
|
||||||
@ -1403,8 +1389,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
|
|
||||||
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
|
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
|
||||||
|
|
||||||
virtual dur_millis_t getPeriodicOperationFrequency() const override;
|
|
||||||
|
|
||||||
void parseReply(const uint8_t *receivedData, size_t receivedDataLen);
|
void parseReply(const uint8_t *receivedData, size_t receivedDataLen);
|
||||||
|
|
||||||
void handleTransitionToOnMode(Mode_t commandedMode, Submode_t commandedSubmode);
|
void handleTransitionToOnMode(Mode_t commandedMode, Submode_t commandedSubmode);
|
||||||
@ -1425,5 +1409,3 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
void disableCommandsAndReplies();
|
void disableCommandsAndReplies();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_
|
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_
|
||||||
|
|
||||||
#include "../action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
#include "../datapoollocal/localPoolDefinitions.h"
|
|
||||||
#include "../events/Event.h"
|
#include "../events/Event.h"
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../modes/HasModesIF.h"
|
#include "../modes/HasModesIF.h"
|
||||||
#include "DeviceHandlerMessage.h"
|
#include "DeviceHandlerMessage.h"
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is used to uniquely identify commands that are sent to a device
|
* This is used to uniquely identify commands that are sent to a device
|
||||||
@ -120,10 +120,10 @@ class DeviceHandlerIF {
|
|||||||
NOTHING //!< Do nothing.
|
NOTHING //!< Do nothing.
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr uint32_t DEFAULT_THERMAL_SET_ID = sid_t::INVALID_SET_ID - 1;
|
static constexpr uint32_t DEFAULT_THERMAL_SET_ID = dp::sid_t::INVALID_SET_ID - 1;
|
||||||
|
|
||||||
static constexpr lp_id_t DEFAULT_THERMAL_STATE_POOL_ID = localpool::INVALID_LPID - 2;
|
static constexpr dp::id_t DEFAULT_THERMAL_STATE_POOL_ID = dp::INVALID_LPID - 2;
|
||||||
static constexpr lp_id_t DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID = localpool::INVALID_LPID - 1;
|
static constexpr dp::id_t DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID = dp::INVALID_LPID - 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Destructor
|
* Default Destructor
|
||||||
@ -138,8 +138,8 @@ class DeviceHandlerIF {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ThermalStateCfg {
|
struct ThermalStateCfg {
|
||||||
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID;
|
dp::id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID;
|
||||||
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID;
|
dp::id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID;
|
||||||
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID;
|
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,27 +1,29 @@
|
|||||||
#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_
|
#ifndef FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_
|
||||||
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_
|
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_
|
||||||
|
|
||||||
#include "../datapoollocal/LocalPoolVariable.h"
|
#include <fsfw/datapool/StaticSharedSet.h>
|
||||||
#include "../datapoollocal/StaticLocalDataSet.h"
|
#include <fsfw/housekeeping/GeneratesPeriodicHkIF.h>
|
||||||
#include "DeviceHandlerIF.h"
|
|
||||||
|
|
||||||
class DeviceHandlerThermalSet : public StaticLocalDataSet<2> {
|
#include "DeviceHandlerIF.h"
|
||||||
|
#include "fsfw/datapool/PoolVariable.h"
|
||||||
|
|
||||||
|
class DeviceHandlerThermalSet : public dp::StaticSharedSet<2> {
|
||||||
public:
|
public:
|
||||||
DeviceHandlerThermalSet(HasLocalDataPoolIF* hkOwner, ThermalStateCfg cfg)
|
DeviceHandlerThermalSet(hk::GeneratesPeriodicHkIF* hkOwner, ThermalStateCfg cfg)
|
||||||
: DeviceHandlerThermalSet(hkOwner->getObjectId(), cfg) {}
|
: DeviceHandlerThermalSet(hkOwner->getObjectId(), cfg) {}
|
||||||
|
|
||||||
DeviceHandlerThermalSet(object_id_t deviceHandler, ThermalStateCfg cfg)
|
DeviceHandlerThermalSet(object_id_t deviceHandler, ThermalStateCfg cfg)
|
||||||
: StaticLocalDataSet(sid_t(deviceHandler, cfg.thermalSetId)),
|
: StaticSharedSet(dp::structure_id_t(deviceHandler, cfg.thermalSetId), true),
|
||||||
thermalStatePoolId(cfg.thermalStatePoolId),
|
thermalStatePoolId(cfg.thermalStatePoolId),
|
||||||
heaterRequestPoolId(cfg.thermalRequestPoolId) {}
|
heaterRequestPoolId(cfg.thermalRequestPoolId) {}
|
||||||
|
|
||||||
const lp_id_t thermalStatePoolId;
|
const dp::id_t thermalStatePoolId;
|
||||||
const lp_id_t heaterRequestPoolId;
|
const dp::id_t heaterRequestPoolId;
|
||||||
|
|
||||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t> thermalState =
|
dp::var_t<DeviceHandlerIF::dh_thermal_state_t> thermalState =
|
||||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t>(sid.objectId, thermalStatePoolId, this);
|
dp::var_t<DeviceHandlerIF::dh_thermal_state_t>(sid.objectId, thermalStatePoolId, this);
|
||||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t> heaterRequest =
|
dp::var_t<DeviceHandlerIF::dh_heater_request_t> heaterRequest =
|
||||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t>(sid.objectId, heaterRequestPoolId, this);
|
dp::var_t<DeviceHandlerIF::dh_heater_request_t>(sid.objectId, heaterRequestPoolId, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_ */
|
||||||
|
@ -8,12 +8,12 @@ FreshDeviceHandlerBase::FreshDeviceHandlerBase(DhbConfig config)
|
|||||||
: SystemObject(config.objectId),
|
: SystemObject(config.objectId),
|
||||||
actionHelper(this, nullptr),
|
actionHelper(this, nullptr),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
healthHelper(this, getObjectId()),
|
healthHelper(this, FreshDeviceHandlerBase::getObjectId()),
|
||||||
paramHelper(this),
|
paramHelper(this),
|
||||||
poolManager(this, nullptr),
|
hkHelper(this, nullptr),
|
||||||
fdirInstance(config.fdirInstance),
|
fdirInstance(config.fdirInstance),
|
||||||
defaultFdirParent(config.defaultFdirParent) {
|
defaultFdirParent(config.defaultFdirParent) {
|
||||||
auto mqArgs = MqArgs(config.objectId, static_cast<void*>(this));
|
auto mqArgs = MqArgs(config.objectId, this);
|
||||||
messageQueue = QueueFactory::instance()->createMessageQueue(
|
messageQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
config.msgQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
config.msgQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ ReturnValue_t FreshDeviceHandlerBase::performOperation(uint8_t opCode) {
|
|||||||
handleQueue();
|
handleQueue();
|
||||||
fdirInstance->checkForFailures();
|
fdirInstance->checkForFailures();
|
||||||
performDeviceOperation(opCode);
|
performDeviceOperation(opCode);
|
||||||
poolManager.performHkOperation();
|
hkHelper.performHkOperation();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,6 @@ ReturnValue_t FreshDeviceHandlerBase::performDeviceOperationPreQueueHandling(uin
|
|||||||
|
|
||||||
void FreshDeviceHandlerBase::startTransition(Mode_t mode_, Submode_t submode_) {
|
void FreshDeviceHandlerBase::startTransition(Mode_t mode_, Submode_t submode_) {
|
||||||
triggerEvent(CHANGING_MODE, mode_, submode_);
|
triggerEvent(CHANGING_MODE, mode_, submode_);
|
||||||
// Complete mode transition immediately by default.
|
|
||||||
setMode(mode_, submode_);
|
setMode(mode_, submode_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +96,7 @@ ReturnValue_t FreshDeviceHandlerBase::handleQueue() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = poolManager.handleHousekeepingMessage(&command);
|
result = hkHelper.handleHousekeepingMessage(&command);
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -127,17 +126,6 @@ ReturnValue_t FreshDeviceHandlerBase::connectModeTreeParent(HasModeTreeChildrenI
|
|||||||
// Executable Overrides.
|
// Executable Overrides.
|
||||||
void FreshDeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
void FreshDeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
||||||
|
|
||||||
// Pool Manager overrides.
|
|
||||||
LocalDataPoolManager* FreshDeviceHandlerBase::getHkManagerHandle() { return &poolManager; }
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t FreshDeviceHandlerBase::getPeriodicOperationFrequency() const {
|
|
||||||
return this->executingTask->getPeriodMs();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::initializeAfterTaskCreation() {
|
|
||||||
return poolManager.initializeAfterTaskCreation();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FreshDeviceHandlerBase::setHealth(HasHealthIF::HealthState health) {
|
ReturnValue_t FreshDeviceHandlerBase::setHealth(HasHealthIF::HealthState health) {
|
||||||
// Assembly should handle commanding to OFF.
|
// Assembly should handle commanding to OFF.
|
||||||
healthHelper.setHealth(health);
|
healthHelper.setHealth(health);
|
||||||
@ -174,7 +162,7 @@ ReturnValue_t FreshDeviceHandlerBase::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = poolManager.initialize(messageQueue);
|
result = hkHelper.initialize(messageQueue);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -201,3 +189,5 @@ ReturnValue_t FreshDeviceHandlerBase::getParameter(uint8_t domainId, uint8_t uni
|
|||||||
}
|
}
|
||||||
return INVALID_DOMAIN_ID;
|
return INVALID_DOMAIN_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
datapool::SharedPool* FreshDeviceHandlerBase::getOptionalSharedPool() { return nullptr; }
|
@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/housekeeping/PeriodicHkHelper.h>
|
||||||
|
|
||||||
#include "fsfw/action.h"
|
#include "fsfw/action.h"
|
||||||
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||||
#include "fsfw/fdir/FailureIsolationBase.h"
|
#include "fsfw/fdir/FailureIsolationBase.h"
|
||||||
#include "fsfw/health/HasHealthIF.h"
|
#include "fsfw/health/HasHealthIF.h"
|
||||||
#include "fsfw/health/HealthHelper.h"
|
#include "fsfw/health/HealthHelper.h"
|
||||||
|
#include "fsfw/housekeeping/GeneratesPeriodicHkIF.h"
|
||||||
#include "fsfw/modes/HasModesIF.h"
|
#include "fsfw/modes/HasModesIF.h"
|
||||||
#include "fsfw/objectmanager.h"
|
#include "fsfw/objectmanager.h"
|
||||||
#include "fsfw/parameters/ParameterHelper.h"
|
#include "fsfw/parameters/ParameterHelper.h"
|
||||||
@ -61,7 +62,7 @@ class FreshDeviceHandlerBase : public SystemObject,
|
|||||||
public ModeTreeConnectionIF,
|
public ModeTreeConnectionIF,
|
||||||
public HasActionsIF,
|
public HasActionsIF,
|
||||||
public ReceivesParameterMessagesIF,
|
public ReceivesParameterMessagesIF,
|
||||||
public HasLocalDataPoolIF {
|
public hk::GeneratesPeriodicHkIF {
|
||||||
public:
|
public:
|
||||||
explicit FreshDeviceHandlerBase(DhbConfig config);
|
explicit FreshDeviceHandlerBase(DhbConfig config);
|
||||||
~FreshDeviceHandlerBase() override;
|
~FreshDeviceHandlerBase() override;
|
||||||
@ -96,16 +97,12 @@ class FreshDeviceHandlerBase : public SystemObject,
|
|||||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
||||||
ModeTreeChildIF& getModeTreeChildIF() override;
|
ModeTreeChildIF& getModeTreeChildIF() override;
|
||||||
|
|
||||||
[[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Pool Manager overrides.
|
|
||||||
LocalDataPoolManager* getHkManagerHandle() override;
|
|
||||||
ActionHelper actionHelper;
|
ActionHelper actionHelper;
|
||||||
ModeHelper modeHelper;
|
ModeHelper modeHelper;
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
ParameterHelper paramHelper;
|
ParameterHelper paramHelper;
|
||||||
LocalDataPoolManager poolManager;
|
hk::PeriodicHelper hkHelper;
|
||||||
|
|
||||||
bool hasCustomFdir = false;
|
bool hasCustomFdir = false;
|
||||||
FailureIsolationBase* fdirInstance;
|
FailureIsolationBase* fdirInstance;
|
||||||
@ -151,6 +148,24 @@ class FreshDeviceHandlerBase : public SystemObject,
|
|||||||
// System Object overrides.
|
// System Object overrides.
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is implemented to serialize a housekeeping packet when a HK message to
|
||||||
|
* generate the packet is received, or periodic generation is necessary. The user should serialize
|
||||||
|
* the HK set into the provided buffer, which will have the size specified in the set
|
||||||
|
* specification.
|
||||||
|
*/
|
||||||
|
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf,
|
||||||
|
size_t maxSize) override = 0;
|
||||||
|
/**
|
||||||
|
* This function is implemented by the user to specify the available housekeeping sets.
|
||||||
|
*/
|
||||||
|
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) override = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this device handler has an optional pool, return it. Otherwise, nullptr can be returned.
|
||||||
|
*/
|
||||||
|
datapool::SharedPool* getOptionalSharedPool() override = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implemented by child class. Handle all command messages which are
|
* Implemented by child class. Handle all command messages which are
|
||||||
* not health, mode, action or housekeeping messages.
|
* not health, mode, action or housekeeping messages.
|
||||||
@ -159,18 +174,7 @@ class FreshDeviceHandlerBase : public SystemObject,
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) = 0;
|
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) = 0;
|
||||||
|
|
||||||
// HK manager abstract functions.
|
// Mode abstract functions
|
||||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
|
||||||
LocalDataPoolManager& poolManager) override = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HasModesIF implementation to check the validity of a mode command.
|
|
||||||
* @param mode
|
|
||||||
* @param submode
|
|
||||||
* @param msToReachTheMode
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t* msToReachTheMode) override = 0;
|
uint32_t* msToReachTheMode) override = 0;
|
||||||
// Health Overrides.
|
// Health Overrides.
|
||||||
@ -202,7 +206,6 @@ class FreshDeviceHandlerBase : public SystemObject,
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
ReturnValue_t initializeAfterTaskCreation() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This calls the FDIR instance event trigger function.
|
* This calls the FDIR instance event trigger function.
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
#ifndef FSFW_INC_FSFW_HOUSEKEEPING_H_
|
#pragma once
|
||||||
#define FSFW_INC_FSFW_HOUSEKEEPING_H_
|
|
||||||
|
|
||||||
#include "src/core/housekeeping/HousekeepingMessage.h"
|
#include "fsfw/housekeeping/Dataset.h"
|
||||||
#include "src/core/housekeeping/HousekeepingPacketDownlink.h"
|
#include "fsfw/housekeeping/DatasetElement.h"
|
||||||
#include "src/core/housekeeping/HousekeepingSetPacket.h"
|
|
||||||
#include "src/core/housekeeping/HousekeepingSnapshot.h"
|
|
||||||
|
|
||||||
#endif /* FSFW_INC_FSFW_HOUSEKEEPING_H_ */
|
|
@ -1,2 +1,2 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE HousekeepingMessage.cpp
|
target_sources(${LIB_FSFW_NAME} PRIVATE HousekeepingMessage.cpp
|
||||||
PeriodicHousekeepingHelper.cpp)
|
PeriodicHkHelper.cpp)
|
||||||
|
128
src/fsfw/housekeeping/Dataset.h
Normal file
128
src/fsfw/housekeeping/Dataset.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "SerializableWithValidityIF.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
#include "fsfw/globalfunctions/bitutility.h"
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
class Dataset : public SerializeIF {
|
||||||
|
public:
|
||||||
|
explicit Dataset(dp::structure_id_t sid, bool serializeWithValidityBlob = true)
|
||||||
|
: serializeWithValidityBlob(serializeWithValidityBlob), sid(sid) {}
|
||||||
|
|
||||||
|
[[nodiscard]] dp::structure_id_t getStructureId() const { return sid; }
|
||||||
|
|
||||||
|
void addSerializable(const std::reference_wrapper<SerializableWithValidityIF> serializable) {
|
||||||
|
serializables.push_back(serializable);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getNumberOfSerializables() const { return serializables.size(); }
|
||||||
|
|
||||||
|
[[nodiscard]] ReturnValue_t doSerializeWithValidityBlob(uint8_t **buffer, size_t *size,
|
||||||
|
size_t maxSize,
|
||||||
|
Endianness streamEndianness) const {
|
||||||
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
|
const uint8_t validityMaskSize = std::ceil(static_cast<float>(serializables.size()) / 8.0);
|
||||||
|
uint8_t *validityPtr = nullptr;
|
||||||
|
#if defined(_MSC_VER) || defined(__clang__)
|
||||||
|
// Use a std::vector here because MSVC will (rightly) not create a fixed size array
|
||||||
|
// with a non constant size specifier. The Apple compiler (LLVM) will not accept
|
||||||
|
// the initialization of a variable sized array
|
||||||
|
std::vector<uint8_t> validityMask(validityMaskSize, 0);
|
||||||
|
validityPtr = validityMask.data();
|
||||||
|
#else
|
||||||
|
uint8_t validityMask[validityMaskSize] = {};
|
||||||
|
validityPtr = validityMask;
|
||||||
|
#endif
|
||||||
|
uint8_t validBufferIndex = 0;
|
||||||
|
uint8_t validBufferIndexBit = 0;
|
||||||
|
for (auto &serializable : serializables) {
|
||||||
|
if (serializable.get().isValid()) {
|
||||||
|
// Set bit at correct position
|
||||||
|
bitutil::set(validityPtr + validBufferIndex, validBufferIndexBit);
|
||||||
|
}
|
||||||
|
if (validBufferIndexBit == 7) {
|
||||||
|
validBufferIndex++;
|
||||||
|
validBufferIndexBit = 0;
|
||||||
|
} else {
|
||||||
|
validBufferIndexBit++;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = serializable.get().serialize(buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*size + validityMaskSize > maxSize) {
|
||||||
|
return SerializeIF::BUFFER_TOO_SHORT;
|
||||||
|
}
|
||||||
|
// copy validity buffer to end
|
||||||
|
std::memcpy(*buffer, validityPtr, validityMaskSize);
|
||||||
|
*size += validityMaskSize;
|
||||||
|
*buffer += validityMaskSize;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const override {
|
||||||
|
if (serializeWithValidityBlob) {
|
||||||
|
return doSerializeWithValidityBlob(buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
for (auto &serializable : serializables) {
|
||||||
|
result = serializable.get().serialize(buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ReturnValue_t serialize(uint8_t *buffer, size_t &serSize, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const override {
|
||||||
|
return SerializeIF::serialize(buffer, serSize, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setChildrenValidity(bool valid) {
|
||||||
|
for (auto &serializable : serializables) {
|
||||||
|
serializable.get().setValid(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getSerializedSize() const override {
|
||||||
|
size_t size = 0;
|
||||||
|
for (auto &serializable : serializables) {
|
||||||
|
size += serializable.get().getSerializedSize();
|
||||||
|
}
|
||||||
|
if (serializeWithValidityBlob) {
|
||||||
|
size += std::ceil(static_cast<float>(serializables.size()) / 8.0);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
|
const Endianness streamEndianness) override {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
for (auto &serializable : serializables) {
|
||||||
|
result = serializable.get().deSerialize(buffer, size, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool serializeWithValidityBlob = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
dp::structure_id_t sid;
|
||||||
|
std::vector<std::reference_wrapper<SerializableWithValidityIF>> serializables;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace hk
|
165
src/fsfw/housekeeping/DatasetElement.h
Normal file
165
src/fsfw/housekeeping/DatasetElement.h
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "Dataset.h"
|
||||||
|
#include "SerializableWithValidityIF.h"
|
||||||
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class ListVariable : public SerializableWithValidityIF {
|
||||||
|
public:
|
||||||
|
template <typename... Args>
|
||||||
|
explicit ListVariable(Dataset& list, Args... args) : entry(std::forward<Args>(args)...) {
|
||||||
|
list.addSerializable(*this);
|
||||||
|
}
|
||||||
|
explicit ListVariable(Dataset& list) : entry() { list.addSerializable(*this); }
|
||||||
|
|
||||||
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const override {
|
||||||
|
return SerializeAdapter::serialize(&entry, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getSerializedSize() const override {
|
||||||
|
return SerializeAdapter::getSerializedSize(&entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
|
Endianness streamEndianness) override {
|
||||||
|
return SerializeAdapter::deSerialize(&entry, buffer, size, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator T() { return entry; }
|
||||||
|
|
||||||
|
ListVariable& operator=(T newValue) {
|
||||||
|
entry = newValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool isValid() const override { return valid; };
|
||||||
|
|
||||||
|
void setValid(bool _valid) override { this->valid = _valid; }
|
||||||
|
|
||||||
|
T* operator->() { return &entry; }
|
||||||
|
|
||||||
|
T get() const { return entry; }
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
T entry{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using LVar = ListVariable<T>;
|
||||||
|
|
||||||
|
using lvar_u8 = LVar<uint8_t>;
|
||||||
|
using lvar_u16 = LVar<uint16_t>;
|
||||||
|
using lvar_u32 = LVar<uint32_t>;
|
||||||
|
using lvar_u64 = LVar<uint64_t>;
|
||||||
|
using lvar_i8 = LVar<int8_t>;
|
||||||
|
using lvar_i16 = LVar<int16_t>;
|
||||||
|
using lvar_i32 = LVar<int32_t>;
|
||||||
|
using lvar_i64 = LVar<int64_t>;
|
||||||
|
using lvar_f32 = LVar<float>;
|
||||||
|
using lvar_f64 = LVar<double>;
|
||||||
|
|
||||||
|
template <typename T, size_t N>
|
||||||
|
class ListVector : public SerializableWithValidityIF {
|
||||||
|
public:
|
||||||
|
template <typename... Args>
|
||||||
|
explicit ListVector(Dataset& list, Args... args) : entry(std::forward<Args>(args)...) {
|
||||||
|
list.addSerializable(*this);
|
||||||
|
}
|
||||||
|
explicit ListVector(Dataset& list) : entry() { list.addSerializable(*this); }
|
||||||
|
|
||||||
|
const T* get() const { return entry; }
|
||||||
|
T* getMut() { return entry; }
|
||||||
|
|
||||||
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const override {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
result = SerializeAdapter::serialize(entry + i, buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getSerializedSize() const override {
|
||||||
|
return SerializeAdapter::getSerializedSize(entry) * N;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||||
|
Endianness streamEndianness) override {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
result = SerializeAdapter::deSerialize(entry + i, buffer, size, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator T() { return entry; }
|
||||||
|
|
||||||
|
ListVector& operator=(T newValue[N]) {
|
||||||
|
entry = newValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array subscript operator for access
|
||||||
|
T& operator[](size_t index) {
|
||||||
|
// No exceptions, so user takes care of index validation..
|
||||||
|
return entry[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator[](size_t index) const { return entry[index]; }
|
||||||
|
|
||||||
|
// Conversion operator
|
||||||
|
explicit operator T*() { return entry; }
|
||||||
|
explicit operator const T*() const { return entry; }
|
||||||
|
|
||||||
|
// Iterators for range-based for loops and STL compatibility
|
||||||
|
T* begin() { return std::begin(entry); }
|
||||||
|
T* end() { return std::end(entry); }
|
||||||
|
const T* begin() const { return std::begin(entry); }
|
||||||
|
const T* end() const { return std::end(entry); }
|
||||||
|
const T* cbegin() const { return std::begin(entry); }
|
||||||
|
const T* cend() const { return std::end(entry); }
|
||||||
|
|
||||||
|
[[nodiscard]] bool isValid() const override { return valid; };
|
||||||
|
|
||||||
|
void setValid(bool _valid) override { this->valid = _valid; }
|
||||||
|
|
||||||
|
// Additional utility methods
|
||||||
|
[[nodiscard]] constexpr size_t size() const { return N; }
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
T entry[N];
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t N>
|
||||||
|
using LVec = ListVector<T, N>;
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_u8 = LVec<uint8_t, N>;
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_u16 = LVec<uint16_t, N>;
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_u32 = LVec<uint32_t, N>;
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_i8 = LVec<int8_t, N>;
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_i16 = LVec<int16_t, N>;
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_i32 = LVec<int32_t, N>;
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_f32 = LVec<float, N>;
|
||||||
|
template <size_t N>
|
||||||
|
using lvec_f64 = LVec<double, N>;
|
||||||
|
|
||||||
|
} // namespace hk
|
65
src/fsfw/housekeeping/GeneratesPeriodicHkIF.h
Normal file
65
src/fsfw/housekeeping/GeneratesPeriodicHkIF.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/datapool/SharedPool.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "definitions.h"
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This interface is implemented by classes which posses a local data pool (not
|
||||||
|
* the managing class). It defines the relationship between the local data pool owner and the
|
||||||
|
* LocalDataPoolManager.
|
||||||
|
* @details
|
||||||
|
* Any class implementing this interface shall also have a LocalDataPoolManager member class which
|
||||||
|
* contains the actual pool data structure and exposes the public interface for it.
|
||||||
|
*
|
||||||
|
* The local data pool can be accessed using helper classes by using the
|
||||||
|
* LocalPoolVariable, LocalPoolVector or LocalDataSet classes. Every local pool variable can
|
||||||
|
* be uniquely identified by a global pool ID (gp_id_t) and every dataset tied
|
||||||
|
* to a pool manager can be uniqely identified by a global structure ID (sid_t).
|
||||||
|
*
|
||||||
|
* All software objects which want to use the local pool of another object shall also use this
|
||||||
|
* interface, for example to get a handle to the subscription interface. The interface
|
||||||
|
* can be retrieved using the object manager, provided the target object is a SystemObject.
|
||||||
|
* For example, the following line of code can be used to retrieve the interface
|
||||||
|
*
|
||||||
|
* HasLocalDataPoolIF* poolIF = ObjectManager::instance()->
|
||||||
|
* get<HasLocalDataPoolIF>(objects::SOME_OBJECT);
|
||||||
|
* if(poolIF != nullptr) {
|
||||||
|
* doSomething()
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
class GeneratesPeriodicHkIF {
|
||||||
|
friend class PeriodicHelper;
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] virtual object_id_t getObjectId() const = 0;
|
||||||
|
|
||||||
|
/** Command queue for housekeeping messages. */
|
||||||
|
[[nodiscard]] virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
|
||||||
|
virtual datapool::SharedPool* getOptionalSharedPool() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~GeneratesPeriodicHkIF() = default;
|
||||||
|
|
||||||
|
static constexpr uint32_t INVALID_LPID = dp::INVALID_LPID;
|
||||||
|
|
||||||
|
virtual ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf, size_t maxSize) = 0;
|
||||||
|
virtual ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These function can be implemented by pool owner, if they are required
|
||||||
|
* and used by the housekeeping message interface.
|
||||||
|
* */
|
||||||
|
virtual ReturnValue_t addDataSet(dp::sid_t sid) { return returnvalue::FAILED; };
|
||||||
|
virtual ReturnValue_t removeDataSet(dp::sid_t sid) { return returnvalue::FAILED; };
|
||||||
|
virtual ReturnValue_t changeCollectionInterval(dp::sid_t sid, float newIntervalSeconds) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace hk
|
@ -1,12 +1,14 @@
|
|||||||
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
||||||
|
|
||||||
|
#include <fsfw/timemanager/clockDefinitions.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
|
||||||
HousekeepingMessage::~HousekeepingMessage() {}
|
HousekeepingMessage::~HousekeepingMessage() {}
|
||||||
|
|
||||||
void HousekeepingMessage::setHkReportReply(CommandMessage *message, sid_t sid,
|
void HousekeepingMessage::setHkReportReply(CommandMessage *message, dp::structure_id_t sid,
|
||||||
store_address_t storeId) {
|
store_address_t storeId) {
|
||||||
message->setCommand(HK_REPORT);
|
message->setCommand(HK_REPORT);
|
||||||
message->setMessageSize(HK_MESSAGE_SIZE);
|
message->setMessageSize(HK_MESSAGE_SIZE);
|
||||||
@ -14,15 +16,15 @@ void HousekeepingMessage::setHkReportReply(CommandMessage *message, sid_t sid,
|
|||||||
message->setParameter3(storeId.raw);
|
message->setParameter3(storeId.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getHkDataReply(const CommandMessage *message,
|
dp::structure_id_t HousekeepingMessage::getHkDataReply(const CommandMessage *message,
|
||||||
store_address_t *storeIdToSet) {
|
store_address_t *storeIdToSet) {
|
||||||
if (storeIdToSet != nullptr) {
|
if (storeIdToSet != nullptr) {
|
||||||
*storeIdToSet = message->getParameter3();
|
*storeIdToSet = message->getParameter3();
|
||||||
}
|
}
|
||||||
return getSid(message);
|
return getStructureId(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, sid_t sid,
|
void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, dp::structure_id_t sid,
|
||||||
bool enableReporting) {
|
bool enableReporting) {
|
||||||
if (enableReporting) {
|
if (enableReporting) {
|
||||||
message->setCommand(ENABLE_PERIODIC_HK_REPORT_GENERATION);
|
message->setCommand(ENABLE_PERIODIC_HK_REPORT_GENERATION);
|
||||||
@ -33,74 +35,72 @@ void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, sid
|
|||||||
setSid(message, sid);
|
setSid(message, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setStructureReportingCommand(CommandMessage *command, sid_t sid) {
|
void HousekeepingMessage::setStructureReportingCommand(CommandMessage *command,
|
||||||
|
dp::structure_id_t sid) {
|
||||||
command->setCommand(REPORT_HK_REPORT_STRUCTURES);
|
command->setCommand(REPORT_HK_REPORT_STRUCTURES);
|
||||||
|
|
||||||
setSid(command, sid);
|
setSid(command, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setOneShotReportCommand(CommandMessage *command, sid_t sid) {
|
void HousekeepingMessage::setOneShotReportCommand(CommandMessage *command, dp::structure_id_t sid) {
|
||||||
command->setCommand(GENERATE_ONE_PARAMETER_REPORT);
|
command->setCommand(GENERATE_ONE_PARAMETER_REPORT);
|
||||||
|
|
||||||
setSid(command, sid);
|
setSid(command, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setCollectionIntervalModificationCommand(CommandMessage *command,
|
void HousekeepingMessage::setCollectionIntervalModificationCommand(
|
||||||
sid_t sid,
|
CommandMessage *command, dp::structure_id_t sid, dur_millis_t collectionIntervalMs) {
|
||||||
float collectionInterval) {
|
|
||||||
command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL);
|
command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL);
|
||||||
|
|
||||||
/* Raw storage of the float in the message. Do not use setParameter3, does
|
/* Raw storage of the float in the message. Do not use setParameter3, does
|
||||||
implicit conversion to integer type! */
|
implicit conversion to integer type! */
|
||||||
std::memcpy(command->getData() + 2 * sizeof(uint32_t), &collectionInterval,
|
std::memcpy(command->getData() + 2 * sizeof(uint32_t), &collectionIntervalMs,
|
||||||
sizeof(collectionInterval));
|
sizeof(collectionIntervalMs));
|
||||||
|
|
||||||
setSid(command, sid);
|
setSid(command, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getCollectionIntervalModificationCommand(const CommandMessage *command,
|
dp::structure_id_t HousekeepingMessage::getCollectionIntervalModificationCommand(
|
||||||
float *newCollectionInterval) {
|
const CommandMessage *command, dur_millis_t &newCollectionIntervalMs) {
|
||||||
if (newCollectionInterval != nullptr) {
|
std::memcpy(&newCollectionIntervalMs, command->getData() + 2 * sizeof(uint32_t),
|
||||||
std::memcpy(newCollectionInterval, command->getData() + 2 * sizeof(uint32_t),
|
sizeof(newCollectionIntervalMs));
|
||||||
sizeof(*newCollectionInterval));
|
|
||||||
}
|
|
||||||
|
|
||||||
return getSid(command);
|
return getStructureId(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setHkRequestSuccessReply(CommandMessage *reply, sid_t sid) {
|
void HousekeepingMessage::setHkRequestSuccessReply(CommandMessage *reply, dp::structure_id_t sid) {
|
||||||
setSid(reply, sid);
|
setSid(reply, sid);
|
||||||
reply->setCommand(HK_REQUEST_SUCCESS);
|
reply->setCommand(HK_REQUEST_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setHkRequestFailureReply(CommandMessage *reply, sid_t sid,
|
void HousekeepingMessage::setHkRequestFailureReply(CommandMessage *reply, dp::structure_id_t sid,
|
||||||
ReturnValue_t error) {
|
ReturnValue_t error) {
|
||||||
setSid(reply, sid);
|
setSid(reply, sid);
|
||||||
reply->setCommand(HK_REQUEST_FAILURE);
|
reply->setCommand(HK_REQUEST_FAILURE);
|
||||||
reply->setParameter3(error);
|
reply->setParameter3(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getHkRequestFailureReply(const CommandMessage *reply,
|
dp::structure_id_t HousekeepingMessage::getHkRequestFailureReply(const CommandMessage *reply,
|
||||||
ReturnValue_t *error) {
|
ReturnValue_t *error) {
|
||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
*error = reply->getParameter3();
|
*error = reply->getParameter3();
|
||||||
}
|
}
|
||||||
return getSid(reply);
|
return getStructureId(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getSid(const CommandMessage *message) {
|
dp::structure_id_t HousekeepingMessage::getStructureId(const CommandMessage *message) {
|
||||||
sid_t sid;
|
dp::structure_id_t sid;
|
||||||
std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw));
|
std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw));
|
||||||
return sid;
|
return sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
gp_id_t HousekeepingMessage::getGpid(const CommandMessage *message) {
|
dp::g_id_t HousekeepingMessage::getGpid(const CommandMessage *message) {
|
||||||
gp_id_t globalPoolId;
|
dp::g_id_t globalPoolId;
|
||||||
std::memcpy(&globalPoolId.raw, message->getData(), sizeof(globalPoolId.raw));
|
std::memcpy(&globalPoolId.raw, message->getData(), sizeof(globalPoolId.raw));
|
||||||
return globalPoolId;
|
return globalPoolId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply, sid_t sid,
|
void HousekeepingMessage::setHkStuctureReportReply(CommandMessage *reply, dp::structure_id_t sid,
|
||||||
store_address_t storeId) {
|
store_address_t storeId) {
|
||||||
reply->setCommand(HK_DEFINITIONS_REPORT);
|
reply->setCommand(HK_DEFINITIONS_REPORT);
|
||||||
setSid(reply, sid);
|
setSid(reply, sid);
|
||||||
@ -111,13 +111,10 @@ void HousekeepingMessage::clear(CommandMessage *message) {
|
|||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
case (HK_REPORT):
|
case (HK_REPORT):
|
||||||
case (DIAGNOSTICS_REPORT):
|
case (DIAGNOSTICS_REPORT):
|
||||||
case (HK_DEFINITIONS_REPORT):
|
case (HK_DEFINITIONS_REPORT): {
|
||||||
case (UPDATE_SNAPSHOT_SET):
|
|
||||||
case (UPDATE_SNAPSHOT_VARIABLE): {
|
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
getHkDataReply(message, &storeId);
|
getHkDataReply(message, &storeId);
|
||||||
StorageManagerIF *ipcStore =
|
auto *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
|
||||||
if (ipcStore != nullptr) {
|
if (ipcStore != nullptr) {
|
||||||
ipcStore->deleteData(storeId);
|
ipcStore->deleteData(storeId);
|
||||||
}
|
}
|
||||||
@ -126,49 +123,25 @@ void HousekeepingMessage::clear(CommandMessage *message) {
|
|||||||
message->setCommand(CommandMessage::CMD_NONE);
|
message->setCommand(CommandMessage::CMD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setUpdateNotificationSetCommand(CommandMessage *command, sid_t sid) {
|
dp::structure_id_t HousekeepingMessage::getUpdateNotificationSetCommand(
|
||||||
command->setCommand(UPDATE_NOTIFICATION_SET);
|
const CommandMessage *command) {
|
||||||
setSid(command, sid);
|
return getStructureId(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setUpdateNotificationVariableCommand(CommandMessage *command,
|
dp::g_id_t HousekeepingMessage::getUpdateNotificationVariableCommand(
|
||||||
gp_id_t globalPoolId) {
|
const CommandMessage *command) {
|
||||||
command->setCommand(UPDATE_NOTIFICATION_VARIABLE);
|
|
||||||
setGpid(command, globalPoolId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HousekeepingMessage::setUpdateSnapshotSetCommand(CommandMessage *command, sid_t sid,
|
|
||||||
store_address_t storeId) {
|
|
||||||
command->setCommand(UPDATE_SNAPSHOT_SET);
|
|
||||||
setSid(command, sid);
|
|
||||||
command->setParameter3(storeId.raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HousekeepingMessage::setUpdateSnapshotVariableCommand(CommandMessage *command,
|
|
||||||
gp_id_t globalPoolId,
|
|
||||||
store_address_t storeId) {
|
|
||||||
command->setCommand(UPDATE_SNAPSHOT_VARIABLE);
|
|
||||||
setGpid(command, globalPoolId);
|
|
||||||
command->setParameter3(storeId.raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getUpdateNotificationSetCommand(const CommandMessage *command) {
|
|
||||||
return getSid(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
gp_id_t HousekeepingMessage::getUpdateNotificationVariableCommand(const CommandMessage *command) {
|
|
||||||
return getGpid(command);
|
return getGpid(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t HousekeepingMessage::getUpdateSnapshotSetCommand(const CommandMessage *command,
|
dp::structure_id_t HousekeepingMessage::getUpdateSnapshotSetCommand(const CommandMessage *command,
|
||||||
store_address_t *storeId) {
|
store_address_t *storeId) {
|
||||||
if (storeId != nullptr) {
|
if (storeId != nullptr) {
|
||||||
*storeId = command->getParameter3();
|
*storeId = command->getParameter3();
|
||||||
}
|
}
|
||||||
return getSid(command);
|
return getStructureId(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
gp_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(const CommandMessage *command,
|
dp::g_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(const CommandMessage *command,
|
||||||
store_address_t *storeId) {
|
store_address_t *storeId) {
|
||||||
if (storeId != nullptr) {
|
if (storeId != nullptr) {
|
||||||
*storeId = command->getParameter3();
|
*storeId = command->getParameter3();
|
||||||
@ -176,10 +149,10 @@ gp_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(const CommandMessa
|
|||||||
return getGpid(command);
|
return getGpid(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) {
|
void HousekeepingMessage::setSid(CommandMessage *message, dp::structure_id_t sid) {
|
||||||
std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw));
|
std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setGpid(CommandMessage *message, gp_id_t globalPoolId) {
|
void HousekeepingMessage::setGpid(CommandMessage *message, dp::g_id_t globalPoolId) {
|
||||||
std::memcpy(message->getData(), &globalPoolId.raw, sizeof(globalPoolId.raw));
|
std::memcpy(message->getData(), &globalPoolId.raw, sizeof(globalPoolId.raw));
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
||||||
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/localPoolDefinitions.h"
|
#include <fsfw/timemanager/clockDefinitions.h>
|
||||||
|
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
#include "fsfw/ipc/CommandMessage.h"
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
#include "fsfw/ipc/FwMessageTypes.h"
|
#include "fsfw/ipc/FwMessageTypes.h"
|
||||||
#include "fsfw/objectmanager/frameworkObjects.h"
|
#include "fsfw/objectmanager/frameworkObjects.h"
|
||||||
@ -16,7 +18,7 @@
|
|||||||
class HousekeepingMessage {
|
class HousekeepingMessage {
|
||||||
public:
|
public:
|
||||||
static constexpr size_t HK_MESSAGE_SIZE =
|
static constexpr size_t HK_MESSAGE_SIZE =
|
||||||
CommandMessageIF::HEADER_SIZE + sizeof(sid_t) + sizeof(uint32_t);
|
CommandMessageIF::HEADER_SIZE + sizeof(dp::structure_id_t) + sizeof(uint32_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete instance is not used, instead this class operates on
|
* Concrete instance is not used, instead this class operates on
|
||||||
@ -44,33 +46,35 @@ class HousekeepingMessage {
|
|||||||
static constexpr Command_t HK_REQUEST_SUCCESS = MAKE_COMMAND_ID(128);
|
static constexpr Command_t HK_REQUEST_SUCCESS = MAKE_COMMAND_ID(128);
|
||||||
static constexpr Command_t HK_REQUEST_FAILURE = MAKE_COMMAND_ID(129);
|
static constexpr Command_t HK_REQUEST_FAILURE = MAKE_COMMAND_ID(129);
|
||||||
|
|
||||||
static constexpr Command_t UPDATE_NOTIFICATION_SET = MAKE_COMMAND_ID(130);
|
// static constexpr Command_t UPDATE_NOTIFICATION_SET = MAKE_COMMAND_ID(130);
|
||||||
static constexpr Command_t UPDATE_NOTIFICATION_VARIABLE = MAKE_COMMAND_ID(131);
|
// static constexpr Command_t UPDATE_NOTIFICATION_VARIABLE = MAKE_COMMAND_ID(131);
|
||||||
|
|
||||||
static constexpr Command_t UPDATE_SNAPSHOT_SET = MAKE_COMMAND_ID(132);
|
// static constexpr Command_t UPDATE_SNAPSHOT_SET = MAKE_COMMAND_ID(132);
|
||||||
static constexpr Command_t UPDATE_SNAPSHOT_VARIABLE = MAKE_COMMAND_ID(133);
|
// static constexpr Command_t UPDATE_SNAPSHOT_VARIABLE = MAKE_COMMAND_ID(133);
|
||||||
|
|
||||||
// static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(134);
|
// static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(134);
|
||||||
|
|
||||||
static sid_t getSid(const CommandMessage* message);
|
static dp::sid_t getStructureId(const CommandMessage* message);
|
||||||
static gp_id_t getGpid(const CommandMessage* message);
|
static dp::g_id_t getGpid(const CommandMessage* message);
|
||||||
|
|
||||||
/* Housekeeping Interface Messages */
|
/* Housekeeping Interface Messages */
|
||||||
|
|
||||||
static void setToggleReportingCommand(CommandMessage* command, sid_t sid, bool enableReporting);
|
static void setToggleReportingCommand(CommandMessage* command, dp::sid_t sid,
|
||||||
static void setStructureReportingCommand(CommandMessage* command, sid_t sid);
|
bool enableReporting);
|
||||||
static void setOneShotReportCommand(CommandMessage* command, sid_t sid);
|
static void setStructureReportingCommand(CommandMessage* command, dp::sid_t sid);
|
||||||
static void setCollectionIntervalModificationCommand(CommandMessage* command, sid_t sid,
|
static void setOneShotReportCommand(CommandMessage* command, dp::sid_t sid);
|
||||||
float collectionInterval);
|
static void setCollectionIntervalModificationCommand(CommandMessage* command, dp::sid_t sid,
|
||||||
|
dur_millis_t collectionIntervalMs);
|
||||||
|
|
||||||
static void setHkReportReply(CommandMessage* reply, sid_t sid, store_address_t storeId);
|
static void setHkReportReply(CommandMessage* reply, dp::sid_t sid, store_address_t storeId);
|
||||||
|
|
||||||
static void setHkRequestSuccessReply(CommandMessage* reply, sid_t sid);
|
static void setHkRequestSuccessReply(CommandMessage* reply, dp::sid_t sid);
|
||||||
static void setHkRequestFailureReply(CommandMessage* reply, sid_t sid, ReturnValue_t error);
|
static void setHkRequestFailureReply(CommandMessage* reply, dp::sid_t sid, ReturnValue_t error);
|
||||||
|
|
||||||
static void setHkStuctureReportReply(CommandMessage* reply, sid_t sid, store_address_t storeId);
|
static void setHkStuctureReportReply(CommandMessage* reply, dp::sid_t sid,
|
||||||
|
store_address_t storeId);
|
||||||
|
|
||||||
static sid_t getHkRequestFailureReply(const CommandMessage* reply, ReturnValue_t* error);
|
static dp::sid_t getHkRequestFailureReply(const CommandMessage* reply, ReturnValue_t* error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generic getter function for housekeeping data replies
|
* @brief Generic getter function for housekeeping data replies
|
||||||
@ -79,33 +83,35 @@ class HousekeepingMessage {
|
|||||||
* regular HK packets. This getter function should be used for the
|
* regular HK packets. This getter function should be used for the
|
||||||
* command IDs 10, 12, 25 and 26.
|
* command IDs 10, 12, 25 and 26.
|
||||||
*/
|
*/
|
||||||
static sid_t getHkDataReply(const CommandMessage* message, store_address_t* storeIdToSet);
|
static dp::sid_t getHkDataReply(const CommandMessage* message, store_address_t* storeIdToSet);
|
||||||
static sid_t getCollectionIntervalModificationCommand(const CommandMessage* command,
|
static dp::sid_t getCollectionIntervalModificationCommand(const CommandMessage* command,
|
||||||
float* newCollectionInterval);
|
dur_millis_t& newCollectionInterval);
|
||||||
|
|
||||||
/* Update Notification Messages */
|
/* Update Notification Messages */
|
||||||
|
|
||||||
static void setUpdateNotificationSetCommand(CommandMessage* command, sid_t sid);
|
static void setUpdateNotificationSetCommand(CommandMessage* command, dp::sid_t sid);
|
||||||
static void setUpdateNotificationVariableCommand(CommandMessage* command, gp_id_t globalPoolId);
|
static void setUpdateNotificationVariableCommand(CommandMessage* command,
|
||||||
|
dp::g_id_t globalPoolId);
|
||||||
|
|
||||||
static void setUpdateSnapshotSetCommand(CommandMessage* command, sid_t sid,
|
static void setUpdateSnapshotSetCommand(CommandMessage* command, dp::sid_t sid,
|
||||||
store_address_t storeId);
|
store_address_t storeId);
|
||||||
static void setUpdateSnapshotVariableCommand(CommandMessage* command, gp_id_t globalPoolId,
|
static void setUpdateSnapshotVariableCommand(CommandMessage* command, dp::g_id_t globalPoolId,
|
||||||
store_address_t storeId);
|
store_address_t storeId);
|
||||||
|
|
||||||
static sid_t getUpdateNotificationSetCommand(const CommandMessage* command);
|
static dp::sid_t getUpdateNotificationSetCommand(const CommandMessage* command);
|
||||||
static gp_id_t getUpdateNotificationVariableCommand(const CommandMessage* command);
|
static dp::g_id_t getUpdateNotificationVariableCommand(const CommandMessage* command);
|
||||||
|
|
||||||
static sid_t getUpdateSnapshotSetCommand(const CommandMessage* command, store_address_t* storeId);
|
static dp::sid_t getUpdateSnapshotSetCommand(const CommandMessage* command,
|
||||||
static gp_id_t getUpdateSnapshotVariableCommand(const CommandMessage* command,
|
store_address_t* storeId);
|
||||||
|
static dp::g_id_t getUpdateSnapshotVariableCommand(const CommandMessage* command,
|
||||||
store_address_t* storeId);
|
store_address_t* storeId);
|
||||||
|
|
||||||
/** Utility */
|
/** Utility */
|
||||||
static void clear(CommandMessage* message);
|
static void clear(CommandMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void setSid(CommandMessage* message, sid_t sid);
|
static void setSid(CommandMessage* message, dp::sid_t sid);
|
||||||
static void setGpid(CommandMessage* message, gp_id_t globalPoolId);
|
static void setGpid(CommandMessage* message, dp::g_id_t globalPoolId);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_ */
|
#endif /* FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_ */
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
|
#pragma once
|
||||||
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
|
|
||||||
|
|
||||||
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
#include <fsfw/serialize/SerialBufferAdapter.h>
|
||||||
#include "../serialize/SerialLinkedListAdapter.h"
|
|
||||||
#include "../storagemanager/StorageManagerIF.h"
|
#include "fsfw/datapool/SharedSetBase.h"
|
||||||
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class will be used to serialize general housekeeping packets
|
* @brief This class will be used to serialize general housekeeping packets
|
||||||
@ -18,8 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
class HousekeepingPacketDownlink : public SerialLinkedListAdapter<SerializeIF> {
|
class HousekeepingPacketDownlink : public SerialLinkedListAdapter<SerializeIF> {
|
||||||
public:
|
public:
|
||||||
HousekeepingPacketDownlink(sid_t sid, LocalPoolDataSetBase* dataSetPtr)
|
HousekeepingPacketDownlink(dp::sid_t sid, const uint8_t* hkData, size_t hkDataLen)
|
||||||
: sourceId(sid.objectId), setId(sid.ownerSetId), hkData(dataSetPtr) {
|
: sourceId(sid.objectId), setId(sid.ownerSetId), hkData(hkData, hkDataLen) {
|
||||||
setLinks();
|
setLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,5 @@ class HousekeepingPacketDownlink : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
|
|
||||||
SerializeElement<object_id_t> sourceId;
|
SerializeElement<object_id_t> sourceId;
|
||||||
SerializeElement<uint32_t> setId;
|
SerializeElement<uint32_t> setId;
|
||||||
LinkedElement<SerializeIF> hkData;
|
SerializeElement<SerialBufferAdapter<uint32_t>> hkData;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ */
|
|
||||||
|
@ -1,60 +1,28 @@
|
|||||||
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGSETPACKET_H_
|
#pragma once
|
||||||
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGSETPACKET_H_
|
|
||||||
|
|
||||||
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||||
#include "../housekeeping/HousekeepingMessage.h"
|
|
||||||
#include "../serialize/SerialLinkedListAdapter.h"
|
|
||||||
|
|
||||||
class HousekeepingSetPacket : public SerialLinkedListAdapter<SerializeIF> {
|
class HousekeepingSetPacket : public SerialLinkedListAdapter<SerializeIF> {
|
||||||
public:
|
public:
|
||||||
HousekeepingSetPacket(sid_t sid, bool reportingEnabled, bool valid, float collectionInterval,
|
HousekeepingSetPacket(dp::sid_t sid, bool reportingEnabled, dur_millis_t collectionIntervalMs)
|
||||||
LocalPoolDataSetBase* dataSetPtr)
|
|
||||||
: objectId(sid.objectId),
|
: objectId(sid.objectId),
|
||||||
setId(sid.ownerSetId),
|
setId(sid.ownerSetId),
|
||||||
reportingEnabled(reportingEnabled),
|
reportingEnabled(reportingEnabled),
|
||||||
valid(valid),
|
collectionIntervalMs(collectionIntervalMs) {
|
||||||
collectionIntervalSeconds(collectionInterval),
|
|
||||||
dataSet(dataSetPtr) {
|
|
||||||
setLinks();
|
setLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
|
||||||
Endianness streamEndianness) const override {
|
|
||||||
ReturnValue_t result =
|
|
||||||
SerialLinkedListAdapter::serialize(buffer, size, maxSize, streamEndianness);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return dataSet->serializeLocalPoolIds(buffer, size, maxSize, streamEndianness);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getSerializedSize() const override {
|
|
||||||
size_t linkedSize = SerialLinkedListAdapter::getSerializedSize();
|
|
||||||
linkedSize += dataSet->getLocalPoolIdsSerializedSize();
|
|
||||||
return linkedSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
|
||||||
Endianness streamEndianness) override {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setLinks() {
|
void setLinks() {
|
||||||
setStart(&objectId);
|
setStart(&objectId);
|
||||||
objectId.setNext(&setId);
|
objectId.setNext(&setId);
|
||||||
setId.setNext(&reportingEnabled);
|
setId.setNext(&reportingEnabled);
|
||||||
reportingEnabled.setNext(&valid);
|
reportingEnabled.setNext(&collectionIntervalMs);
|
||||||
valid.setNext(&collectionIntervalSeconds);
|
collectionIntervalMs.setEnd();
|
||||||
collectionIntervalSeconds.setEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializeElement<object_id_t> objectId;
|
SerializeElement<object_id_t> objectId;
|
||||||
SerializeElement<uint32_t> setId;
|
SerializeElement<uint32_t> setId;
|
||||||
SerializeElement<bool> reportingEnabled;
|
SerializeElement<bool> reportingEnabled;
|
||||||
SerializeElement<bool> valid;
|
SerializeElement<uint32_t> collectionIntervalMs;
|
||||||
SerializeElement<float> collectionIntervalSeconds;
|
|
||||||
LocalPoolDataSetBase* dataSet;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_HOUSEKEEPING_HOUSEKEEPINGSETPACKET_H_ */
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGSNAPSHOT_H_
|
#pragma once
|
||||||
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGSNAPSHOT_H_
|
|
||||||
|
|
||||||
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
#include "fsfw/datapool/LocalPoolObjectBase.h"
|
||||||
#include "../datapoollocal/LocalPoolObjectBase.h"
|
#include "fsfw/datapool/SharedSetBase.h"
|
||||||
#include "../serialize/SerialBufferAdapter.h"
|
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||||
#include "../serialize/SerialLinkedListAdapter.h"
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||||
#include "../timemanager/CCSDSTime.h"
|
#include "fsfw/timemanager/CCSDSTime.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This helper class will be used to serialize and deserialize update housekeeping packets
|
* @brief This helper class will be used to serialize and deserialize update housekeeping packets
|
||||||
@ -20,7 +19,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
* @param dataSetPtr Pointer to the dataset instance to serialize or deserialize the
|
* @param dataSetPtr Pointer to the dataset instance to serialize or deserialize the
|
||||||
* data into
|
* data into
|
||||||
*/
|
*/
|
||||||
HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, LocalPoolDataSetBase* dataSetPtr)
|
HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, SerializeIF* dataSetPtr)
|
||||||
: timeStamp(reinterpret_cast<uint8_t*>(cdsShort)),
|
: timeStamp(reinterpret_cast<uint8_t*>(cdsShort)),
|
||||||
timeStampSize(sizeof(CCSDSTime::CDS_short)),
|
timeStampSize(sizeof(CCSDSTime::CDS_short)),
|
||||||
updateData(dataSetPtr) {};
|
updateData(dataSetPtr) {};
|
||||||
@ -31,27 +30,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
* @param timeStampSize Size of the timestamp
|
* @param timeStampSize Size of the timestamp
|
||||||
* @param dataSetPtr Pointer to the dataset instance to deserialize the data into
|
* @param dataSetPtr Pointer to the dataset instance to deserialize the data into
|
||||||
*/
|
*/
|
||||||
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, LocalPoolDataSetBase* dataSetPtr)
|
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, SerializeIF* dataSetPtr)
|
||||||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr) {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update packet constructor for pool variables.
|
|
||||||
* @param timeStamp
|
|
||||||
* @param timeStampSize
|
|
||||||
* @param dataSetPtr
|
|
||||||
*/
|
|
||||||
HousekeepingSnapshot(CCSDSTime::CDS_short* cdsShort, LocalPoolObjectBase* dataSetPtr)
|
|
||||||
: timeStamp(reinterpret_cast<uint8_t*>(cdsShort)),
|
|
||||||
timeStampSize(sizeof(CCSDSTime::CDS_short)),
|
|
||||||
updateData(dataSetPtr) {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update packet constructor for pool variables.
|
|
||||||
* @param timeStamp
|
|
||||||
* @param timeStampSize
|
|
||||||
* @param dataSetPtr
|
|
||||||
*/
|
|
||||||
HousekeepingSnapshot(uint8_t* timeStamp, size_t timeStampSize, LocalPoolObjectBase* dataSetPtr)
|
|
||||||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr) {};
|
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr) {};
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||||
@ -107,5 +86,3 @@ class HousekeepingSnapshot : public SerializeIF {
|
|||||||
|
|
||||||
SerializeIF* updateData = nullptr;
|
SerializeIF* updateData = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_HOUSEKEEPING_HOUSEKEEPINGSNAPSHOT_H_ */
|
|
||||||
|
410
src/fsfw/housekeeping/PeriodicHkHelper.cpp
Normal file
410
src/fsfw/housekeeping/PeriodicHkHelper.cpp
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
#include "PeriodicHkHelper.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
||||||
|
#include "fsfw/housekeeping/HousekeepingSetPacket.h"
|
||||||
|
#include "fsfw/housekeeping/HousekeepingSnapshot.h"
|
||||||
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/timemanager/CCSDSTime.h"
|
||||||
|
|
||||||
|
using namespace hk;
|
||||||
|
|
||||||
|
PeriodicHelper::PeriodicHelper(GeneratesPeriodicHkIF* owner, MessageQueueIF* queueToUse,
|
||||||
|
MessageQueueId_t hkDestQueue)
|
||||||
|
: hkDestinationId(hkDestQueue) {
|
||||||
|
if (owner == nullptr) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "PeriodicHkHelper", returnvalue::FAILED,
|
||||||
|
"Invalid supplied owner");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->owner = owner;
|
||||||
|
hkQueue = queueToUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::initialize(MessageQueueIF* queueToUse) {
|
||||||
|
if (queueToUse != nullptr) {
|
||||||
|
hkQueue = queueToUse;
|
||||||
|
}
|
||||||
|
if (hkQueue == nullptr) {
|
||||||
|
// Error, all destinations invalid
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
|
if (ipcStore == nullptr) {
|
||||||
|
// Error, all destinations invalid
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", returnvalue::FAILED,
|
||||||
|
"Could not set IPC store.");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
||||||
|
if (const auto* hkPacketReceiver =
|
||||||
|
ObjectManager::instance()->get<AcceptsHkPacketsIF>(objects::PUS_SERVICE_3_HOUSEKEEPING);
|
||||||
|
hkPacketReceiver != nullptr) {
|
||||||
|
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||||
|
} else {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID);
|
||||||
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
owner->specifyHkDatasets(setList);
|
||||||
|
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::performHkOperation() {
|
||||||
|
timeval now{};
|
||||||
|
Clock::getClockMonotonic(&now);
|
||||||
|
for (auto& setSpec : setList) {
|
||||||
|
switch (setSpec.reportingType) {
|
||||||
|
case (ReportingType::PERIODIC): {
|
||||||
|
if (setSpec.dataType == DataType::LOCAL_POOL_VARIABLE) {
|
||||||
|
// Periodic packets shall only be generated from datasets
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (not setSpec.periodicCollectionEnabled) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
performPeriodicHkGeneration(setSpec, now);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// This should never happen.
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::handleHousekeepingMessage(CommandMessage* message) {
|
||||||
|
Command_t command = message->getCommand();
|
||||||
|
dp::sid_t sid = HousekeepingMessage::getStructureId(message);
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
switch (command) {
|
||||||
|
// Houskeeping interface handling.
|
||||||
|
case (HousekeepingMessage::ENABLE_PERIODIC_HK_REPORT_GENERATION): {
|
||||||
|
result = togglePeriodicGeneration(sid, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case (HousekeepingMessage::DISABLE_PERIODIC_HK_REPORT_GENERATION): {
|
||||||
|
result = togglePeriodicGeneration(sid, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case (HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): {
|
||||||
|
result = generateSetStructurePacket(sid);
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (HousekeepingMessage::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL): {
|
||||||
|
dur_millis_t newCollIntvl = 0;
|
||||||
|
HousekeepingMessage::getCollectionIntervalModificationCommand(message, newCollIntvl);
|
||||||
|
result = setCollectionInterval(sid, newCollIntvl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): {
|
||||||
|
return generateHousekeepingPacket(HousekeepingMessage::getStructureId(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CommandMessageIF::UNKNOWN_COMMAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandMessage reply;
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
if (result == INVALID_HK_REQUEST) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
||||||
|
INVALID_HK_REQUEST);
|
||||||
|
}
|
||||||
|
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
||||||
|
} else {
|
||||||
|
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
||||||
|
}
|
||||||
|
hkQueue->sendMessage(hkDestinationId, &reply);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GeneratesPeriodicHkIF* PeriodicHelper::getOwner() const { return owner; }
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::generateHousekeepingPacket(const dp::sid_t sid,
|
||||||
|
MessageQueueId_t destination) {
|
||||||
|
store_address_t storeId;
|
||||||
|
const auto optSetSpec = getMutSetSpecification(sid);
|
||||||
|
if (!optSetSpec.has_value()) {
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
const auto& setSpec = optSetSpec.value().get();
|
||||||
|
uint8_t* dataPtr = nullptr;
|
||||||
|
const size_t maxSize = setSpec.serializedSize + dp::structure_id_t::SIZE;
|
||||||
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &dataPtr);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
size_t serSize = 0;
|
||||||
|
result = SerializeAdapter::serialize(&sid.objectId, &dataPtr, &serSize, maxSize,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = SerializeAdapter::serialize(&sid.ownerSetId, &dataPtr, &serSize, maxSize,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = owner->serializeHkDataset(sid, dataPtr, maxSize - 8);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we set a HK message and send it the HK packet destination.
|
||||||
|
CommandMessage hkMessage;
|
||||||
|
HousekeepingMessage::setHkReportReply(&hkMessage, sid, storeId);
|
||||||
|
|
||||||
|
if (hkQueue == nullptr) {
|
||||||
|
// 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 (hkDestinationId == MessageQueueIF::NO_QUEUE) {
|
||||||
|
// Error, all destinations invalid
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
||||||
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
|
}
|
||||||
|
destination = hkDestinationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hkQueue->sendMessage(destination, &hkMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeriodicHelper::performPeriodicHkGeneration(SetSpecification& setSpec, timeval& now) {
|
||||||
|
const dp::sid_t sid = setSpec.dataId.sid;
|
||||||
|
|
||||||
|
auto [tv_sec, tv_usec] = now - setSpec.lastGenerated;
|
||||||
|
if (const dur_millis_t diffMillis = tv_sec * 1000 + tv_usec / 1000;
|
||||||
|
diffMillis >= setSpec.collectionFrequency) {
|
||||||
|
const ReturnValue_t result = generateHousekeepingPacket(sid);
|
||||||
|
setSpec.lastGenerated = now;
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// Configuration error
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "hk::PeriodicHelper::performPeriodicHkOperation: HK generation failed."
|
||||||
|
<< std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("hk::PeriodicHelper::performPeriodicHkOperation: HK generation failed.\n");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::togglePeriodicGeneration(const dp::sid_t sid, const bool enable) {
|
||||||
|
const auto optSetSpec = getMutSetSpecification(sid);
|
||||||
|
if (!optSetSpec.has_value()) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
|
||||||
|
DATASET_NOT_FOUND);
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
optSetSpec.value().get().periodicCollectionEnabled = enable;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<SetSpecification>> PeriodicHelper::getMutSetSpecification(
|
||||||
|
dp::sid_t structureId) {
|
||||||
|
for (auto& receiver : setList) {
|
||||||
|
if (receiver.dataId.sid == structureId) {
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<const SetSpecification>> PeriodicHelper::getSetSpecification(
|
||||||
|
dp::sid_t structureId) const {
|
||||||
|
for (const auto& receiver : setList) {
|
||||||
|
if (receiver.dataId.sid == structureId) {
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::setCollectionInterval(dp::sid_t sid,
|
||||||
|
dur_millis_t newCollectionIntervalMs) {
|
||||||
|
bool wasUpdated = false;
|
||||||
|
for (auto& receiver : setList) {
|
||||||
|
if (receiver.dataId.sid == sid) {
|
||||||
|
receiver.collectionFrequency = newCollectionIntervalMs;
|
||||||
|
wasUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!wasUpdated) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "setCollectionInterval", DATASET_NOT_FOUND);
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::generateSetStructurePacket(dp::structure_id_t sid) {
|
||||||
|
// Get and check dataset first.
|
||||||
|
auto optSetSpec = getMutSetSpecification(sid);
|
||||||
|
if (!optSetSpec.has_value()) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration",
|
||||||
|
DATASET_NOT_FOUND);
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
auto& setSpec = optSetSpec.value().get();
|
||||||
|
|
||||||
|
uint8_t* storePtr = nullptr;
|
||||||
|
store_address_t storeId;
|
||||||
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId, setSpec.serializedSize, &storePtr);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "generateSetStructurePacket",
|
||||||
|
returnvalue::FAILED, "Could not get free element from IPC store.");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
dur_millis_t collectionInterval = 0;
|
||||||
|
|
||||||
|
HousekeepingSetPacket setPacket(sid, setSpec.periodicCollectionEnabled, collectionInterval);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
size_t expectedSize = setPacket.getSerializedSize();
|
||||||
|
|
||||||
|
// Serialize set packet into store.
|
||||||
|
size_t size = 0;
|
||||||
|
result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::NETWORK);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
ipcStore->deleteData(storeId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (expectedSize != size) {
|
||||||
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket",
|
||||||
|
returnvalue::FAILED, "Expected size is not equal to serialized size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send structure reporting reply.
|
||||||
|
CommandMessage reply;
|
||||||
|
HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId);
|
||||||
|
|
||||||
|
result = hkQueue->reply(&reply);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
ipcStore->deleteData(storeId);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::enablePeriodicPacket(const dp::structure_id_t structureId,
|
||||||
|
const std::optional<dur_millis_t> frequencyMs) {
|
||||||
|
// Get and check dataset first.
|
||||||
|
const auto optSetSpec = getMutSetSpecification(structureId);
|
||||||
|
if (!optSetSpec.has_value()) {
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
auto& setSpec = optSetSpec.value().get();
|
||||||
|
setSpec.periodicCollectionEnabled = true;
|
||||||
|
if (frequencyMs) {
|
||||||
|
setSpec.collectionFrequency = frequencyMs.value();
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::enablePeriodicPacket(const dp::structure_id_t structureId) {
|
||||||
|
return enablePeriodicPacket(structureId, std::nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::disablePeriodicPacket(const dp::structure_id_t structureId) {
|
||||||
|
// Get and check dataset first.
|
||||||
|
const auto optSetSpec = getMutSetSpecification(structureId);
|
||||||
|
if (!optSetSpec.has_value()) {
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
auto& setSpec = optSetSpec.value().get();
|
||||||
|
setSpec.periodicCollectionEnabled = false;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PeriodicHelper::collectionEnabled(dp::sid_t structureId,
|
||||||
|
bool& collectionEnabled) const {
|
||||||
|
// Get and check dataset first.
|
||||||
|
const auto optSetSpec = getSetSpecification(structureId);
|
||||||
|
if (!optSetSpec.has_value()) {
|
||||||
|
return DATASET_NOT_FOUND;
|
||||||
|
}
|
||||||
|
auto& setSpec = optSetSpec.value().get();
|
||||||
|
collectionEnabled = setSpec.periodicCollectionEnabled;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
object_id_t PeriodicHelper::getCreatorObjectId() const { return owner->getObjectId(); }
|
||||||
|
|
||||||
|
void PeriodicHelper::printWarningOrError(sif::OutputTypes outputType, const char* functionName,
|
||||||
|
ReturnValue_t error, const char* errorPrint) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
if (errorPrint == nullptr) {
|
||||||
|
if (error == DATASET_NOT_FOUND) {
|
||||||
|
errorPrint = "Dataset not found";
|
||||||
|
} else if (error == INVALID_HK_REQUEST) {
|
||||||
|
errorPrint = "Invalid HK request";
|
||||||
|
} else if (error == returnvalue::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 == dp::POOL_ENTRY_TYPE_CONFLICT) {
|
||||||
|
errorPrint = "Pool entry type conflict";
|
||||||
|
} else if (error == dp::POOL_ENTRY_NOT_FOUND) {
|
||||||
|
errorPrint = "Pool entry not found";
|
||||||
|
} else {
|
||||||
|
errorPrint = "Unknown error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object_id_t objectId = 0xffffffff;
|
||||||
|
if (owner != nullptr) {
|
||||||
|
objectId = owner->getObjectId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8)
|
||||||
|
<< std::setfill('0') << std::hex << objectId << " | " << errorPrint << std::dec
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, objectId,
|
||||||
|
errorPrint);
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
} else if (outputType == sif::OutputTypes::OUT_ERROR) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" << std::setw(8)
|
||||||
|
<< std::setfill('0') << std::hex << objectId << " | " << errorPrint << std::dec
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n", functionName, objectId,
|
||||||
|
errorPrint);
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
}
|
||||||
|
#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeriodicHelper::setHkDestinationId(const MessageQueueId_t hkDestId) {
|
||||||
|
hkDestinationId = hkDestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeriodicHelper::addSetSpecification(const SetSpecification& setSpec) {
|
||||||
|
setList.push_back(setSpec);
|
||||||
|
}
|
193
src/fsfw/housekeeping/PeriodicHkHelper.h
Normal file
193
src/fsfw/housekeeping/PeriodicHkHelper.h
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "GeneratesPeriodicHkIF.h"
|
||||||
|
#include "PeriodicHkHelperIF.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
#include "fsfw/datapool/DataSetIF.h"
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
||||||
|
#include "fsfw/housekeeping/HousekeepingPacketDownlink.h"
|
||||||
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class is the managing instance for the local data pool.
|
||||||
|
* @details
|
||||||
|
* The actual data pool structure is a member of this class. Any class which
|
||||||
|
* has a local data pool shall have this manager class as a member and implement
|
||||||
|
* the HasLocalDataPoolIF.
|
||||||
|
*
|
||||||
|
* The manager offers some adaption points and functions which can be used
|
||||||
|
* by the owning class to simplify data handling significantly.
|
||||||
|
*
|
||||||
|
* Please ensure that both initialize and initializeAfterTaskCreation are
|
||||||
|
* called at some point by the owning class in the respective functions of the
|
||||||
|
* same name!
|
||||||
|
*
|
||||||
|
* Users of the data pool use the helper classes LocalDataSet,
|
||||||
|
* LocalPoolVariable and LocalPoolVector to access pool entries in
|
||||||
|
* a thread-safe and efficient way.
|
||||||
|
*
|
||||||
|
* The local data pools employ a blackboard logic: Only the most recent
|
||||||
|
* value is stored. The helper classes offer a read() and commit() interface
|
||||||
|
* through the PoolVariableIF which is used to read and update values.
|
||||||
|
* Each pool entry has a valid state too.
|
||||||
|
* @author R. Mueller
|
||||||
|
*/
|
||||||
|
class PeriodicHelper : public PeriodicHelperIF {
|
||||||
|
//! 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 SharedPoolAttorney;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This constructor is used by a class which wants to implement
|
||||||
|
* a personal local data pool. The queueToUse can be supplied if it
|
||||||
|
* is already known.
|
||||||
|
*
|
||||||
|
* initialize() has to be called in any case before using the object!
|
||||||
|
* @param owner
|
||||||
|
* @param queueToUse
|
||||||
|
* validity state is generated when serializing or deserializing packets.
|
||||||
|
*/
|
||||||
|
PeriodicHelper(GeneratesPeriodicHkIF* owner, MessageQueueIF* queueToUse,
|
||||||
|
MessageQueueId_t hkDestQueue = MessageQueueIF::NO_QUEUE);
|
||||||
|
|
||||||
|
void setHkDestinationId(MessageQueueId_t hkDestId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the queue to use. Make sure to call this in the #initialize
|
||||||
|
* function of the owner.
|
||||||
|
* @param queueToUse
|
||||||
|
*/
|
||||||
|
ReturnValue_t initialize(MessageQueueIF* queueToUse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This should be called in the periodic handler of the owner.
|
||||||
|
* @details
|
||||||
|
* This in generally called in the #performOperation function of the owner.
|
||||||
|
* It performs all the periodic functionalities of the data pool manager,
|
||||||
|
* for example generating periodic HK packets.
|
||||||
|
* Marked virtual as an adaption point for custom data pool managers.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t performHkOperation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The manager is also able to handle housekeeping messages.
|
||||||
|
* @details
|
||||||
|
* This most commonly is used to handle messages for the housekeeping
|
||||||
|
* interface, but the manager is also able to handle update notifications
|
||||||
|
* and calls a special function which can be overriden by a child class
|
||||||
|
* to handle data set or pool variable updates. This is relevant
|
||||||
|
* for classes like controllers which have their own local datapool
|
||||||
|
* but pull their data from other local datapools.
|
||||||
|
* @param message
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a housekeeping packet with a given SID.
|
||||||
|
* @param sid
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReturnValue_t generateHousekeepingPacket(dp::sid_t sid,
|
||||||
|
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
||||||
|
|
||||||
|
[[nodiscard]] GeneratesPeriodicHkIF* getOwner() const;
|
||||||
|
|
||||||
|
void addSetSpecification(const SetSpecification& setSpec);
|
||||||
|
ReturnValue_t printPoolEntry(dp::id_t localPoolId);
|
||||||
|
|
||||||
|
/* Copying forbidden */
|
||||||
|
PeriodicHelper(const PeriodicHkGenerationHelper&) = delete;
|
||||||
|
PeriodicHelper operator=(const PeriodicHkGenerationHelper&) = 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();
|
||||||
|
|
||||||
|
[[nodiscard]] object_id_t getCreatorObjectId() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the pointer to the mutex. Can be used to lock the data pool
|
||||||
|
* externally. Use with care and don't forget to unlock locked mutexes!
|
||||||
|
* For now, only friend classes can accss this function.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
MutexIF* getMutexHandle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the periodic generation frequency without enabling the periodic generation of packets.
|
||||||
|
*/
|
||||||
|
ReturnValue_t enablePeriodicPacket(dp::sid_t structureId,
|
||||||
|
std::optional<dur_millis_t> frequencyMs) override;
|
||||||
|
ReturnValue_t enablePeriodicPacket(dp::sid_t structureId) override;
|
||||||
|
ReturnValue_t disablePeriodicPacket(dp::sid_t structureId) override;
|
||||||
|
ReturnValue_t collectionEnabled(dp::sid_t structureId, bool& collectionEnabled) const override;
|
||||||
|
|
||||||
|
ReturnValue_t setCollectionInterval(dp::sid_t structureId,
|
||||||
|
dur_millis_t newCollectionIntervalMs) override;
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<SetSpecification>> getMutSetSpecification(
|
||||||
|
dp::sid_t structureId);
|
||||||
|
|
||||||
|
std::optional<std::reference_wrapper<const SetSpecification>> getSetSpecification(
|
||||||
|
dp::sid_t structureId) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::optional<dur_millis_t> getCollectionFrequency(dp::sid_t structureId);
|
||||||
|
|
||||||
|
/** The class which actually owns the manager (and its datapool). */
|
||||||
|
hk::GeneratesPeriodicHkIF* owner = nullptr;
|
||||||
|
|
||||||
|
/** Default receiver for periodic HK packets */
|
||||||
|
MessageQueueId_t hkDestinationId = MessageQueueIF::NO_QUEUE;
|
||||||
|
|
||||||
|
/** This vector will contain the list of HK receivers. */
|
||||||
|
using SetList = std::vector<SetSpecification>;
|
||||||
|
|
||||||
|
SetList setList{};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Queue used for communication, for example commands.
|
||||||
|
* Is also used to send messages. Can be set either in the constructor
|
||||||
|
* or in the initialize() function.
|
||||||
|
*/
|
||||||
|
MessageQueueIF* hkQueue = nullptr;
|
||||||
|
|
||||||
|
/** Global IPC store is used to store all packets. */
|
||||||
|
StorageManagerIF* ipcStore = nullptr;
|
||||||
|
|
||||||
|
ReturnValue_t serializeHkPacketIntoStore(HousekeepingPacketDownlink& hkPacket,
|
||||||
|
store_address_t& storeId, size_t* serializedSize);
|
||||||
|
|
||||||
|
void performPeriodicHkGeneration(SetSpecification& hkReceiver, timeval& now);
|
||||||
|
ReturnValue_t togglePeriodicGeneration(dp::sid_t sid, bool enable);
|
||||||
|
ReturnValue_t generateSetStructurePacket(dp::sid_t sid);
|
||||||
|
|
||||||
|
// void handleChangeResetLogic(periodicHk::DataType type, periodicHk::DataId dataId,
|
||||||
|
// MarkChangedIF* toReset);
|
||||||
|
// void resetHkUpdateResetHelper();
|
||||||
|
|
||||||
|
// ReturnValue_t addUpdateToStore(HousekeepingSnapshot& updatePacket, store_address_t& storeId);
|
||||||
|
|
||||||
|
void printWarningOrError(sif::OutputTypes outputType, const char* functionName,
|
||||||
|
ReturnValue_t errorCode = returnvalue::FAILED,
|
||||||
|
const char* errorPrint = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace hk
|
32
src/fsfw/housekeeping/PeriodicHkHelperIF.h
Normal file
32
src/fsfw/housekeeping/PeriodicHkHelperIF.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/timemanager/clockDefinitions.h>
|
||||||
|
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
#include "fsfw/retval.h"
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
class PeriodicHelperIF {
|
||||||
|
public:
|
||||||
|
virtual ~PeriodicHelperIF() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the periodic generation frequency without enabling the periodic generation of packets.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t setCollectionInterval(dp::sid_t structureId,
|
||||||
|
dur_millis_t newCollectionIntervalMs) = 0;
|
||||||
|
virtual ReturnValue_t enablePeriodicPacket(dp::sid_t structureId,
|
||||||
|
std::optional<dur_millis_t> frequencyMs) = 0;
|
||||||
|
/**
|
||||||
|
* @brief Enables periodic packet generation for a given structure, and
|
||||||
|
* keeps the previous configured collection interval.
|
||||||
|
*
|
||||||
|
* @param structureId
|
||||||
|
* @return ReturnValue_t
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t enablePeriodicPacket(dp::sid_t structureId) = 0;
|
||||||
|
virtual ReturnValue_t disablePeriodicPacket(dp::sid_t structureId) = 0;
|
||||||
|
virtual ReturnValue_t collectionEnabled(dp::sid_t structureId, bool& collectionEnabled) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace hk
|
@ -1,39 +0,0 @@
|
|||||||
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "fsfw/datapoollocal/LocalPoolDataSetBase.h"
|
|
||||||
#include "fsfw/serviceinterface.h"
|
|
||||||
|
|
||||||
PeriodicHousekeepingHelper::PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner)
|
|
||||||
: owner(owner) {}
|
|
||||||
|
|
||||||
void PeriodicHousekeepingHelper::initialize(float collectionInterval,
|
|
||||||
dur_millis_t minimumPeriodicInterval) {
|
|
||||||
this->minimumPeriodicInterval = minimumPeriodicInterval;
|
|
||||||
changeCollectionInterval(collectionInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() const {
|
|
||||||
return collectionInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PeriodicHousekeepingHelper::checkOpNecessary() {
|
|
||||||
if (hkGenerationCd.hasTimedOut()) {
|
|
||||||
hkGenerationCd.resetTimer();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PeriodicHousekeepingHelper::changeCollectionInterval(float newIntervalSeconds) {
|
|
||||||
uint32_t intervalMs = newIntervalSeconds * 1000;
|
|
||||||
if (newIntervalSeconds <= 0) {
|
|
||||||
intervalMs = minimumPeriodicInterval;
|
|
||||||
newIntervalSeconds = static_cast<float>(minimumPeriodicInterval) / 1000.0;
|
|
||||||
}
|
|
||||||
collectionInterval = newIntervalSeconds;
|
|
||||||
hkGenerationCd.setTimeout(intervalMs);
|
|
||||||
// We want an immediate HK packet at the start, so time out the generation CD immediately.
|
|
||||||
hkGenerationCd.timeOut();
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_
|
|
||||||
#define FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "fsfw/timemanager/Clock.h"
|
|
||||||
#include "fsfw/timemanager/Countdown.h"
|
|
||||||
|
|
||||||
class LocalPoolDataSetBase;
|
|
||||||
|
|
||||||
class PeriodicHousekeepingHelper {
|
|
||||||
public:
|
|
||||||
PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner);
|
|
||||||
|
|
||||||
void initialize(float collectionInterval, dur_millis_t minimumPeriodicInterval);
|
|
||||||
|
|
||||||
void changeCollectionInterval(float newInterval);
|
|
||||||
float getCollectionIntervalInSeconds() const;
|
|
||||||
bool checkOpNecessary();
|
|
||||||
|
|
||||||
private:
|
|
||||||
LocalPoolDataSetBase* owner = nullptr;
|
|
||||||
Countdown hkGenerationCd;
|
|
||||||
float collectionInterval = 0.0;
|
|
||||||
|
|
||||||
dur_millis_t minimumPeriodicInterval = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ */
|
|
10
src/fsfw/housekeeping/SerializableWithValidityIF.h
Normal file
10
src/fsfw/housekeeping/SerializableWithValidityIF.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
|
|
||||||
|
class SerializableWithValidityIF : public SerializeIF {
|
||||||
|
public:
|
||||||
|
[[nodiscard]] virtual bool isValid() const = 0;
|
||||||
|
|
||||||
|
virtual void setValid(bool valid) = 0;
|
||||||
|
};
|
86
src/fsfw/housekeeping/definitions.h
Normal file
86
src/fsfw/housekeeping/definitions.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/ipc/MessageQueueIF.h>
|
||||||
|
#include <fsfw/ipc/messageQueueDefinitions.h>
|
||||||
|
#include <fsfw/timemanager/clockDefinitions.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
|
||||||
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::PERIODIC_HK_IF;
|
||||||
|
|
||||||
|
static constexpr ReturnValue_t DATASET_NOT_FOUND = MAKE_RETURN_CODE(0);
|
||||||
|
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_INVALID = MAKE_RETURN_CODE(1);
|
||||||
|
static constexpr ReturnValue_t INVALID_HK_REQUEST = MAKE_RETURN_CODE(2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Different types of housekeeping reporting are possible.
|
||||||
|
* 1. PERIODIC:
|
||||||
|
* HK packets are generated in fixed intervals and sent to
|
||||||
|
* destination. Fromat will be raw.
|
||||||
|
* 2. UPDATE_NOTIFICATION:
|
||||||
|
* Notification will be sent out if HK data has changed.
|
||||||
|
* 3. UPDATE_SNAPSHOT:
|
||||||
|
* HK packets are only generated if explicitely requested.
|
||||||
|
* Propably not necessary, just use multiple local data sets or
|
||||||
|
* shared datasets.
|
||||||
|
*/
|
||||||
|
enum class ReportingType : uint8_t {
|
||||||
|
//! Periodic generation of HK packets.
|
||||||
|
PERIODIC,
|
||||||
|
};
|
||||||
|
|
||||||
|
union DataId {
|
||||||
|
DataId() : sid() {}
|
||||||
|
static DataId forSetId(dp::structure_id_t sid) {
|
||||||
|
DataId d;
|
||||||
|
d.sid = sid;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
dp::sid_t sid;
|
||||||
|
dp::id_t localPoolId;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Different data types are possible in the HK receiver map. For example, updates can be
|
||||||
|
requested for full datasets or for single pool variables. Periodic reporting is only possible
|
||||||
|
for data sets. */
|
||||||
|
enum class DataType : uint8_t { LOCAL_POOL_VARIABLE, DATA_SET };
|
||||||
|
|
||||||
|
struct SetSpecification {
|
||||||
|
friend class PeriodicHelper;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SetSpecification(const dp::structure_id_t structureId, const size_t serializedSize,
|
||||||
|
const dur_millis_t collectionFrequency,
|
||||||
|
const MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE)
|
||||||
|
: dataId(DataId::forSetId(structureId)),
|
||||||
|
destinationQueue(destinationQueue),
|
||||||
|
serializedSize(serializedSize),
|
||||||
|
collectionFrequency(collectionFrequency) {};
|
||||||
|
// Object ID of receiver
|
||||||
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
|
|
||||||
|
DataType dataType = DataType::DATA_SET;
|
||||||
|
DataId dataId;
|
||||||
|
|
||||||
|
ReportingType reportingType = ReportingType::PERIODIC;
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getSerializedSize() const { return serializedSize; }
|
||||||
|
|
||||||
|
[[nodiscard]] dur_millis_t getCollectionFrequency() const { return collectionFrequency; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool collectionEnabled() const { return periodicCollectionEnabled; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
||||||
|
bool periodicCollectionEnabled = false;
|
||||||
|
size_t serializedSize = 0;
|
||||||
|
dur_millis_t collectionFrequency = 0;
|
||||||
|
timeval lastGenerated{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace hk
|
@ -1,22 +1,25 @@
|
|||||||
#ifndef FSFW_INTERNALERROR_INTERNALERRORDATASET_H_
|
#ifndef FSFW_INTERNALERROR_INTERNALERRORDATASET_H_
|
||||||
#define FSFW_INTERNALERROR_INTERNALERRORDATASET_H_
|
#define FSFW_INTERNALERROR_INTERNALERRORDATASET_H_
|
||||||
|
|
||||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
#include <fsfw/datapool/PoolVariable.h>
|
||||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
#include <fsfw/datapool/StaticSharedSet.h>
|
||||||
|
|
||||||
enum errorPoolIds { TM_HITS, QUEUE_HITS, STORE_HITS };
|
enum errorPoolIds { TM_HITS = 0, QUEUE_HITS = 1, STORE_HITS = 2, VALID = 3 };
|
||||||
|
|
||||||
class InternalErrorDataset : public StaticLocalDataSet<3 * sizeof(uint32_t)> {
|
class InternalErrorDataset : public dp::StaticSharedSet<4> {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t ERROR_SET_ID = 0;
|
static constexpr uint8_t ERROR_SET_ID = 0;
|
||||||
|
|
||||||
InternalErrorDataset(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, ERROR_SET_ID) {}
|
InternalErrorDataset(dp::SharedPool& sharedPool)
|
||||||
|
: StaticSharedSet(sharedPool, ERROR_SET_ID, false) {}
|
||||||
|
|
||||||
InternalErrorDataset(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, ERROR_SET_ID)) {}
|
InternalErrorDataset(object_id_t objectId)
|
||||||
|
: StaticSharedSet(dp::structure_id_t(objectId, ERROR_SET_ID), false) {}
|
||||||
|
|
||||||
lp_var_t<uint32_t> tmHits = lp_var_t<uint32_t>(sid.objectId, TM_HITS, this);
|
dp::var_t<uint8_t> valid = dp::var_t<uint8_t>(sid.objectId, VALID, this);
|
||||||
lp_var_t<uint32_t> queueHits = lp_var_t<uint32_t>(sid.objectId, QUEUE_HITS, this);
|
dp::var_t<uint32_t> tmHits = dp::var_t<uint32_t>(sid.objectId, TM_HITS, this);
|
||||||
lp_var_t<uint32_t> storeHits = lp_var_t<uint32_t>(sid.objectId, STORE_HITS, this);
|
dp::var_t<uint32_t> queueHits = dp::var_t<uint32_t>(sid.objectId, QUEUE_HITS, this);
|
||||||
|
dp::var_t<uint32_t> storeHits = dp::var_t<uint32_t>(sid.objectId, STORE_HITS, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ */
|
#endif /* FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ */
|
||||||
|
@ -6,16 +6,18 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth,
|
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth,
|
||||||
bool enableSetByDefault, float generationFrequency)
|
bool enableSetByDefault,
|
||||||
|
dur_millis_t generationFrequency)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
poolManager(this, commandQueue),
|
sharedPool(getObjectId()),
|
||||||
|
hkHelper(this, nullptr),
|
||||||
enableSetByDefault(enableSetByDefault),
|
enableSetByDefault(enableSetByDefault),
|
||||||
generationFrequency(generationFrequency),
|
generationFrequency(generationFrequency),
|
||||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||||
internalErrorDataset(this) {
|
internalErrorDataset(sharedPool) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
auto mqArgs = MqArgs(setObjectId, this);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
@ -29,11 +31,25 @@ void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
|
|||||||
this->diagnosticPrintout = enable;
|
this->diagnosticPrintout = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t InternalErrorReporter::initialize() {
|
||||||
|
ReturnValue_t result = hkHelper.initialize(commandQueue);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedPool.addPoolEntry(errorPoolIds::STORE_HITS, &storeHitsEntry);
|
||||||
|
sharedPool.addPoolEntry(errorPoolIds::TM_HITS, &tmHitsEntry);
|
||||||
|
sharedPool.addPoolEntry(errorPoolIds::QUEUE_HITS, &queueHitsEntry);
|
||||||
|
sharedPool.addPoolEntry(errorPoolIds::VALID, &setIsValid);
|
||||||
|
internalErrorDataset.valid = false;
|
||||||
|
return SystemObject::initialize();
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
||||||
CommandMessage message;
|
CommandMessage message;
|
||||||
ReturnValue_t result = commandQueue->receiveMessage(&message);
|
ReturnValue_t result = commandQueue->receiveMessage(&message);
|
||||||
if (result != MessageQueueIF::EMPTY) {
|
if (result != MessageQueueIF::EMPTY) {
|
||||||
poolManager.handleHousekeepingMessage(&message);
|
hkHelper.handleHousekeepingMessage(&message);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t newQueueHits = getAndResetQueueHits();
|
uint32_t newQueueHits = getAndResetQueueHits();
|
||||||
@ -64,14 +80,11 @@ 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.valid = true;
|
||||||
if ((newQueueHits != 0) or (newStoreHits != 0) or (newTmHits != 0)) {
|
|
||||||
internalErrorDataset.setChanged(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
poolManager.performHkOperation();
|
hkHelper.performHkOperation();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,42 +145,27 @@ MessageQueueId_t InternalErrorReporter::getCommandQueue() const {
|
|||||||
return this->commandQueue->getId();
|
return this->commandQueue->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t InternalErrorReporter::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
|
||||||
LocalDataPoolManager &poolManager) {
|
|
||||||
localDataPoolMap.emplace(errorPoolIds::TM_HITS, &tmHitsEntry);
|
|
||||||
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, &queueHitsEntry);
|
|
||||||
localDataPoolMap.emplace(errorPoolIds::STORE_HITS, &storeHitsEntry);
|
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
|
||||||
subdp::RegularHkPeriodicParams(internalErrorSid, enableSetByDefault, generationFrequency));
|
|
||||||
internalErrorDataset.setValidity(true, true);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const {
|
|
||||||
return this->executingTask->getPeriodMs();
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPoolDataSetBase *InternalErrorReporter::getDataSetHandle(sid_t sid) {
|
|
||||||
return &internalErrorDataset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalErrorReporter::setTaskIF(PeriodicTaskIF *task) { this->executingTask = task; }
|
void InternalErrorReporter::setTaskIF(PeriodicTaskIF *task) { this->executingTask = task; }
|
||||||
|
|
||||||
ReturnValue_t InternalErrorReporter::initialize() {
|
|
||||||
ReturnValue_t result = poolManager.initialize(commandQueue);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return SystemObject::initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() {
|
|
||||||
return poolManager.initializeAfterTaskCreation();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalErrorReporter::setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
void InternalErrorReporter::setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||||
this->timeoutType = timeoutType;
|
this->timeoutType = timeoutType;
|
||||||
this->timeoutMs = timeoutMs;
|
this->timeoutMs = timeoutMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDataPoolManager *InternalErrorReporter::getHkManagerHandle() { return &poolManager; }
|
ReturnValue_t InternalErrorReporter::serializeHkDataset(dp::structure_id_t structureId,
|
||||||
|
uint8_t *buf, size_t maxSize) {
|
||||||
|
if (structureId == internalErrorDataset.getStructureId()) {
|
||||||
|
size_t serSize = 0;
|
||||||
|
return internalErrorDataset.serialize(buf, serSize, maxSize, SerializeIF::Endianness::NETWORK);
|
||||||
|
}
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t InternalErrorReporter::specifyHkDatasets(
|
||||||
|
std::vector<hk::SetSpecification> &setSpecification) {
|
||||||
|
setSpecification.emplace_back(internalErrorDataset.getStructureId(),
|
||||||
|
internalErrorDataset.getSerializedSize(), generationFrequency);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
dp::SharedPool *InternalErrorReporter::getOptionalSharedPool() { return &sharedPool; }
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#ifndef FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_
|
#ifndef FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_
|
||||||
#define FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_
|
#define FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_
|
||||||
|
|
||||||
|
#include <fsfw/housekeeping/PeriodicHkHelper.h>
|
||||||
|
|
||||||
#include "InternalErrorReporterIF.h"
|
#include "InternalErrorReporterIF.h"
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
#include "fsfw/housekeeping/GeneratesPeriodicHkIF.h"
|
||||||
#include "fsfw/internalerror/InternalErrorDataset.h"
|
#include "fsfw/internalerror/InternalErrorDataset.h"
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
@ -19,10 +21,10 @@
|
|||||||
class InternalErrorReporter : public SystemObject,
|
class InternalErrorReporter : public SystemObject,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
public InternalErrorReporterIF,
|
public InternalErrorReporterIF,
|
||||||
public HasLocalDataPoolIF {
|
public hk::GeneratesPeriodicHkIF {
|
||||||
public:
|
public:
|
||||||
InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth,
|
InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth,
|
||||||
bool enableSetByDefault, float generationFrequency);
|
bool enableSetByDefault, dur_millis_t generationFrequency);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable diagnostic printout. Please note that this feature will
|
* Enable diagnostic printout. Please note that this feature will
|
||||||
@ -33,31 +35,32 @@ class InternalErrorReporter : public SystemObject,
|
|||||||
|
|
||||||
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
||||||
|
|
||||||
virtual ~InternalErrorReporter();
|
~InternalErrorReporter() override;
|
||||||
|
|
||||||
virtual object_id_t getObjectId() const override;
|
[[nodiscard]] object_id_t getObjectId() const override;
|
||||||
virtual MessageQueueId_t getCommandQueue() const override;
|
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
|
||||||
LocalDataPoolManager& poolManager) override;
|
|
||||||
virtual dur_millis_t getPeriodicOperationFrequency() const override;
|
|
||||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
|
||||||
LocalDataPoolManager* getHkManagerHandle() override;
|
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
dp::SharedPool* getOptionalSharedPool() override;
|
||||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
|
||||||
|
|
||||||
virtual void queueMessageNotSent() override;
|
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf, size_t maxSize) override;
|
||||||
|
|
||||||
virtual void lostTm() override;
|
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setSpecification) override;
|
||||||
|
|
||||||
virtual void storeFull() override;
|
ReturnValue_t initialize() override;
|
||||||
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
virtual void setTaskIF(PeriodicTaskIF* task) override;
|
void queueMessageNotSent() override;
|
||||||
|
|
||||||
|
void lostTm() override;
|
||||||
|
|
||||||
|
void storeFull() override;
|
||||||
|
|
||||||
|
void setTaskIF(PeriodicTaskIF* task) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* commandQueue;
|
MessageQueueIF* commandQueue;
|
||||||
LocalDataPoolManager poolManager;
|
dp::SharedPool sharedPool;
|
||||||
|
hk::PeriodicHelper hkHelper;
|
||||||
|
|
||||||
PeriodicTaskIF* executingTask = nullptr;
|
PeriodicTaskIF* executingTask = nullptr;
|
||||||
|
|
||||||
@ -65,9 +68,9 @@ class InternalErrorReporter : public SystemObject,
|
|||||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
uint32_t timeoutMs = 20;
|
uint32_t timeoutMs = 20;
|
||||||
bool enableSetByDefault;
|
bool enableSetByDefault;
|
||||||
float generationFrequency;
|
dur_millis_t generationFrequency;
|
||||||
|
|
||||||
sid_t internalErrorSid;
|
dp::structure_id_t internalErrorSid;
|
||||||
InternalErrorDataset internalErrorDataset;
|
InternalErrorDataset internalErrorDataset;
|
||||||
|
|
||||||
bool diagnosticPrintout = true;
|
bool diagnosticPrintout = true;
|
||||||
@ -75,6 +78,7 @@ class InternalErrorReporter : public SystemObject,
|
|||||||
uint32_t queueHits = 0;
|
uint32_t queueHits = 0;
|
||||||
uint32_t tmHits = 0;
|
uint32_t tmHits = 0;
|
||||||
uint32_t storeHits = 0;
|
uint32_t storeHits = 0;
|
||||||
|
PoolEntry<uint8_t> setIsValid = PoolEntry<uint8_t>();
|
||||||
PoolEntry<uint32_t> tmHitsEntry = PoolEntry<uint32_t>();
|
PoolEntry<uint32_t> tmHitsEntry = PoolEntry<uint32_t>();
|
||||||
PoolEntry<uint32_t> storeHitsEntry = PoolEntry<uint32_t>();
|
PoolEntry<uint32_t> storeHitsEntry = PoolEntry<uint32_t>();
|
||||||
PoolEntry<uint32_t> queueHitsEntry = PoolEntry<uint32_t>();
|
PoolEntry<uint32_t> queueHitsEntry = PoolEntry<uint32_t>();
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class AbsLimitMonitor : public MonitorBase<T> {
|
class AbsLimitMonitor : public MonitorBase<T> {
|
||||||
public:
|
public:
|
||||||
AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, gp_id_t globalPoolId,
|
AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, dp::g_id_t globalPoolId,
|
||||||
uint16_t confirmationLimit, T limit,
|
uint16_t confirmationLimit, T limit,
|
||||||
Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE,
|
Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE,
|
||||||
bool aboveIsViolation = true)
|
bool aboveIsViolation = true)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class LimitMonitor : public MonitorBase<T> {
|
class LimitMonitor : public MonitorBase<T> {
|
||||||
public:
|
public:
|
||||||
LimitMonitor(object_id_t reporterId, uint8_t monitorId, gp_id_t globalPoolId,
|
LimitMonitor(object_id_t reporterId, uint8_t monitorId, dp::g_id_t globalPoolId,
|
||||||
uint16_t confirmationLimit, T lowerLimit, T upperLimit,
|
uint16_t confirmationLimit, T lowerLimit, T upperLimit,
|
||||||
Event belowLowEvent = MonitoringIF::VALUE_BELOW_LOW_LIMIT,
|
Event belowLowEvent = MonitoringIF::VALUE_BELOW_LOW_LIMIT,
|
||||||
Event aboveHighEvent = MonitoringIF::VALUE_ABOVE_HIGH_LIMIT)
|
Event aboveHighEvent = MonitoringIF::VALUE_ABOVE_HIGH_LIMIT)
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#ifndef FSFW_MONITORING_MONITORBASE_H_
|
#ifndef FSFW_MONITORING_MONITORBASE_H_
|
||||||
#define FSFW_MONITORING_MONITORBASE_H_
|
#define FSFW_MONITORING_MONITORBASE_H_
|
||||||
|
|
||||||
#include "../datapoollocal/LocalPoolVariable.h"
|
|
||||||
#include "LimitViolationReporter.h"
|
#include "LimitViolationReporter.h"
|
||||||
#include "MonitorReporter.h"
|
#include "MonitorReporter.h"
|
||||||
#include "MonitoringIF.h"
|
#include "MonitoringIF.h"
|
||||||
#include "MonitoringMessageContent.h"
|
#include "MonitoringMessageContent.h"
|
||||||
|
#include "fsfw/datapool/PoolVariable.h"
|
||||||
#include "monitoringConf.h"
|
#include "monitoringConf.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,7 +22,7 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class MonitorBase : public MonitorReporter<T> {
|
class MonitorBase : public MonitorReporter<T> {
|
||||||
public:
|
public:
|
||||||
MonitorBase(object_id_t reporterId, uint8_t monitorId, gp_id_t globalPoolId,
|
MonitorBase(object_id_t reporterId, uint8_t monitorId, dp::g_id_t globalPoolId,
|
||||||
uint16_t confirmationLimit)
|
uint16_t confirmationLimit)
|
||||||
: MonitorReporter<T>(reporterId, monitorId, globalPoolId, confirmationLimit),
|
: MonitorReporter<T>(reporterId, monitorId, globalPoolId, confirmationLimit),
|
||||||
poolVariable(globalPoolId) {}
|
poolVariable(globalPoolId) {}
|
||||||
@ -66,7 +66,7 @@ class MonitorBase : public MonitorReporter<T> {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPoolVariable<T> poolVariable;
|
dp::PoolVariable<T> poolVariable;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_MONITORING_MONITORBASE_H_ */
|
#endif /* FSFW_MONITORING_MONITORBASE_H_ */
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#ifndef FSFW_MONITORING_MONITORREPORTER_H_
|
#pragma once
|
||||||
#define FSFW_MONITORING_MONITORREPORTER_H_
|
|
||||||
|
|
||||||
#include "../datapoollocal/localPoolDefinitions.h"
|
|
||||||
#include "../events/EventManagerIF.h"
|
#include "../events/EventManagerIF.h"
|
||||||
#include "../parameters/HasParametersIF.h"
|
#include "../parameters/HasParametersIF.h"
|
||||||
#include "LimitViolationReporter.h"
|
#include "LimitViolationReporter.h"
|
||||||
#include "MonitoringIF.h"
|
#include "MonitoringIF.h"
|
||||||
#include "MonitoringMessageContent.h"
|
#include "MonitoringMessageContent.h"
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
#include "monitoringConf.h"
|
#include "monitoringConf.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -17,7 +16,7 @@ class MonitorReporter : public HasParametersIF {
|
|||||||
|
|
||||||
// TODO: Adapt to use SID instead of parameter ID.
|
// TODO: Adapt to use SID instead of parameter ID.
|
||||||
|
|
||||||
MonitorReporter(object_id_t reportingId, uint8_t monitorId, gp_id_t globalPoolId,
|
MonitorReporter(object_id_t reportingId, uint8_t monitorId, dp::g_id_t globalPoolId,
|
||||||
uint16_t confirmationLimit)
|
uint16_t confirmationLimit)
|
||||||
: monitorId(monitorId),
|
: monitorId(monitorId),
|
||||||
globalPoolId(globalPoolId),
|
globalPoolId(globalPoolId),
|
||||||
@ -84,7 +83,7 @@ class MonitorReporter : public HasParametersIF {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
const uint8_t monitorId;
|
const uint8_t monitorId;
|
||||||
const gp_id_t globalPoolId;
|
const dp::g_id_t globalPoolId;
|
||||||
object_id_t reportingId;
|
object_id_t reportingId;
|
||||||
ReturnValue_t oldState;
|
ReturnValue_t oldState;
|
||||||
|
|
||||||
@ -162,5 +161,3 @@ class MonitorReporter : public HasParametersIF {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_MONITORING_MONITORREPORTER_H_ */
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#ifndef FSFW_MONITORING_MONITORINGMESSAGECONTENT_H_
|
#pragma once
|
||||||
#define FSFW_MONITORING_MONITORINGMESSAGECONTENT_H_
|
|
||||||
|
|
||||||
#include "../datapoollocal/localPoolDefinitions.h"
|
|
||||||
#include "../objectmanager/ObjectManager.h"
|
#include "../objectmanager/ObjectManager.h"
|
||||||
#include "../serialize/SerialBufferAdapter.h"
|
#include "../serialize/SerialBufferAdapter.h"
|
||||||
#include "../serialize/SerialFixedArrayListAdapter.h"
|
#include "../serialize/SerialFixedArrayListAdapter.h"
|
||||||
@ -11,6 +9,7 @@
|
|||||||
#include "../timemanager/TimeWriterIF.h"
|
#include "../timemanager/TimeWriterIF.h"
|
||||||
#include "HasMonitorsIF.h"
|
#include "HasMonitorsIF.h"
|
||||||
#include "MonitoringIF.h"
|
#include "MonitoringIF.h"
|
||||||
|
#include "fsfw/datapool/definitions.h"
|
||||||
#include "monitoringConf.h"
|
#include "monitoringConf.h"
|
||||||
|
|
||||||
namespace Factory {
|
namespace Factory {
|
||||||
@ -29,7 +28,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
public:
|
public:
|
||||||
SerializeElement<uint8_t> monitorId;
|
SerializeElement<uint8_t> monitorId;
|
||||||
SerializeElement<uint32_t> parameterObjectId;
|
SerializeElement<uint32_t> parameterObjectId;
|
||||||
SerializeElement<lp_id_t> localPoolId;
|
SerializeElement<dp::id_t> localPoolId;
|
||||||
SerializeElement<T> parameterValue;
|
SerializeElement<T> parameterValue;
|
||||||
SerializeElement<T> limitValue;
|
SerializeElement<T> limitValue;
|
||||||
SerializeElement<ReturnValue_t> oldState;
|
SerializeElement<ReturnValue_t> oldState;
|
||||||
@ -50,7 +49,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
timeStamper(nullptr) {
|
timeStamper(nullptr) {
|
||||||
setAllNext();
|
setAllNext();
|
||||||
}
|
}
|
||||||
MonitoringReportContent(gp_id_t globalPoolId, T value, T limitValue, ReturnValue_t oldState,
|
MonitoringReportContent(dp::g_id_t globalPoolId, T value, T limitValue, ReturnValue_t oldState,
|
||||||
ReturnValue_t newState)
|
ReturnValue_t newState)
|
||||||
: SerialLinkedListAdapter<SerializeIF>(¶meterObjectId),
|
: SerialLinkedListAdapter<SerializeIF>(¶meterObjectId),
|
||||||
monitorId(0),
|
monitorId(0),
|
||||||
@ -94,5 +93,3 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
object_id_t MonitoringReportContent<T>::timeStamperId = 0;
|
object_id_t MonitoringReportContent<T>::timeStamperId = 0;
|
||||||
|
|
||||||
#endif /* FSFW_MONITORING_MONITORINGMESSAGECONTENT_H_ */
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user