Merge branch 'development' into mueller/possible-ring-buffer-fix

This commit is contained in:
Robin Müller 2022-04-11 17:35:42 +02:00
commit 7a5ce57bbc
14 changed files with 115 additions and 34 deletions

View File

@ -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(

View File

@ -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 <cmath>

View File

@ -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;
}

View File

@ -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);

View File

@ -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<DeviceCommandId_t, DeviceCommandInfo>;
/**

View File

@ -97,7 +97,11 @@ void PeriodicTask::taskFunctionality() {
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(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;
}

View File

@ -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;

View File

@ -102,11 +102,15 @@ void PeriodicTask::taskFunctionality() {
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(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;
}

View File

@ -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);

View File

@ -28,7 +28,11 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(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;
}

View File

@ -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;

View File

@ -68,11 +68,15 @@ void PeriodicTask::taskFunctionality() {
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(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;
}

View File

@ -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;

View File

@ -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;