refactor periodic HK helpers

This commit is contained in:
Robin Müller 2024-11-04 17:32:21 +01:00
parent f90241bdd6
commit b1bd0d3af7
Signed by: muellerr
GPG Key ID: A649FB78196E3849
66 changed files with 993 additions and 1710 deletions

View File

@ -141,9 +141,7 @@ if(FSFW_BUILD_TESTS)
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
project(${FSFW_TEST_TGT} CXX C)
add_executable(
${FSFW_TEST_TGT}
)
add_executable(${FSFW_TEST_TGT})
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
TRUE)

View File

@ -16,9 +16,9 @@ ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
object_id_t ExtendedControllerBase::getObjectId() const { return SystemObject::getObjectId(); }
uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const {
return this->executingTask->getPeriodMs();
}
// uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const {
// return this->executingTask->getPeriodMs();
//}
ReturnValue_t ExtendedControllerBase::handleCommandMessage(CommandMessage *message) {
ReturnValue_t result = actionHelper.handleActionMessage(message);
@ -76,7 +76,7 @@ ReturnValue_t ExtendedControllerBase::initialize() {
}
ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
return poolManager.initializeAfterTaskCreation();
//return poolManager.initializeAfterTaskCreation();
}
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
@ -90,4 +90,4 @@ ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
MessageQueueId_t ExtendedControllerBase::getCommandQueue() const { return commandQueue->getId(); }
LocalDataPoolManager *ExtendedControllerBase::getHkManagerHandle() { return &poolManager; }
PeriodicHkGenerationHelper *ExtendedControllerBase::getHkManagerHandle() { return &poolManager; }

View File

@ -3,8 +3,8 @@
#include "ControllerBase.h"
#include "fsfw/action.h"
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationIF.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationHelper.h"
/**
* @brief Extends the basic ControllerBase with commonly used components
@ -15,7 +15,7 @@
*/
class ExtendedControllerBase : public ControllerBase,
public HasActionsIF,
public HasLocalDataPoolIF {
public PeriodicHkGenerationIF {
public:
ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth = 3);
~ExtendedControllerBase() override;
@ -30,7 +30,7 @@ class ExtendedControllerBase : public ControllerBase,
ReturnValue_t initializeAfterTaskCreation() override;
protected:
LocalDataPoolManager poolManager;
PeriodicHkGenerationHelper poolManager;
ActionHelper actionHelper;
/**
@ -54,13 +54,12 @@ class ExtendedControllerBase : public ControllerBase,
const uint8_t* data, size_t size) override;
/* HasLocalDatapoolIF overrides */
LocalDataPoolManager* getHkManagerHandle() override;
PeriodicHkGenerationHelper* getHkManagerHandle() override;
[[nodiscard]] object_id_t getObjectId() const override;
[[nodiscard]] uint32_t getPeriodicOperationFrequency() 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;
PeriodicHkGenerationHelper& poolManager) override = 0;
// Mode abstract functions
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,

View File

@ -30,6 +30,8 @@
* @ingroup data_pool
*/
class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
friend class LocalPoolDataSetBase;
public:
/**
* @brief Creates an empty dataset. Use registerVariable or
@ -99,24 +101,23 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
* thread-safety. Default implementation is empty
* @return Always returns -@c returnvalue::OK
*/
virtual ReturnValue_t lockDataPool(
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
ReturnValue_t lockDataPool(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t timeoutMs = 20) override;
/**
* Provides the means to unlock the underlying data structure to ensure
* thread-safety. Default implementation is empty
* @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 */
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
[[nodiscard]] size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
/**
* Can be used to individually protect every read and commit call.

View File

@ -28,7 +28,7 @@ class PoolDataSetIF : virtual public DataSetIF, virtual public ReadCommitIF {
*/
virtual ReturnValue_t unlockDataPool() = 0;
virtual bool isValid() const = 0;
// virtual bool isValid() const = 0;
};
#endif /* FSFW_DATAPOOL_POOLDATASETIF_H_ */

View File

@ -46,15 +46,6 @@ class PoolVariableIF : public SerializeIF, public ReadCommitIF {
* @brief This operation shall return the data pool id of the variable.
*/
virtual uint32_t getDataPoolId() const = 0;
/**
* @brief With this call, the valid information of the
* variable is returned.
*/
virtual bool isValid() const = 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;

View File

@ -1,7 +1,7 @@
#ifndef FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
#define FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
class LocalDataPoolManager;
class PeriodicHkGenerationHelper;
class MutexIF;
/**
@ -18,7 +18,7 @@ class AccessPoolManagerIF {
* This function is protected because it should only be used by the
* class imlementing the interface.
*/
virtual LocalDataPoolManager* getPoolManagerHandle() = 0;
virtual PeriodicHkGenerationHelper* getPoolManagerHandle() = 0;
protected:
};

View File

@ -1,6 +1,7 @@
target_sources(
${LIB_FSFW_NAME}
PRIVATE LocalDataPoolManager.cpp LocalDataSet.cpp LocalPoolDataSetBase.cpp
LocalPoolObjectBase.cpp SharedLocalDataSet.cpp)
PRIVATE PeriodicHkGenerationHelper.cpp LocalDataSet.cpp
LocalPoolDataSetBase.cpp LocalPoolObjectBase.cpp
SharedLocalDataSet.cpp)
add_subdirectory(internal)

View File

@ -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(
&notification, gp_id_t(owner->getObjectId(), receiver.dataId.localPoolId));
ReturnValue_t result = hkQueue->sendMessage(receiver.destinationQueue, &notification);
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(&notification, receiver.dataId.sid);
ReturnValue_t result = hkQueue->sendMessage(receiver.destinationQueue, &notification);
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(
&notification, gp_id_t(owner->getObjectId(), receiver.dataId.localPoolId), storeId);
result = hkQueue->sendMessage(receiver.destinationQueue, &notification);
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(&notification, receiver.dataId.sid, storeId);
result = hkQueue->sendMessage(receiver.destinationQueue, &notification);
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;
}

View File

@ -1,12 +1,6 @@
#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,
LocalDataSet::LocalDataSet(PeriodicHkGenerationIF *hkOwner, uint32_t setId,
const size_t maxNumberOfVariables)
: LocalPoolDataSetBase(hkOwner, setId, nullptr, maxNumberOfVariables),
poolVarList(maxNumberOfVariables) {

View File

@ -20,7 +20,7 @@
*/
class LocalDataSet : public LocalPoolDataSetBase {
public:
LocalDataSet(HasLocalDataPoolIF* hkOwner, uint32_t setId, const size_t maxSize);
LocalDataSet(PeriodicHkGenerationIF* hkOwner, uint32_t setId, const size_t maxSize);
LocalDataSet(sid_t sid, const size_t maxSize);

View File

@ -2,7 +2,7 @@
#include <cstring>
#include "fsfw/datapoollocal.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationHelper.h"
#include "fsfw/globalfunctions/bitutility.h"
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
#include "fsfw/objectmanager/ObjectManager.h"
@ -10,10 +10,10 @@
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "internal/HasLocalDpIFUserAttorney.h"
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId,
LocalPoolDataSetBase::LocalPoolDataSetBase(PeriodicHkGenerationIF *hkOwner, uint32_t setId,
PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables, bool periodicHandling)
: PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
const size_t maxNumberOfVariables)
: base(registeredVariablesArray, maxNumberOfVariables) {
if (hkOwner == nullptr) {
// Configuration error.
#if FSFW_CPP_OSTREAM_ENABLED == 1
@ -36,15 +36,15 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t
this->sid.ownerSetId = setId;
/* Data creators get a periodic helper for periodic HK data generation. */
if (periodicHandling) {
periodicHelper = new PeriodicHousekeepingHelper(this);
}
// 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);
: base(registeredVariablesArray, maxNumberOfVariables) {
auto *hkOwner = ObjectManager::instance()->get<PeriodicHkGenerationIF>(sid.objectId);
if (hkOwner != nullptr) {
AccessPoolManagerIF *accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);
if (accessor != nullptr) {
@ -59,21 +59,16 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, PoolVariableIF **registere
LocalPoolDataSetBase::LocalPoolDataSetBase(PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables,
bool protectEveryReadCommitCall)
: PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
this->setReadCommitProtectionBehaviour(protectEveryReadCommitCall);
: base(registeredVariablesArray, maxNumberOfVariables) {
base.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);
// 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);
}
}
}
@ -87,83 +82,6 @@ ReturnValue_t LocalPoolDataSetBase::lockDataPool(MutexIF::TimeoutType timeoutTyp
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();
@ -176,12 +94,12 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t **buffer, size
SerializeIF::Endianness streamEndianness,
bool serializeFillCount) const {
/* Serialize fill count as uint8_t */
uint8_t fillCount = this->fillCount;
uint8_t fillCount = this->getFillCount();
if (serializeFillCount) {
SerializeAdapter::serialize(&fillCount, buffer, size, maxSize, streamEndianness);
}
for (uint16_t count = 0; count < fillCount; count++) {
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
lp_id_t currentPoolId = base.registeredVariables[count]->getDataPoolId();
auto result =
SerializeAdapter::serialize(&currentPoolId, buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
@ -201,41 +119,28 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t **buffer, size
uint8_t LocalPoolDataSetBase::getLocalPoolIdsSerializedSize(bool serializeFillCount) const {
if (serializeFillCount) {
return fillCount * sizeof(lp_id_t) + sizeof(uint8_t);
return base.getFillCount() * sizeof(lp_id_t) + sizeof(uint8_t);
} else {
return fillCount * sizeof(lp_id_t);
return base.getFillCount() * 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;
}
size_t LocalPoolDataSetBase::getSerializedSize() const { return base.getSerializedSize(); }
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);
}
return base.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);
}
return base.serialize(buffer, size, maxSize, streamEndianness);
}
[[nodiscard]] ReturnValue_t LocalPoolDataSetBase::serialize(
uint8_t *buffer, size_t &serLen, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
return SerializeIF::serialize(buffer, serLen, maxSize, streamEndianness);
}
void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) {
@ -244,28 +149,8 @@ void LocalPoolDataSetBase::setReportingEnabled(bool 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();
@ -275,16 +160,20 @@ object_id_t LocalPoolDataSetBase::getCreatorObjectId() {
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;
base.registeredVariables[idx]->setReadWriteMode(pool_rwm_t::VAR_READ);
}
}
void LocalPoolDataSetBase::printSet() { return; }
ReturnValue_t LocalPoolDataSetBase::read(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
return base.read(timeoutType, timeoutMs);
}
ReturnValue_t LocalPoolDataSetBase::commit(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
return base.commit(timeoutType, timeoutMs);
}
uint16_t LocalPoolDataSetBase::getFillCount() const { return base.getFillCount(); }
ReturnValue_t LocalPoolDataSetBase::registerVariable(PoolVariableIF *variable) {
base.registerVariable(variable);
}

View File

@ -8,8 +8,8 @@
#include "fsfw/datapool/PoolDataSetBase.h"
#include "localPoolDefinitions.h"
class LocalDataPoolManager;
class HasLocalDataPoolIF;
class PeriodicHkGenerationHelper;
class PeriodicHkGenerationIF;
class PeriodicHousekeepingHelper;
/**
@ -40,7 +40,7 @@ class PeriodicHousekeepingHelper;
*
* @ingroup data_pool
*/
class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
class LocalPoolDataSetBase : public SerializeIF, public PoolDataSetIF {
friend class LocalPoolDataSetAttorney;
friend class PeriodicHousekeepingHelper;
@ -51,9 +51,8 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
* This constructor also initializes the components required for
* periodic handling.
*/
LocalPoolDataSetBase(HasLocalDataPoolIF* hkOwner, uint32_t setId,
PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables,
bool periodicHandling = true);
LocalPoolDataSetBase(PeriodicHkGenerationIF* hkOwner, uint32_t setId,
PoolVariableIF** registeredVariablesArray, size_t maxNumberOfVariables);
/**
* @brief Constructor for users of the local pool data, which need
@ -67,7 +66,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
* @param maxNumberOfVariables
*/
LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables);
size_t maxNumberOfVariables);
/**
* @brief Simple constructor, if the dataset is not the owner by
@ -87,7 +86,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
* multiple creators, this flag can be set to protect all read and
* commit calls separately.
*/
LocalPoolDataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables,
LocalPoolDataSetBase(PoolVariableIF** registeredVariablesArray, size_t maxNumberOfVariables,
bool protectEveryReadCommitCall = true);
/**
@ -98,7 +97,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
* 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".
*/
~LocalPoolDataSetBase();
~LocalPoolDataSetBase() override;
/* 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
@ -114,54 +113,27 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
void setAllVariablesReadOnly();
void setValidityBufferGeneration(bool withValidityBuffer);
sid_t getSid() const;
[[nodiscard]] ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override;
[[nodiscard]] ReturnValue_t serialize(uint8_t* buffer, size_t& serLen, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
/** SerializeIF overrides */
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
size_t getSerializedSize() const override;
Endianness streamEndianness) override;
[[nodiscard]] sid_t getSid() const;
[[nodiscard]] size_t getSerializedSize() const override;
/**
* Special version of the serilization function which appends a
* validity buffer at the end. Each bit of this validity buffer
* denotes whether the container data set entries are valid from left
* to right, MSB first. (length = ceil(N/8), N = number of pool variables)
* @param buffer
* @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,
SerializeIF::Endianness streamEndianness,
bool serializeFillCount = true) 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;
[[nodiscard]] uint8_t getLocalPoolIdsSerializedSize(bool serializeFillCount = true) const;
object_id_t getCreatorObjectId();
bool getReportingEnabled() const;
[[nodiscard]] bool getReportingEnabled() const;
void setReportingEnabled(bool enabled);
/**
@ -177,7 +149,20 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
*/
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;
protected:
// I am tired of inheritance trees. This is the better solution, even if it means a bit more code.
PoolDataSetBase base;
sid_t sid;
//! This mutex is used if the data is created by one object only.
MutexIF* mutexIfSingleDataCreator = nullptr;
@ -208,7 +193,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
* The size of validity buffer thus will be ceil(N / 8) with N = number of
* pool variables.
*/
bool withValidityBuffer = true;
// bool withValidityBuffer = true;
/**
* @brief This is a small helper function to facilitate locking
@ -226,8 +211,9 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
*/
ReturnValue_t unlockDataPool() override;
PeriodicHousekeepingHelper* periodicHelper = nullptr;
LocalDataPoolManager* poolManager = nullptr;
// PeriodicHousekeepingHelper* periodicHelper = nullptr;
// dur_millis_t collectionFrequency = 0;
PeriodicHkGenerationHelper* poolManager = nullptr;
};
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ */

