Compare commits

..

1 Commits

Author SHA1 Message Date
97e92c0dd2 Refactor and clean up HK and Local Pool Modules 2024-11-13 17:59:49 +01:00
64 changed files with 167 additions and 893 deletions

View File

@@ -26,7 +26,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Added
- FreeRTOS monotonic clock which is not subjected to time jumps of the system clock
- add CFDP subsystem ID
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742
- `PusTmZcWriter` now exposes API to set message counter field.
@@ -35,20 +34,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Changed
- Complete overhaul of HK subsystem. Replaced local data pool manager by periodic HK
- Complete refactoring of HK subsystem. Replaced local data pool manager by periodic HK
helper. The shared pool and the periodic HK generation are now distinct concepts.
- The local HK manager was replaced by a periodic HK helper which has reduced responsibilities.
It takes care of tracking the HK generation using a set specification provided by the user.n
However, it leaves serialization of the HK data completely to the developer. This removes a major
constraint on the format of the HK data, which was previously constrained to implementors of a
certain base class.
- The former set classes and pool objects are still available for HK set specification and
generation. The API has changed, but the general usage and their architecture has not.
- A new set of set classes and helper objects to specify HK sets and data which does not need to be
shared was added as well. The majority of datasets do not need to be shared anyway.
- The non-shared API retain the capability of appending of a validity blob for each piece of set
data at the end of the HK data. For both non-shared and shared data, this capability can be
specified in the constructor, and defaults to true.
- Improved File System Abstraction to be more in line with normal filesystems.
- CFDP implementation was improved, has now even less dependencies on other FSFW components
and allows one inserted packet per state machine call.

View File

@@ -11,12 +11,12 @@ PduHeaderReader::PduHeaderReader(const uint8_t *pduBuf, size_t maxSize) {
}
ReturnValue_t PduHeaderReader::parseData() {
if (maxSize < 7) {
return SerializeIF::STREAM_TOO_SHORT;
}
if (pointers.rawPtr == nullptr) {
return returnvalue::FAILED;
}
if (maxSize < 7) {
return SerializeIF::STREAM_TOO_SHORT;
}
pointers.fixedHeader =
reinterpret_cast<PduHeaderFixedStruct *>(const_cast<uint8_t *>(pointers.rawPtr));
sourceIdRaw = &pointers.fixedHeader->variableFieldsStart;

View File

@@ -34,12 +34,11 @@ class ExtendedControllerBase : public ControllerBase,
ActionHelper actionHelper;
// Periodic HK methods, default method assumes that no shared pool is required.
datapool::SharedPool* getOptionalSharedPool() override = 0;
virtual datapool::SharedPool* getOptionalSharedPool() override;
// Periodic HK abstract methods.
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf,
size_t maxSize) override = 0;
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) override = 0;
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf, size_t maxSize) = 0;
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) = 0;
/**
* Implemented by child class. Handle all command messages which are

View File

@@ -48,14 +48,6 @@ PoolObjectBase::PoolObjectBase(object_id_t poolOwner, id_t poolId, DataSetIF* da
return;
}
sharedPool = hkOwner->getOptionalSharedPool();
if (sharedPool == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PoolObjectBase: HK owner 0x" << std::hex << poolOwner << std::dec
<< "does not have a shared pool " << std::endl;
#else
sif::printError("PoolObjectBase: HK owner 0x%08x does not have a shared pool\n", poolOwner);
#endif
}
if (dataSet != nullptr) {
dataSet->registerVariable(this);
@@ -72,10 +64,6 @@ void PoolObjectBase::setReadWriteMode(pool_rwm_t newReadWriteMode) {
this->readWriteMode = newReadWriteMode;
}
[[nodiscard]] bool PoolObjectBase::isValid() const { return valid; }
void PoolObjectBase::setValid(bool valid) { this->valid = valid; }
void PoolObjectBase::reportReadCommitError(const char* variableType, ReturnValue_t error, bool read,
object_id_t objectId, id_t lpId) {
#if FSFW_DISABLE_PRINTOUT == 0

View File

@@ -27,9 +27,6 @@ class PoolObjectBase : public PoolVariableIF {
[[nodiscard]] dp::id_t getDataPoolId() const override;
void setDataPoolId(dp::id_t poolId);
[[nodiscard]] bool isValid() const;
void setValid(bool valid);
protected:
/**
* @brief To access the correct data pool entry on read and commit calls,
@@ -43,8 +40,6 @@ class PoolObjectBase : public PoolVariableIF {
*/
ReadWriteMode_t readWriteMode = pool_rwm_t::VAR_READ_WRITE;
bool valid = false;
//! @brief Pointer to the class which manages the HK pool.
dp::SharedPool* sharedPool = nullptr;
@@ -52,4 +47,4 @@ class PoolObjectBase : public PoolVariableIF {
object_id_t objectId, dp::id_t lpId);
};
} // namespace datapool
} // namespace datapool

View File

@@ -216,7 +216,6 @@ class PoolVector : public PoolObjectBase {
if (result != returnvalue::OK) {
return result;
}
this->valid = poolEntry->getValid();
std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize());
return returnvalue::OK;
}
@@ -238,7 +237,6 @@ class PoolVector : public PoolObjectBase {
if (result != returnvalue::OK) {
return result;
}
poolEntry->setValid(this->valid);
std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize());
return returnvalue::OK;
}

View File

@@ -1,19 +1,15 @@
#include "fsfw/datapool/PoolDataSetBase.h"
#include <cmath>
#include <cstring>
#include "fsfw/datapool/ReadCommitIFAttorney.h"
#include "fsfw/globalfunctions/bitutility.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
const size_t maxFillCount, bool serializeWithValidityBlob)
: serializeWithValidityBlob(serializeWithValidityBlob),
registeredVariables(registeredVariablesArray),
maxFillCount(maxFillCount) {}
const size_t maxFillCount)
: registeredVariables(registeredVariablesArray), maxFillCount(maxFillCount) {}
PoolDataSetBase::~PoolDataSetBase() = default;
PoolDataSetBase::~PoolDataSetBase() {}
ReturnValue_t PoolDataSetBase::registerVariable(PoolVariableIF* variable) {
if (registeredVariables == nullptr) {
@@ -176,9 +172,6 @@ ReturnValue_t PoolDataSetBase::unlockDataPool() { return returnvalue::OK; }
ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
if (this->serializeWithValidityBlob) {
return doSerializeWithValidityBlob(buffer, size, maxSize, streamEndianness);
}
ReturnValue_t result = returnvalue::FAILED;
for (uint16_t count = 0; count < fillCount; count++) {
result = registeredVariables[count]->serialize(buffer, size, maxSize, streamEndianness);
@@ -189,51 +182,6 @@ ReturnValue_t PoolDataSetBase::serialize(uint8_t** buffer, size_t* size, const s
return result;
}
ReturnValue_t PoolDataSetBase::doSerializeWithValidityBlob(
uint8_t** buffer, size_t* size, const size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = returnvalue::FAILED;
const uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount) / 8.0);
uint8_t* validityPtr = nullptr;
#if defined(_MSC_VER) || defined(__clang__)
// Use a std::vector here because MSVC will (rightly) not create a fixed size array
// with a non constant size specifier. The Apple compiler (LLVM) will not accept
// the initialization of a variable sized array
std::vector<uint8_t> validityMask(validityMaskSize, 0);
validityPtr = validityMask.data();
#else
uint8_t validityMask[validityMaskSize] = {};
validityPtr = validityMask;
#endif
uint8_t validBufferIndex = 0;
uint8_t validBufferIndexBit = 0;
for (uint16_t count = 0; count < fillCount; count++) {
if (registeredVariables[count]->isValid()) {
// Set bit at correct position
bitutil::set(validityPtr + validBufferIndex, validBufferIndexBit);
}
if (validBufferIndexBit == 7) {
validBufferIndex++;
validBufferIndexBit = 0;
} else {
validBufferIndexBit++;
}
result = registeredVariables[count]->serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
}
if (*size + validityMaskSize > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
// copy validity buffer to end
std::memcpy(*buffer, validityPtr, validityMaskSize);
*size += validityMaskSize;
return result;
}
ReturnValue_t PoolDataSetBase::deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) {
ReturnValue_t result = returnvalue::FAILED;
@@ -251,9 +199,6 @@ size_t PoolDataSetBase::getSerializedSize() const {
for (uint16_t count = 0; count < fillCount; count++) {
size += registeredVariables[count]->getSerializedSize();
}
if (serializeWithValidityBlob) {
size += std::ceil(static_cast<float>(fillCount) / 8.0);
}
return size;
}
@@ -270,9 +215,3 @@ void PoolDataSetBase::setReadCommitProtectionBehaviour(bool protectEveryReadComm
this->timeoutTypeForSingleVars = timeoutType;
this->mutexTimeoutForSingleVars = mutexTimeout;
}
void PoolDataSetBase::setChildrenValidity(bool valid) {
for (uint16_t count = 0; count < fillCount; count++) {
registeredVariables[count]->setValid(valid);
}
}

View File

@@ -41,8 +41,7 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
* supply a pointer to this dataset to PoolVariable
* initializations to register pool variables.
*/
PoolDataSetBase(PoolVariableIF** registeredVariablesArray, size_t maxFillCount,
bool serializeWithValidityBlob = true);
PoolDataSetBase(PoolVariableIF** registeredVariablesArray, size_t maxFillCount);
/* Forbidden for now */
PoolDataSetBase(const PoolDataSetBase& otherSet) = delete;
@@ -116,15 +115,13 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
[[nodiscard]] uint16_t getFillCount() const override;
// SerializeIF implementations
/* SerializeIF implementations */
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;
ReturnValue_t doSerializeWithValidityBlob(uint8_t** buffer, size_t* size, const size_t maxSize,
SerializeIF::Endianness streamEndianness) const;
/**
* Can be used to individually protect every read and commit call.
* @param protectEveryReadCommit
@@ -134,13 +131,6 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
bool protectEveryReadCommit, MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
uint32_t mutexTimeout = 20);
/**
* Set the validity of all children
*/
void setChildrenValidity(bool valid);
bool serializeWithValidityBlob = false;
protected:
/**
* @brief The fill_count attribute ensures that the variables

View File

@@ -52,16 +52,6 @@ void* PoolEntry<T>::getRawData() {
return this->address;
}
template <typename T>
void PoolEntry<T>::setValid(bool isValid) {
this->valid = isValid;
}
template <typename T>
bool PoolEntry<T>::getValid() {
return valid;
}
template <typename T>
void PoolEntry<T>::print() {
const char* validString = nullptr;

View File

@@ -105,17 +105,6 @@ class PoolEntry : public PoolEntryIF {
*/
void* getRawData();
/**
* @brief This method allows to set the valid information
* of the pool entry.
*/
void setValid(bool isValid) override;
/**
* @brief This method allows to get the valid information
* of the pool entry.
*/
bool getValid() override;
/**
* @brief This is a debug method that prints all values and the valid
* information to the screen. It prints all array entries in a row.

View File

@@ -51,15 +51,6 @@ class PoolEntryIF {
* Returns the type of the entry.
*/
virtual Type getType() = 0;
/**
* @brief This method allows to set the valid information of the pool entry.
*/
virtual void setValid(bool isValid) = 0;
/**
* @brief This method allows to set the valid information of the pool entry.
*/
virtual bool getValid() = 0;
};
#endif /* FSFW_DATAPOOL_POOLENTRYIF_H_ */

View File

@@ -20,9 +20,9 @@ class PoolReadGuard {
if (readResult != returnvalue::OK) {
#if FSFW_VERBOSE_LEVEL == 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PoolReadGuard: Read failed!" << std::endl;
sif::error << "PoolReadHelper: Read failed!" << std::endl;
#else
sif::printError("PoolReadGuard: Read failed!\n");
sif::printError("PoolReadHelper: Read failed!\n");
#endif /* FSFW_PRINT_VERBOSITY_LEVEL == 1 */
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
}

View File

@@ -210,7 +210,6 @@ inline ReturnValue_t PoolVariable<T>::readWithoutLock() {
}
this->value = *(poolEntry->getDataPtr());
this->valid = poolEntry->getValid();
return returnvalue::OK;
}
@@ -242,7 +241,6 @@ ReturnValue_t PoolVariable<T>::commitWithoutLock() {
}
*(poolEntry->getDataPtr()) = this->value;
poolEntry->setValid(this->valid);
return returnvalue::OK;
}

