Compare commits
24 Commits
refactor-p
...
event-defi
Author | SHA1 | Date | |
---|---|---|---|
a994be47c3 | |||
893e0a41d7 | |||
b8979d8f90 | |||
9557db7036 | |||
c9fcabccd6 | |||
ecd36f5e52 | |||
fc19c0838e | |||
8c3f366d1a | |||
6efb2641a7 | |||
260bbad9a0 | |||
9edd6221f8 | |||
735e341aab | |||
921bfb1e99 | |||
5b1651e1a6 | |||
e916b9b096 | |||
b14e761bad | |||
33f3ae2434 | |||
f0087d5b0d | |||
69c33587e8 | |||
d1bf04cc29 | |||
8e3bc1b8aa | |||
64f97fc3ba | |||
1427fbd2fe | |||
81cd8bd290 |
15
CHANGELOG.md
15
CHANGELOG.md
@ -26,6 +26,7 @@ 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.
|
||||
@ -34,8 +35,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Changed
|
||||
|
||||
- Complete refactoring of HK subsystem. Replaced local data pool manager by periodic HK
|
||||
- Complete overhaul of HK subsystem. Replaced local data pool manager by periodic HK
|
||||
helper. The shared pool and the periodic HK generation are now distinct concepts.
|
||||
- The local HK manager was replaced by a periodic HK helper which has reduced responsibilities.
|
||||
It takes care of tracking the HK generation using a set specification provided by the user.n
|
||||
However, it leaves serialization of the HK data completely to the developer. This removes a major
|
||||
constraint on the format of the HK data, which was previously constrained to implementors of a
|
||||
certain base class.
|
||||
- The former set classes and pool objects are still available for HK set specification and
|
||||
generation. The API has changed, but the general usage and their architecture has not.
|
||||
- A new set of set classes and helper objects to specify HK sets and data which does not need to be
|
||||
shared was added as well. The majority of datasets do not need to be shared anyway.
|
||||
- The non-shared API retain the capability of appending of a validity blob for each piece of set
|
||||
data at the end of the HK data. For both non-shared and shared data, this capability can be
|
||||
specified in the constructor, and defaults to true.
|
||||
- Improved File System Abstraction to be more in line with normal filesystems.
|
||||
- CFDP implementation was improved, has now even less dependencies on other FSFW components
|
||||
and allows one inserted packet per state machine call.
|
||||
|
@ -142,7 +142,7 @@ if(FSFW_BUILD_TESTS)
|
||||
configure_file(unittests/testcfg/TestsConfig.h.in tests/TestsConfig.h)
|
||||
|
||||
project(${FSFW_TEST_TGT} CXX C)
|
||||
add_executable(${FSFW_TEST_TGT} unittests/datapool/testDataset.cpp)
|
||||
add_executable(${FSFW_TEST_TGT})
|
||||
if(IPO_SUPPORTED AND FSFW_ENABLE_IPO)
|
||||
set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION
|
||||
TRUE)
|
||||
|
@ -34,11 +34,12 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
ActionHelper actionHelper;
|
||||
|
||||
// Periodic HK methods, default method assumes that no shared pool is required.
|
||||
virtual datapool::SharedPool* getOptionalSharedPool() override;
|
||||
datapool::SharedPool* getOptionalSharedPool() override = 0;
|
||||
|
||||
// Periodic HK abstract methods.
|
||||
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf, size_t maxSize) = 0;
|
||||
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) = 0;
|
||||
ReturnValue_t serializeHkDataset(dp::sid_t structureId, uint8_t* buf,
|
||||
size_t maxSize) override = 0;
|
||||
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) override = 0;
|
||||
|
||||
/**
|
||||
* Implemented by child class. Handle all command messages which are
|
||||
|
@ -48,6 +48,14 @@ 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);
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||
const size_t maxFillCount, bool serializeWithValidityBlob)
|
||||
: registeredVariables(registeredVariablesArray),
|
||||
maxFillCount(maxFillCount),
|
||||
serializeWithValidityBlob(serializeWithValidityBlob) {}
|
||||
: serializeWithValidityBlob(serializeWithValidityBlob),
|
||||
registeredVariables(registeredVariablesArray),
|
||||
maxFillCount(maxFillCount) {}
|
||||
|
||||
PoolDataSetBase::~PoolDataSetBase() = default;
|
||||
|
||||
@ -251,6 +251,9 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,8 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
||||
*/
|
||||
void setChildrenValidity(bool valid);
|
||||
|
||||
bool serializeWithValidityBlob = false;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief The fill_count attribute ensures that the variables
|
||||
@ -166,7 +168,6 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF {
|
||||
*/
|
||||
PoolVariableIF** registeredVariables = nullptr;
|
||||
const size_t maxFillCount = 0;
|
||||
bool serializeWithValidityBlob = false;
|
||||
|
||||
void setContainer(PoolVariableIF** variablesContainer);
|
||||
PoolVariableIF** getContainer() const;
|
||||
|
@ -20,9 +20,9 @@ class PoolReadGuard {
|
||||
if (readResult != returnvalue::OK) {
|
||||
#if FSFW_VERBOSE_LEVEL == 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PoolReadHelper: Read failed!" << std::endl;
|
||||
sif::error << "PoolReadGuard: Read failed!" << std::endl;
|
||||
#else
|
||||
sif::printError("PoolReadHelper: Read failed!\n");
|
||||
sif::printError("PoolReadGuard: Read failed!\n");
|
||||
#endif /* FSFW_PRINT_VERBOSITY_LEVEL == 1 */
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
}
|
||||
|
@ -210,6 +210,7 @@ inline ReturnValue_t PoolVariable<T>::readWithoutLock() {
|
||||
}
|
||||
|
||||
this->value = *(poolEntry->getDataPtr());
|
||||
this->valid = poolEntry->getValid();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -241,6 +242,7 @@ ReturnValue_t PoolVariable<T>::commitWithoutLock() {
|
||||
}
|
||||
|
||||
*(poolEntry->getDataPtr()) = this->value;
|
||||
poolEntry->setValid(this->valid);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
using namespace dp;
|
||||
|
||||
SharedSet::SharedSet(dp::SharedPool& sharedPool, uint32_t setId, const size_t maxNumberOfVariables,
|
||||
bool serializeWithValídityBlob)
|
||||
bool serializeWithValidityBlob)
|
||||
: SharedSetBase(sharedPool, setId, nullptr, maxNumberOfVariables, serializeWithValidityBlob),
|
||||
poolVarList(maxNumberOfVariables) {
|
||||
this->setContainer(poolVarList.data());
|
||||
|
@ -105,9 +105,6 @@ ReturnValue_t SharedSetBase::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
|
||||
ReturnValue_t SharedSetBase::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
SerializeIF::Endianness streamEndianness) const {
|
||||
if (serializeWithValidityBlob) {
|
||||
return base.doSerializeWithValidityBlob(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
return base.serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
@ -143,10 +140,17 @@ void SharedSetBase::setAllVariablesReadOnly() {
|
||||
void SharedSetBase::printSet() { return; }
|
||||
|
||||
ReturnValue_t SharedSetBase::read(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||
return base.read(timeoutType, timeoutMs);
|
||||
lockDataPool(timeoutType, timeoutMs);
|
||||
ReturnValue_t result = base.read(timeoutType, timeoutMs);
|
||||
unlockDataPool();
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t SharedSetBase::commit(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||
return base.commit(timeoutType, timeoutMs);
|
||||
lockDataPool(timeoutType, timeoutMs);
|
||||
ReturnValue_t result = base.commit(timeoutType, timeoutMs);
|
||||
unlockDataPool();
|
||||
return result;
|
||||
}
|
||||
uint16_t SharedSetBase::getFillCount() const { return base.getFillCount(); }
|
||||
|
||||
@ -158,3 +162,8 @@ 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; }
|
||||
|
@ -159,11 +159,8 @@ class SharedSetBase : public SerializeIF, public PoolDataSetIF {
|
||||
*/
|
||||
void setChildrenValidity(bool valid);
|
||||
|
||||
/**
|
||||
* If the valid state of a dataset is always relevant to the whole
|
||||
* data set we can use this flag.
|
||||
*/
|
||||
bool serializeWithValidityBlob = false;
|
||||
void updateValidityBlobSerialization(bool enable);
|
||||
bool getValidityBlobSerialization() const;
|
||||
|
||||
protected:
|
||||
PoolDataSetBase base;
|
||||
|
@ -148,20 +148,24 @@ class FreshDeviceHandlerBase : public SystemObject,
|
||||
// System Object overrides.
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
// Default implementation assumes that no optional shared pool is required.
|
||||
datapool::SharedPool* getOptionalSharedPool() 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.
|
||||
* 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 serializeHkDataset(dp::sid_t structureId, uint8_t* buf, size_t maxSize) override = 0;
|
||||
/**
|
||||
* This function is implemented by the user to specify the available housekeeping sets.
|
||||
*/
|
||||
ReturnValue_t specifyHkDatasets(std::vector<hk::SetSpecification>& setList) override = 0;
|
||||
|
||||
/*
|
||||
* If this device handler has an optional pool, return it. Otherwise, nullptr can be returned.
|
||||
*/
|
||||
datapool::SharedPool* getOptionalSharedPool() override = 0;
|
||||
|
||||
/**
|
||||
* Implemented by child class. Handle all command messages which are
|
||||
* not health, mode, action or housekeeping messages.
|
||||
@ -202,7 +206,6 @@ class FreshDeviceHandlerBase : public SystemObject,
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
/**
|
||||
* This calls the FDIR instance event trigger function.
|
||||
|
@ -1,9 +1,4 @@
|
||||
#ifndef FSFW_INC_FSFW_HOUSEKEEPING_H_
|
||||
#define FSFW_INC_FSFW_HOUSEKEEPING_H_
|
||||
#pragma once
|
||||
|
||||
#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_ */
|
||||
#include "fsfw/housekeeping/Dataset.h"
|
||||
#include "fsfw/housekeeping/DatasetElement.h"
|
@ -17,12 +17,6 @@ class Dataset : public SerializeIF {
|
||||
|
||||
[[nodiscard]] dp::structure_id_t getStructureId() const { return sid; }
|
||||
|
||||
void setAllChildrenValidity(bool valid) {
|
||||
for (auto &serializable : serializables) {
|
||||
serializable.get().setValid(valid);
|
||||
}
|
||||
}
|
||||
|
||||
void addSerializable(const std::reference_wrapper<SerializableWithValidityIF> serializable) {
|
||||
serializables.push_back(serializable);
|
||||
}
|
||||
@ -95,11 +89,20 @@ class Dataset : public SerializeIF {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ PeriodicHelper::PeriodicHelper(GeneratesPeriodicHkIF* owner, MessageQueueIF* que
|
||||
MessageQueueId_t hkDestQueue)
|
||||
: hkDestinationId(hkDestQueue) {
|
||||
if (owner == nullptr) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "LocalDataPoolManager", returnvalue::FAILED,
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "PeriodicHkHelper", returnvalue::FAILED,
|
||||
"Invalid supplied owner");
|
||||
return;
|
||||
}
|
||||
@ -200,11 +200,10 @@ void PeriodicHelper::performPeriodicHkGeneration(SetSpecification& setSpec, time
|
||||
if (result != returnvalue::OK) {
|
||||
// Configuration error
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed."
|
||||
sif::warning << "hk::PeriodicHelper::performPeriodicHkOperation: HK generation failed."
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n");
|
||||
sif::printWarning("hk::PeriodicHelper::performPeriodicHkOperation: HK generation failed.\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "fsfw/globalfunctions/timevalOperations.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterfacePrinter.h"
|
||||
#include "fsfw/osal/freertos/Timekeeper.h"
|
||||
#include "task.h"
|
||||
|
||||
@ -47,8 +48,8 @@ ReturnValue_t Clock::getClock(timeval* time) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClockMonotonic(timeval* time) {
|
||||
// TODO: I don't actually know if the timekeeper is monotonic..
|
||||
return getClock_timeval(time);
|
||||
*time = Timekeeper::instance()->getMonotonicClockOffset() + getUptime();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
@ -58,7 +59,7 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
}
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
TickType_t ticksSinceStart = xTaskGetTickCount();
|
||||
TickType_t ticksSinceStart = Timekeeper::instance()->getTicks();
|
||||
return Timekeeper::ticksToTimeval(ticksSinceStart);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,13 @@ Timekeeper* Timekeeper::instance() {
|
||||
return myinstance;
|
||||
}
|
||||
|
||||
void Timekeeper::setOffset(const timeval& offset) { this->offset = offset; }
|
||||
void Timekeeper::setOffset(const timeval& offset) {
|
||||
if (not monotonicClockInitialized) {
|
||||
this->monotonicClockOffset = offset;
|
||||
monotonicClockInitialized = true;
|
||||
}
|
||||
this->offset = offset;
|
||||
}
|
||||
|
||||
timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
|
||||
timeval uptime;
|
||||
@ -33,3 +39,7 @@ timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
|
||||
}
|
||||
|
||||
TickType_t Timekeeper::getTicks() { return xTaskGetTickCount(); }
|
||||
|
||||
const timeval Timekeeper::getMonotonicClockOffset() const {
|
||||
return monotonicClockOffset;
|
||||
}
|
||||
|
@ -18,9 +18,14 @@ 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();
|
||||
@ -34,6 +39,7 @@ class Timekeeper {
|
||||
|
||||
const timeval& getOffset() const;
|
||||
void setOffset(const timeval& offset);
|
||||
const timeval getMonotonicClockOffset() const;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ */
|
||||
|
@ -49,7 +49,7 @@ class Service11TelecommandScheduling final : public PusServiceBase {
|
||||
|
||||
//! [EXPORT] : [COMMENT] Deletion of a TC from the map failed.
|
||||
//! P1: First 32 bit of request ID, P2. Last 32 bit of Request ID
|
||||
static constexpr Event TC_DELETION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
static constexpr Event TC_DELETION_FAILED = MAKE_EVENT(0, severity::MEDIUM);
|
||||
|
||||
// The types of PUS-11 subservices
|
||||
enum Subservice : uint8_t {
|
||||
|
@ -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, " | %lu:%02lu:%02lu.%03lu | ", (unsigned long)now.hour,
|
||||
len += sprintf(bufferPosition + len, " | %02lu:%02lu:%02lu.%03lu | ", (unsigned long)now.hour,
|
||||
(unsigned long)now.minute, (unsigned long)now.second,
|
||||
(unsigned long)now.usecond / 1000);
|
||||
|
||||
|
@ -79,22 +79,36 @@ void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submod
|
||||
}
|
||||
|
||||
if (healthHelper.healthTable->hasHealth(object)) {
|
||||
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)) {
|
||||
|
||||
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 {
|
||||
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);
|
||||
|
@ -25,7 +25,7 @@ static constexpr ReturnValue_t INCORRECT_SECONDARY_HEADER = MAKE_RETURN_CODE(11)
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TMTC_DISTRIBUTION;
|
||||
//! P1: Returnvalue, P2: 0 for TM issues, 1 for TC issues
|
||||
static constexpr Event HANDLE_PACKET_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
|
||||
static constexpr Event HANDLE_PACKET_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||
|
||||
}; // namespace tmtcdistrib
|
||||
#endif // FSFW_TMTCPACKET_DEFINITIONS_H
|
||||
|
@ -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;
|
||||
deltaTemp = oldTemperature - outputTemperature.value;
|
||||
if (deltaTemp < 0) {
|
||||
deltaTemp = -deltaTemp;
|
||||
}
|
||||
@ -160,13 +160,13 @@ class TemperatureSensor : public AbstractTemperatureSensor {
|
||||
outputTemperature.setValid(PoolVariableIF::INVALID);
|
||||
outputTemperature = thermal::INVALID_TEMPERATURE;
|
||||
} else {
|
||||
oldTemperature = outputTemperature;
|
||||
oldTemperature = outputTemperature.value;
|
||||
uptimeOfOldTemperature = uptime;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
float getTemperature() { return outputTemperature; }
|
||||
float getTemperature() { return outputTemperature.value; }
|
||||
|
||||
bool isValid() { return outputTemperature.isValid(); }
|
||||
|
||||
|
@ -192,6 +192,8 @@ class Clock {
|
||||
static MutexIF *timeMutex;
|
||||
static uint16_t leapSeconds;
|
||||
static bool leapSecondsSet;
|
||||
static bool monotonicClockInitialized;
|
||||
static timeval monotonicClockOffset;
|
||||
};
|
||||
|
||||
#endif /* FSFW_TIMEMANAGER_CLOCK_H_ */
|
||||
|
@ -62,6 +62,7 @@ TEST_CASE("Pool Dataset Test", "[datapool]") {
|
||||
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);
|
||||
@ -70,7 +71,7 @@ TEST_CASE("Pool Dataset Test", "[datapool]") {
|
||||
SECTION("Larger Pool Dataset Serialization With Validity") {
|
||||
uint8_t buf[64]{};
|
||||
TestDatasetLarger datasetLarge;
|
||||
datasetLarge.setAllChildrenValidity(true);
|
||||
datasetLarge.setChildrenValidity(true);
|
||||
size_t serLen = 0;
|
||||
uint8_t* dataPtr = buf;
|
||||
datasetLarge.serializeWithValidityBlob = true;
|
||||
|
@ -23,6 +23,7 @@ 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);
|
||||
@ -156,7 +157,7 @@ TEST_CASE("DataSetTest", "[datapool]") {
|
||||
}
|
||||
|
||||
SECTION("Serialize with Validity Blob") {
|
||||
localSet.serializeWithValidityBlob = true;
|
||||
localSet.updateValidityBlobSerialization(true);
|
||||
CHECK(!localSet.localPoolVarUint8.isValid());
|
||||
CHECK(!localSet.localPoolUint16Vec.isValid());
|
||||
CHECK(!localSet.localPoolVarFloat.isValid());
|
||||
@ -168,6 +169,7 @@ TEST_CASE("DataSetTest", "[datapool]") {
|
||||
// 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);
|
||||
|
Reference in New Issue
Block a user