View File

@ -1,12 +1,12 @@
#include "fsfw/datapoollocal/LocalPoolObjectBase.h"
#include "fsfw/datapoollocal/AccessLocalPoolF.h"
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationIF.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationHelper.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "internal/HasLocalDpIFUserAttorney.h"
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, PeriodicHkGenerationIF* hkOwner,
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
: localPoolId(poolId), readWriteMode(setReadWriteMode) {
if (poolId == PoolVariableIF::NO_PARAMETER) {
@ -44,7 +44,7 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
"which is the NO_PARAMETER value!\n");
#endif
}
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
auto* hkOwner = ObjectManager::instance()->get<PeriodicHkGenerationIF>(poolOwner);
if (hkOwner == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
@ -71,10 +71,6 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
pool_rwm_t LocalPoolObjectBase::getReadWriteMode() const { return readWriteMode; }
bool LocalPoolObjectBase::isValid() const { return valid; }
void LocalPoolObjectBase::setValid(bool valid) { this->valid = valid; }
lp_id_t LocalPoolObjectBase::getDataPoolId() const { return localPoolId; }
void LocalPoolObjectBase::setDataPoolId(lp_id_t poolId) { this->localPoolId = poolId; }

View File

@ -7,9 +7,9 @@
#include "fsfw/returnvalues/returnvalue.h"
#include "localPoolDefinitions.h"
class LocalDataPoolManager;
class PeriodicHkGenerationHelper;
class DataSetIF;
class HasLocalDataPoolIF;
class PeriodicHkGenerationIF;
/**
* @brief This class serves as a non-template base for pool objects like pool variables
@ -17,7 +17,7 @@ class HasLocalDataPoolIF;
*/
class LocalPoolObjectBase : public PoolVariableIF, public MarkChangedIF {
public:
LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, DataSetIF* dataSet,
LocalPoolObjectBase(lp_id_t poolId, PeriodicHkGenerationIF* hkOwner, DataSetIF* dataSet,
pool_rwm_t setReadWriteMode);
LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
@ -26,9 +26,6 @@ class LocalPoolObjectBase : public PoolVariableIF, public MarkChangedIF {
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;
@ -59,7 +56,7 @@ class LocalPoolObjectBase : public PoolVariableIF, public MarkChangedIF {
ReadWriteMode_t readWriteMode = pool_rwm_t::VAR_READ_WRITE;
//! @brief Pointer to the class which manages the HK pool.
LocalDataPoolManager* hkManager = nullptr;
PeriodicHkGenerationHelper* hkManager = nullptr;
void reportReadCommitError(const char* variableType, ReturnValue_t error, bool read,
object_id_t objectId, lp_id_t lpId);

View File

@ -7,9 +7,9 @@
#include "../serialize/SerializeAdapter.h"
#include "../serviceinterface/ServiceInterface.h"
#include "AccessLocalPoolF.h"
#include "HasLocalDataPoolIF.h"
#include "LocalDataPoolManager.h"
#include "PeriodicHkGenerationIF.h"
#include "LocalPoolObjectBase.h"
#include "PeriodicHkGenerationHelper.h"
#include "internal/LocalDpManagerAttorney.h"
/**
@ -45,7 +45,7 @@ class LocalPoolVariable : public LocalPoolObjectBase {
* 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,
LocalPoolVariable(PeriodicHkGenerationIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**

View File

@ -6,7 +6,7 @@
#endif
template <typename T>
inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
inline LocalPoolVariable<T>::LocalPoolVariable(PeriodicHkGenerationIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet, pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
@ -60,13 +60,6 @@ inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
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) {

View File

@ -4,7 +4,7 @@
#include "../datapool/DataSetIF.h"
#include "../datapool/PoolEntry.h"
#include "../datapool/PoolVariableIF.h"
#include "../datapoollocal/LocalDataPoolManager.h"
#include "../datapoollocal/PeriodicHkGenerationHelper.h"
#include "../serialize/SerializeAdapter.h"
#include "../serviceinterface/ServiceInterface.h"
#include "LocalPoolObjectBase.h"
@ -47,7 +47,7 @@ class LocalPoolVector : public LocalPoolObjectBase {
* @param dataSet The data set in which the variable shall register itself.
* If nullptr, the variable is not registered.
*/
LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
LocalPoolVector(PeriodicHkGenerationIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/**

View File

@ -6,7 +6,7 @@
#endif
template <typename T, uint16_t vectorSize>
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(PeriodicHkGenerationIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet,
pool_rwm_t setReadWriteMode)
: LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
@ -57,14 +57,14 @@ template <typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(bool valid,
MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) {
this->setValid(valid);
//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);
MutexGuard mg(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs);
return commitWithoutLock();
}

View File

@ -0,0 +1,456 @@
#include "fsfw/datapoollocal/PeriodicHkGenerationHelper.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 PeriodicHkGenerationHelper::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
PeriodicHkGenerationHelper::PeriodicHkGenerationHelper(PeriodicHkGenerationIF* 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;
}
PeriodicHkGenerationHelper::~PeriodicHkGenerationHelper() {
if (mutex != nullptr) {
MutexFactory::instance()->deleteMutex(mutex);
}
}
ReturnValue_t PeriodicHkGenerationHelper::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;
}
}
owner->specifyDatasets(setList);
return returnvalue::OK;
}
ReturnValue_t PeriodicHkGenerationHelper::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 PeriodicHkGenerationHelper::performHkOperation() {
ReturnValue_t status = returnvalue::OK;
for (auto& setSpec : setList) {
switch (setSpec.reportingType) {
case (periodicHk::ReportingType::PERIODIC): {
if (setSpec.dataType == periodicHk::DataType::LOCAL_POOL_VARIABLE) {
/* Periodic packets shall only be generated from datasets */
continue;
}
performPeriodicHkGeneration(setSpec);
break;
}
default:
// This should never happen.
return returnvalue::FAILED;
}
}
resetHkUpdateResetHelper();
return status;
}
ReturnValue_t PeriodicHkGenerationHelper::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;
;
}
/*
ReturnValue_t PeriodicHkGenerationHelper::subscribeForPeriodicPacket(subdp::ParamsBase& params) {
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);
}
hkReceivers.push_back(hkReceiver);
return returnvalue::OK;
}
*/
ReturnValue_t PeriodicHkGenerationHelper::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): {
dur_millis_t newCollIntvl = 0;
HousekeepingMessage::getCollectionIntervalModificationCommand(message, newCollIntvl);
result = changeCollectionInterval(sid, newCollIntvl);
break;
}
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): {
return generateHousekeepingPacket(HousekeepingMessage::getSid(message));
}
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 PeriodicHkGenerationHelper::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* PeriodicHkGenerationHelper::getMutexHandle() { return mutex; }
PeriodicHkGenerationIF* PeriodicHkGenerationHelper::getOwner() { return owner; }
ReturnValue_t PeriodicHkGenerationHelper::generateHousekeepingPacket(sid_t sid,
MessageQueueId_t destination) {
store_address_t storeId;
HousekeepingPacketDownlink hkPacket(sid, dataSet);
size_t serializedSize = 0;
ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, storeId, &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 PeriodicHkGenerationHelper::serializeHkPacketIntoStore(
HousekeepingPacketDownlink& hkPacket, store_address_t& storeId, 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;
}
return hkPacket.serialize(&dataPtr, serializedSize, maxSize, SerializeIF::Endianness::NETWORK);
}
void PeriodicHkGenerationHelper::performPeriodicHkGeneration(SetSpecification& 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 PeriodicHkGenerationHelper::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;
}
std::optional<periodicHk::SetSpecification> PeriodicHkGenerationHelper::getSetSpecification(sid_t structureId) {
for(auto& receiver: setList) {
if (receiver.dataId.sid == structureId) {
return receiver;
}
}
return std::nullopt;
}
ReturnValue_t PeriodicHkGenerationHelper::changeCollectionInterval(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, "changeCollectionInterval",
DATASET_NOT_FOUND);
return DATASET_NOT_FOUND;
}
return returnvalue::OK;
}
ReturnValue_t PeriodicHkGenerationHelper::generateSetStructurePacket(sid_t sid) {
/* Get and check dataset first. */
auto optSetSpec = getSetSpecification(sid);
if (!optSetSpec.has_value()) {
printWarningOrError(sif::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration",
DATASET_NOT_FOUND);
return DATASET_NOT_FOUND;
}
auto setSpec = *optSetSpec;
bool reportingEnabled = setSpec.;
dur_millis_t collectionInterval = 0;
auto optCollectionInterval = getCollectionFrequency(sid);
if (optCollectionInterval.has_value()) {
collectionInterval = optCollectionInterval.value();
}
// Generate set packet which can be serialized.
HousekeepingSetPacket setPacket(sid, reportingEnabled, 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;
}
MutexIF* PeriodicHkGenerationHelper::getLocalPoolMutex() { return this->mutex; }
object_id_t PeriodicHkGenerationHelper::getCreatorObjectId() const { return owner->getObjectId(); }
void PeriodicHkGenerationHelper::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 */
}
PeriodicHkGenerationHelper* PeriodicHkGenerationHelper::getPoolManagerHandle() { return this; }
void PeriodicHkGenerationHelper::setHkDestinationId(MessageQueueId_t hkDestId) {
hkDestinationId = hkDestId;
}