View File

@@ -47,9 +47,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;
virtual bool isValid() const = 0;
virtual void setValid(bool valid) = 0;
};
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;

View File

@@ -2,17 +2,14 @@
using namespace dp;
SharedSet::SharedSet(dp::SharedPool& sharedPool, uint32_t setId, const size_t maxNumberOfVariables,
bool serializeWithValidityBlob)
: SharedSetBase(sharedPool, setId, nullptr, maxNumberOfVariables, serializeWithValidityBlob),
SharedSet::SharedSet(dp::SharedPool& sharedPool, uint32_t setId, const size_t maxNumberOfVariables)
: SharedSetBase(sharedPool, setId, nullptr, maxNumberOfVariables),
poolVarList(maxNumberOfVariables) {
this->setContainer(poolVarList.data());
}
SharedSet::SharedSet(dp::structure_id_t sid, const size_t maxNumberOfVariables,
bool serializeWithValidityBlob)
: SharedSetBase(sid, nullptr, maxNumberOfVariables, serializeWithValidityBlob),
poolVarList(maxNumberOfVariables) {
SharedSet::SharedSet(dp::structure_id_t sid, const size_t maxNumberOfVariables)
: SharedSetBase(sid, nullptr, maxNumberOfVariables), poolVarList(maxNumberOfVariables) {
this->setContainer(poolVarList.data());
}

View File

@@ -21,10 +21,9 @@ namespace datapool {
*/
class SharedSet : public SharedSetBase {
public:
SharedSet(SharedPool& sharedPool, uint32_t setId, size_t maxSize,
bool serializeWithValidityBlob = true);
SharedSet(SharedPool& sharedPool, uint32_t setId, size_t maxSize);
SharedSet(sid_t sid, size_t maxSize, bool serializeWithValidityBlob = true);
SharedSet(sid_t sid, size_t maxSize);
~SharedSet() override;

View File

@@ -14,9 +14,8 @@ using namespace datapool;
SharedSetBase::SharedSetBase(SharedPool &sharedPool, uint32_t setId,
PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables, bool serializeWithValidityBlob)
: base(registeredVariablesArray, maxNumberOfVariables, serializeWithValidityBlob),
sharedPool(&sharedPool) {
const size_t maxNumberOfVariables)
: base(registeredVariablesArray, maxNumberOfVariables), sharedPool(&sharedPool) {
mutexIfSingleDataCreator = sharedPool.getPoolMutex();
this->sid.objectId = sharedPool.getOwnerId();
@@ -24,8 +23,8 @@ SharedSetBase::SharedSetBase(SharedPool &sharedPool, uint32_t setId,
}
SharedSetBase::SharedSetBase(structure_id_t sid, PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables, bool serializeWithValidityBlob)
: base(registeredVariablesArray, maxNumberOfVariables, serializeWithValidityBlob) {
const size_t maxNumberOfVariables)
: base(registeredVariablesArray, maxNumberOfVariables) {
auto *hkOwner = ObjectManager::instance()->get<hk::GeneratesPeriodicHkIF>(sid.objectId);
if (hkOwner != nullptr) {
sharedPool = hkOwner->getOptionalSharedPool();
@@ -38,9 +37,8 @@ SharedSetBase::SharedSetBase(structure_id_t sid, PoolVariableIF **registeredVari
}
SharedSetBase::SharedSetBase(PoolVariableIF **registeredVariablesArray,
const size_t maxNumberOfVariables, bool protectEveryReadCommitCall,
bool serializeWithValidityBlob)
: base(registeredVariablesArray, maxNumberOfVariables, serializeWithValidityBlob) {
const size_t maxNumberOfVariables, bool protectEveryReadCommitCall)
: base(registeredVariablesArray, maxNumberOfVariables) {
base.setReadCommitProtectionBehaviour(protectEveryReadCommitCall);
}
@@ -122,8 +120,6 @@ bool SharedSetBase::getReportingEnabled() const { return reportingEnabled; }
structure_id_t SharedSetBase::getStructureId() const { return sid; }
void SharedSetBase::setChildrenValidity(bool valid) { return base.setChildrenValidity(valid); }
object_id_t SharedSetBase::getCreatorObjectId() {
if (sharedPool != nullptr) {
return sharedPool->getOwnerId();
@@ -140,17 +136,10 @@ void SharedSetBase::setAllVariablesReadOnly() {
void SharedSetBase::printSet() { return; }
ReturnValue_t SharedSetBase::read(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
lockDataPool(timeoutType, timeoutMs);
ReturnValue_t result = base.read(timeoutType, timeoutMs);
unlockDataPool();
return result;
return base.read(timeoutType, timeoutMs);
}
ReturnValue_t SharedSetBase::commit(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
lockDataPool(timeoutType, timeoutMs);
ReturnValue_t result = base.commit(timeoutType, timeoutMs);
unlockDataPool();
return result;
return base.commit(timeoutType, timeoutMs);
}
uint16_t SharedSetBase::getFillCount() const { return base.getFillCount(); }
@@ -162,8 +151,3 @@ void SharedSetBase::setContainer(PoolVariableIF **variablesContainer) {
return base.setContainer(variablesContainer);
}
PoolVariableIF **SharedSetBase::getContainer() const { return base.getContainer(); }
void SharedSetBase::updateValidityBlobSerialization(bool enable) {
base.serializeWithValidityBlob = enable;
}
bool SharedSetBase::getValidityBlobSerialization() const { return base.serializeWithValidityBlob; }

View File

@@ -40,6 +40,8 @@ namespace datapool {
* @ingroup data_pool
*/
class SharedSetBase : public SerializeIF, public PoolDataSetIF {
// friend class PeriodicHousekeepingHelper;
public:
/**
* @brief Constructor for the creator of local pool data.
@@ -48,7 +50,7 @@ class SharedSetBase : public SerializeIF, public PoolDataSetIF {
* periodic handling.
*/
SharedSetBase(SharedPool& sharedPool, uint32_t setId, PoolVariableIF** registeredVariablesArray,
size_t maxNumberOfVariables, bool serializeWithValidityBlob = true);
size_t maxNumberOfVariables);
/**
* @brief Constructor for users of the local pool data, which need
@@ -61,8 +63,7 @@ class SharedSetBase : public SerializeIF, public PoolDataSetIF {
* @param registeredVariablesArray
* @param maxNumberOfVariables
*/
SharedSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray, size_t maxNumberOfVariables,
bool serializeWithValidityBlob = true);
SharedSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray, size_t maxNumberOfVariables);
/**
* @brief Simple constructor, if the dataset is not the owner by
@@ -83,7 +84,7 @@ class SharedSetBase : public SerializeIF, public PoolDataSetIF {
* commit calls separately.
*/
SharedSetBase(PoolVariableIF** registeredVariablesArray, size_t maxNumberOfVariables,
bool serializeWithValidityBlob, bool protectEveryReadCommitCall = true);
bool protectEveryReadCommitCall = true);
/**
* @brief The destructor automatically manages writing the valid
@@ -108,14 +109,14 @@ class SharedSetBase : public SerializeIF, public PoolDataSetIF {
*/
void setAllVariablesReadOnly();
[[nodiscard]] virtual 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* 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;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override;
[[nodiscard]] dp::sid_t getStructureId() const;
@@ -154,14 +155,6 @@ class SharedSetBase : public SerializeIF, public PoolDataSetIF {
void setContainer(PoolVariableIF** variablesContainer);
PoolVariableIF** getContainer() const;
/**
* Set the validity of all children
*/
void setChildrenValidity(bool valid);
void updateValidityBlobSerialization(bool enable);
bool getValidityBlobSerialization() const;
protected:
PoolDataSetBase base;
@@ -176,6 +169,12 @@ class SharedSetBase : public SerializeIF, public PoolDataSetIF {
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval);
/**
* If the valid state of a dataset is always relevant to the whole
* data set we can use this flag.
*/
bool valid = false;
/**
* @brief This is a small helper function to facilitate locking
* the global data pool.

View File

@@ -28,9 +28,8 @@ class StaticSharedSet : public datapool::SharedSetBase {
* @param sharedPool Shared pool this dataset will read from or write to.
* @param setId
*/
StaticSharedSet(SharedPool& sharedPool, const uint32_t setId,
bool serializeWithValidityBlob = true)
: SharedSetBase(sharedPool, setId, nullptr, NUM_VARIABLES, serializeWithValidityBlob) {
StaticSharedSet(SharedPool& sharedPool, const uint32_t setId)
: SharedSetBase(sharedPool, setId, nullptr, NUM_VARIABLES) {
this->setContainer(poolVarList.data());
}
@@ -38,8 +37,7 @@ class StaticSharedSet : public datapool::SharedSetBase {
* Constructor used by data users like controllers.
* @param sid
*/
explicit StaticSharedSet(const structure_id_t sid, bool serializeWithValidityBlob = true)
: SharedSetBase(sid, nullptr, NUM_VARIABLES, serializeWithValidityBlob) {
explicit StaticSharedSet(const structure_id_t sid) : SharedSetBase(sid, nullptr, NUM_VARIABLES) {
this->setContainer(poolVarList.data());
}

View File

@@ -35,7 +35,7 @@ union structure_id_t {
static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT;
static constexpr uint32_t INVALID_SET_ID = -1;
constexpr structure_id_t() : raw(INVALID_SID) {}
structure_id_t() : raw(INVALID_SID) {}
constexpr structure_id_t(object_id_t objectId, uint32_t setId)
: objectId(objectId), ownerSetId(setId) {}
@@ -43,8 +43,9 @@ union structure_id_t {
struct {
object_id_t objectId;
/**
* A generic 32 bit ID to identify unique HK set packets for a single
* object.
* A generic 32 bit ID to identify unique HK packets for a single
* object. For example, the DeviceCommandId_t is used for
* DeviceHandlers
*/
uint32_t ownerSetId;
};
@@ -90,4 +91,4 @@ union g_id_t {
} // namespace datapool
namespace dp = datapool;
namespace dp = datapool;

View File

@@ -243,8 +243,8 @@ bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty(EventMessage* ev
if (owner == nullptr) {
// Configuration error.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "DeviceHandlerFailureIsolation::"
<< "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl;
sif::error << "DeviceHandlerFailureIsolation::" << "isFdirInActionOrAreWeFaulty: Owner not set!"
<< std::endl;
#endif
return false;
}

View File

@@ -13,7 +13,7 @@ class DeviceHandlerThermalSet : public dp::StaticSharedSet<2> {
: DeviceHandlerThermalSet(hkOwner->getObjectId(), cfg) {}
DeviceHandlerThermalSet(object_id_t deviceHandler, ThermalStateCfg cfg)
: StaticSharedSet(dp::structure_id_t(deviceHandler, cfg.thermalSetId), true),
: StaticSharedSet(dp::structure_id_t(deviceHandler, cfg.thermalSetId)),
thermalStatePoolId(cfg.thermalStatePoolId),
heaterRequestPoolId(cfg.thermalRequestPoolId) {}

View File

@@ -26,33 +26,6 @@ struct DhbConfig {
uint32_t msgQueueDepth = 10;
};
/**
* @brief
* This is a base class which can be used for handler classes which drive physical devices.
*
* @details
* This class performs some boilerplate tasks to make it compatible to the FSFW ecosystem.
* For example, it adds all required interfaces and helpers which are required for the majority
* of physical devices:
*
* - SystemObject to become globally addressable
* - HasModesIF and the ModeHelper: Expose modes. It is expected that most device handlers
* use the default device handler modes OFF, ON and NORMAL at the very least.
* - HasHealthIF, HealthHelper and a FDIR object: Physical devices can break down or require
* power cycling as the most common FDIR reaction. The FDHB implements the necessary interface
* and is also composed of a FDIR object which can set the health state to FAULTY or
* NEEDS_RECOVERY to cause FDIR reactions.
* - ModeTreeChildIF: Many device handlers are part of a mode tree.
* - HasActionsIF and the ActionHelper: Most device handlers expose executable commands, for example
* to re-configure the physical device or to poll data from the physical device.
* - ReceivesParameterMessagesIF and the ParameterHelper: Most device handlers have tweakable
* parameters.
*
* This class is used to extending it in a concrete device handler class and then implementing
* all abstract methods. The abstract methods provide adaption points for users which were
* deemed sufficient for most use-cases. The behaviour of the base-class can also be further
* configured by implementing other virtual functions.
*/
class FreshDeviceHandlerBase : public SystemObject,
public DeviceHandlerIF,
public HasModesIF,
@@ -68,20 +41,7 @@ class FreshDeviceHandlerBase : public SystemObject,
~FreshDeviceHandlerBase() override;
/**
* @brief
* Periodic helper executed function, implemented by child class.
*
* @details
* This will be called by the default performOperation call. This is the main adaption point
* for the actual device handling logic. It is expected that the following common tasks are
* performed in this method:
*
* 1. Performing periodic polling of the physical device in NORMAL mode. This is usually required
* to poll housekeeping data from the device periodically.
* 2. Handle on-going mode transitions if the mode transitions can only be handled asynchronously.
* This might also involve communication with the physical device and power switch
* handling/polling for transition to OFF or ON/NORMAL.
* 3. Perform other periodic tasks which always need to be done irrespective of mode.
*/
virtual void performDeviceOperation(uint8_t opCode) = 0;
@@ -129,17 +89,13 @@ class FreshDeviceHandlerBase : public SystemObject,
// Mode Helpers.
virtual void modeChanged(Mode_t mode, Submode_t submode);
/**
* This method is called when a mode message to set a new mode is received.
*
* The default implementation sets the new mode immediately. If this is not applicable for
* certain modes, the user should provide a custom implementation, which performs roughly
* the same functionality of this function, when all the steps have been taken to reach the
* new mode.
*/
void startTransition(Mode_t mode, Submode_t submode) override;
virtual void setMode(Mode_t newMode, Submode_t newSubmode);
virtual void setMode(Mode_t newMode);
void getMode(Mode_t* mode, Submode_t* submode) override;
@@ -148,23 +104,12 @@ class FreshDeviceHandlerBase : public SystemObject,
// System Object overrides.
ReturnValue_t initialize() override;
/**
* This function is implemented to serialize a housekeeping packet when a HK message to
* generate the packet is received, or periodic generation is necessary. The user should serialize
* the HK set into the provided buffer, which will have the size specified in the set
* specification.
*/
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf,
size_t maxSize) override = 0;
/**
* This function is implemented by the user to specify the available housekeeping sets.
*/
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) override = 0;
// Default implementation assumes that no optional shared pool is required.
virtual datapool::SharedPool* getOptionalSharedPool();
/*
* If this device handler has an optional pool, return it. Otherwise, nullptr can be returned.
*/
datapool::SharedPool* getOptionalSharedPool() override = 0;
// Implemented by child, required for periodic HK.
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf, size_t maxSize) = 0;
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) = 0;
/**
* Implemented by child class. Handle all command messages which are
@@ -179,33 +124,11 @@ class FreshDeviceHandlerBase : public SystemObject,
uint32_t* msToReachTheMode) override = 0;
// Health Overrides.
ReturnValue_t setHealth(HealthState health) override;
/**
* This is called when an ActionMessage is received to execute it.
* @param actionId
* @param commandedBy
* @param data
* @param size
* @return
*/
// Action override. Forward to user.
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override = 0;
/**
* This is the default periodic operation handler.
*
* Currently, it performs the following tasks:
*
* 1. Handle the message queue and all message types covered by the base class as specified
* in the class documentation. It uses the composed helper classes for this.
* 2. Poll the FDIR instance to check for failures. The FDIR works by checking all events
* received by the FDHB. An FDIR reaction sets the health state of the FDHB, which might
* in turn trigger FDIR reactions.
* 3. Call the performDeviceOperation user hook.
* 4. Handle periodic housekeeping data generation.
* @param opCode
* @return
*/
virtual ReturnValue_t performOperation(uint8_t opCode) override;
// Executable overrides.
ReturnValue_t performOperation(uint8_t opCode) override;
/**
* This calls the FDIR instance event trigger function.

View File

@@ -5,28 +5,28 @@
#include "fwSubsystemIdRanges.h"
using EventId_t = uint16_t;
using EventSeverity_t = uint8_t;
using GroupId_t = uint16_t;
using UniqueEventId_t = uint16_t;
using UniqueEventId_t = uint8_t;
namespace severity {
enum Severity : EventSeverity_t { INFO = 0, LOW = 1, MEDIUM = 2, HIGH = 3 };
enum Severity : EventSeverity_t { INFO = 1, LOW = 2, MEDIUM = 3, HIGH = 4 };
} // namespace severity
#define MAKE_EVENT(id, severity) (((severity) << 30) | (SUBSYSTEM_ID << 16) | id)
#define MAKE_EVENT(id, severity) (((severity) << 16) + (SUBSYSTEM_ID * 100) + (id))
typedef uint32_t Event;
namespace event {
constexpr UniqueEventId_t getEventId(Event event) { return (event & 0xFFFF); }
constexpr EventId_t getEventId(Event event) { return (event & 0xFFFF); }
constexpr EventSeverity_t getSeverity(Event event) { return ((event >> 30) & 0b11); }
constexpr EventSeverity_t getSeverity(Event event) { return ((event >> 16) & 0xFF); }
constexpr Event makeEvent(GroupId_t groupId, UniqueEventId_t uniqueEventId,
constexpr Event makeEvent(uint8_t subsystemId, UniqueEventId_t uniqueEventId,
EventSeverity_t eventSeverity) {
return (eventSeverity << 30) | (groupId << 16) | uniqueEventId;
return (eventSeverity << 16) + (subsystemId * 100) + uniqueEventId;
}
} // namespace event

View File

@@ -62,8 +62,7 @@ ReturnValue_t FailureIsolationBase::initialize() {
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
if (parentIF == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FailureIsolationBase::intialize: Parent object "
<< "invalid" << std::endl;
sif::error << "FailureIsolationBase::intialize: Parent object " << "invalid" << std::endl;
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
#else
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");

View File

@@ -1,4 +1,9 @@
#pragma once
#ifndef FSFW_INC_FSFW_HOUSEKEEPING_H_
#define FSFW_INC_FSFW_HOUSEKEEPING_H_
#include "fsfw/housekeeping/Dataset.h"
#include "fsfw/housekeeping/DatasetElement.h"
#include "src/core/housekeeping/HousekeepingMessage.h"
#include "src/core/housekeeping/HousekeepingPacketDownlink.h"
#include "src/core/housekeeping/HousekeepingSetPacket.h"
#include "src/core/housekeeping/HousekeepingSnapshot.h"
#endif /* FSFW_INC_FSFW_HOUSEKEEPING_H_ */

View File

@@ -1,128 +0,0 @@
#pragma once
#include <cmath>
#include <cstring>
#include <functional>
#include <vector>
#include "SerializableWithValidityIF.h"
#include "definitions.h"
#include "fsfw/globalfunctions/bitutility.h"
namespace hk {
class Dataset : public SerializeIF {
public:
explicit Dataset(dp::structure_id_t sid, bool serializeWithValidityBlob = true)
: serializeWithValidityBlob(serializeWithValidityBlob), sid(sid) {}
[[nodiscard]] dp::structure_id_t getStructureId() const { return sid; }
void addSerializable(const std::reference_wrapper<SerializableWithValidityIF> serializable) {
serializables.push_back(serializable);
}
[[nodiscard]] size_t getNumberOfSerializables() const { return serializables.size(); }
[[nodiscard]] ReturnValue_t doSerializeWithValidityBlob(uint8_t **buffer, size_t *size,
size_t maxSize,
Endianness streamEndianness) const {
ReturnValue_t result = returnvalue::FAILED;
const uint8_t validityMaskSize = std::ceil(static_cast<float>(serializables.size()) / 8.0);
uint8_t *validityPtr = nullptr;
#if defined(_MSC_VER) || defined(__clang__)
// Use a std::vector here because MSVC will (rightly) not create a fixed size array
// with a non constant size specifier. The Apple compiler (LLVM) will not accept
// the initialization of a variable sized array
std::vector<uint8_t> validityMask(validityMaskSize, 0);
validityPtr = validityMask.data();
#else
uint8_t validityMask[validityMaskSize] = {};
validityPtr = validityMask;
#endif
uint8_t validBufferIndex = 0;
uint8_t validBufferIndexBit = 0;
for (auto &serializable : serializables) {
if (serializable.get().isValid()) {
// Set bit at correct position
bitutil::set(validityPtr + validBufferIndex, validBufferIndexBit);
}
if (validBufferIndexBit == 7) {
validBufferIndex++;
validBufferIndexBit = 0;
} else {
validBufferIndexBit++;
}
result = serializable.get().serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
}
if (*size + validityMaskSize > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
// copy validity buffer to end
std::memcpy(*buffer, validityPtr, validityMaskSize);
*size += validityMaskSize;
*buffer += validityMaskSize;
return result;
}
[[nodiscard]] ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override {
if (serializeWithValidityBlob) {
return doSerializeWithValidityBlob(buffer, size, maxSize, streamEndianness);
}
ReturnValue_t result = returnvalue::OK;
for (auto &serializable : serializables) {
result = serializable.get().serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
}
return result;
}
[[nodiscard]] ReturnValue_t serialize(uint8_t *buffer, size_t &serSize, size_t maxSize,
Endianness streamEndianness) const override {
return SerializeIF::serialize(buffer, serSize, maxSize, streamEndianness);
}
void setChildrenValidity(bool valid) {
for (auto &serializable : serializables) {
serializable.get().setValid(true);
}
}
[[nodiscard]] size_t getSerializedSize() const override {
size_t size = 0;
for (auto &serializable : serializables) {
size += serializable.get().getSerializedSize();
}
if (serializeWithValidityBlob) {
size += std::ceil(static_cast<float>(serializables.size()) / 8.0);
}
return size;
}
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
const Endianness streamEndianness) override {
ReturnValue_t result = returnvalue::OK;
for (auto &serializable : serializables) {
result = serializable.get().deSerialize(buffer, size, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
}
return result;
}
bool serializeWithValidityBlob = false;
private:
dp::structure_id_t sid;
std::vector<std::reference_wrapper<SerializableWithValidityIF>> serializables;
};
} // namespace hk

View File

@@ -1,165 +0,0 @@
#pragma once
#include <utility>
#include "Dataset.h"
#include "SerializableWithValidityIF.h"
#include "fsfw/serialize/SerializeAdapter.h"
namespace hk {
template <typename T>
class ListVariable : public SerializableWithValidityIF {
public:
template <typename... Args>
explicit ListVariable(Dataset& list, Args... args) : entry(std::forward<Args>(args)...) {
list.addSerializable(*this);
}
explicit ListVariable(Dataset& list) : entry() { list.addSerializable(*this); }
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
return SerializeAdapter::serialize(&entry, buffer, size, maxSize, streamEndianness);
}
[[nodiscard]] size_t getSerializedSize() const override {
return SerializeAdapter::getSerializedSize(&entry);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
return SerializeAdapter::deSerialize(&entry, buffer, size, streamEndianness);
}
explicit operator T() { return entry; }
ListVariable& operator=(T newValue) {
entry = newValue;
return *this;
}
[[nodiscard]] bool isValid() const override { return valid; };
void setValid(bool _valid) override { this->valid = _valid; }
T* operator->() { return &entry; }
T get() const { return entry; }
bool valid = false;
T entry{};
};
template <typename T>
using LVar = ListVariable<T>;
using lvar_u8 = LVar<uint8_t>;
using lvar_u16 = LVar<uint16_t>;
using lvar_u32 = LVar<uint32_t>;
using lvar_u64 = LVar<uint64_t>;
using lvar_i8 = LVar<int8_t>;
using lvar_i16 = LVar<int16_t>;
using lvar_i32 = LVar<int32_t>;
using lvar_i64 = LVar<int64_t>;
using lvar_f32 = LVar<float>;
using lvar_f64 = LVar<double>;
template <typename T, size_t N>
class ListVector : public SerializableWithValidityIF {
public:
template <typename... Args>
explicit ListVector(Dataset& list, Args... args) : entry(std::forward<Args>(args)...) {
list.addSerializable(*this);
}
explicit ListVector(Dataset& list) : entry() { list.addSerializable(*this); }
const T* get() const { return entry; }
T* getMut() { return entry; }
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
ReturnValue_t result = returnvalue::OK;
for (size_t i = 0; i < N; i++) {
result = SerializeAdapter::serialize(entry + i, buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
}
return result;
}
[[nodiscard]] size_t getSerializedSize() const override {
return SerializeAdapter::getSerializedSize(entry) * N;
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override {
ReturnValue_t result = returnvalue::OK;
for (size_t i = 0; i < N; i++) {
result = SerializeAdapter::deSerialize(entry + i, buffer, size, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
}
return result;
}
explicit operator T() { return entry; }
ListVector& operator=(T newValue[N]) {
entry = newValue;
return *this;
}
// Array subscript operator for access
T& operator[](size_t index) {
// No exceptions, so user takes care of index validation..
return entry[index];
}
const T& operator[](size_t index) const { return entry[index]; }
// Conversion operator
explicit operator T*() { return entry; }
explicit operator const T*() const { return entry; }
// Iterators for range-based for loops and STL compatibility
T* begin() { return std::begin(entry); }
T* end() { return std::end(entry); }
const T* begin() const { return std::begin(entry); }
const T* end() const { return std::end(entry); }
const T* cbegin() const { return std::begin(entry); }
const T* cend() const { return std::end(entry); }
[[nodiscard]] bool isValid() const override { return valid; };
void setValid(bool _valid) override { this->valid = _valid; }
// Additional utility methods
[[nodiscard]] constexpr size_t size() const { return N; }
bool valid = false;
T entry[N];
};
template <typename T, size_t N>
using LVec = ListVector<T, N>;
template <size_t N>
using lvec_u8 = LVec<uint8_t, N>;
template <size_t N>
using lvec_u16 = LVec<uint16_t, N>;
template <size_t N>
using lvec_u32 = LVec<uint32_t, N>;
template <size_t N>
using lvec_i8 = LVec<int8_t, N>;
template <size_t N>
using lvec_i16 = LVec<int16_t, N>;
template <size_t N>
using lvec_i32 = LVec<int32_t, N>;
template <size_t N>
using lvec_f32 = LVec<float, N>;
template <size_t N>
using lvec_f64 = LVec<double, N>;
} // namespace hk

View File

@@ -17,7 +17,7 @@ PeriodicHelper::PeriodicHelper(GeneratesPeriodicHkIF* owner, MessageQueueIF* que
MessageQueueId_t hkDestQueue)
: hkDestinationId(hkDestQueue) {
if (owner == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_WARNING, "PeriodicHkHelper", returnvalue::FAILED,
printWarningOrError(sif::OutputTypes::OUT_WARNING, "LocalDataPoolManager", returnvalue::FAILED,
"Invalid supplied owner");
return;
}
@@ -200,10 +200,11 @@ void PeriodicHelper::performPeriodicHkGeneration(SetSpecification& setSpec, time
if (result != returnvalue::OK) {
// Configuration error
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "hk::PeriodicHelper::performPeriodicHkOperation: HK generation failed."
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed."
<< std::endl;
#else
sif::printWarning("hk::PeriodicHelper::performPeriodicHkOperation: HK generation failed.\n");
sif::printWarning(
"LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n");
#endif
return;
}
@@ -322,10 +323,6 @@ ReturnValue_t PeriodicHelper::enablePeriodicPacket(const dp::structure_id_t stru
return returnvalue::OK;
}
ReturnValue_t PeriodicHelper::enablePeriodicPacket(const dp::structure_id_t structureId) {
return enablePeriodicPacket(structureId, std::nullopt);
}
ReturnValue_t PeriodicHelper::disablePeriodicPacket(const dp::structure_id_t structureId) {
// Get and check dataset first.
const auto optSetSpec = getMutSetSpecification(structureId);

View File

@@ -135,7 +135,6 @@ class PeriodicHelper : public PeriodicHelperIF {
*/
ReturnValue_t enablePeriodicPacket(dp::sid_t structureId,
std::optional<dur_millis_t> frequencyMs) override;
ReturnValue_t enablePeriodicPacket(dp::sid_t structureId) override;
ReturnValue_t disablePeriodicPacket(dp::sid_t structureId) override;
ReturnValue_t collectionEnabled(dp::sid_t structureId, bool& collectionEnabled) const override;

View File

@@ -17,14 +17,6 @@ class PeriodicHelperIF {
dur_millis_t newCollectionIntervalMs) = 0;
virtual ReturnValue_t enablePeriodicPacket(dp::sid_t structureId,
std::optional<dur_millis_t> frequencyMs) = 0;
/**
* @brief Enables periodic packet generation for a given structure, and
* keeps the previous configured collection interval.
*
* @param structureId
* @return ReturnValue_t
*/
virtual ReturnValue_t enablePeriodicPacket(dp::sid_t structureId) = 0;
virtual ReturnValue_t disablePeriodicPacket(dp::sid_t structureId) = 0;
virtual ReturnValue_t collectionEnabled(dp::sid_t structureId, bool& collectionEnabled) const = 0;
};

View File

@@ -1,10 +0,0 @@
#pragma once
#include "fsfw/serialize/SerializeIF.h"
class SerializableWithValidityIF : public SerializeIF {
public:
[[nodiscard]] virtual bool isValid() const = 0;
virtual void setValid(bool valid) = 0;
};

View File

@@ -10,16 +10,15 @@ class InternalErrorDataset : public dp::StaticSharedSet<4> {
public:
static constexpr uint8_t ERROR_SET_ID = 0;
InternalErrorDataset(dp::SharedPool& sharedPool)
: StaticSharedSet(sharedPool, ERROR_SET_ID, false) {}
InternalErrorDataset(dp::SharedPool& sharedPool) : StaticSharedSet(sharedPool, ERROR_SET_ID) {}
InternalErrorDataset(object_id_t objectId)
: StaticSharedSet(dp::structure_id_t(objectId, ERROR_SET_ID), false) {}
: StaticSharedSet(dp::structure_id_t(objectId, ERROR_SET_ID)) {}
dp::var_t<uint8_t> valid = dp::var_t<uint8_t>(sid.objectId, VALID, this);
dp::var_t<uint32_t> tmHits = dp::var_t<uint32_t>(sid.objectId, TM_HITS, this);
dp::var_t<uint32_t> queueHits = dp::var_t<uint32_t>(sid.objectId, QUEUE_HITS, this);
dp::var_t<uint32_t> storeHits = dp::var_t<uint32_t>(sid.objectId, STORE_HITS, this);
dp::var_t<uint8_t> valid = dp::var_t<uint8_t>(sid.objectId, VALID, this);
};
#endif /* FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ */

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

@@ -321,8 +321,8 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
// Possible configuration error, too much data or/and data coming in too fast,
// requiring larger buffers
sif::warning << "TcpTmTcServer::handleServerOperation: Ring buffer reached "
<< "fill count" << std::endl;
sif::warning << "TcpTmTcServer::handleServerOperation: Ring buffer reached " << "fill count"
<< std::endl;
#else
sif::printWarning(
"TcpTmTcServer::handleServerOperation: Ring buffer reached "

View File

@@ -5,7 +5,6 @@
#include "FreeRTOS.h"
#include "fsfw/globalfunctions/timevalOperations.h"
#include "fsfw/serviceinterface/ServiceInterfacePrinter.h"
#include "fsfw/osal/freertos/Timekeeper.h"
#include "task.h"
@@ -48,8 +47,8 @@ ReturnValue_t Clock::getClock(timeval* time) {
}
ReturnValue_t Clock::getClockMonotonic(timeval* time) {
*time = Timekeeper::instance()->getMonotonicClockOffset() + getUptime();
return returnvalue::OK;
// TODO: I don't actually know if the timekeeper is monotonic..
return getClock_timeval(time);
}
ReturnValue_t Clock::getUptime(timeval* uptime) {
@@ -59,7 +58,7 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
}
timeval Clock::getUptime() {
TickType_t ticksSinceStart = Timekeeper::instance()->getTicks();
TickType_t ticksSinceStart = xTaskGetTickCount();
return Timekeeper::ticksToTimeval(ticksSinceStart);
}

View File

@@ -17,13 +17,7 @@ Timekeeper* Timekeeper::instance() {
return myinstance;
}
void Timekeeper::setOffset(const timeval& offset) {
if (not monotonicClockInitialized) {
this->monotonicClockOffset = offset;
monotonicClockInitialized = true;
}
this->offset = offset;
}
void Timekeeper::setOffset(const timeval& offset) { this->offset = offset; }
timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
timeval uptime;
@@ -39,7 +33,3 @@ timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
}
TickType_t Timekeeper::getTicks() { return xTaskGetTickCount(); }
const timeval Timekeeper::getMonotonicClockOffset() const {
return monotonicClockOffset;
}

View File

@@ -18,14 +18,9 @@ class Timekeeper {
Timekeeper();
timeval offset;
// Set when offset is initialized the first time
timeval monotonicClockOffset;
bool monotonicClockInitialized = false;
static Timekeeper* myinstance;
void setMonotonicClockOffset(const timeval& monotonicClockOffset);
public:
static Timekeeper* instance();
virtual ~Timekeeper();
@@ -39,7 +34,6 @@ class Timekeeper {
const timeval& getOffset() const;
void setOffset(const timeval& offset);
const timeval getMonotonicClockOffset() const;
};
#endif /* FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ */

View File

@@ -60,14 +60,14 @@ ReturnValue_t Fuse::check() {
set.read();
if (!healthHelper.healthTable->isHealthy(getObjectId())) {
setAllMonitorsToUnchecked();
set.setChildrenValidity(false);
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 (!set.power.isValid() || (set.state == 0) || !set.state.isValid()) {
if (!set.setValid.value || (set.state == 0)) {
result = powerMonitor.setToInvalid();
} else {
float lowLimit = 0.0;
@@ -87,7 +87,7 @@ ReturnValue_t Fuse::check() {
ReturnValue_t Fuse::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const {
ReturnValue_t result = returnvalue::FAILED;
for (auto iter = devices.begin(); iter != devices.end(); iter++) {
for (DeviceList::const_iterator iter = devices.begin(); iter != devices.end(); iter++) {
result = (*iter)->serialize(buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
@@ -98,7 +98,7 @@ ReturnValue_t Fuse::serialize(uint8_t** buffer, size_t* size, size_t maxSize,
size_t Fuse::getSerializedSize() const {
uint32_t size = 0;
for (auto iter = devices.begin(); iter != devices.end(); iter++) {
for (DeviceList::const_iterator iter = devices.begin(); iter != devices.end(); iter++) {
size += (*iter)->getSerializedSize();
}
return size;
@@ -119,12 +119,12 @@ uint8_t Fuse::getFuseId() const { return fuseId; }
void Fuse::calculateFusePower() {
ReturnValue_t result1 = currentLimit.check();
if (result1 != returnvalue::OK || !(set.voltage.isValid())) {
set.power.setValid(false);
if (result1 != returnvalue::OK || !(set.setValid.value)) {
set.powerValid = false;
}
// Calculate fuse power.
set.power = set.current.value * set.voltage.value;
set.power.setValid(true);
set.powerValid = true;
}
ReturnValue_t Fuse::performOperation(uint8_t opCode) {
@@ -169,7 +169,7 @@ void Fuse::checkCommandQueue() {
}
void Fuse::checkFuseState() {
if (!set.state.isValid()) {
if (!set.setValid.value) {
oldFuseState = 0;
return;
}
@@ -182,7 +182,7 @@ void Fuse::checkFuseState() {
}
float Fuse::getPower() {
if (set.power.isValid()) {
if (set.powerValid.value) {
return set.power.value;
} else {
return 0.0;
@@ -191,7 +191,8 @@ float Fuse::getPower() {
void Fuse::setDataPoolEntriesInvalid() {
set.read();
set.setChildrenValidity(false);
set.setValid = false;
set.powerValid = false;
set.commit();
}
@@ -219,7 +220,7 @@ bool Fuse::areSwitchesOfComponentOn(DeviceList::iterator iter) {
return true;
}
bool Fuse::isPowerValid() { return set.power.isValid(); }
bool Fuse::isPowerValid() { return set.powerValid.value; }
ReturnValue_t Fuse::setHealth(HealthState health) {
healthHelper.setHealth(health);

View File

@@ -29,14 +29,16 @@ class FuseSet : public datapool::StaticSharedSet<6> {
public:
static constexpr uint8_t FUSE_SET_ID = 0;
FuseSet(dp::SharedPool &sharedPool) : StaticSharedSet(sharedPool, FUSE_SET_ID, true) {}
FuseSet(dp::SharedPool &sharedPool) : StaticSharedSet(sharedPool, FUSE_SET_ID) {}
FuseSet(object_id_t objectId) : StaticSharedSet(dp::sid_t(objectId, FUSE_SET_ID), true) {}
FuseSet(object_id_t objectId) : StaticSharedSet(dp::sid_t(objectId, FUSE_SET_ID)) {}
dp::f32_t voltage = dp::f32_t(sid.objectId, FusePoolId::VOLTAGE, this);
dp::f32_t current = dp::f32_t(sid.objectId, FusePoolId::CURRENT, this);
dp::u8_t state = dp::u8_t(sid.objectId, FusePoolId::STATE, this);
dp::f32_t power = dp::f32_t(sid.objectId, FusePoolId::POWER, this);
dp::u8_t powerValid = dp::u8_t(sid.objectId, FusePoolId::POWER_VALID, this);
dp::u8_t setValid = dp::u8_t(sid.objectId, FusePoolId::SET_VALID, this);
};
class Fuse : public SystemObject,

View File

@@ -21,11 +21,10 @@ class PowerSensorSet : public dp::StaticSharedSet<6> {
public:
static constexpr uint8_t POWER_SENSOR_SET_ID = 0;
PowerSensorSet(dp::SharedPool &sharedPool)
: StaticSharedSet(sharedPool, POWER_SENSOR_SET_ID, true) {}
PowerSensorSet(dp::SharedPool &sharedPool) : StaticSharedSet(sharedPool, POWER_SENSOR_SET_ID) {}
PowerSensorSet(object_id_t objectId)
: StaticSharedSet(dp::sid_t(objectId, POWER_SENSOR_SET_ID), true) {}
: StaticSharedSet(dp::sid_t(objectId, POWER_SENSOR_SET_ID)) {}
dp::f32_t current{sid.objectId, PowerSensorPoolId::CURRENT, this};
dp::f32_t voltage{sid.objectId, PowerSensorPoolId::VOLTAGE, this};

View File

@@ -49,8 +49,8 @@ ReturnValue_t Service20ParameterManagement::checkAndAcquireTargetID(object_id_t*
if (SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen,
SerializeIF::Endianness::BIG) != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service20ParameterManagement::checkAndAcquireTargetID: "
<< "Invalid data." << std::endl;
sif::error << "Service20ParameterManagement::checkAndAcquireTargetID: " << "Invalid data."
<< std::endl;
#else
sif::printError(
"Service20ParameterManagement::"

View File

@@ -197,8 +197,8 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
<< "reply command " << command << std::endl;
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with " << "reply command "
<< command << std::endl;
#else
sif::printWarning(
"Service3Housekeeping::handleReply: Invalid reply with "

View File

@@ -44,7 +44,7 @@ ReturnValue_t Service5EventReporting::performService() {
}
ReturnValue_t Service5EventReporting::generateEventReport(EventMessage message) {
EventReport report(message.getEvent(), message.getReporter(), message.getParameter1(),
EventReport report(message.getEventId(), message.getReporter(), message.getParameter1(),
message.getParameter2());
storeHelper.preparePacket(psbParams.serviceId, message.getSeverity(), tmHelper.sendCounter);
storeHelper.setSourceDataSerializable(report);

View File

@@ -17,13 +17,17 @@
*/
class EventReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3, 4
public:
EventReport(Event event_, object_id_t objectId_, uint32_t parameter1_, uint32_t parameter2_)
: event(event_), objectId(objectId_), parameter1(parameter1_), parameter2(parameter2_) {}
EventReport(EventId_t reportId_, object_id_t objectId_, uint32_t parameter1_,
uint32_t parameter2_)
: reportId(reportId_),
objectId(objectId_),
parameter1(parameter1_),
parameter2(parameter2_) {}
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const override {
ReturnValue_t result =
SerializeAdapter::serialize(&event, buffer, size, maxSize, streamEndianness);
SerializeAdapter::serialize(&reportId, buffer, size, maxSize, streamEndianness);
if (result != returnvalue::OK) {
return result;
}
@@ -44,7 +48,7 @@ class EventReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3,
size_t getSerializedSize() const override {
uint32_t size = 0;
size += SerializeAdapter::getSerializedSize(&event);
size += SerializeAdapter::getSerializedSize(&reportId);
size += SerializeAdapter::getSerializedSize(&objectId);
size += SerializeAdapter::getSerializedSize(&parameter1);
size += SerializeAdapter::getSerializedSize(&parameter2);
@@ -57,7 +61,7 @@ class EventReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3,
}
private:
Event event;
EventId_t reportId;
object_id_t objectId;
uint32_t parameter1;
uint32_t parameter2;

View File

@@ -68,9 +68,6 @@ class ListVector : public SerializeIF {
}
explicit ListVector(List& list) : entry() { list.addSerializable(*this); }
const T* get() const { return entry; }
T* getMut() { return entry; }
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
Endianness streamEndianness) const override {
ReturnValue_t result = returnvalue::OK;

View File

@@ -53,17 +53,17 @@ void fsfwPrint(sif::PrintLevel printType, const char *fmt, va_list arg) {
#endif
if (printType == sif::PrintLevel::INFO_LEVEL) {
len += sprintf(bufferPosition + len, "INFO ");
len += sprintf(bufferPosition + len, "INFO");
}
if (printType == sif::PrintLevel::DEBUG_LEVEL) {
len += sprintf(bufferPosition + len, "DEBUG ");
len += sprintf(bufferPosition + len, "DEBUG");
}
if (printType == sif::PrintLevel::WARNING_LEVEL) {
len += sprintf(bufferPosition + len, "WARNING");
}
if (printType == sif::PrintLevel::ERROR_LEVEL) {
len += sprintf(bufferPosition + len, "ERROR ");
len += sprintf(bufferPosition + len, "ERROR");
}
#if FSFW_COLORED_OUTPUT == 1
@@ -75,7 +75,7 @@ void fsfwPrint(sif::PrintLevel printType, const char *fmt, va_list arg) {
/*
* Log current time to terminal if desired.
*/
len += sprintf(bufferPosition + len, " | %02lu:%02lu:%02lu.%03lu | ", (unsigned long)now.hour,
len += sprintf(bufferPosition + len, " | %lu:%02lu:%02lu.%03lu | ", (unsigned long)now.hour,
(unsigned long)now.minute, (unsigned long)now.second,
(unsigned long)now.usecond / 1000);

View File

@@ -12,8 +12,7 @@ LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig,
spillsToHigherPools(spillsToHigherPools) {
if (NUMBER_OF_SUBPOOLS == 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPool::LocalPool: Passed pool configuration is "
<< " invalid!" << std::endl;
sif::error << "LocalPool::LocalPool: Passed pool configuration is " << " invalid!" << std::endl;
#endif
}
max_subpools_t index = 0;

View File

@@ -38,10 +38,9 @@ ReturnValue_t Subsystem::checkSequence(HybridIterator<ModeListEntry> iter,
if (!existsModeTable(iter->getTableId())) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
using namespace std;
sif::warning << "Subsystem::checkSequence: "
<< "Object " << setfill('0') << hex << "0x" << setw(8) << getObjectId()
<< setw(0) << ": Mode table for mode ID "
<< "0x" << setw(8) << iter->getTableId() << " does not exist" << dec << endl;
sif::warning << "Subsystem::checkSequence: " << "Object " << setfill('0') << hex << "0x"
<< setw(8) << getObjectId() << setw(0) << ": Mode table for mode ID " << "0x"
<< setw(8) << iter->getTableId() << " does not exist" << dec << endl;
#endif
return TABLE_DOES_NOT_EXIST;
} else {

View File

@@ -79,36 +79,22 @@ void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submod
}
if (healthHelper.healthTable->hasHealth(object)) {
switch (healthHelper.healthTable->getHealth(object)) {
case NEEDS_RECOVERY:
case FAULTY:
case PERMANENT_FAULTY:
ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND, HasModesIF::MODE_OFF,
SUBMODE_NONE);
break;
case HEALTHY:
if (modeHelper.isForced()) {
ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND_FORCED,
tableIter.value->getMode(), submodeToCommand);
} else {
if (healthHelper.healthTable->isFaulty(object)) {
ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND, HasModesIF::MODE_OFF,
SUBMODE_NONE);
} else {
if (modeHelper.isForced()) {
ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND_FORCED,
tableIter.value->getMode(), submodeToCommand);
} else {
if (healthHelper.healthTable->isCommandable(object)) {
ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND,
tableIter.value->getMode(), submodeToCommand);
}
break;
case EXTERNAL_CONTROL:
if (modeHelper.isForced()) {
ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND_FORCED,
tableIter.value->getMode(), submodeToCommand);
} else {
continue;
}
break;
default:
// This never happens
break;
}
}
} else {
ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND,
tableIter.value->getMode(), submodeToCommand);

View File

@@ -101,8 +101,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
if (result != returnvalue::OK) {
// Continue for now but print error output.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FixedSlotSequence::checkSequence:"
<< " Custom check failed!" << std::endl;
sif::error << "FixedSlotSequence::checkSequence:" << " Custom check failed!" << std::endl;
#endif
}
}

View File

@@ -142,7 +142,7 @@ class TemperatureSensor : public AbstractTemperatureSensor {
deltaTime = (uptime.tv_sec + uptime.tv_usec / 1000000.) -
(uptimeOfOldTemperature.tv_sec + uptimeOfOldTemperature.tv_usec / 1000000.);
deltaTemp = oldTemperature - outputTemperature.value;
deltaTemp = oldTemperature - outputTemperature;
if (deltaTemp < 0) {
deltaTemp = -deltaTemp;
}
@@ -160,13 +160,13 @@ class TemperatureSensor : public AbstractTemperatureSensor {
outputTemperature.setValid(PoolVariableIF::INVALID);
outputTemperature = thermal::INVALID_TEMPERATURE;
} else {
oldTemperature = outputTemperature.value;
oldTemperature = outputTemperature;
uptimeOfOldTemperature = uptime;
}
}
public:
float getTemperature() { return outputTemperature.value; }
float getTemperature() { return outputTemperature; }
bool isValid() { return outputTemperature.isValid(); }

View File

@@ -192,8 +192,6 @@ class Clock {
static MutexIF *timeMutex;
static uint16_t leapSeconds;
static bool leapSecondsSet;
static bool monotonicClockInitialized;
static timeval monotonicClockOffset;
};
#endif /* FSFW_TIMEMANAGER_CLOCK_H_ */

View File

@@ -1,4 +1,3 @@
#include <fsfw/globalfunctions/CRC.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/tmtcservices/SpacePacketParser.h>
@@ -7,8 +6,6 @@
SpacePacketParser::SpacePacketParser(std::vector<uint16_t> validPacketIds)
: validPacketIds(validPacketIds) {}
void SpacePacketParser::enableCrcCheck() { checkCrc = true; }
ReturnValue_t SpacePacketParser::parseSpacePackets(const uint8_t** buffer, const size_t maxSize,
FoundPacketInfo& packetInfo) {
if (buffer == nullptr or nextStartIdx > maxSize) {
@@ -34,11 +31,6 @@ ReturnValue_t SpacePacketParser::parseSpacePackets(const uint8_t** buffer, const
}
*buffer += packetInfo.sizeFound;
packetInfo.startIdx = localIdx + amountRead;
if (checkCrc) {
if (CRC::crc16ccitt(bufPtr + localIdx, packetSize) != 0) {
return CRC_CHECK_FAILED;
}
}
nextStartIdx = localIdx + amountRead + packetInfo.sizeFound;
amountRead = nextStartIdx;
return result;

View File

@@ -25,13 +25,6 @@ class SpacePacketParser {
static constexpr uint8_t INTERFACE_ID = CLASS_ID::SPACE_PACKET_PARSER;
static constexpr ReturnValue_t NO_PACKET_FOUND = MAKE_RETURN_CODE(0x00);
static constexpr ReturnValue_t SPLIT_PACKET = MAKE_RETURN_CODE(0x01);
static constexpr ReturnValue_t CRC_CHECK_FAILED = MAKE_RETURN_CODE(0x02);
/**
* brief If the last to bytes of a space packet hold a CRC16, this function can be used to enable
* the CRC16 check when parsing the data.
*/
void enableCrcCheck();
/**
* @brief Parser constructor.
@@ -68,7 +61,6 @@ class SpacePacketParser {
std::vector<uint16_t> validPacketIds;
size_t nextStartIdx = 0;
size_t amountRead = 0;
bool checkCrc = false;
};
#endif /* FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ */

View File

@@ -34,8 +34,7 @@ ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(unsigned int maxNumberOfPa
} else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcBridge::setMaxNumberOfPacketsStored: Number of "
<< "packets stored exceeds limits. "
<< "Keeping default value." << std::endl;
<< "packets stored exceeds limits. " << "Keeping default value." << std::endl;
#endif
return returnvalue::FAILED;
}
@@ -79,15 +78,13 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) {
result = handleTc();
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "TmTcBridge::performOperation: "
<< "Error handling TCs" << std::endl;
sif::debug << "TmTcBridge::performOperation: " << "Error handling TCs" << std::endl;
#endif
}
result = handleTm();
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "TmTcBridge::performOperation: "
<< "Error handling TMs" << std::endl;
sif::debug << "TmTcBridge::performOperation: " << "Error handling TMs" << std::endl;
#endif
}
return result;

View File

@@ -418,8 +418,8 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsById(gpioId_t gpioIdToCheck,
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO "
"definition with ID "
<< gpioIdToCheck << " detected. "
<< "Duplicate will be removed from map to add" << std::endl;
<< gpioIdToCheck << " detected. " << "Duplicate will be removed from map to add"
<< std::endl;
#else
sif::printWarning(
"LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition "

View File

@@ -49,8 +49,7 @@ ReturnValue_t I2cComIF::initializeInterface(CookieIF* cookie) {
if (not statusPair.second) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "I2cComIF::initializeInterface: Failed to insert device with address "
<< i2cAddress << "to I2C device "
<< "map" << std::endl;
<< i2cAddress << "to I2C device " << "map" << std::endl;
#endif
return returnvalue::FAILED;
}
@@ -91,8 +90,8 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
auto i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not "
<< "registered in i2cDeviceMap" << std::endl;
sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not " << "registered in i2cDeviceMap"
<< std::endl;
#endif
return returnvalue::FAILED;
}

View File

@@ -197,9 +197,8 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
if (result == MutexIF::MUTEX_TIMEOUT) {
sif::error << "SpiComIF::sendMessage: Lock timeout" << std::endl;
} else {
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
<< std::endl;
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code " << "0x" << std::hex
<< std::setfill('0') << std::setw(4) << result << std::dec << std::endl;
}
#else
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
@@ -307,9 +306,8 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
if (result != returnvalue::OK) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
<< std::endl;
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code " << "0x" << std::hex
<< std::setfill('0') << std::setw(4) << result << std::dec << std::endl;
#else
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
#endif

View File

@@ -1,4 +1,3 @@
target_sources(
${FSFW_TEST_TGT}
PRIVATE testLocalPoolVariable.cpp testLocalPoolVector.cpp testSharedSet.cpp
testPeriodicHkHelper.cpp testDataset.cpp)
${FSFW_TEST_TGT} PRIVATE testLocalPoolVariable.cpp testLocalPoolVector.cpp
testDataSet.cpp testPeriodicHkHelper.cpp)

View File

@@ -14,7 +14,7 @@
using namespace returnvalue;
using namespace lpool;
TEST_CASE("DataSetTest", "[datapool]") {
TEST_CASE("DataSetTest", "[DataSetTest]") {
auto queue = MessageQueueMock(1, MessageQueueIF::NO_QUEUE);
TestPoolOwner poolOwner(queue, objects::TEST_LOCAL_POOL_OWNER_BASE);
poolOwner.initialize();
@@ -23,7 +23,6 @@ TEST_CASE("DataSetTest", "[datapool]") {
SECTION("BasicTest") {
/* Test some basic functions */
CHECK(localSet.getReportingEnabled() == false);
CHECK(localSet.getSerializedSize() == 11);
CHECK(localSet.getLocalPoolIdsSerializedSize() == 3 * sizeof(dp::id_t));
CHECK(localSet.getStructureId() == lpool::testSid1);
CHECK(localSet.getCreatorObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE);
@@ -58,23 +57,17 @@ TEST_CASE("DataSetTest", "[datapool]") {
PoolReadGuard readHelper(&localSet);
REQUIRE(readHelper.getReadResult() == returnvalue::OK);
CHECK(localSet.localPoolVarUint8.value == 0);
CHECK(!localSet.localPoolVarUint8.isValid());
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(0.0));
CHECK(!localSet.localPoolVarFloat.isValid());
CHECK(localSet.localPoolUint16Vec.value[0] == 0);
CHECK(localSet.localPoolUint16Vec.value[1] == 0);
CHECK(localSet.localPoolUint16Vec.value[2] == 0);
CHECK(!localSet.localPoolUint16Vec.isValid());
// Now set new values, commit should be done by read helper automatically
localSet.localPoolVarUint8 = 232;
localSet.localPoolVarUint8.setValid(true);
localSet.localPoolVarFloat = -2324.322;
localSet.localPoolVarFloat.setValid(true);
localSet.localPoolUint16Vec.value[0] = 232;
localSet.localPoolUint16Vec.value[1] = 23923;
localSet.localPoolUint16Vec.value[2] = 1;
localSet.localPoolUint16Vec.setValid(true);
}
// Zero out some values for next test
@@ -92,13 +85,10 @@ TEST_CASE("DataSetTest", "[datapool]") {
PoolReadGuard readHelper(&localSet);
REQUIRE(readHelper.getReadResult() == returnvalue::OK);
CHECK(localSet.localPoolVarUint8.value == 232);
CHECK(localSet.localPoolVarUint8.isValid());
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(-2324.322));
CHECK(localSet.localPoolVarFloat.isValid());
CHECK(localSet.localPoolUint16Vec.value[0] == 232);
CHECK(localSet.localPoolUint16Vec.value[1] == 23923);
CHECK(localSet.localPoolUint16Vec.value[2] == 1);
CHECK(localSet.localPoolUint16Vec.isValid());
// Now we serialize these values into a buffer without the validity buffer
maxSize = localSet.getSerializedSize();
@@ -139,7 +129,7 @@ TEST_CASE("DataSetTest", "[datapool]") {
SECTION("SharedDataSet") {
object_id_t sharedSetId = objects::SHARED_SET_ID;
SharedSet sharedSet(poolOwner.sharedPool, sharedSetId, 5, false);
SharedSet sharedSet(poolOwner.sharedPool, sharedSetId, 5);
localSet.localPoolVarUint8.setReadWriteMode(pool_rwm_t::VAR_WRITE);
localSet.localPoolUint16Vec.setReadWriteMode(pool_rwm_t::VAR_WRITE);
CHECK(sharedSet.registerVariable(&localSet.localPoolVarUint8) == returnvalue::OK);
@@ -155,24 +145,4 @@ TEST_CASE("DataSetTest", "[datapool]") {
CHECK(sharedSet.commit() == returnvalue::OK);
}
}
SECTION("Serialize with Validity Blob") {
localSet.updateValidityBlobSerialization(true);
CHECK(!localSet.localPoolVarUint8.isValid());
CHECK(!localSet.localPoolUint16Vec.isValid());
CHECK(!localSet.localPoolVarFloat.isValid());
localSet.setChildrenValidity(true);
CHECK(localSet.localPoolVarUint8.isValid());
CHECK(localSet.localPoolUint16Vec.isValid());
CHECK(localSet.localPoolVarFloat.isValid());
size_t serSize = 0;
// Already reserve additional space for validity buffer, will be needed later
uint8_t buffer[128]{};
uint8_t* buffPtr = buffer;
CHECK(localSet.getSerializedSize() == 12);
CHECK(localSet.serialize(&buffPtr, &serSize, sizeof(buffer),
SerializeIF::Endianness::MACHINE) == returnvalue::OK);
CHECK(serSize == 12);
CHECK(buffer[11] == 0b11100000);
}
}

View File

@@ -1,85 +0,0 @@
#include <fsfw/housekeeping/Dataset.h>
#include <fsfw/housekeeping/DatasetElement.h>
#include <fsfw/serialize/SerializeElement.h>
#include <catch2/catch_test_macros.hpp>
constexpr auto TEST_ID = dp::structure_id_t(1, 2);
class TestDatasetSmall : public hk::Dataset {
public:
TestDatasetSmall() : hk::Dataset(TEST_ID, false) {}
hk::lvar_u8 test0{*this};
hk::lvar_u32 test1{*this};
};
class TestDatasetLarger : public hk::Dataset {
public:
TestDatasetLarger() : hk::Dataset(TEST_ID, false) {}
hk::lvar_u8 test0{*this};
hk::lvar_u32 test1{*this};
hk::lvar_u16 test2{*this};
hk::lvar_i32 test3{*this};
hk::lvar_f32 test4{*this};
hk::lvar_f64 test5{*this};
hk::lvar_u8 test6{*this};
hk::lvar_i16 test7{*this};
hk::lvec_u16<2> test8{*this};
};
TEST_CASE("Pool Dataset Test", "[datapool]") {
TestDatasetSmall dataset;
CHECK(dataset.getStructureId() == TEST_ID);
CHECK(!dataset.test0.isValid());
dataset.test0.setValid(true);
CHECK(dataset.test0.isValid());
SECTION("Pool Dataset Serialization Test 1") {
uint8_t buf[64]{};
dataset.test0 = 55;
dataset.test1 = 502392;
size_t serLen = 0;
CHECK(dataset.serialize(buf, serLen, sizeof(buf), SerializeIF::Endianness::NETWORK) ==
returnvalue::OK);
CHECK(buf[0] == 55);
CHECK(serLen == 5);
uint32_t readBack = 0;
size_t dummy = 0;
CHECK(SerializeAdapter::deSerialize(&readBack, buf + 1, &dummy,
SerializeIF::Endianness::NETWORK) == returnvalue::OK);
CHECK(readBack == 502392);
CHECK(buf[5] == 0);
}
SECTION("Pool Dataset Serialization With Validity") {
uint8_t buf[64]{};
dataset.test0 = 55;
dataset.test1 = 502392;
dataset.test0.setValid(true);
dataset.test1.setValid(true);
size_t serLen = 0;
uint8_t* dataPtr = buf;
dataset.serializeWithValidityBlob = true;
CHECK(dataset.getSerializedSize() == 6);
CHECK(dataset.serialize(&dataPtr, &serLen, sizeof(buf), SerializeIF::Endianness::NETWORK) ==
returnvalue::OK);
CHECK(buf[5] == 0b11000000);
}
SECTION("Larger Pool Dataset Serialization With Validity") {
uint8_t buf[64]{};
TestDatasetLarger datasetLarge;
datasetLarge.setChildrenValidity(true);
size_t serLen = 0;
uint8_t* dataPtr = buf;
datasetLarge.serializeWithValidityBlob = true;
CHECK(datasetLarge.serialize(&dataPtr, &serLen, sizeof(buf),
SerializeIF::Endianness::NETWORK) == returnvalue::OK);
CHECK(serLen == 32);
CHECK(buf[30] == 0b11111111);
CHECK(buf[31] == 0b10000000);
CHECK(buf[32] == 0);
}
}

View File

@@ -1,6 +1,5 @@
#pragma once
#include <fsfw/housekeeping/GeneratesPeriodicHkIF.h>
#include <fsfw/housekeeping/PeriodicHkHelper.h>
#include <fsfw/objectmanager/SystemObject.h>
#include "poolDefinitions.h"

View File

@@ -45,10 +45,9 @@ class Dataset : public List {
class StaticTestDataset : public StaticSharedSet<3> {
public:
StaticTestDataset() : StaticSharedSet(lpool::testSid1, false) {}
StaticTestDataset() : StaticSharedSet(lpool::testSid1) {}
StaticTestDataset(SharedPool& sharedPool, uint32_t setId)
: StaticSharedSet(sharedPool, setId, false) {}
StaticTestDataset(SharedPool& sharedPool, uint32_t setId) : StaticSharedSet(sharedPool, setId) {}
u8_t localPoolVarUint8{lpool::uint8VarGpid, this};
f32_t localPoolVarFloat{lpool::floatVarGpid, this};
@@ -59,10 +58,10 @@ class StaticTestDataset : public StaticSharedSet<3> {
class TestDataset : public SharedSet {
public:
TestDataset() : SharedSet(lpool::testSid2, lpool::dataSetMaxVariables, false) {}
TestDataset() : SharedSet(lpool::testSid2, lpool::dataSetMaxVariables) {}
TestDataset(SharedPool& sharedPool, uint32_t setId)
: SharedSet(sharedPool, setId, lpool::dataSetMaxVariables, false) {}
: SharedSet(sharedPool, setId, lpool::dataSetMaxVariables) {}
u8_t localPoolVarUint8{lpool::uint8VarGpid, this};
f32_t localPoolVarFloat{lpool::floatVarGpid, this};