diff --git a/CMakeLists.txt b/CMakeLists.txt index 9786d5728..7ef114939 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,9 +48,10 @@ add_library(${LIB_FSFW_NAME}) if(FSFW_BUILD_UNITTESTS) message(STATUS "Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first - find_package(Catch2 3) + find_package(Catch2 3 QUIET) # Not installed, so use FetchContent to download and provide Catch2 if(NOT Catch2_FOUND) + message(STATUS "Catch2 installation not found. Downloading Catch2 library with FetchContent") include(FetchContent) FetchContent_Declare( diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 69f6311e3..52b6dc07b 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -1,9 +1,6 @@ #include "MgmLIS3MDLHandler.h" #include "fsfw/datapool/PoolReadGuard.h" -#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 -#include "fsfw/globalfunctions/PeriodicOperationDivider.h" -#endif #include diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index acfa23c55..6053bd438 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -787,6 +787,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i // Serialize set packet into store. size_t size = 0; result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); + return result; + } if (expectedSize != size) { printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED, @@ -801,7 +805,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId); } - hkQueue->reply(&reply); + result = hkQueue->reply(&reply); + if(result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); + } return result; } diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 08a15d5ff..0e2802ac1 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -410,7 +410,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet, size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) { // No need to check, as we may try to insert multiple times. - insertInCommandMap(deviceCommand); + insertInCommandMap(deviceCommand, hasDifferentReplyId, replyId); if (hasDifferentReplyId) { return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic); } else { @@ -437,11 +437,15 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, } } -ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) { +ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand, + bool useAlternativeReply, + DeviceCommandId_t alternativeReplyId) { DeviceCommandInfo info; info.expectedReplies = 0; info.isExecuting = false; info.sendReplyTo = NO_COMMANDER; + info.useAlternativeReplyId = alternativeReplyId; + info.alternativeReplyId = alternativeReplyId; auto resultPair = deviceCommandMap.emplace(deviceCommand, info); if (resultPair.second) { return RETURN_OK; @@ -451,12 +455,21 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm } size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) { - DeviceReplyIter iter = deviceReplyMap.find(commandId); - if (iter != deviceReplyMap.end()) { - return iter->second.replyLen; - } else { - return 0; + DeviceCommandId_t replyId = NO_COMMAND_ID; + DeviceCommandMap::iterator command = cookieInfo.pendingCommand; + if (command->second.useAlternativeReplyId) { + replyId = command->second.alternativeReplyId; } + else { + replyId = commandId; + } + DeviceReplyIter iter = deviceReplyMap.find(replyId); + if (iter != deviceReplyMap.end()) { + if (iter->second.delayCycles != 0) { + return iter->second.replyLen; + } + } + return 0; } ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, @@ -651,7 +664,9 @@ void DeviceHandlerBase::doGetWrite() { // We need to distinguish here, because a raw command never expects a reply. //(Could be done in eRIRM, but then child implementations need to be careful. - result = enableReplyInReplyMap(cookieInfo.pendingCommand); + DeviceCommandMap::iterator command = cookieInfo.pendingCommand; + result = enableReplyInReplyMap(command, 1, command->second.useAlternativeReplyId, + command->second.alternativeReplyId); } else { // always generate a failure event, so that FDIR knows what's up triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first); diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index c8b8b86d7..5e974831e 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -478,7 +478,9 @@ class DeviceHandlerBase : public DeviceHandlerIF, * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ - ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); + ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand, + bool useAlternativeReply = false, + DeviceCommandId_t alternativeReplyId = 0); /** * Enables a periodic reply for a given command. It sets to delay cycles to the specified @@ -751,6 +753,8 @@ class DeviceHandlerBase : public DeviceHandlerIF, //! if this is != NO_COMMANDER, DHB was commanded externally and shall //! report everything to commander. MessageQueueId_t sendReplyTo; + bool useAlternativeReplyId; + DeviceCommandId_t alternativeReplyId; }; using DeviceCommandMap = std::map; /** diff --git a/src/fsfw/osal/freertos/PeriodicTask.cpp b/src/fsfw/osal/freertos/PeriodicTask.cpp index 8dfa02908..d2c46ea8d 100644 --- a/src/fsfw/osal/freertos/PeriodicTask.cpp +++ b/src/fsfw/osal/freertos/PeriodicTask.cpp @@ -97,7 +97,11 @@ void PeriodicTask::taskFunctionality() { ReturnValue_t PeriodicTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - if (newObject == nullptr) { + return addComponent(newObject); +} + +ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) { + if (object == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" "it implement ExecutableObjectIF" @@ -105,8 +109,8 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object) { #endif return HasReturnvaluesIF::RETURN_FAILED; } - objectList.push_back(newObject); - newObject->setTaskIF(this); + objectList.push_back(object); + object->setTaskIF(this); return HasReturnvaluesIF::RETURN_OK; } diff --git a/src/fsfw/osal/freertos/PeriodicTask.h b/src/fsfw/osal/freertos/PeriodicTask.h index cc3951768..fc8e90927 100644 --- a/src/fsfw/osal/freertos/PeriodicTask.h +++ b/src/fsfw/osal/freertos/PeriodicTask.h @@ -63,6 +63,16 @@ class PeriodicTask : public PeriodicTaskIF, public FreeRTOSTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; + /** + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. + * @param object Id of the object to add. + * @return + * -@c RETURN_OK on success + * -@c RETURN_FAILED if the object could not be added. + */ + ReturnValue_t addComponent(ExecutableObjectIF* object) override; + uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; diff --git a/src/fsfw/osal/host/PeriodicTask.cpp b/src/fsfw/osal/host/PeriodicTask.cpp index 1de4aedfc..cdcfafa67 100644 --- a/src/fsfw/osal/host/PeriodicTask.cpp +++ b/src/fsfw/osal/host/PeriodicTask.cpp @@ -102,11 +102,15 @@ void PeriodicTask::taskFunctionality() { ReturnValue_t PeriodicTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - if (newObject == nullptr) { + return addComponent(newObject); +} + +ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) { + if (object == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } - newObject->setTaskIF(this); - objectList.push_back(newObject); + object->setTaskIF(this); + objectList.push_back(object); return HasReturnvaluesIF::RETURN_OK; } diff --git a/src/fsfw/osal/host/PeriodicTask.h b/src/fsfw/osal/host/PeriodicTask.h index 0c41c0f70..6c4d5e8bb 100644 --- a/src/fsfw/osal/host/PeriodicTask.h +++ b/src/fsfw/osal/host/PeriodicTask.h @@ -59,6 +59,16 @@ class PeriodicTask : public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object); + /** + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. + * @param object pointer to the object to add. + * @return + * -@c RETURN_OK on success + * -@c RETURN_FAILED if the object could not be added. + */ + ReturnValue_t addComponent(ExecutableObjectIF* object); + uint32_t getPeriodMs() const; ReturnValue_t sleepFor(uint32_t ms); diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index ca346670d..e1937df4a 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -28,7 +28,11 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - if (newObject == nullptr) { + return addComponent(newObject); +} + +ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) { + if (object == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" << " it implements ExecutableObjectIF!" << std::endl; @@ -39,8 +43,8 @@ ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { #endif return HasReturnvaluesIF::RETURN_FAILED; } - objectList.push_back(newObject); - newObject->setTaskIF(this); + objectList.push_back(object); + object->setTaskIF(this); return HasReturnvaluesIF::RETURN_OK; } diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 1c3a52c7e..3cd9847ad 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -42,6 +42,14 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; + /** + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. + * @param object pointer to the object to add. + * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. + */ + ReturnValue_t addComponent(ExecutableObjectIF* object) override; + uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; diff --git a/src/fsfw/osal/rtems/PeriodicTask.cpp b/src/fsfw/osal/rtems/PeriodicTask.cpp index 1785c8cfb..ae2ec4265 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.cpp +++ b/src/fsfw/osal/rtems/PeriodicTask.cpp @@ -68,11 +68,15 @@ void PeriodicTask::taskFunctionality() { ReturnValue_t PeriodicTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - if (newObject == nullptr) { + return addComponent(newObject); +} + +ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) { + if (object == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } - objectList.push_back(newObject); - newObject->setTaskIF(this); + objectList.push_back(object); + object->setTaskIF(this); return HasReturnvaluesIF::RETURN_OK; } diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index 119329f2a..24ce4af1e 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -59,6 +59,15 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; +/** + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. + * @param object pointer to the object to add. + * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. + */ + ReturnValue_t addComponent(ExecutableObjectIF* object) override; + + uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h index a8a512296..c78a32dec 100644 --- a/src/fsfw/tasks/PeriodicTaskIF.h +++ b/src/fsfw/tasks/PeriodicTaskIF.h @@ -26,21 +26,25 @@ class PeriodicTaskIF { virtual ReturnValue_t startTask() = 0; /** - * Add a component (object) to a periodic task. The pointer to the - * task can be set optionally + * Add a component (object) to a periodic task. * @param object - * Add an object to the task. The most important case is to add an - * executable object with a function which will be called regularly - * (see ExecutableObjectIF) - * @param setTaskIF - * Can be used to specify whether the task object pointer is passed - * to the component. + * Add an object to the task. The object needs to implement ExecutableObjectIF * @return */ virtual ReturnValue_t addComponent(object_id_t object) { return HasReturnvaluesIF::RETURN_FAILED; }; + /** + * Add an object to a periodic task. + * @param object + * Add an object to the task. + * @return + */ + virtual ReturnValue_t addComponent(ExecutableObjectIF* object) { + return HasReturnvaluesIF::RETURN_FAILED; + }; + virtual ReturnValue_t sleepFor(uint32_t ms) = 0; virtual uint32_t getPeriodMs() const = 0;