View File

@ -2,6 +2,7 @@
#define FSFW_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
#include <map>
#include <optional>
#include <vector>
#include "AccessLocalPoolF.h"
@ -19,13 +20,63 @@
#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
namespace Factory {
void setStaticFrameworkObjectIds();
namespace periodicHk {
/**
* 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(sid_t sid) {
DataId d;
d.sid = sid;
return d;
}
sid_t sid;
lp_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 };
/** The data pool manager will keep an internal map of HK receivers. */
struct SetSpecification {
SetSpecification(sid_t structureId, dur_millis_t collectionFrequency,
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE)
: dataId(DataId::forSetId(structureId)),
collectionFrequency(collectionFrequency),
destinationQueue(destinationQueue) {};
/** Object ID of receiver */
object_id_t objectId = objects::NO_OBJECT;
DataType dataType = DataType::DATA_SET;
DataId dataId;
dur_millis_t collectionFrequency = 0;
ReportingType reportingType = ReportingType::PERIODIC;
bool periodicCollectionEnabled = false;
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
};
}
class LocalPoolDataSetBase;
class HousekeepingSnapshot;
class HasLocalDataPoolIF;
class PeriodicHkGenerationIF;
class LocalDataPool;
/**
@ -52,8 +103,8 @@ class LocalDataPool;
* Each pool entry has a valid state too.
* @author R. Mueller
*/
class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public AccessPoolManagerIF {
friend void(Factory::setStaticFrameworkObjectIds)();
class PeriodicHkGenerationHelper : public PeriodicHkGenerationProviderIF,
public AccessPoolManagerIF {
//! 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;
@ -79,9 +130,9 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
* @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;
PeriodicHkGenerationHelper(PeriodicHkGenerationIF* owner, MessageQueueIF* queueToUse,
bool appendValidityBuffer = true);
~PeriodicHkGenerationHelper() override;
void setHkDestinationId(MessageQueueId_t hkDestId);
@ -89,21 +140,9 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
* 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
@ -115,43 +154,6 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
*/
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
@ -171,54 +173,23 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
* @param sid
* @return
*/
ReturnValue_t generateHousekeepingPacket(sid_t sid, LocalPoolDataSetBase* dataSet,
bool forDownlink,
ReturnValue_t generateHousekeepingPacket(sid_t sid,
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
ReturnValue_t changeCollectionInterval(sid_t sid, float newCollectionInterval);
HasLocalDataPoolIF* getOwner();
PeriodicHkGenerationIF* 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;
PeriodicHkGenerationHelper(const PeriodicHkGenerationHelper&) = delete;
PeriodicHkGenerationHelper 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();
// void clearReceiversList();
[[nodiscard]] object_id_t getCreatorObjectId() const;
@ -230,17 +201,27 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
*/
MutexIF* getMutexHandle();
LocalDataPoolManager* getPoolManagerHandle() override;
ReturnValue_t subscribeForRegularPeriodicPacket(subdp::RegularHkPeriodicParams params) override;
ReturnValue_t subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams params) override;
PeriodicHkGenerationHelper* getPoolManagerHandle() override;
/**
* Set the periodic generation frequency without enabling the periodic generation of packets.
*/
ReturnValue_t setPeriodicFrequency(sid_t structureId, dur_millis_t frequencyMs) override;
ReturnValue_t enableRegularPeriodicPacket(sid_t structureId,
std::optional<dur_millis_t> frequencyMs) override;
ReturnValue_t disablePeriodicPacket(sid_t structureId) override;
ReturnValue_t changeCollectionInterval(sid_t sid,
dur_millis_t newCollectionIntervalMs);
ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) override;
ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) override;
protected:
std::optional<periodicHk::SetSpecification> getSetSpecification(sid_t structureId);
ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params);
ReturnValue_t subscribeForUpdatePacket(subdp::ParamsBase& params);
std::optional<dur_millis_t> getCollectionFrequency(sid_t structureId);
/** Core data structure for the actual pool data */
localpool::DataPool localPoolMap;
/** Every housekeeping data manager has a mutex to protect access
@ -248,7 +229,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
MutexIF* mutex = nullptr;
/** The class which actually owns the manager (and its datapool). */
HasLocalDataPoolIF* owner = nullptr;
PeriodicHkGenerationIF* owner = nullptr;
uint8_t nonDiagnosticIntervalFactor = 0;
@ -256,40 +237,10 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
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>;
using SetList = std::vector<periodicHk::SetSpecification>;
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();
SetList setList;
/** This is the map holding the actual data. Should only be initialized
* once ! */
@ -333,20 +284,15 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
MutexIF* getLocalPoolMutex() override;
ReturnValue_t serializeHkPacketIntoStore(HousekeepingPacketDownlink& hkPacket,
store_address_t& storeId, bool forDownlink,
size_t* serializedSize);
store_address_t& storeId, size_t* serializedSize);
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
void performPeriodicHkGeneration(periodicHk::SetSpecification& 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 handleChangeResetLogic(periodicHk::DataType type, periodicHk::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,
@ -355,8 +301,8 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
};
template <class T>
inline ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
PoolEntry<T>** poolEntry) {
inline ReturnValue_t PeriodicHkGenerationHelper::fetchPoolEntry(lp_id_t localPoolId,
PoolEntry<T>** poolEntry) {
if (poolEntry == nullptr) {
return returnvalue::FAILED;
}

View File

@ -3,7 +3,7 @@
#include <map>
#include "LocalDataPoolManager.h"
#include "PeriodicHkGenerationHelper.h"
#include "fsfw/datapool/PoolEntryIF.h"
#include "fsfw/housekeeping/HousekeepingMessage.h"
#include "fsfw/ipc/MessageQueueSenderIF.h"
@ -11,7 +11,7 @@
#include "localPoolDefinitions.h"
class AccessPoolManagerIF;
class ProvidesDataPoolSubscriptionIF;
class PeriodicHkGenerationProviderIF;
class LocalPoolDataSetBase;
class LocalPoolObjectBase;
@ -39,19 +39,23 @@ class LocalPoolObjectBase;
* doSomething()
* }
*/
class HasLocalDataPoolIF {
class PeriodicHkGenerationIF {
friend class HasLocalDpIFManagerAttorney;
friend class HasLocalDpIFUserAttorney;
public:
virtual ~HasLocalDataPoolIF() {};
virtual ~PeriodicHkGenerationIF() = default;
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
virtual object_id_t getObjectId() const = 0;
[[nodiscard]] virtual object_id_t getObjectId() const = 0;
/** Command queue for housekeeping messages. */
virtual MessageQueueId_t getCommandQueue() const = 0;
[[nodiscard]] virtual MessageQueueId_t getCommandQueue() const = 0;
virtual ReturnValue_t serializeDataset(sid_t structureId, uint8_t* buf, size_t maxSize) = 0;
virtual ReturnValue_t specifyDatasets(std::vector<periodicHk::SetSpecification>& setList) = 0;
/**
* Is used by pool owner to initialize the pool map once
@ -59,52 +63,14 @@ class HasLocalDataPoolIF {
* It can be used to subscribe for periodic packets for for updates.
*/
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) = 0;
PeriodicHkGenerationHelper& 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;
}
}
//[[nodiscard]] virtual dur_millis_t getPeriodicOperationFrequency() const = 0;
/**
* These function can be implemented by pool owner, if they are required
@ -124,7 +90,7 @@ class HasLocalDataPoolIF {
* Returns the HK manager casted to the required interface by default.
* @return
*/
virtual ProvidesDataPoolSubscriptionIF* getSubscriptionInterface() {
virtual PeriodicHkGenerationProviderIF* getSubscriptionInterface() {
return getHkManagerHandle();
}
@ -134,7 +100,7 @@ class HasLocalDataPoolIF {
* function will return a reference to the manager.
* @return
*/
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
virtual PeriodicHkGenerationHelper* getHkManagerHandle() = 0;
/**
* Accessor handle required for internal handling. Not intended for users and therefore
@ -145,16 +111,6 @@ class HasLocalDataPoolIF {
*/
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

View File

@ -1,6 +1,10 @@
#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"
@ -10,17 +14,14 @@
namespace subdp {
struct ParamsBase {
ParamsBase(sid_t sid, bool enableReporting, float collectionInterval, bool diagnostics)
: sid(sid),
enableReporting(enableReporting),
collectionInterval(collectionInterval),
diagnostics(diagnostics) {}
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;
float collectionInterval;
dur_millis_t collectionIntervalMs;
MessageQueueId_t receiver = MessageQueueIF::NO_QUEUE;
protected:
@ -28,125 +29,31 @@ struct ParamsBase {
};
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) {}
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.0, false) {}
RegularHkUpdateParams(sid_t sid, bool enableReporting) : ParamsBase(sid, enableReporting, 0) {}
};
struct DiagnosticsHkUpdateParams : public ParamsBase {
DiagnosticsHkUpdateParams(sid_t sid, bool enableReporting)
: ParamsBase(sid, enableReporting, 0.0, true) {}
: ParamsBase(sid, enableReporting, 0) {}
};
} // namespace subdp
class ProvidesDataPoolSubscriptionIF {
class PeriodicHkGenerationProviderIF {
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);
}
}
virtual ~PeriodicHkGenerationProviderIF() = default;
/**
* @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
* Set the periodic generation frequency without enabling the periodic generation of packets.
*/
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;
virtual ReturnValue_t setPeriodicFrequency(sid_t structureId, dur_millis_t frequencyMs) = 0;
virtual ReturnValue_t enableRegularPeriodicPacket(sid_t structureId,
std::optional<dur_millis_t> frequencyMs) = 0;
virtual ReturnValue_t disablePeriodicPacket(sid_t structureId) = 0;
};
#endif /* FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_ */

View File

@ -6,7 +6,7 @@ SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, sid_t sid, const si
datasetLock = MutexFactory::instance()->createMutex();
}
SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, HasLocalDataPoolIF *owner,
SharedLocalDataSet::SharedLocalDataSet(object_id_t objectId, PeriodicHkGenerationIF *owner,
uint32_t setId, const size_t maxSize)
: SystemObject(objectId),
LocalPoolDataSetBase(owner, setId, nullptr, maxSize),

View File

@ -19,7 +19,7 @@ class SharedLocalDataSet : public SystemObject,
public LocalPoolDataSetBase,
public SharedDataSetIF {
public:
SharedLocalDataSet(object_id_t objectId, HasLocalDataPoolIF* owner, uint32_t setId,
SharedLocalDataSet(object_id_t objectId, PeriodicHkGenerationIF* owner, uint32_t setId,
const size_t maxSize);
SharedLocalDataSet(object_id_t objectId, sid_t sid, const size_t maxSize);

View File

@ -31,7 +31,7 @@ class StaticLocalDataSet : public LocalPoolDataSetBase {
* @param hkOwner
* @param setId
*/
StaticLocalDataSet(HasLocalDataPoolIF* hkOwner, uint32_t setId)
StaticLocalDataSet(PeriodicHkGenerationIF* hkOwner, uint32_t setId)
: LocalPoolDataSetBase(hkOwner, setId, nullptr, NUM_VARIABLES) {
this->setContainer(poolVarList.data());
}

View File

@ -1,19 +1,14 @@
#include "HasLocalDpIFManagerAttorney.h"
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationIF.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) {
LocalPoolObjectBase* HasLocalDpIFManagerAttorney::getPoolObjectHandle(
PeriodicHkGenerationIF* clientIF, lp_id_t localPoolId) {
return clientIF->getPoolObjectHandle(localPoolId);
}
object_id_t HasLocalDpIFManagerAttorney::getObjectId(HasLocalDataPoolIF* clientIF) {
object_id_t HasLocalDpIFManagerAttorney::getObjectId(PeriodicHkGenerationIF* clientIF) {
return clientIF->getObjectId();
}

View File

@ -3,19 +3,17 @@
#include "fsfw/datapoollocal/localPoolDefinitions.h"
class HasLocalDataPoolIF;
class PeriodicHkGenerationIF;
class LocalPoolDataSetBase;
class LocalPoolObjectBase;
class HasLocalDpIFManagerAttorney {
static LocalPoolDataSetBase* getDataSetHandle(HasLocalDataPoolIF* clientIF, sid_t sid);
static LocalPoolObjectBase* getPoolObjectHandle(HasLocalDataPoolIF* clientIF,
static LocalPoolObjectBase* getPoolObjectHandle(PeriodicHkGenerationIF* clientIF,
lp_id_t localPoolId);
static object_id_t getObjectId(HasLocalDataPoolIF* clientIF);
static object_id_t getObjectId(PeriodicHkGenerationIF* clientIF);
friend class LocalDataPoolManager;
friend class PeriodicHkGenerationHelper;
};
#endif /* FSFW_DATAPOOLLOCAL_HASLOCALDPIFMANAGERATTORNEY_H_ */

View File

@ -1,8 +1,8 @@
#include "HasLocalDpIFUserAttorney.h"
#include "fsfw/datapoollocal/AccessLocalPoolF.h"
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationIF.h"
AccessPoolManagerIF* HasLocalDpIFUserAttorney::getAccessorHandle(HasLocalDataPoolIF* clientIF) {
AccessPoolManagerIF* HasLocalDpIFUserAttorney::getAccessorHandle(PeriodicHkGenerationIF* clientIF) {
return clientIF->getAccessorHandle();
}

View File

@ -1,12 +1,12 @@
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
#define FSFW_DATAPOOLLOCAL_HASLOCALDPIFUSERATTORNEY_H_
class HasLocalDataPoolIF;
class PeriodicHkGenerationIF;
class AccessPoolManagerIF;
class HasLocalDpIFUserAttorney {
private:
static AccessPoolManagerIF* getAccessorHandle(HasLocalDataPoolIF* clientIF);
static AccessPoolManagerIF* getAccessorHandle(PeriodicHkGenerationIF* clientIF);
friend class LocalPoolObjectBase;
friend class LocalPoolDataSetBase;

View File

@ -1,7 +1,7 @@
#ifndef FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
#define FSFW_DATAPOOLLOCAL_LOCALDPMANAGERATTORNEY_H_
#include "../LocalDataPoolManager.h"
#include "../PeriodicHkGenerationHelper.h"
/**
* @brief This is a helper class implements the Attorney-Client idiom for access to
@ -16,12 +16,14 @@
class LocalDpManagerAttorney {
private:
template <typename T>
static ReturnValue_t fetchPoolEntry(LocalDataPoolManager& manager, lp_id_t localPoolId,
static ReturnValue_t fetchPoolEntry(PeriodicHkGenerationHelper& manager, lp_id_t localPoolId,
PoolEntry<T>** poolEntry) {
return manager.fetchPoolEntry(localPoolId, poolEntry);
}
static MutexIF* getMutexHandle(LocalDataPoolManager& manager) { return manager.getMutexHandle(); }
static MutexIF* getMutexHandle(PeriodicHkGenerationHelper& manager) {
return manager.getMutexHandle();
}
template <typename T>
friend class LocalPoolVariable;

View File

@ -5,10 +5,10 @@
class LocalPoolDataSetAttorney {
private:
static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
uint32_t minimumPeriodicIntervalMs) {
set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs);
}
// static void initializePeriodicHelper(LocalPoolDataSetBase& set, float collectionInterval,
// uint32_t minimumPeriodicIntervalMs) {
// set.initializePeriodicHelper(collectionInterval, minimumPeriodicIntervalMs);
//}
static void setReportingEnabled(LocalPoolDataSetBase& set, bool enabled) {
set.setReportingEnabled(enabled);
@ -16,11 +16,11 @@ class LocalPoolDataSetAttorney {
static bool getReportingEnabled(LocalPoolDataSetBase& set) { return set.getReportingEnabled(); }
static PeriodicHousekeepingHelper* getPeriodicHelper(LocalPoolDataSetBase& set) {
return set.periodicHelper;
}
// static PeriodicHousekeepingHelper* getPeriodicHelper(LocalPoolDataSetBase& set) {
// return set.periodicHelper;
//}
friend class LocalDataPoolManager;
friend class PeriodicHkGenerationHelper;
};
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETATTORNEY_H_ */

View File

@ -32,7 +32,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
modeHelper(this),
parameterHelper(this),
actionHelper(this, nullptr),
poolManager(this, nullptr),
periodicHkHelper(this, nullptr),
childTransitionFailure(returnvalue::OK),
fdirInstance(fdirInstance),
defaultFDIRUsed(fdirInstance == nullptr),
@ -111,7 +111,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
doGetRead();
/* This will be performed after datasets have been updated by the
custom device implementation. */
poolManager.performHkOperation();
periodicHkHelper.performHkOperation();
break;
default:
break;
@ -152,7 +152,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
}
if (rawDataReceiverId != objects::NO_OBJECT) {
AcceptsDeviceResponsesIF* rawReceiver =
auto* rawReceiver =
ObjectManager::instance()->get<AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == nullptr) {
@ -214,7 +214,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
return result;
}
result = poolManager.initialize(commandQueue);
result = periodicHkHelper.initialize(commandQueue);
if (result != returnvalue::OK) {
return result;
}
@ -226,7 +226,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
// Set temperature target state to NON_OP.
if (pg.getReadResult() == returnvalue::OK) {
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
thermalSet->heaterRequest.setValid(true);
// thermalSet->heaterRequest.setValid(true);
}
}
@ -288,7 +288,7 @@ void DeviceHandlerBase::readCommandQueue() {
return;
}
result = poolManager.handleHousekeepingMessage(&command);
result = periodicHkHelper.handleHousekeepingMessage(&command);
if (result == returnvalue::OK) {
return;
}
@ -593,7 +593,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
if (thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) {
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 */
@ -1469,7 +1469,7 @@ Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
void DeviceHandlerBase::performOperationHook() {}
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
PeriodicHkGenerationHelper& poolManager) {
if (thermalStateCfg.has_value()) {
localDataPoolMap.emplace(thermalStateCfg.value().thermalStatePoolId,
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>());
@ -1485,7 +1485,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
if (executingTask != nullptr) {
pstIntervalMs = executingTask->getPeriodMs();
}
this->poolManager.initializeAfterTaskCreation();
//this->poolManager.initializeAfterTaskCreation();
if (thermalStateCfg.has_value()) {
ThermalStateCfg& cfg = thermalStateCfg.value();
@ -1497,20 +1497,11 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
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(); }
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 {
if (cookieInfo.pendingCommand != deviceCommandMap.end()) {
@ -1519,17 +1510,6 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
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,
ReturnValue_t errorCode, const char* errorPrint) {
if (errorPrint == nullptr) {
@ -1570,7 +1550,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType, const ch
}
}
LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() { return &poolManager; }
PeriodicHkGenerationHelper* DeviceHandlerBase::getHkManagerHandle() { return &periodicHkHelper; }
MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyId) const {
auto commandIter = deviceCommandMap.find(replyId);

View File

@ -11,8 +11,8 @@
#include "fsfw/action/ActionHelper.h"
#include "fsfw/action/HasActionsIF.h"
#include "fsfw/datapool/PoolVariableIF.h"
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationIF.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationHelper.h"
#include "fsfw/health/HealthHelper.h"
#include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/modes/HasModesIF.h"
@ -88,7 +88,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
public ModeTreeChildIF,
public ModeTreeConnectionIF,
public ReceivesParameterMessagesIF,
public HasLocalDataPoolIF {
public PeriodicHkGenerationIF {
friend void(Factory::setStaticFrameworkObjectIds)();
public:
@ -608,7 +608,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
* @return
*/
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
PeriodicHkGenerationHelper &poolManager) override;
/**
* @brief Set all datapool variables that are update periodically in
* normal mode invalid
@ -619,15 +619,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
* method optionally.
*/
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 */
virtual void startTransition(Mode_t mode, Submode_t submode) override;
@ -806,7 +797,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
/* Action helper for HasActionsIF */
ActionHelper actionHelper;
/* Housekeeping Manager */
LocalDataPoolManager poolManager;
PeriodicHkGenerationHelper periodicHkHelper;
/**
* @brief Information about commands
@ -1010,7 +1001,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
* Required for HasLocalDataPoolIF, return a handle to the local pool manager.
* @return
*/
LocalDataPoolManager *getHkManagerHandle() override;
PeriodicHkGenerationHelper *getHkManagerHandle() override;
const HasHealthIF *getOptHealthIF() const override;
const HasModesIF &getModeIF() const override;
@ -1403,7 +1394,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message);
virtual dur_millis_t getPeriodicOperationFrequency() const override;
// virtual dur_millis_t getPeriodicOperationFrequency() const override;
void parseReply(const uint8_t *receivedData, size_t receivedDataLen);

View File

@ -7,7 +7,7 @@
class DeviceHandlerThermalSet : public StaticLocalDataSet<2> {
public:
DeviceHandlerThermalSet(HasLocalDataPoolIF* hkOwner, ThermalStateCfg cfg)
DeviceHandlerThermalSet(PeriodicHkGenerationIF* hkOwner, ThermalStateCfg cfg)
: DeviceHandlerThermalSet(hkOwner->getObjectId(), cfg) {}
DeviceHandlerThermalSet(object_id_t deviceHandler, ThermalStateCfg cfg)

View File

@ -128,14 +128,14 @@ ReturnValue_t FreshDeviceHandlerBase::connectModeTreeParent(HasModeTreeChildrenI
void FreshDeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
// Pool Manager overrides.
LocalDataPoolManager* FreshDeviceHandlerBase::getHkManagerHandle() { return &poolManager; }
PeriodicHkGenerationHelper* FreshDeviceHandlerBase::getHkManagerHandle() { return &poolManager; }
[[nodiscard]] uint32_t FreshDeviceHandlerBase::getPeriodicOperationFrequency() const {
return this->executingTask->getPeriodMs();
}
//[[nodiscard]] uint32_t FreshDeviceHandlerBase::getPeriodicOperationFrequency() const {
// return this->executingTask->getPeriodMs();
//}
ReturnValue_t FreshDeviceHandlerBase::initializeAfterTaskCreation() {
return poolManager.initializeAfterTaskCreation();
//return poolManager.initializeAfterTaskCreation();
}
ReturnValue_t FreshDeviceHandlerBase::setHealth(HasHealthIF::HealthState health) {

View File

@ -1,8 +1,8 @@
#pragma once
#include "fsfw/action.h"
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationIF.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationHelper.h"
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
#include "fsfw/fdir/FailureIsolationBase.h"
#include "fsfw/health/HasHealthIF.h"
@ -34,7 +34,7 @@ class FreshDeviceHandlerBase : public SystemObject,
public ModeTreeConnectionIF,
public HasActionsIF,
public ReceivesParameterMessagesIF,
public HasLocalDataPoolIF {
public PeriodicHkGenerationIF {
public:
explicit FreshDeviceHandlerBase(DhbConfig config);
~FreshDeviceHandlerBase() override;
@ -56,16 +56,16 @@ class FreshDeviceHandlerBase : public SystemObject,
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
ModeTreeChildIF& getModeTreeChildIF() override;
[[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
// [[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
protected:
// Pool Manager overrides.
LocalDataPoolManager* getHkManagerHandle() override;
PeriodicHkGenerationHelper* getHkManagerHandle() override;
ActionHelper actionHelper;
ModeHelper modeHelper;
HealthHelper healthHelper;
ParameterHelper paramHelper;
LocalDataPoolManager poolManager;
PeriodicHkGenerationHelper poolManager;
bool hasCustomFdir = false;
FailureIsolationBase* fdirInstance;
@ -116,9 +116,8 @@ class FreshDeviceHandlerBase : public SystemObject,
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) = 0;
// HK manager abstract functions.
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override = 0;
PeriodicHkGenerationHelper& poolManager) override = 0;
// Mode abstract functions
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,

View File

@ -1,5 +1,7 @@
#include "fsfw/housekeeping/HousekeepingMessage.h"
#include <fsfw/timemanager/clockDefinitions.h>
#include <cstring>
#include "fsfw/objectmanager/ObjectManager.h"
@ -59,11 +61,9 @@ void HousekeepingMessage::setCollectionIntervalModificationCommand(CommandMessag
}
sid_t HousekeepingMessage::getCollectionIntervalModificationCommand(const CommandMessage *command,
float *newCollectionInterval) {
if (newCollectionInterval != nullptr) {
std::memcpy(newCollectionInterval, command->getData() + 2 * sizeof(uint32_t),
sizeof(*newCollectionInterval));
}
dur_millis_t& newCollectionIntervalMs) {
std::memcpy(&newCollectionIntervalMs, command->getData() + 2 * sizeof(uint32_t),
sizeof(newCollectionIntervalMs));
return getSid(command);
}
@ -111,13 +111,10 @@ void HousekeepingMessage::clear(CommandMessage *message) {
switch (message->getCommand()) {
case (HK_REPORT):
case (DIAGNOSTICS_REPORT):
case (HK_DEFINITIONS_REPORT):
case (UPDATE_SNAPSHOT_SET):
case (UPDATE_SNAPSHOT_VARIABLE): {
case (HK_DEFINITIONS_REPORT): {
store_address_t storeId;
getHkDataReply(message, &storeId);
StorageManagerIF *ipcStore =
ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
auto *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore != nullptr) {
ipcStore->deleteData(storeId);
}
@ -126,32 +123,6 @@ void HousekeepingMessage::clear(CommandMessage *message) {
message->setCommand(CommandMessage::CMD_NONE);
}
void HousekeepingMessage::setUpdateNotificationSetCommand(CommandMessage *command, sid_t sid) {
command->setCommand(UPDATE_NOTIFICATION_SET);
setSid(command, sid);
}
void HousekeepingMessage::setUpdateNotificationVariableCommand(CommandMessage *command,
gp_id_t globalPoolId) {
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);
}

View File

@ -1,6 +1,8 @@
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGMESSAGE_H_
#include <fsfw/timemanager/clockDefinitions.h>
#include "fsfw/datapoollocal/localPoolDefinitions.h"
#include "fsfw/ipc/CommandMessage.h"
#include "fsfw/ipc/FwMessageTypes.h"
@ -44,11 +46,11 @@ class HousekeepingMessage {
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 UPDATE_NOTIFICATION_SET = MAKE_COMMAND_ID(130);
static constexpr Command_t UPDATE_NOTIFICATION_VARIABLE = MAKE_COMMAND_ID(131);
// 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_SNAPSHOT_SET = MAKE_COMMAND_ID(132);
static constexpr Command_t UPDATE_SNAPSHOT_VARIABLE = MAKE_COMMAND_ID(133);
// 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_HK_REPORT = MAKE_COMMAND_ID(134);
@ -81,7 +83,7 @@ class HousekeepingMessage {
*/
static sid_t getHkDataReply(const CommandMessage* message, store_address_t* storeIdToSet);
static sid_t getCollectionIntervalModificationCommand(const CommandMessage* command,
float* newCollectionInterval);
dur_millis_t& newCollectionInterval);
/* Update Notification Messages */

View File

@ -1,6 +1,8 @@
#ifndef FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
#define FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
#include <fsfw/serialize/SerialBufferAdapter.h>
#include "../datapoollocal/LocalPoolDataSetBase.h"
#include "../serialize/SerialLinkedListAdapter.h"
#include "../storagemanager/StorageManagerIF.h"
@ -18,8 +20,8 @@
*/
class HousekeepingPacketDownlink : public SerialLinkedListAdapter<SerializeIF> {
public:
HousekeepingPacketDownlink(sid_t sid, LocalPoolDataSetBase* dataSetPtr)
: sourceId(sid.objectId), setId(sid.ownerSetId), hkData(dataSetPtr) {
HousekeepingPacketDownlink(sid_t sid, const uint8_t* hkData, size_t hkDataLen)
: sourceId(sid.objectId), setId(sid.ownerSetId), hkData(hkData, hkDataLen) {
setLinks();
}
@ -32,7 +34,7 @@ class HousekeepingPacketDownlink : public SerialLinkedListAdapter<SerializeIF> {
SerializeElement<object_id_t> sourceId;
SerializeElement<uint32_t> setId;
LinkedElement<SerializeIF> hkData;
SerializeElement<SerialBufferAdapter<uint32_t>> hkData;
};
#endif /* FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ */

View File

@ -7,13 +7,12 @@
class HousekeepingSetPacket : public SerialLinkedListAdapter<SerializeIF> {
public:
HousekeepingSetPacket(sid_t sid, bool reportingEnabled, bool valid, float collectionInterval,
HousekeepingSetPacket(sid_t sid, bool reportingEnabled, dur_millis_t collectionIntervalMs,
LocalPoolDataSetBase* dataSetPtr)
: objectId(sid.objectId),
setId(sid.ownerSetId),
reportingEnabled(reportingEnabled),
valid(valid),
collectionIntervalSeconds(collectionInterval),
collectionIntervalMs(collectionIntervalMs),
dataSet(dataSetPtr) {
setLinks();
}
@ -28,7 +27,7 @@ class HousekeepingSetPacket : public SerialLinkedListAdapter<SerializeIF> {
return dataSet->serializeLocalPoolIds(buffer, size, maxSize, streamEndianness);
}
size_t getSerializedSize() const override {
[[nodiscard]] size_t getSerializedSize() const override {
size_t linkedSize = SerialLinkedListAdapter::getSerializedSize();
linkedSize += dataSet->getLocalPoolIdsSerializedSize();
return linkedSize;
@ -44,16 +43,14 @@ class HousekeepingSetPacket : public SerialLinkedListAdapter<SerializeIF> {
setStart(&objectId);
objectId.setNext(&setId);
setId.setNext(&reportingEnabled);
reportingEnabled.setNext(&valid);
valid.setNext(&collectionIntervalSeconds);
collectionIntervalSeconds.setEnd();
reportingEnabled.setNext(&collectionIntervalMs);
collectionIntervalMs.setEnd();
}
SerializeElement<object_id_t> objectId;
SerializeElement<uint32_t> setId;
SerializeElement<bool> reportingEnabled;
SerializeElement<bool> valid;
SerializeElement<float> collectionIntervalSeconds;
SerializeElement<uint32_t> collectionIntervalMs;
LocalPoolDataSetBase* dataSet;
};

View File

@ -4,19 +4,20 @@
#include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.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)> {
public:
static constexpr uint8_t ERROR_SET_ID = 0;
InternalErrorDataset(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, ERROR_SET_ID) {}
InternalErrorDataset(PeriodicHkGenerationIF* owner) : StaticLocalDataSet(owner, ERROR_SET_ID) {}
InternalErrorDataset(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, ERROR_SET_ID)) {}
lp_var_t<uint32_t> tmHits = lp_var_t<uint32_t>(sid.objectId, TM_HITS, this);
lp_var_t<uint32_t> queueHits = lp_var_t<uint32_t>(sid.objectId, QUEUE_HITS, this);
lp_var_t<uint32_t> storeHits = lp_var_t<uint32_t>(sid.objectId, STORE_HITS, this);
lp_var_t<uint8_t> valid = lp_var_t<uint8_t>(sid.objectId, VALID, this);
};
#endif /* FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ */

View File

@ -6,7 +6,8 @@
#include "fsfw/serviceinterface/ServiceInterface.h"
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth,
bool enableSetByDefault, float generationFrequency)
bool enableSetByDefault,
dur_millis_t generationFrequency)
: SystemObject(setObjectId),
poolManager(this, commandQueue),
enableSetByDefault(enableSetByDefault),
@ -15,7 +16,7 @@ InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t m
internalErrorDataset(this) {
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
mutex = MutexFactory::instance()->createMutex();
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
auto mqArgs = MqArgs(setObjectId, this);
commandQueue = QueueFactory::instance()->createMessageQueue(
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
}
@ -64,10 +65,7 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
internalErrorDataset.queueHits.value += newQueueHits;
internalErrorDataset.storeHits.value += newStoreHits;
internalErrorDataset.tmHits.value += newTmHits;
internalErrorDataset.setValidity(true, true);
if ((newQueueHits != 0) or (newStoreHits != 0) or (newTmHits != 0)) {
internalErrorDataset.setChanged(true);
}
internalErrorDataset.valid = true;
}
}
@ -132,24 +130,23 @@ MessageQueueId_t InternalErrorReporter::getCommandQueue() const {
return this->commandQueue->getId();
}
ReturnValue_t InternalErrorReporter::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
ReturnValue_t InternalErrorReporter::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, PeriodicHkGenerationHelper &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);
poolManager.enableRegularPeriodicPacket(internalErrorSid, generationFrequency);
internalErrorDataset.valid = false;
return returnvalue::OK;
}
dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const {
return this->executingTask->getPeriodMs();
}
// dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const {
// return this->executingTask->getPeriodMs();
//}
LocalPoolDataSetBase *InternalErrorReporter::getDataSetHandle(sid_t sid) {
return &internalErrorDataset;
}
// LocalPoolDataSetBase *InternalErrorReporter::getDataSetHandle(sid_t sid) {
// return &internalErrorDataset;
//}
void InternalErrorReporter::setTaskIF(PeriodicTaskIF *task) { this->executingTask = task; }
@ -162,7 +159,7 @@ ReturnValue_t InternalErrorReporter::initialize() {
}
ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() {
return poolManager.initializeAfterTaskCreation();
//return poolManager.initializeAfterTaskCreation();
}
void InternalErrorReporter::setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
@ -170,4 +167,19 @@ void InternalErrorReporter::setMutexTimeout(MutexIF::TimeoutType timeoutType, ui
this->timeoutMs = timeoutMs;
}
LocalDataPoolManager *InternalErrorReporter::getHkManagerHandle() { return &poolManager; }
PeriodicHkGenerationHelper *InternalErrorReporter::getHkManagerHandle() { return &poolManager; }
ReturnValue_t InternalErrorReporter::serializeDataset(sid_t structureId, uint8_t *buf,
size_t maxSize) {
if (structureId == internalErrorDataset.getSid()) {
size_t serSize = 0;
internalErrorDataset.serialize(buf, serSize, maxSize, SerializeIF::Endianness::NETWORK);
}
}
ReturnValue_t InternalErrorReporter::specifyDatasets(
std::vector<periodicHk::SetSpecification> &setSpecification) {
setSpecification.emplace_back(internalErrorDataset.getSid(),
internalErrorDataset.getSerializedSize());
return returnvalue::OK;
}

View File

@ -2,7 +2,7 @@
#define FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_
#include "InternalErrorReporterIF.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationHelper.h"
#include "fsfw/internalerror/InternalErrorDataset.h"
#include "fsfw/ipc/MutexIF.h"
#include "fsfw/objectmanager/SystemObject.h"
@ -19,10 +19,10 @@
class InternalErrorReporter : public SystemObject,
public ExecutableObjectIF,
public InternalErrorReporterIF,
public HasLocalDataPoolIF {
public PeriodicHkGenerationIF {
public:
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
@ -38,10 +38,16 @@ class InternalErrorReporter : public SystemObject,
virtual object_id_t getObjectId() const override;
virtual 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;
PeriodicHkGenerationHelper& poolManager) override;
// virtual dur_millis_t getPeriodicOperationFrequency() const override;
virtual ReturnValue_t serializeDataset(sid_t structureId, uint8_t* buf, size_t maxSize) override;
virtual ReturnValue_t specifyDatasets(
std::vector<periodicHk::SetSpecification>& setSpecification) override;
// virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
PeriodicHkGenerationHelper* getHkManagerHandle() override;
virtual ReturnValue_t initialize() override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
@ -57,7 +63,7 @@ class InternalErrorReporter : public SystemObject,
protected:
MessageQueueIF* commandQueue;
LocalDataPoolManager poolManager;
PeriodicHkGenerationHelper poolManager;
PeriodicTaskIF* executingTask = nullptr;
@ -65,7 +71,7 @@ class InternalErrorReporter : public SystemObject,
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t timeoutMs = 20;
bool enableSetByDefault;
float generationFrequency;
dur_millis_t generationFrequency;
sid_t internalErrorSid;
InternalErrorDataset internalErrorDataset;

View File

@ -59,9 +59,6 @@ class MonitorBase : public MonitorReporter<T> {
if (result != returnvalue::OK) {
return result;
}
if (not poolVariable.isValid()) {
return MonitoringIF::INVALID;
}
*sample = poolVariable.value;
return returnvalue::OK;
}

View File

@ -8,19 +8,15 @@
object_id_t Fuse::powerSwitchId = 0;
Fuse::Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,
float maxCurrent, uint16_t confirmationCount)
Fuse::Fuse(object_id_t ownerId, object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet,
VariableIds ids, float maxCurrent, uint16_t confirmationCount)
: SystemObject(fuseObjectId),
oldFuseState(0),
fuseId(fuseId),
currentLimit(fuseObjectId, 1, ids.pidCurrent, confirmationCount, maxCurrent,
FUSE_CURRENT_HIGH),
powerMonitor(fuseObjectId, 2, ids.poolIdPower, confirmationCount),
set(variableSet),
voltage(ids.pidVoltage, &set),
current(ids.pidCurrent, &set),
state(ids.pidState, &set),
power(ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE),
set(ownerId),
parameterHelper(this),
healthHelper(this, fuseObjectId) {
commandQueue = QueueFactory::instance()->createMessageQueue();
@ -63,20 +59,20 @@ ReturnValue_t Fuse::check() {
set.read();
if (!healthHelper.healthTable->isHealthy(getObjectId())) {
setAllMonitorsToUnchecked();
set.setValidity(false, true);
set.setValid = false;
return set.commit();
}
ReturnValue_t result = returnvalue::OK;
checkFuseState();
calculateFusePower();
// Check if power is valid and if fuse state is off or invalid.
if (!power.isValid() || (state == 0) || !state.isValid()) {
if (!set.setValid.value || (set.state == 0)) {
result = powerMonitor.setToInvalid();
} else {
float lowLimit = 0.0;
float highLimit = RESIDUAL_POWER;
calculatePowerLimits(&lowLimit, &highLimit);
result = powerMonitor.checkPower(power.value, lowLimit, highLimit);
result = powerMonitor.checkPower(set.power.value, lowLimit, highLimit);
if (result == MonitoringIF::BELOW_LOW_LIMIT) {
reportEvents(POWER_BELOW_LOW_LIMIT);
} else if (result == MonitoringIF::ABOVE_HIGH_LIMIT) {
@ -122,13 +118,12 @@ uint8_t Fuse::getFuseId() const { return fuseId; }
void Fuse::calculateFusePower() {
ReturnValue_t result1 = currentLimit.check();
if (result1 != returnvalue::OK || !(voltage.isValid())) {
power.setValid(PoolVariableIF::INVALID);
return;
if (result1 != returnvalue::OK || !(set.setValid.value)) {
set.powerValid = false;
}
// Calculate fuse power.
power.value = current.value * voltage.value;
power.setValid(PoolVariableIF::VALID);
set.power = set.current.value * set.voltage.value;
set.powerValid = true;
}
ReturnValue_t Fuse::performOperation(uint8_t opCode) {
@ -173,21 +168,21 @@ void Fuse::checkCommandQueue() {
}
void Fuse::checkFuseState() {
if (!state.isValid()) {
if (!set.setValid.value) {
oldFuseState = 0;
return;
}
if (state == 0) {
if (set.state == 0) {
if (oldFuseState != 0) {
reportEvents(FUSE_WENT_OFF);
}
}
oldFuseState = state.value;
oldFuseState = set.state.value;
}
float Fuse::getPower() {
if (power.isValid()) {
return power.value;
if (set.powerValid.value) {
return set.power.value;
} else {
return 0.0;
}
@ -195,7 +190,8 @@ float Fuse::getPower() {
void Fuse::setDataPoolEntriesInvalid() {
set.read();
set.setValidity(false, true);
set.setValid = false;
set.powerValid = false;
set.commit();
}
@ -223,7 +219,7 @@ bool Fuse::areSwitchesOfComponentOn(DeviceList::iterator iter) {
return true;
}
bool Fuse::isPowerValid() { return power.isValid(); }
bool Fuse::isPowerValid() { return set.powerValid.value; }
ReturnValue_t Fuse::setHealth(HealthState health) {
healthHelper.setHealth(health);

View File

@ -14,6 +14,32 @@ namespace Factory {
void setStaticFrameworkObjectIds();
}
enum FusePoolId {
VOLTAGE = 0,
CURRENT = 1,
STATE = 2,
POWER = 3,
POWER_VALID = 4,
SET_VALID = 5
};
class FuseSet : public StaticLocalDataSet<6> {
public:
static constexpr uint8_t FUSE_SET_ID = 0;
FuseSet(PeriodicHkGenerationIF *owner) : StaticLocalDataSet(owner, FUSE_SET_ID) {}
FuseSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, FUSE_SET_ID)) {}
lp_var_t<float> voltage = lp_var_t<float>(sid.objectId, FusePoolId::VOLTAGE, this);
lp_var_t<float> current = lp_var_t<float>(sid.objectId, FusePoolId::CURRENT, this);
lp_var_t<uint8_t> state = lp_var_t<uint8_t>(sid.objectId, FusePoolId::STATE, this);
lp_var_t<float> power = lp_var_t<float>(sid.objectId, FusePoolId::POWER, this);
lp_var_t<uint8_t> powerValid = lp_var_t<uint8_t>(sid.objectId, FusePoolId::POWER_VALID, this);
lp_var_t<uint8_t> setValid = lp_var_t<uint8_t>(sid.objectId, FusePoolId::SET_VALID, this);
};
class Fuse : public SystemObject,
public HasHealthIF,
public ReceivesParameterMessagesIF,
@ -43,8 +69,8 @@ class Fuse : public SystemObject,
static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW);
typedef std::list<PowerComponentIF *> DeviceList;
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,
float maxCurrent, uint16_t confirmationCount = 2);
Fuse(object_id_t ownerId, object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet,
VariableIds ids, float maxCurrent, uint16_t confirmationCount = 2);
virtual ~Fuse();
void addDevice(PowerComponentIF *set);
float getPower();
@ -83,13 +109,8 @@ class Fuse : public SystemObject,
void sendTransitionEvent(float currentValue, ReturnValue_t state) {}
};
PowerMonitor powerMonitor;
StaticLocalDataSet<3> set;
lp_var_t<float> voltage;
lp_var_t<float> current;
lp_var_t<uint8_t> state;
lp_var_t<float> power;
FuseSet set;
MessageQueueIF *commandQueue = nullptr;
ParameterHelper parameterHelper;
HealthHelper healthHelper;

View File

@ -1,5 +1,6 @@
#include "fsfw/power/PowerSensor.h"
#include "definitions.h"
#include "fsfw/ipc/QueueFactory.h"
PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, DefaultLimits limits,
@ -7,10 +8,8 @@ PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, Def
: SystemObject(objectId),
parameterHelper(this),
healthHelper(this, objectId),
powerSensorSet(setId),
current(ids.pidCurrent, &powerSensorSet),
voltage(ids.pidVoltage, &powerSensorSet),
power(ids.poolIdPower, &powerSensorSet, PoolVariableIF::VAR_WRITE),
powerSensorSet(objectId),
// valid(ids.valid, &powerSensorSet),
currentLimit(objectId, MODULE_ID_CURRENT, ids.pidCurrent, confirmationCount,
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
@ -24,10 +23,9 @@ ReturnValue_t PowerSensor::calculatePower() {
powerSensorSet.read();
ReturnValue_t result1 = returnvalue::FAILED;
ReturnValue_t result2 = returnvalue::FAILED;
if (healthHelper.healthTable->isHealthy(getObjectId()) && voltage.isValid() &&
current.isValid()) {
result1 = voltageLimit.doCheck(voltage.value);
result2 = currentLimit.doCheck(current.value);
if (healthHelper.healthTable->isHealthy(getObjectId()) && powerSensorSet.setIsValid.value) {
result1 = voltageLimit.doCheck(powerSensorSet.voltage.value);
result2 = currentLimit.doCheck(powerSensorSet.current.value);
} else {
voltageLimit.setToInvalid();
currentLimit.setToInvalid();
@ -35,10 +33,10 @@ ReturnValue_t PowerSensor::calculatePower() {
}
if (result1 != returnvalue::OK || result2 != returnvalue::OK) {
result1 = MonitoringIF::INVALID;
power.setValid(PoolVariableIF::INVALID);
powerSensorSet.setIsValid = false;
} else {
power.setValid(PoolVariableIF::VALID);
power.value = current.value * voltage.value;
powerSensorSet.setIsValid = true;
powerSensorSet.power = powerSensorSet.current.value * powerSensorSet.voltage.value;
}
powerSensorSet.commit();
return result1;
@ -92,13 +90,13 @@ void PowerSensor::checkCommandQueue() {
void PowerSensor::setDataPoolEntriesInvalid() {
powerSensorSet.read();
powerSensorSet.setValidity(false, true);
powerSensorSet.setIsValid = false;
powerSensorSet.commit();
}
float PowerSensor::getPower() {
if (power.isValid()) {
return power.value;
if (powerSensorSet.setIsValid.value) {
return powerSensorSet.power.value;
} else {
return 0.0;
}

View File

@ -10,6 +10,27 @@
class PowerController;
enum PowerSensorPoolId {
CURRENT = 0,
VOLTAGE = 1,
POWER = 2,
SET_VALID = 3
};
class PowerSensorSet : public StaticLocalDataSet<6> {
public:
static constexpr uint8_t POWER_SENSOR_SET_ID = 0;
PowerSensorSet(PeriodicHkGenerationIF *owner) : StaticLocalDataSet(owner, POWER_SENSOR_SET_ID) {}
PowerSensorSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, POWER_SENSOR_SET_ID)) {}
lp_var_t<float> current = lp_var_t<float>(sid.objectId, PowerSensorPoolId::CURRENT, this);
lp_var_t<float> voltage = lp_var_t<float>(sid.objectId, PowerSensorPoolId::VOLTAGE, this);
lp_var_t<float> power = lp_var_t<float>(sid.objectId, PowerSensorPoolId::POWER, this);
lp_var_t<uint8_t> setIsValid =
lp_var_t<uint8_t>(sid.objectId, PowerSensorPoolId::SET_VALID, this);
};
/**
* @brief Does magic.
*/
@ -21,6 +42,7 @@ class PowerSensor : public SystemObject, public ReceivesParameterMessagesIF, pub
gp_id_t pidCurrent;
gp_id_t pidVoltage;
gp_id_t poolIdPower;
gp_id_t valid;
};
struct DefaultLimits {
float currentMin;
@ -53,16 +75,7 @@ class PowerSensor : public SystemObject, public ReceivesParameterMessagesIF, pub
MessageQueueIF *commandQueue = nullptr;
ParameterHelper parameterHelper;
HealthHelper healthHelper;
// GlobDataSet set;
StaticLocalDataSet<3> powerSensorSet;
// Variables in
lp_var_t<float> current;
lp_var_t<float> voltage;
// PIDReader<float> current;
// PIDReader<float> voltage;
// Variables out
lp_var_t<float> power;
// gp_float_t power;
PowerSensorSet powerSensorSet;
static const uint8_t MODULE_ID_CURRENT = 1;
static const uint8_t MODULE_ID_VOLTAGE = 2;

View File

@ -1,6 +1,6 @@
#include "fsfw/pus/Service3Housekeeping.h"
#include "fsfw/datapoollocal/HasLocalDataPoolIF.h"
#include "fsfw/datapoollocal/PeriodicHkGenerationIF.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/pus/servicepackets/Service3Packets.h"
@ -58,8 +58,8 @@ ReturnValue_t Service3Housekeeping::checkAndAcquireTargetID(object_id_t* objectI
ReturnValue_t Service3Housekeeping::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
// check HasLocalDataPoolIF property of target
HasLocalDataPoolIF* possibleTarget =
ObjectManager::instance()->get<HasLocalDataPoolIF>(*objectId);
PeriodicHkGenerationIF* possibleTarget =
ObjectManager::instance()->get<PeriodicHkGenerationIF>(*objectId);
if (possibleTarget == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}

View File

@ -26,7 +26,7 @@ ReturnValue_t ThermalComponent::setTargetState(int8_t newState) {
switch (newState) {
case STATE_REQUEST_NON_OPERATIONAL:
targetState = newState;
targetState.setValid(true);
// targetState.setValid(true);
targetState.commit(PoolVariableIF::VALID);
return returnvalue::OK;
default:

View File

@ -20,7 +20,7 @@ ThermalComponentCore::ThermalComponentCore(object_id_t reportingObjectId, uint8_
ReturnValue_t result = targetState.read();
if (result == returnvalue::OK) {
targetState = initialTargetState;
targetState.setValid(true);
// targetState.setValid(true);
targetState.commit();
}
targetState.setReadWriteMode(PoolVariableIF::VAR_READ);
@ -59,20 +59,20 @@ ThermalComponentIF::HeaterRequest ThermalComponentCore::performOperation(uint8_t
temperature = getTemperature();
updateMinMaxTemp();
if (temperature != thermal::INVALID_TEMPERATURE) {
temperature.setValid(PoolVariableIF::VALID);
// temperature.setValid(PoolVariableIF::VALID);
State state = getState(temperature.value, getParameters(), targetState.value);
currentState = state;
checkLimits(state);
request = getHeaterRequest(targetState.value, temperature.value, getParameters());
} else {
temperatureMonitor.setToInvalid();
temperature.setValid(PoolVariableIF::INVALID);
// temperature.setValid(PoolVariableIF::INVALID);
currentState = UNKNOWN;
request = HEATER_DONT_CARE;
}
currentState.setValid(PoolVariableIF::VALID);
// currentState.setValid(PoolVariableIF::VALID);
heaterRequest = request;
heaterRequest.setValid(PoolVariableIF::VALID);
// heaterRequest.setValid(PoolVariableIF::VALID);
return request;
}
@ -104,17 +104,17 @@ ReturnValue_t ThermalComponentCore::setTargetState(int8_t newState) {
default:
return INVALID_TARGET_STATE;
}
targetState.setValid(true);
// targetState.setValid(true);
targetState.commit();
return returnvalue::OK;
}
void ThermalComponentCore::setOutputInvalid() {
temperature = thermal::INVALID_TEMPERATURE;
temperature.setValid(PoolVariableIF::INVALID);
currentState.setValid(PoolVariableIF::INVALID);
// temperature.setValid(PoolVariableIF::INVALID);
// currentState.setValid(PoolVariableIF::INVALID);
heaterRequest = HEATER_DONT_CARE;
heaterRequest.setValid(PoolVariableIF::INVALID);
// heaterRequest.setValid(PoolVariableIF::INVALID);
temperatureMonitor.setToUnchecked();
}

View File

@ -87,12 +87,13 @@ void ThermalModule::calculateTemperature() {
numberOfValidSensors++;
}
}
// TODO: Reintroduce validity.
if (numberOfValidSensors != 0) {
moduleTemperature = moduleTemperature.value / numberOfValidSensors;
moduleTemperature.setValid(PoolVariableIF::VALID);
// moduleTemperature.setValid(PoolVariableIF::VALID);
} else {
moduleTemperature.value = thermal::INVALID_TEMPERATURE;
moduleTemperature.setValid(PoolVariableIF::INVALID);
// moduleTemperature.setValid(PoolVariableIF::INVALID);
}
}
@ -194,7 +195,7 @@ void ThermalModule::initialize(PowerSwitchIF* powerSwitch) {
}
bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus(Strategy strategy) {
currentState.setValid(PoolVariableIF::VALID);
// currentState.setValid(PoolVariableIF::VALID);
if (moduleTemperature == thermal::INVALID_TEMPERATURE) {
currentState = UNKNOWN;
return false;
@ -240,7 +241,7 @@ void ThermalModule::setHeating(bool on) {
targetState.value = STATE_REQUEST_PASSIVE;
}
}
targetState.setValid(true);
// targetState.setValid(true);
}
void ThermalModule::updateTargetTemperatures(ThermalComponentIF* component, bool isSafe) {
@ -257,9 +258,9 @@ void ThermalModule::updateTargetTemperatures(ThermalComponentIF* component, bool
void ThermalModule::setOutputInvalid() {
moduleTemperature = thermal::INVALID_TEMPERATURE;
moduleTemperature.setValid(PoolVariableIF::INVALID);
currentState.setValid(PoolVariableIF::INVALID);
std::list<ComponentData>::iterator iter = components.begin();
// moduleTemperature.setValid(PoolVariableIF::INVALID);
// currentState.setValid(PoolVariableIF::INVALID);
auto iter = components.begin();
for (; iter != components.end(); iter++) {
iter->component->setOutputInvalid();
}

View File

@ -210,27 +210,27 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
if (readSet.getReadResult() == returnvalue::OK) {
if (std::abs(angVelocX) < this->absLimitX) {
dataset.angVelocX = angVelocX;
dataset.angVelocX.setValid(true);
// dataset.angVelocX.setValid(true);
} else {
dataset.angVelocX.setValid(false);
// dataset.angVelocX.setValid(false);
}
if (std::abs(angVelocY) < this->absLimitY) {
dataset.angVelocY = angVelocY;
dataset.angVelocY.setValid(true);
// dataset.angVelocY.setValid(true);
} else {
dataset.angVelocY.setValid(false);
// dataset.angVelocY.setValid(false);
}
if (std::abs(angVelocZ) < this->absLimitZ) {
dataset.angVelocZ = angVelocZ;
dataset.angVelocZ.setValid(true);
// dataset.angVelocZ.setValid(true);
} else {
dataset.angVelocZ.setValid(false);
// dataset.angVelocZ.setValid(false);
}
dataset.temperature = temperature;
dataset.temperature.setValid(true);
// dataset.temperature.setValid(true);
}
break;
}
@ -247,12 +247,12 @@ uint32_t GyroHandlerL3GD20H::getTransitionDelayMs(Mode_t from, Mode_t to) {
void GyroHandlerL3GD20H::setToGoToNormalMode(bool enable) { this->goNormalModeImmediately = true; }
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_Y, 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}));
poolManager.subscribeForRegularPeriodicPacket(
hkGenHelper.enableRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(dataset.getSid(), false, 10.0));
return returnvalue::OK;
}

View File

@ -52,7 +52,7 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase {
void modeChanged() override;
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
PeriodicHkGenerationHelper &hkGenHelper) override;
private:
uint32_t transitionDelayMs = 0;

View File

@ -273,7 +273,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
if (readHelper.getReadResult() == returnvalue::OK) {
if (std::abs(mgmX) > absLimitX or std::abs(mgmY) > absLimitY or
std::abs(mgmZ) > absLimitZ) {
dataset.fieldStrengths.setValid(false);
dataset.setIsValid = false;
}
if (std::abs(mgmX) < absLimitX) {
dataset.fieldStrengths[0] = mgmX;
@ -286,7 +286,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
if (std::abs(mgmZ) < absLimitZ) {
dataset.fieldStrengths[2] = mgmZ;
}
dataset.fieldStrengths.setValid(true);
dataset.setIsValid = true;
}
break;
}
@ -416,10 +416,10 @@ uint32_t MgmLIS3MDLHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { retur
void MgmLIS3MDLHandler::modeChanged(void) { internalState = InternalState::STATE_NONE; }
ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
PeriodicHkGenerationHelper &poolManager) {
localDataPoolMap.emplace(mgmLis3::FIELD_STRENGTHS, &mgmXYZ);
localDataPoolMap.emplace(mgmLis3::TEMPERATURE_CELCIUS, &temperature);
poolManager.subscribeForRegularPeriodicPacket({dataset.getSid(), false, 10.0});
poolManager.setPeriodicFrequency(dataset.getSid(), 10'000);
return returnvalue::OK;
}

View File

@ -64,7 +64,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
void fillCommandAndReplyMap() override;
void modeChanged(void) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
PeriodicHkGenerationHelper &poolManager) override;
private:
mgmLis3::MgmPrimaryDataset dataset;

View File

@ -308,9 +308,9 @@ void MgmRM3100Handler::fillCommandAndReplyMap() {
void MgmRM3100Handler::modeChanged() { internalState = InternalState::NONE; }
ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
PeriodicHkGenerationHelper &poolManager) {
localDataPoolMap.emplace(mgmRm3100::FIELD_STRENGTHS, &mgmXYZ);
poolManager.subscribeForRegularPeriodicPacket({primaryDataset.getSid(), false, 10.0});
poolManager.setPeriodicFrequency(primaryDataset.getSid(), 10'000);
return returnvalue::OK;
}
@ -356,7 +356,7 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
primaryDataset.fieldStrengths[0] = fieldStrengthX;
primaryDataset.fieldStrengths[1] = fieldStrengthY;
primaryDataset.fieldStrengths[2] = fieldStrengthZ;
primaryDataset.setValidity(true, true);
primaryDataset.valid = true;
}
return returnvalue::OK;
}

View File

@ -53,7 +53,7 @@ class MgmRM3100Handler : public DeviceHandlerBase {
void modeChanged(void) override;
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
PeriodicHkGenerationHelper &poolManager) override;
private:
enum class InternalState {

View File

@ -124,7 +124,7 @@ class GyroPrimaryDataset : public StaticLocalDataSet<5> {
setAllVariablesReadOnly();
}
/** Constructor for the data creator */
GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner)
GyroPrimaryDataset(PeriodicHkGenerationIF* hkOwner)
: StaticLocalDataSet(hkOwner, l3gd20h::GYRO_DATASET_ID) {}
/* Angular velocities in degrees per second (DPS) */

View File

@ -169,11 +169,12 @@ static const uint8_t CTRL_REG5_DEFAULT = 0;
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> {
public:
MgmPrimaryDataset(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, MGM_DATA_SET_ID) {}
MgmPrimaryDataset(PeriodicHkGenerationIF* hkOwner)
: StaticLocalDataSet(hkOwner, 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_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

View File

@ -101,11 +101,12 @@ class CycleCountCommand : public SerialLinkedListAdapter<SerializeIF> {
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> {
public:
Rm3100PrimaryDataset(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, MGM_DATASET_ID) {}
Rm3100PrimaryDataset(PeriodicHkGenerationIF* hkOwner)
: StaticLocalDataSet(hkOwner, 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
*/
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

View File

@ -32,7 +32,7 @@ void Factory::produceFrameworkObjects(void* args) {
setStaticFrameworkObjectIds();
new EventManager(objects::EVENT_MANAGER, 80);
new HealthTable(objects::HEALTH_TABLE);
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER, 20, false, 5.0);
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER, 20, false, 5000);
{
PoolManager::LocalPoolConfig poolCfg = {{100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024}};
@ -57,7 +57,7 @@ void Factory::setStaticFrameworkObjectIds() {
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT;
PeriodicHkGenerationHelper::defaultHkDestination = objects::NO_OBJECT;
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
}

View File

@ -40,7 +40,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") {
SECTION("Basic Test") {
{
/* For code coverage, should not crash */
LocalDataPoolManager manager(nullptr, nullptr);
PeriodicHkGenerationHelper manager(nullptr, nullptr);
}
auto owner = poolOwner.poolManager.getOwner();
REQUIRE(owner != nullptr);
@ -150,7 +150,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") {
SECTION("VariableSnapshotTest") {
/* Acquire subscription interface */
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner.getSubscriptionInterface();
PeriodicHkGenerationProviderIF* subscriptionIF = poolOwner.getSubscriptionInterface();
REQUIRE(subscriptionIF != nullptr);
/* Subscribe for variable snapshot */
@ -208,7 +208,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") {
SECTION("VariableNotificationTest") {
/* Acquire subscription interface */
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner.getSubscriptionInterface();
PeriodicHkGenerationProviderIF* subscriptionIF = poolOwner.getSubscriptionInterface();
REQUIRE(subscriptionIF != nullptr);
/* Subscribe for variable update */

View File

@ -17,7 +17,7 @@ ReturnValue_t LocalPoolOwnerBase::initializeHkManager() {
}
ReturnValue_t LocalPoolOwnerBase::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
PeriodicHkGenerationHelper &poolManager) {
// Default initialization empty for now.
localDataPoolMap.emplace(lpool::uint8VarId, &u8PoolEntry);
localDataPoolMap.emplace(lpool::floatVarId, &floatPoolEntry);
@ -45,7 +45,7 @@ LocalPoolObjectBase *LocalPoolOwnerBase::getPoolObjectHandle(lp_id_t localPoolId
}
ReturnValue_t LocalPoolOwnerBase::reset() {
resetSubscriptionList();
// resetSubscriptionList();
ReturnValue_t status = returnvalue::OK;
{
PoolReadGuard readHelper(&dataset);
@ -57,7 +57,7 @@ ReturnValue_t LocalPoolOwnerBase::reset() {
dataset.localPoolUint16Vec.value[0] = 0;
dataset.localPoolUint16Vec.value[1] = 0;
dataset.localPoolUint16Vec.value[2] = 0;
dataset.setValidity(false, true);
// dataset.setValidity(false, true);
}
{
@ -66,7 +66,7 @@ ReturnValue_t LocalPoolOwnerBase::reset() {
status = readHelper.getReadResult();
}
testUint32.value = 0;
testUint32.setValid(false);
// testUint32.setValid(false);
}
{
@ -76,7 +76,7 @@ ReturnValue_t LocalPoolOwnerBase::reset() {
}
testInt64Vec.value[0] = 0;
testInt64Vec.value[1] = 0;
testInt64Vec.setValid(false);
// testInt64Vec.setValid(false);
}
return status;
}
@ -93,11 +93,13 @@ bool LocalPoolOwnerBase::changedDataSetCallbackWasCalled(sid_t &sid, store_addre
return condition;
}
/*
void LocalPoolOwnerBase::handleChangedDataset(sid_t sid, store_address_t storeId,
bool *clearMessage) {
this->changedDatasetSid = sid;
this->storeIdForChangedSet = storeId;
}
*/
bool LocalPoolOwnerBase::changedVariableCallbackWasCalled(gp_id_t &gpid, store_address_t &storeId) {
bool condition = false;
@ -119,10 +121,12 @@ ReturnValue_t LocalPoolOwnerBase::initializeHkManagerAfterTaskCreation() {
return returnvalue::OK;
}
/*
void LocalPoolOwnerBase::handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
bool *clearMessage) {
this->changedPoolVariableGpid = globPoolId;
this->storeIdForChangedVariable = storeId;
}
*/
void LocalPoolOwnerBase::setHkDestId(MessageQueueId_t id) { poolManager.setHkDestinationId(id); }

View File

@ -37,7 +37,7 @@ class LocalPoolStaticTestDataSet : public StaticLocalDataSet<3> {
public:
LocalPoolStaticTestDataSet() : StaticLocalDataSet(lpool::testSid) {}
LocalPoolStaticTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId)
LocalPoolStaticTestDataSet(PeriodicHkGenerationIF* owner, uint32_t setId)
: StaticLocalDataSet(owner, setId) {}
lp_var_t<uint8_t> localPoolVarUint8 = lp_var_t<uint8_t>(lpool::uint8VarGpid, this);
@ -51,7 +51,7 @@ class LocalPoolTestDataSet : public LocalDataSet {
public:
LocalPoolTestDataSet() : LocalDataSet(lpool::testSid, lpool::dataSetMaxVariables) {}
LocalPoolTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId)
LocalPoolTestDataSet(PeriodicHkGenerationIF* owner, uint32_t setId)
: LocalDataSet(owner, setId, lpool::dataSetMaxVariables) {}
lp_var_t<uint8_t> localPoolVarUint8 = lp_var_t<uint8_t>(lpool::uint8VarGpid, this);
@ -61,7 +61,7 @@ class LocalPoolTestDataSet : public LocalDataSet {
private:
};
class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
class LocalPoolOwnerBase : public SystemObject, public PeriodicHkGenerationIF {
public:
explicit LocalPoolOwnerBase(MessageQueueIF& queue,
object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE);
@ -81,11 +81,11 @@ class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
// This is called by initializeAfterTaskCreation of the HK manager.
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
PeriodicHkGenerationHelper& poolManager) override;
LocalDataPoolManager* getHkManagerHandle() override { return &poolManager; }
PeriodicHkGenerationHelper* getHkManagerHandle() override { return &poolManager; }
[[nodiscard]] dur_millis_t getPeriodicOperationFrequency() const override { return 200; }
//[[nodiscard]] dur_millis_t getPeriodicOperationFrequency() const override { return 200; }
/**
* This function is used by the pool manager to get a valid dataset
@ -102,7 +102,7 @@ class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
}
ReturnValue_t subscribePeriodicHk(bool enableReporting) {
return poolManager.subscribeForRegularPeriodicPacket(
return poolManager.enableRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(lpool::testSid, enableReporting, 0.2));
}
@ -145,21 +145,21 @@ class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
ReturnValue_t reset();
void resetSubscriptionList() { poolManager.clearReceiversList(); }
// void resetSubscriptionList() { poolManager.clearReceiversList(); }
bool changedDataSetCallbackWasCalled(sid_t& sid, store_address_t& storeId);
bool changedVariableCallbackWasCalled(gp_id_t& gpid, store_address_t& storeId);
LocalDataPoolManager poolManager;
PeriodicHkGenerationHelper poolManager;
LocalPoolTestDataSet dataset;
private:
void handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) override;
// void handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) override;
sid_t changedDatasetSid;
store_address_t storeIdForChangedSet;
void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
bool* clearMessage) override;
// void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
// bool* clearMessage) override;
gp_id_t changedPoolVariableGpid;
store_address_t storeIdForChangedVariable;