diff --git a/.idea/cmake.xml b/.idea/cmake.xml
new file mode 100644
index 00000000..b0a4921a
--- /dev/null
+++ b/.idea/cmake.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d3e03c4f..9f5bb9bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,40 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
+## Fixes
+
+- The `PusTmCreator` API only accepted 255 bytes of source data. It can now accept source
+ data with a size limited only by the size of `size_t`.
+- Important bugfix in CFDP PDU header format: The entity length field and the transaction sequence
+ number fields stored the actual length of the field instead of the length minus 1 like specified
+ in the CFDP standard.
+- PUS Health Service: Size check for set health command.
+ Perform operation completion for announce health command.
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/746
+- Linux OSAL `getUptime` fix: Check validity of `/proc/uptime` file before reading uptime.
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/745
+- Small tweak for version getter
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/744
+
+## Added
+
+- add CFDP subsystem ID
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742
+- `PusTmZcWriter` now exposes API to set message counter field.
+
+## Changed
+
+- HK generation is now countdown based.
+- Bump ETL version to 20.35.14
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/748
+- Renamed `PCDU_2` subsystem ID to `POWER_SWITCH_IF`.
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/743
+- Add new `PowerSwitchIF::SWITCH_UNKNOWN` returnvalue.
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/743
+- Assert that `FixedArrayList` is larger than 0 at compile time.
+ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/740
+- Health functions are virtual now.
+
# [v6.0.0] 2023-02-10
## Fixes
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5eddde7f..5d35e6ff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,7 +72,7 @@ set(FSFW_ETL_LIB_MAJOR_VERSION
20
CACHE STRING "ETL library major version requirement")
set(FSFW_ETL_LIB_VERSION
- ${FSFW_ETL_LIB_MAJOR_VERSION}.28.0
+ ${FSFW_ETL_LIB_MAJOR_VERSION}.35.14
CACHE STRING "ETL library exact version requirement")
set(FSFW_ETL_LINK_TARGET etl::etl)
diff --git a/src/fsfw/action/ActionHelper.cpp b/src/fsfw/action/ActionHelper.cpp
index fd6c8afb..81a1a727 100644
--- a/src/fsfw/action/ActionHelper.cpp
+++ b/src/fsfw/action/ActionHelper.cpp
@@ -59,17 +59,24 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
store_address_t dataAddress) {
+ bool hasAdditionalData = false;
const uint8_t* dataPtr = nullptr;
size_t size = 0;
- ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
- if (result != returnvalue::OK) {
- CommandMessage reply;
- ActionMessage::setStepReply(&reply, actionId, 0, result);
- queueToUse->sendMessage(commandedBy, &reply);
- return;
+ ReturnValue_t result;
+ if (dataAddress != store_address_t::invalid()) {
+ hasAdditionalData = true;
+ ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
+ if (result != returnvalue::OK) {
+ CommandMessage reply;
+ ActionMessage::setStepReply(&reply, actionId, 0, result);
+ queueToUse->sendMessage(commandedBy, &reply);
+ return;
+ }
}
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
- ipcStore->deleteData(dataAddress);
+ if (hasAdditionalData) {
+ ipcStore->deleteData(dataAddress);
+ }
if (result == HasActionsIF::EXECUTION_FINISHED) {
CommandMessage reply;
ActionMessage::setCompletionReply(&reply, actionId, true, result);
diff --git a/src/fsfw/cfdp.h b/src/fsfw/cfdp.h
index f6c01ad0..b2645978 100644
--- a/src/fsfw/cfdp.h
+++ b/src/fsfw/cfdp.h
@@ -2,7 +2,6 @@
#define FSFW_CFDP_H
#include "cfdp/definitions.h"
-#include "cfdp/handler/CfdpHandler.h"
#include "cfdp/handler/DestHandler.h"
#include "cfdp/handler/FaultHandlerBase.h"
#include "cfdp/helpers.h"
diff --git a/src/fsfw/cfdp/handler/CMakeLists.txt b/src/fsfw/cfdp/handler/CMakeLists.txt
index d96ce91c..7ad995c0 100644
--- a/src/fsfw/cfdp/handler/CMakeLists.txt
+++ b/src/fsfw/cfdp/handler/CMakeLists.txt
@@ -1,3 +1,2 @@
-target_sources(
- ${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp
- FaultHandlerBase.cpp UserBase.cpp CfdpHandler.cpp)
+target_sources(${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp
+ FaultHandlerBase.cpp UserBase.cpp)
diff --git a/src/fsfw/cfdp/handler/CfdpHandler.cpp b/src/fsfw/cfdp/handler/CfdpHandler.cpp
deleted file mode 100644
index 902097b6..00000000
--- a/src/fsfw/cfdp/handler/CfdpHandler.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-#include "CfdpHandler.h"
-
-#include "fsfw/cfdp/pdu/AckPduReader.h"
-#include "fsfw/cfdp/pdu/PduHeaderReader.h"
-#include "fsfw/globalfunctions/arrayprinter.h"
-#include "fsfw/ipc/QueueFactory.h"
-#include "fsfw/tmtcservices/TmTcMessage.h"
-
-using namespace returnvalue;
-using namespace cfdp;
-
-CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg)
- : SystemObject(fsfwParams.objectId),
- msgQueue(fsfwParams.msgQueue),
- destHandler(
- DestHandlerParams(LocalEntityCfg(cfdpCfg.id, cfdpCfg.indicCfg, cfdpCfg.faultHandler),
- cfdpCfg.userHandler, cfdpCfg.remoteCfgProvider, cfdpCfg.packetInfoList,
- cfdpCfg.lostSegmentsList),
- FsfwParams(fsfwParams.packetDest, nullptr, this, fsfwParams.tcStore,
- fsfwParams.tmStore)) {
- destHandler.setMsgQueue(msgQueue);
-}
-
-[[nodiscard]] const char* CfdpHandler::getName() const { return "CFDP Handler"; }
-
-[[nodiscard]] uint32_t CfdpHandler::getIdentifier() const {
- return destHandler.getDestHandlerParams().cfg.localId.getValue();
-}
-
-[[nodiscard]] MessageQueueId_t CfdpHandler::getRequestQueue() const { return msgQueue.getId(); }
-
-ReturnValue_t CfdpHandler::initialize() {
- ReturnValue_t result = destHandler.initialize();
- if (result != OK) {
- return result;
- }
- tcStore = destHandler.getTcStore();
- tmStore = destHandler.getTmStore();
-
- return SystemObject::initialize();
-}
-
-ReturnValue_t CfdpHandler::performOperation(uint8_t operationCode) {
- // TODO: Receive TC packets and route them to source and dest handler, depending on which is
- // correct or more appropriate
- ReturnValue_t status;
- ReturnValue_t result = OK;
- TmTcMessage tmtcMsg;
- for (status = msgQueue.receiveMessage(&tmtcMsg); status == returnvalue::OK;
- status = msgQueue.receiveMessage(&tmtcMsg)) {
- result = handleCfdpPacket(tmtcMsg);
- if (result != OK) {
- status = result;
- }
- }
- auto& fsmRes = destHandler.performStateMachine();
- // TODO: Error handling?
- while (fsmRes.callStatus == CallStatus::CALL_AGAIN) {
- destHandler.performStateMachine();
- // TODO: Error handling?
- }
- return status;
-}
-
-ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) {
- auto accessorPair = tcStore->getData(msg.getStorageId());
- if (accessorPair.first != OK) {
- return accessorPair.first;
- }
- PduHeaderReader reader(accessorPair.second.data(), accessorPair.second.size());
- ReturnValue_t result = reader.parseData();
- if (result != returnvalue::OK) {
- return INVALID_PDU_FORMAT;
- }
- // The CFDP distributor should have taken care of ensuring the destination ID is correct
- PduType type = reader.getPduType();
- // Only the destination handler can process these PDUs
- if (type == PduType::FILE_DATA) {
- // Disable auto-deletion of packet
- accessorPair.second.release();
- PacketInfo info(type, msg.getStorageId());
- result = destHandler.passPacket(info);
- } else {
- // Route depending on PDU type and directive type if applicable. It retrieves directive type
- // from the raw stream for better performance (with sanity and directive code check).
- // The routing is based on section 4.5 of the CFDP standard which specifies the PDU forwarding
- // procedure.
-
- // PDU header only. Invalid supplied data. A directive packet should have a valid data field
- // with at least one byte being the directive code
- const uint8_t* pduDataField = reader.getPduDataField();
- if (pduDataField == nullptr) {
- return INVALID_PDU_FORMAT;
- }
- if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) {
- return INVALID_DIRECTIVE_FIELD;
- }
- auto directive = static_cast(pduDataField[0]);
-
- auto passToDestHandler = [&]() {
- accessorPair.second.release();
- PacketInfo info(type, msg.getStorageId(), directive);
- result = destHandler.passPacket(info);
- };
- auto passToSourceHandler = [&]() {
-
- };
- if (directive == FileDirective::METADATA or directive == FileDirective::EOF_DIRECTIVE or
- directive == FileDirective::PROMPT) {
- // Section b) of 4.5.3: These PDUs should always be targeted towards the file receiver a.k.a.
- // the destination handler
- passToDestHandler();
- } else if (directive == FileDirective::FINISH or directive == FileDirective::NAK or
- directive == FileDirective::KEEP_ALIVE) {
- // Section c) of 4.5.3: These PDUs should always be targeted towards the file sender a.k.a.
- // the source handler
- passToSourceHandler();
- } else if (directive == FileDirective::ACK) {
- // Section a): Recipient depends of the type of PDU that is being acknowledged. We can simply
- // extract the PDU type from the raw stream. If it is an EOF PDU, this packet is passed to
- // the source handler, for a Finished PDU, it is passed to the destination handler.
- FileDirective ackedDirective;
- if (not AckPduReader::checkAckedDirectiveField(pduDataField[1], ackedDirective)) {
- return INVALID_ACK_DIRECTIVE_FIELDS;
- }
- if (ackedDirective == FileDirective::EOF_DIRECTIVE) {
- passToSourceHandler();
- } else if (ackedDirective == FileDirective::FINISH) {
- passToDestHandler();
- }
- }
- }
- return result;
-}
diff --git a/src/fsfw/cfdp/handler/CfdpHandler.h b/src/fsfw/cfdp/handler/CfdpHandler.h
deleted file mode 100644
index 2de9f7dd..00000000
--- a/src/fsfw/cfdp/handler/CfdpHandler.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
-#define FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
-
-#include
-
-#include "fsfw/cfdp/handler/DestHandler.h"
-#include "fsfw/objectmanager/SystemObject.h"
-#include "fsfw/tasks/ExecutableObjectIF.h"
-#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
-#include "fsfw/tmtcservices/TmTcMessage.h"
-
-struct FsfwHandlerParams {
- FsfwHandlerParams(object_id_t objectId, HasFileSystemIF& vfs, AcceptsTelemetryIF& packetDest,
- StorageManagerIF& tcStore, StorageManagerIF& tmStore, MessageQueueIF& msgQueue)
- : objectId(objectId),
- vfs(vfs),
- packetDest(packetDest),
- tcStore(tcStore),
- tmStore(tmStore),
- msgQueue(msgQueue) {}
- object_id_t objectId{};
- HasFileSystemIF& vfs;
- AcceptsTelemetryIF& packetDest;
- StorageManagerIF& tcStore;
- StorageManagerIF& tmStore;
- MessageQueueIF& msgQueue;
-};
-
-struct CfdpHandlerCfg {
- CfdpHandlerCfg(cfdp::EntityId localId, cfdp::IndicationCfg indicationCfg,
- cfdp::UserBase& userHandler, cfdp::FaultHandlerBase& userFaultHandler,
- cfdp::PacketInfoListBase& packetInfo, cfdp::LostSegmentsListBase& lostSegmentsList,
- cfdp::RemoteConfigTableIF& remoteCfgProvider)
- : id(std::move(localId)),
- indicCfg(indicationCfg),
- packetInfoList(packetInfo),
- lostSegmentsList(lostSegmentsList),
- remoteCfgProvider(remoteCfgProvider),
- userHandler(userHandler),
- faultHandler(userFaultHandler) {}
-
- cfdp::EntityId id;
- cfdp::IndicationCfg indicCfg;
- cfdp::PacketInfoListBase& packetInfoList;
- cfdp::LostSegmentsListBase& lostSegmentsList;
- cfdp::RemoteConfigTableIF& remoteCfgProvider;
- cfdp::UserBase& userHandler;
- cfdp::FaultHandlerBase& faultHandler;
-};
-
-class CfdpHandler : public SystemObject, public ExecutableObjectIF, public AcceptsTelecommandsIF {
- public:
- explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg);
-
- [[nodiscard]] const char* getName() const override;
- [[nodiscard]] uint32_t getIdentifier() const override;
- [[nodiscard]] MessageQueueId_t getRequestQueue() const override;
-
- ReturnValue_t initialize() override;
- ReturnValue_t performOperation(uint8_t operationCode) override;
-
- private:
- MessageQueueIF& msgQueue;
- cfdp::DestHandler destHandler;
- StorageManagerIF* tcStore = nullptr;
- StorageManagerIF* tmStore = nullptr;
-
- ReturnValue_t handleCfdpPacket(TmTcMessage& msg);
-};
-
-#endif // FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
diff --git a/src/fsfw/cfdp/pdu/HeaderCreator.cpp b/src/fsfw/cfdp/pdu/HeaderCreator.cpp
index 29688575..2db3953c 100644
--- a/src/fsfw/cfdp/pdu/HeaderCreator.cpp
+++ b/src/fsfw/cfdp/pdu/HeaderCreator.cpp
@@ -24,8 +24,8 @@ ReturnValue_t HeaderCreator::serialize(uint8_t **buffer, size_t *size, size_t ma
*buffer += 1;
**buffer = pduDataFieldLen & 0x00ff;
*buffer += 1;
- **buffer = segmentationCtrl << 7 | pduConf.sourceId.getWidth() << 4 | segmentMetadataFlag << 3 |
- pduConf.seqNum.getWidth();
+ **buffer = segmentationCtrl << 7 | ((pduConf.sourceId.getWidth() - 1) << 4) |
+ segmentMetadataFlag << 3 | (pduConf.seqNum.getWidth() - 1);
*buffer += 1;
*size += 4;
ReturnValue_t result = pduConf.sourceId.serialize(buffer, size, maxSize, streamEndianness);
diff --git a/src/fsfw/cfdp/pdu/HeaderReader.cpp b/src/fsfw/cfdp/pdu/HeaderReader.cpp
index 9edf2394..de3d2906 100644
--- a/src/fsfw/cfdp/pdu/HeaderReader.cpp
+++ b/src/fsfw/cfdp/pdu/HeaderReader.cpp
@@ -78,11 +78,11 @@ cfdp::SegmentationControl PduHeaderReader::getSegmentationControl() const {
}
cfdp::WidthInBytes PduHeaderReader::getLenEntityIds() const {
- return static_cast((pointers.fixedHeader->fourthByte >> 4) & 0x07);
+ return static_cast(((pointers.fixedHeader->fourthByte >> 4) & 0b111) + 1);
}
cfdp::WidthInBytes PduHeaderReader::getLenSeqNum() const {
- return static_cast(pointers.fixedHeader->fourthByte & 0x07);
+ return static_cast((pointers.fixedHeader->fourthByte & 0b111) + 1);
}
cfdp::SegmentMetadataFlag PduHeaderReader::getSegmentMetadataFlag() const {
diff --git a/src/fsfw/controller/ControllerBase.cpp b/src/fsfw/controller/ControllerBase.cpp
index c41c4121..2c151f5a 100644
--- a/src/fsfw/controller/ControllerBase.cpp
+++ b/src/fsfw/controller/ControllerBase.cpp
@@ -58,7 +58,7 @@ void ControllerBase::handleQueue() {
void ControllerBase::startTransition(Mode_t mode_, Submode_t submode_) {
changeHK(this->mode, this->submode, false);
- triggerEvent(CHANGING_MODE, mode, submode);
+ triggerEvent(CHANGING_MODE, mode_, submode_);
mode = mode_;
submode = submode_;
modeHelper.modeChanged(mode, submode);
diff --git a/src/fsfw/coordinates/Sgp4Propagator.cpp b/src/fsfw/coordinates/Sgp4Propagator.cpp
index e79ffef5..62c2670e 100644
--- a/src/fsfw/coordinates/Sgp4Propagator.cpp
+++ b/src/fsfw/coordinates/Sgp4Propagator.cpp
@@ -166,9 +166,9 @@ ReturnValue_t Sgp4Propagator::propagate(double* position, double* velocity, time
timeval timeSinceEpoch = time - epoch;
double minutesSinceEpoch = timeSinceEpoch.tv_sec / 60. + timeSinceEpoch.tv_usec / 60000000.;
- double yearsSinceEpoch = minutesSinceEpoch / 60 / 24 / 365;
+ double monthsSinceEpoch = minutesSinceEpoch / 60 / 24 / 30;
- if ((yearsSinceEpoch > 1) || (yearsSinceEpoch < -1)) {
+ if ((monthsSinceEpoch > 1) || (monthsSinceEpoch < -1)) {
return TLE_TOO_OLD;
}
diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
index f66a328c..32de8e6b 100644
--- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
+++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp
@@ -505,9 +505,9 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
float newCollIntvl = 0;
HousekeepingMessage::getCollectionIntervalModificationCommand(message, &newCollIntvl);
if (command == HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL) {
- result = changeCollectionInterval(sid, newCollIntvl, true);
+ result = changeCollectionInterval(sid, newCollIntvl);
} else {
- result = changeCollectionInterval(sid, newCollIntvl, false);
+ result = changeCollectionInterval(sid, newCollIntvl);
}
break;
}
@@ -720,8 +720,8 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool ena
return returnvalue::OK;
}
-ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float newCollectionInterval,
- bool isDiagnostics) {
+ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
+ float newCollectionInterval) {
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
if (dataSet == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval",
@@ -729,11 +729,6 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float ne
return DATASET_NOT_FOUND;
}
- bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet);
- if ((targetIsDiagnostics and not isDiagnostics) or (not targetIsDiagnostics and isDiagnostics)) {
- return WRONG_HK_PACKET_TYPE;
- }
-
PeriodicHousekeepingHelper* periodicHelper =
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.h b/src/fsfw/datapoollocal/LocalDataPoolManager.h
index 65d58d59..cd0d4f62 100644
--- a/src/fsfw/datapoollocal/LocalDataPoolManager.h
+++ b/src/fsfw/datapoollocal/LocalDataPoolManager.h
@@ -174,6 +174,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
ReturnValue_t generateHousekeepingPacket(sid_t sid, LocalPoolDataSetBase* dataSet,
bool forDownlink,
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
+ ReturnValue_t changeCollectionInterval(sid_t sid, float newCollectionInterval);
HasLocalDataPoolIF* getOwner();
@@ -337,8 +338,6 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable, bool isDiagnostics);
- ReturnValue_t changeCollectionInterval(sid_t sid, float newCollectionInterval,
- bool isDiagnostics);
ReturnValue_t generateSetStructurePacket(sid_t sid, bool isDiagnostics);
void handleHkUpdateResetListInsertion(DataType dataType, DataId dataId);
diff --git a/src/fsfw/devicehandlers/DeviceCommunicationIF.h b/src/fsfw/devicehandlers/DeviceCommunicationIF.h
index a5546a36..cf827240 100644
--- a/src/fsfw/devicehandlers/DeviceCommunicationIF.h
+++ b/src/fsfw/devicehandlers/DeviceCommunicationIF.h
@@ -49,6 +49,7 @@ class DeviceCommunicationIF {
// is this needed if there is no open/close call?
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05);
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x06);
+ static constexpr ReturnValue_t BUSY = MAKE_RETURN_CODE(0x07);
virtual ~DeviceCommunicationIF() {}
diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp
index 99b7496c..00d6c451 100644
--- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp
+++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp
@@ -567,7 +567,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
continueToNormal = false;
// TODO: Check whether the following two lines are okay to do so.
transitionSourceMode = MODE_ON;
- transitionSourceSubMode = submode;
+ transitionSourceSubMode = newSubmode;
mode = _MODE_TO_NORMAL;
return;
}
diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h
index 57e9d982..08298bdc 100644
--- a/src/fsfw/devicehandlers/DeviceHandlerBase.h
+++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h
@@ -257,8 +257,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
Mode_t getTransitionSourceMode() const;
Submode_t getTransitionSourceSubMode() const;
virtual void getMode(Mode_t *mode, Submode_t *submode);
- HealthState getHealth();
- ReturnValue_t setHealth(HealthState health);
+ virtual HealthState getHealth() override;
+ virtual ReturnValue_t setHealth(HealthState health) override;
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues,
diff --git a/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.cpp b/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.cpp
index 20e141c3..d3e5753f 100644
--- a/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.cpp
+++ b/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.cpp
@@ -10,8 +10,9 @@
object_id_t DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
-DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent)
- : FailureIsolationBase(owner, parent),
+DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent,
+ uint8_t eventQueueDepth)
+ : FailureIsolationBase(owner, parent, eventQueueDepth),
strangeReplyCount(DEFAULT_MAX_STRANGE_REPLIES, DEFAULT_STRANGE_REPLIES_TIME_MS,
parameterDomainBase++),
missedReplyCount(DEFAULT_MAX_MISSED_REPLY_COUNT, DEFAULT_MISSED_REPLY_TIME_MS,
diff --git a/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.h b/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.h
index 6007ceb8..4835af99 100644
--- a/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.h
+++ b/src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.h
@@ -13,7 +13,8 @@ class DeviceHandlerFailureIsolation : public FailureIsolationBase {
friend class Heater;
public:
- DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent);
+ DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent,
+ uint8_t eventQueueDepth = 10);
~DeviceHandlerFailureIsolation();
ReturnValue_t initialize();
void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0);
diff --git a/src/fsfw/devicehandlers/HealthDevice.cpp b/src/fsfw/devicehandlers/HealthDevice.cpp
index 717fadd1..d3a70c77 100644
--- a/src/fsfw/devicehandlers/HealthDevice.cpp
+++ b/src/fsfw/devicehandlers/HealthDevice.cpp
@@ -29,11 +29,10 @@ ReturnValue_t HealthDevice::initialize() {
if (result != returnvalue::OK) {
return result;
}
- if (parentQueue != 0) {
+ if (parentQueue != MessageQueueIF::NO_QUEUE) {
return healthHelper.initialize(parentQueue);
- } else {
- return healthHelper.initialize();
}
+ return healthHelper.initialize();
}
MessageQueueId_t HealthDevice::getCommandQueue() const { return commandQueue->getId(); }
diff --git a/src/fsfw/devicehandlers/HealthDevice.h b/src/fsfw/devicehandlers/HealthDevice.h
index f4c3520f..a5c28cf7 100644
--- a/src/fsfw/devicehandlers/HealthDevice.h
+++ b/src/fsfw/devicehandlers/HealthDevice.h
@@ -29,10 +29,8 @@ class HealthDevice : public SystemObject, public ExecutableObjectIF, public HasH
protected:
HealthState lastHealth;
- MessageQueueId_t parentQueue;
+ MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE;
MessageQueueIF* commandQueue;
-
- public:
HealthHelper healthHelper;
};
diff --git a/src/fsfw/events/EventManager.cpp b/src/fsfw/events/EventManager.cpp
index f2a099ed..f5cc99c6 100644
--- a/src/fsfw/events/EventManager.cpp
+++ b/src/fsfw/events/EventManager.cpp
@@ -55,8 +55,9 @@ void EventManager::notifyListeners(EventMessage* message) {
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
- << std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
- << result << std::setfill(' ') << std::endl;
+ << std::setw(8) << listener.first << " for event 0x" << std::setw(4)
+ << message->getEventId() << " failed with result 0x" << std::setw(4) << result
+ << std::setfill(' ') << std::endl;
#else
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
listener.first, result);
diff --git a/src/fsfw/globalfunctions/DleParser.h b/src/fsfw/globalfunctions/DleParser.h
index 9802017a..48df0543 100644
--- a/src/fsfw/globalfunctions/DleParser.h
+++ b/src/fsfw/globalfunctions/DleParser.h
@@ -18,8 +18,11 @@
*/
class DleParser {
public:
+ //! [EXPORT] : [SKIP]
static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(1, 1);
+ //! [EXPORT] : [SKIP]
static constexpr ReturnValue_t POSSIBLE_PACKET_LOSS = returnvalue::makeCode(1, 2);
+
using BufPair = std::pair;
enum class ContextType { NONE, PACKET_FOUND, ERROR };
diff --git a/src/fsfw/globalfunctions/math/VectorOperations.h b/src/fsfw/globalfunctions/math/VectorOperations.h
index 197cd46a..b8f6b00f 100644
--- a/src/fsfw/globalfunctions/math/VectorOperations.h
+++ b/src/fsfw/globalfunctions/math/VectorOperations.h
@@ -53,8 +53,9 @@ class VectorOperations {
mulScalar(vector, 1 / norm(vector, size), normalizedVector, size);
}
- static T maxAbsValue(const T *vector, uint8_t size, uint8_t *index = 0) {
- T max = -1;
+ static T maxAbsValue(const T *vector, uint8_t size, uint8_t *index = nullptr) {
+ T max = vector[size - 1];
+ uint8_t foundIndex = size - 1;
for (; size > 0; size--) {
T abs = vector[size - 1];
@@ -64,24 +65,35 @@ class VectorOperations {
if (abs > max) {
max = abs;
if (index != 0) {
- *index = size - 1;
+ foundIndex = size - 1;
}
}
}
+
+ if (index != nullptr) {
+ *index = foundIndex;
+ }
+
return max;
}
- static T maxValue(const T *vector, uint8_t size, uint8_t *index = 0) {
- T max = -1;
+ static T maxValue(const T *vector, uint8_t size, uint8_t *index = nullptr) {
+ T max = vector[size - 1];
+ uint8_t foundIndex = size - 1;
for (; size > 0; size--) {
if (vector[size - 1] > max) {
max = vector[size - 1];
if (index != 0) {
- *index = size - 1;
+ foundIndex = size - 1;
}
}
}
+
+ if (index != nullptr) {
+ *index = foundIndex;
+ }
+
return max;
}
diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp
index b39e45c3..ec34330a 100644
--- a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp
+++ b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp
@@ -3,6 +3,7 @@
#include
#include "fsfw/datapoollocal/LocalPoolDataSetBase.h"
+#include "fsfw/serviceinterface.h"
PeriodicHousekeepingHelper::PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner)
: owner(owner) {}
@@ -10,51 +11,29 @@ PeriodicHousekeepingHelper::PeriodicHousekeepingHelper(LocalPoolDataSetBase* own
void PeriodicHousekeepingHelper::initialize(float collectionInterval,
dur_millis_t minimumPeriodicInterval) {
this->minimumPeriodicInterval = minimumPeriodicInterval;
- collectionIntervalTicks = intervalSecondsToIntervalTicks(collectionInterval);
- /* This will cause a checkOpNecessary call to be true immediately. I think it's okay
- if a HK packet is generated immediately instead of waiting one generation cycle. */
- internalTickCounter = collectionIntervalTicks;
+ changeCollectionInterval(collectionInterval);
}
float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() const {
- return intervalTicksToSeconds(collectionIntervalTicks);
+ return collectionInterval;
}
bool PeriodicHousekeepingHelper::checkOpNecessary() {
- if (internalTickCounter >= collectionIntervalTicks) {
- internalTickCounter = 1;
+ if (hkGenerationCd.hasTimedOut()) {
+ hkGenerationCd.resetTimer();
return true;
}
- internalTickCounter++;
return false;
}
-uint32_t PeriodicHousekeepingHelper::intervalSecondsToIntervalTicks(
- float collectionIntervalSeconds) {
- if (owner == nullptr) {
- return 0;
- }
-
- /* Avoid division by zero */
- if (minimumPeriodicInterval == 0) {
- /* Perform operation each cycle */
- return 1;
-
- } else {
- dur_millis_t intervalInMs = collectionIntervalSeconds * 1000;
- uint32_t divisor = minimumPeriodicInterval;
- uint32_t ticks = std::ceil(static_cast(intervalInMs) / divisor);
-
- return ticks;
- }
-}
-
-float PeriodicHousekeepingHelper::intervalTicksToSeconds(uint32_t collectionInterval) const {
- /* Number of ticks times the minimum interval is in milliseconds, so we divide by 1000 to get
- the value in seconds */
- return static_cast(collectionInterval * minimumPeriodicInterval / 1000.0);
-}
-
void PeriodicHousekeepingHelper::changeCollectionInterval(float newIntervalSeconds) {
- collectionIntervalTicks = intervalSecondsToIntervalTicks(newIntervalSeconds);
+ uint32_t intervalMs = newIntervalSeconds * 1000;
+ if (newIntervalSeconds <= 0) {
+ intervalMs = minimumPeriodicInterval;
+ newIntervalSeconds = static_cast(minimumPeriodicInterval) / 1000.0;
+ }
+ collectionInterval = newIntervalSeconds;
+ hkGenerationCd.setTimeout(intervalMs);
+ // We want an immediate HK packet at the start, so time out the generation CD immediately.
+ hkGenerationCd.timeOut();
}
diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h
index 1ec0febf..1586649c 100644
--- a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h
+++ b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h
@@ -4,6 +4,7 @@
#include
#include "fsfw/timemanager/Clock.h"
+#include "fsfw/timemanager/Countdown.h"
class LocalPoolDataSetBase;
@@ -19,13 +20,10 @@ class PeriodicHousekeepingHelper {
private:
LocalPoolDataSetBase* owner = nullptr;
-
- uint32_t intervalSecondsToIntervalTicks(float collectionIntervalSeconds);
- float intervalTicksToSeconds(uint32_t collectionInterval) const;
+ Countdown hkGenerationCd;
+ float collectionInterval = 0.0;
dur_millis_t minimumPeriodicInterval = 0;
- uint32_t internalTickCounter = 1;
- uint32_t collectionIntervalTicks = 0;
};
#endif /* FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ */
diff --git a/src/fsfw/internalerror/InternalErrorReporter.cpp b/src/fsfw/internalerror/InternalErrorReporter.cpp
index 69faacdd..44910801 100644
--- a/src/fsfw/internalerror/InternalErrorReporter.cpp
+++ b/src/fsfw/internalerror/InternalErrorReporter.cpp
@@ -5,9 +5,12 @@
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
-InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
+InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth,
+ bool enableSetByDefault, float generationFrequency)
: SystemObject(setObjectId),
poolManager(this, commandQueue),
+ enableSetByDefault(enableSetByDefault),
+ generationFrequency(generationFrequency),
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
internalErrorDataset(this) {
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
@@ -134,9 +137,8 @@ ReturnValue_t InternalErrorReporter::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(errorPoolIds::TM_HITS, &tmHitsEntry);
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, &queueHitsEntry);
localDataPoolMap.emplace(errorPoolIds::STORE_HITS, &storeHitsEntry);
- poolManager.subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams(
- internalErrorSid, false,
- static_cast(getPeriodicOperationFrequency()) / static_cast(1000.0)));
+ poolManager.subscribeForRegularPeriodicPacket(
+ subdp::RegularHkPeriodicParams(internalErrorSid, enableSetByDefault, generationFrequency));
internalErrorDataset.setValidity(true, true);
return returnvalue::OK;
}
diff --git a/src/fsfw/internalerror/InternalErrorReporter.h b/src/fsfw/internalerror/InternalErrorReporter.h
index ca82d1a4..f845410b 100644
--- a/src/fsfw/internalerror/InternalErrorReporter.h
+++ b/src/fsfw/internalerror/InternalErrorReporter.h
@@ -21,7 +21,8 @@ class InternalErrorReporter : public SystemObject,
public InternalErrorReporterIF,
public HasLocalDataPoolIF {
public:
- InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth = 5);
+ InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth,
+ bool enableSetByDefault, float generationFrequency);
/**
* Enable diagnostic printout. Please note that this feature will
@@ -63,6 +64,8 @@ class InternalErrorReporter : public SystemObject,
MutexIF* mutex = nullptr;
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t timeoutMs = 20;
+ bool enableSetByDefault;
+ float generationFrequency;
sid_t internalErrorSid;
InternalErrorDataset internalErrorDataset;
diff --git a/src/fsfw/osal/host/TaskFactory.cpp b/src/fsfw/osal/host/TaskFactory.cpp
index 0a27241b..d9552923 100644
--- a/src/fsfw/osal/host/TaskFactory.cpp
+++ b/src/fsfw/osal/host/TaskFactory.cpp
@@ -20,16 +20,18 @@ TaskFactory::~TaskFactory() = default;
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
-PeriodicTaskIF* TaskFactory::createPeriodicTask(
- TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
- TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
+PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
+ TaskStackSize stackSize_,
+ TaskPeriod periodInSeconds_,
+ TaskDeadlineMissedFunction deadLineMissedFunction_,
+ void* args) {
return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_);
}
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
- TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
+ TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_);
}
diff --git a/src/fsfw/osal/linux/Clock.cpp b/src/fsfw/osal/linux/Clock.cpp
index fd861da2..209dba56 100644
--- a/src/fsfw/osal/linux/Clock.cpp
+++ b/src/fsfw/osal/linux/Clock.cpp
@@ -89,8 +89,6 @@ timeval Clock::getUptime() {
}
ReturnValue_t Clock::getUptime(timeval* uptime) {
- // TODO This is not posix compatible and delivers only seconds precision
- // Linux specific file read but more precise.
double uptimeSeconds;
std::ifstream ifile("/proc/uptime");
if (ifile.bad()) {
diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp
index 34729c22..0709f52f 100644
--- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp
+++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp
@@ -7,10 +7,15 @@
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
- TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_)
+ TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
+ PosixThreadArgs* args)
: FixedTimeslotTaskBase(periodSeconds_, dlmFunc_),
- posixThread(name_, priority_, stackSize_),
- started(false) {}
+ posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
+ started(false) {
+ if (args != nullptr) {
+ posixThread.setSchedPolicy(args->policy);
+ }
+}
void* FixedTimeslotTask::taskEntryPoint(void* arg) {
// The argument is re-interpreted as PollingTask.
diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.h b/src/fsfw/osal/linux/FixedTimeslotTask.h
index 1f5766a2..0957bedc 100644
--- a/src/fsfw/osal/linux/FixedTimeslotTask.h
+++ b/src/fsfw/osal/linux/FixedTimeslotTask.h
@@ -23,7 +23,8 @@ class FixedTimeslotTask : public FixedTimeslotTaskBase {
* @param deadlineMissedFunc_
*/
FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
- TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_);
+ TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
+ PosixThreadArgs* args);
~FixedTimeslotTask() override = default;
ReturnValue_t startTask() override;
diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp
index 556a0367..5f1256d7 100644
--- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp
+++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp
@@ -4,10 +4,15 @@
#include "fsfw/tasks/ExecutableObjectIF.h"
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
- TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_)
+ TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_,
+ PosixThreadArgs* args)
: PeriodicTaskBase(period_, dlmFunc_),
- posixThread(name_, priority_, stackSize_),
- started(false) {}
+ posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
+ started(false) {
+ if (args != nullptr) {
+ posixThread.setSchedPolicy(args->policy);
+ }
+}
void* PeriodicPosixTask::taskEntryPoint(void* arg) {
// The argument is re-interpreted as PollingTask.
diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h
index 085c10b9..eac14f0c 100644
--- a/src/fsfw/osal/linux/PeriodicPosixTask.h
+++ b/src/fsfw/osal/linux/PeriodicPosixTask.h
@@ -24,7 +24,7 @@ class PeriodicPosixTask : public PeriodicTaskBase {
* @param deadlineMissedFunc_
*/
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_,
- TaskDeadlineMissedFunction dlmFunc_);
+ TaskDeadlineMissedFunction dlmFunc_, PosixThreadArgs* args);
~PeriodicPosixTask() override = default;
/**
diff --git a/src/fsfw/osal/linux/PosixThread.cpp b/src/fsfw/osal/linux/PosixThread.cpp
index 811d58e2..f420b326 100644
--- a/src/fsfw/osal/linux/PosixThread.cpp
+++ b/src/fsfw/osal/linux/PosixThread.cpp
@@ -7,8 +7,9 @@
#include "fsfw/osal/linux/unixUtility.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
-PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_)
- : thread(0), priority(priority_), stackSize(stackSize_) {
+PosixThread::PosixThread(const char* name_, SchedulingPolicy schedPolciy, int priority_,
+ size_t stackSize_)
+ : thread(0), schedPolicy(schedPolciy), priority(priority_), stackSize(stackSize_) {
name[0] = '\0';
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
}
@@ -178,20 +179,30 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
#ifndef FSFW_USE_REALTIME_FOR_LINUX
#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1"
#endif
+ if (schedPolicy == SchedulingPolicy::RR) {
+ // RR -> This needs root privileges for the process
#if FSFW_USE_REALTIME_FOR_LINUX == 1
- // FIFO -> This needs root privileges for the process
- status = pthread_attr_setschedpolicy(&attributes, SCHED_FIFO);
- if (status != 0) {
- utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
+ status = pthread_attr_setschedpolicy(&attributes, SCHED_RR);
+ if (status != 0) {
+ utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
+ }
+ sched_param scheduleParams;
+ scheduleParams.sched_priority = priority;
+ status = pthread_attr_setschedparam(&attributes, &scheduleParams);
+ if (status != 0) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+ sif::warning << "PosixThread: Setting priority failed" << std::endl;
+#endif
+ }
+#else
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+ sif::warning
+ << "Real time priorities are only allowed if FSFW_USE_REALTIME_FOR_LINUX is set to 1"
+ << std::endl;
+#endif
+#endif
}
- sched_param scheduleParams;
- scheduleParams.__sched_priority = priority;
- status = pthread_attr_setschedparam(&attributes, &scheduleParams);
- if (status != 0) {
- utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedparam");
- }
-#endif
// Set Signal Mask for suspend until startTask is called
sigset_t waitSignal;
sigemptyset(&waitSignal);
@@ -243,3 +254,5 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_destroy");
}
}
+
+void PosixThread::setSchedPolicy(SchedulingPolicy policy) { this->schedPolicy = policy; }
diff --git a/src/fsfw/osal/linux/PosixThread.h b/src/fsfw/osal/linux/PosixThread.h
index add41bf6..133a9884 100644
--- a/src/fsfw/osal/linux/PosixThread.h
+++ b/src/fsfw/osal/linux/PosixThread.h
@@ -9,10 +9,15 @@
#include "../../returnvalues/returnvalue.h"
+enum SchedulingPolicy { REGULAR, RR };
+struct PosixThreadArgs {
+ SchedulingPolicy policy = SchedulingPolicy::REGULAR;
+};
+
class PosixThread {
public:
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
- PosixThread(const char* name_, int priority_, size_t stackSize_);
+ PosixThread(const char* name_, SchedulingPolicy schedPolicy, int priority_, size_t stackSize_);
virtual ~PosixThread();
/**
* Set the Thread to sleep state
@@ -20,6 +25,9 @@ class PosixThread {
* @return Returns Failed if sleep fails
*/
static ReturnValue_t sleep(uint64_t ns);
+
+ void setSchedPolicy(SchedulingPolicy policy);
+
/**
* @brief Function to suspend the task until SIGUSR1 was received
*
@@ -72,6 +80,7 @@ class PosixThread {
private:
char name[PTHREAD_MAX_NAMELEN];
+ SchedulingPolicy schedPolicy;
int priority;
size_t stackSize = 0;
diff --git a/src/fsfw/osal/linux/TaskFactory.cpp b/src/fsfw/osal/linux/TaskFactory.cpp
index bacc4311..c93f3fde 100644
--- a/src/fsfw/osal/linux/TaskFactory.cpp
+++ b/src/fsfw/osal/linux/TaskFactory.cpp
@@ -12,18 +12,20 @@ TaskFactory::~TaskFactory() = default;
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
-PeriodicTaskIF* TaskFactory::createPeriodicTask(
- TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
- TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
+PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
+ TaskStackSize stackSize_,
+ TaskPeriod periodInSeconds_,
+ TaskDeadlineMissedFunction deadLineMissedFunction_,
+ void* args) {
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
- deadLineMissedFunction_);
+ deadLineMissedFunction_, reinterpret_cast(args));
}
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
- TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
+ TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
- deadLineMissedFunction_);
+ deadLineMissedFunction_, reinterpret_cast(args));
}
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
diff --git a/src/fsfw/power/DummyPowerSwitcher.cpp b/src/fsfw/power/DummyPowerSwitcher.cpp
index 952a5a57..80b4cc4a 100644
--- a/src/fsfw/power/DummyPowerSwitcher.cpp
+++ b/src/fsfw/power/DummyPowerSwitcher.cpp
@@ -6,7 +6,11 @@ DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwit
: SystemObject(objectId, registerGlobally),
switcherList(numberOfSwitches),
fuseList(numberOfFuses),
- switchDelayMs(switchDelayMs) {}
+ switchDelayMs(switchDelayMs) {
+ for (auto &switchState : switcherList) {
+ switchState = PowerSwitchIF::SWITCH_UNKNOWN;
+ }
+}
void DummyPowerSwitcher::setInitialSwitcherList(std::vector switcherList) {
this->switcherList = switcherList;
diff --git a/src/fsfw/power/PowerSwitcherComponent.h b/src/fsfw/power/PowerSwitcherComponent.h
index d6fc06cd..8c74e76f 100644
--- a/src/fsfw/power/PowerSwitcherComponent.h
+++ b/src/fsfw/power/PowerSwitcherComponent.h
@@ -42,7 +42,7 @@ class PowerSwitcherComponent : public SystemObject,
private:
MessageQueueIF *queue = nullptr;
- Mode_t mode = MODE_OFF;
+ Mode_t mode = MODE_UNDEFINED;
Submode_t submode = 0;
ModeHelper modeHelper;
diff --git a/src/fsfw/pus/Service3Housekeeping.cpp b/src/fsfw/pus/Service3Housekeeping.cpp
index 0a51aa4b..c6fac20c 100644
--- a/src/fsfw/pus/Service3Housekeeping.cpp
+++ b/src/fsfw/pus/Service3Housekeeping.cpp
@@ -4,9 +4,10 @@
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/pus/servicepackets/Service3Packets.h"
-Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId)
- : CommandingServiceBase(objectId, apid, "PUS 3 HK", serviceId, NUM_OF_PARALLEL_COMMANDS,
- COMMAND_TIMEOUT_SECONDS) {}
+Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId,
+ uint32_t queueDepth, uint8_t numParallelCommands)
+ : CommandingServiceBase(objectId, apid, "PUS 3 HK", serviceId, numParallelCommands,
+ COMMAND_TIMEOUT_SECONDS, queueDepth) {}
Service3Housekeeping::~Service3Housekeeping() {}
diff --git a/src/fsfw/pus/Service3Housekeeping.h b/src/fsfw/pus/Service3Housekeeping.h
index 70f15762..10004bc6 100644
--- a/src/fsfw/pus/Service3Housekeeping.h
+++ b/src/fsfw/pus/Service3Housekeeping.h
@@ -28,7 +28,8 @@ class Service3Housekeeping : public CommandingServiceBase, public AcceptsHkPacke
static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4;
static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60;
- Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId);
+ Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId, uint32_t queueDepth,
+ uint8_t numParallelCommands);
virtual ~Service3Housekeeping();
protected:
diff --git a/src/fsfw/pus/Service8FunctionManagement.cpp b/src/fsfw/pus/Service8FunctionManagement.cpp
index 8b7c6972..2607adca 100644
--- a/src/fsfw/pus/Service8FunctionManagement.cpp
+++ b/src/fsfw/pus/Service8FunctionManagement.cpp
@@ -9,11 +9,11 @@
#include "fsfw/serviceinterface/ServiceInterface.h"
Service8FunctionManagement::Service8FunctionManagement(object_id_t objectId, uint16_t apid,
- uint8_t serviceId,
+ uint8_t serviceId, size_t queueDepth,
uint8_t numParallelCommands,
uint16_t commandTimeoutSeconds)
: CommandingServiceBase(objectId, apid, "PUS 8 Functional Commanding", serviceId,
- numParallelCommands, commandTimeoutSeconds) {}
+ numParallelCommands, commandTimeoutSeconds, queueDepth) {}
Service8FunctionManagement::~Service8FunctionManagement() {}
diff --git a/src/fsfw/pus/Service8FunctionManagement.h b/src/fsfw/pus/Service8FunctionManagement.h
index 38aaf4f4..0ec715b8 100644
--- a/src/fsfw/pus/Service8FunctionManagement.h
+++ b/src/fsfw/pus/Service8FunctionManagement.h
@@ -31,7 +31,8 @@
class Service8FunctionManagement : public CommandingServiceBase {
public:
Service8FunctionManagement(object_id_t objectId, uint16_t apid, uint8_t serviceId,
- uint8_t numParallelCommands = 4, uint16_t commandTimeoutSeconds = 60);
+ size_t queueDepth, uint8_t numParallelCommands = 4,
+ uint16_t commandTimeoutSeconds = 60);
~Service8FunctionManagement() override;
protected:
diff --git a/src/fsfw/subsystem/SubsystemBase.cpp b/src/fsfw/subsystem/SubsystemBase.cpp
index eccd447c..4f62a889 100644
--- a/src/fsfw/subsystem/SubsystemBase.cpp
+++ b/src/fsfw/subsystem/SubsystemBase.cpp
@@ -315,20 +315,7 @@ object_id_t SubsystemBase::getObjectId() const { return SystemObject::getObjectI
void SubsystemBase::modeChanged() {}
ReturnValue_t SubsystemBase::registerChild(const ModeTreeChildIF& child) {
- ChildInfo info;
-
- const HasModesIF& modeChild = child.getModeIF();
- // intentional to force an initial command during system startup
- info.commandQueue = modeChild.getCommandQueue();
- info.mode = HasModesIF::MODE_UNDEFINED;
- info.submode = SUBMODE_NONE;
- info.healthChanged = false;
-
- auto resultPair = childrenMap.emplace(child.getObjectId(), info);
- if (not resultPair.second) {
- return COULD_NOT_INSERT_CHILD;
- }
- return returnvalue::OK;
+ return registerChild(child.getObjectId(), child.getModeIF().getCommandQueue());
}
const HasHealthIF* SubsystemBase::getOptHealthIF() const { return this; }
@@ -336,3 +323,19 @@ const HasHealthIF* SubsystemBase::getOptHealthIF() const { return this; }
const HasModesIF& SubsystemBase::getModeIF() const { return *this; }
ModeTreeChildIF& SubsystemBase::getModeTreeChildIF() { return *this; }
+
+ReturnValue_t SubsystemBase::registerChild(object_id_t childObjectId, MessageQueueId_t childQueue) {
+ ChildInfo info;
+
+ // intentional to force an initial command during system startup
+ info.commandQueue = childQueue;
+ info.mode = HasModesIF::MODE_UNDEFINED;
+ info.submode = SUBMODE_NONE;
+ info.healthChanged = false;
+
+ auto resultPair = childrenMap.emplace(childObjectId, info);
+ if (not resultPair.second) {
+ return COULD_NOT_INSERT_CHILD;
+ }
+ return returnvalue::OK;
+}
diff --git a/src/fsfw/subsystem/SubsystemBase.h b/src/fsfw/subsystem/SubsystemBase.h
index c3886d61..072b4ca4 100644
--- a/src/fsfw/subsystem/SubsystemBase.h
+++ b/src/fsfw/subsystem/SubsystemBase.h
@@ -61,6 +61,8 @@ class SubsystemBase : public SystemObject,
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
*/
ReturnValue_t registerChild(const ModeTreeChildIF &child) override;
+ // TODO: Add this to HasModeTreeChildrenIF.
+ ReturnValue_t registerChild(object_id_t childObjectId, MessageQueueId_t childQueue);
ReturnValue_t initialize() override;
diff --git a/src/fsfw/tasks/TaskFactory.h b/src/fsfw/tasks/TaskFactory.h
index 828c533e..e9b96a77 100644
--- a/src/fsfw/tasks/TaskFactory.h
+++ b/src/fsfw/tasks/TaskFactory.h
@@ -47,7 +47,8 @@ class TaskFactory {
*/
PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
TaskStackSize stackSize_, TaskPeriod periodInSeconds_,
- TaskDeadlineMissedFunction deadLineMissedFunction_);
+ TaskDeadlineMissedFunction deadLineMissedFunction_,
+ void* args = nullptr);
/**
* The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks.
@@ -62,7 +63,8 @@ class TaskFactory {
FixedTimeslotTaskIF* createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_,
TaskStackSize stackSize_,
TaskPeriod periodInSeconds_,
- TaskDeadlineMissedFunction deadLineMissedFunction_);
+ TaskDeadlineMissedFunction deadLineMissedFunction_,
+ void* args = nullptr);
/**
* Function to be called to delete a task
diff --git a/src/fsfw/tmtcpacket/pus/tm/PusTmCreator.h b/src/fsfw/tmtcpacket/pus/tm/PusTmCreator.h
index 626d873e..19922b2f 100644
--- a/src/fsfw/tmtcpacket/pus/tm/PusTmCreator.h
+++ b/src/fsfw/tmtcpacket/pus/tm/PusTmCreator.h
@@ -40,7 +40,7 @@ struct PusTmParams {
size_t dataLen)
: secHeader(service, subservice, timeStamper), adapter(data, dataLen), sourceData(&adapter) {}
PusTmSecHeader secHeader;
- SerialBufferAdapter adapter;
+ SerialBufferAdapter adapter;
const SerializeIF* sourceData = nullptr;
};
diff --git a/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.cpp b/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.cpp
index 6a9f6235..d897aff9 100644
--- a/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.cpp
+++ b/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.cpp
@@ -24,3 +24,9 @@ void PusTmZeroCopyWriter::updateErrorControl() {
crcStart[0] = (crc16 >> 8) & 0xff;
crcStart[1] = crc16 & 0xff;
}
+
+void PusTmZeroCopyWriter::setMessageCount(uint16_t msgCount) {
+ size_t serSize = 0;
+ SerializeAdapter::serialize(&msgCount, const_cast(pointers.secHeaderStart + 3),
+ &serSize, 2, SerializeIF::Endianness::NETWORK);
+}
diff --git a/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h b/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h
index 36c43f51..66ef1405 100644
--- a/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h
+++ b/src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h
@@ -14,6 +14,7 @@ class PusTmZeroCopyWriter : public PusTmReader {
PusTmZeroCopyWriter(TimeReaderIF& timeReader, uint8_t* data, size_t size);
void setSequenceCount(uint16_t seqCount);
+ void setMessageCount(uint16_t msgCount);
void updateErrorControl();
private:
diff --git a/src/fsfw_hal/common/spi/spiCommon.h b/src/fsfw_hal/common/spi/spiCommon.h
index bee86823..072363a5 100644
--- a/src/fsfw_hal/common/spi/spiCommon.h
+++ b/src/fsfw_hal/common/spi/spiCommon.h
@@ -5,8 +5,18 @@
namespace spi {
+static constexpr uint8_t CLASS_ID = CLASS_ID::HAL_SPI;
+static constexpr ReturnValue_t OPENING_FILE_FAILED = returnvalue::makeCode(CLASS_ID, 0);
+/* Full duplex (ioctl) transfer failure */
+static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED = returnvalue::makeCode(CLASS_ID, 1);
+/* Half duplex (read/write) transfer failure */
+static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = returnvalue::makeCode(CLASS_ID, 2);
+static constexpr ReturnValue_t TIMEOUT = returnvalue::makeCode(CLASS_ID, 3);
+static constexpr ReturnValue_t BUSY = returnvalue::makeCode(CLASS_ID, 4);
+static constexpr ReturnValue_t GENERIC_ERROR = returnvalue::makeCode(CLASS_ID, 5);
+
enum SpiModes : uint8_t { MODE_0, MODE_1, MODE_2, MODE_3 };
-}
+} // namespace spi
#endif /* FSFW_HAL_COMMON_SPI_SPICOMMON_H_ */
diff --git a/src/fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h b/src/fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h
index 4aef6811..0135a04c 100644
--- a/src/fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h
+++ b/src/fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h
@@ -73,8 +73,10 @@ static constexpr uint8_t CTRL_REG_4_VAL = SET_BLE;
/* Register 5 */
static constexpr uint8_t SET_REBOOT_MEM = 1 << 7;
static constexpr uint8_t SET_FIFO_ENB = 1 << 6;
+static constexpr uint8_t SET_OUT_SEL_1 = 1 << 1;
+static constexpr uint8_t SET_OUT_SEL_0 = 1 << 0;
-static constexpr uint8_t CTRL_REG_5_VAL = 0b00000000;
+static constexpr uint8_t CTRL_REG_5_VAL = SET_OUT_SEL_1 | SET_OUT_SEL_0;
/* Possible range values in degrees per second (DPS). */
static constexpr uint16_t RANGE_DPS_00 = 245;
diff --git a/src/fsfw_hal/host/HostFilesystem.cpp b/src/fsfw_hal/host/HostFilesystem.cpp
index 315ba422..20984f77 100644
--- a/src/fsfw_hal/host/HostFilesystem.cpp
+++ b/src/fsfw_hal/host/HostFilesystem.cpp
@@ -165,7 +165,8 @@ ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
if (not filesystem::exists(path, e)) {
return FILE_DOES_NOT_EXIST;
}
- ofstream of(path);
+ // Specify truncation flug explicitely.
+ ofstream of(path, std::ios::out | std::ios::trunc);
return returnvalue::OK;
}
diff --git a/src/fsfw_hal/linux/serial/SerialComIF.cpp b/src/fsfw_hal/linux/serial/SerialComIF.cpp
index 177d74e4..f272e787 100644
--- a/src/fsfw_hal/linux/serial/SerialComIF.cpp
+++ b/src/fsfw_hal/linux/serial/SerialComIF.cpp
@@ -88,11 +88,11 @@ int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
return fd;
}
- uart::setParity(options, uartCookie->getParity());
+ serial::setParity(options, uartCookie->getParity());
setStopBitOptions(&options, uartCookie);
setDatasizeOptions(&options, uartCookie);
setFixedOptions(&options);
- uart::setMode(options, uartCookie->getUartMode());
+ serial::setMode(options, uartCookie->getUartMode());
if (uartCookie->getInputShouldBeFlushed()) {
tcflush(fd, TCIFLUSH);
}
@@ -101,7 +101,7 @@ int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
- uart::setBaudrate(options, uartCookie->getBaudrate());
+ serial::setBaudrate(options, uartCookie->getBaudrate());
/* Save option settings */
if (tcsetattr(fd, TCSANOW, &options) != 0) {
diff --git a/src/fsfw_hal/linux/serial/helper.cpp b/src/fsfw_hal/linux/serial/helper.cpp
index ba975f2f..c58689c0 100644
--- a/src/fsfw_hal/linux/serial/helper.cpp
+++ b/src/fsfw_hal/linux/serial/helper.cpp
@@ -3,7 +3,7 @@
#include "fsfw/serviceinterface.h"
-void uart::setMode(struct termios& options, UartModes mode) {
+void serial::setMode(struct termios& options, UartModes mode) {
if (mode == UartModes::NON_CANONICAL) {
/* Disable canonical mode */
options.c_lflag &= ~ICANON;
@@ -12,7 +12,7 @@ void uart::setMode(struct termios& options, UartModes mode) {
}
}
-void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
+void serial::setBaudrate(struct termios& options, UartBaudRate baud) {
switch (baud) {
case UartBaudRate::RATE_50:
cfsetspeed(&options, B50);
@@ -114,7 +114,7 @@ void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
}
}
-void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
+void serial::setBitsPerWord(struct termios& options, BitsPerWord bits) {
options.c_cflag &= ~CSIZE; // Clear all the size bits
if (bits == BitsPerWord::BITS_5) {
options.c_cflag |= CS5;
@@ -127,11 +127,11 @@ void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
}
}
-void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
+void serial::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
-void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
+void serial::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
-void uart::setParity(struct termios& options, Parity parity) {
+void serial::setParity(struct termios& options, Parity parity) {
/* Clear parity bit */
options.c_cflag &= ~PARENB;
switch (parity) {
@@ -148,11 +148,11 @@ void uart::setParity(struct termios& options, Parity parity) {
}
}
-int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
+int serial::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
return ioctl(serialPort, TIOCGICOUNT, &icounter);
}
-void uart::setStopbits(struct termios& options, StopBits bits) {
+void serial::setStopbits(struct termios& options, StopBits bits) {
if (bits == StopBits::TWO_STOP_BITS) {
// Use two stop bits
options.c_cflag |= CSTOPB;
@@ -161,3 +161,7 @@ void uart::setStopbits(struct termios& options, StopBits bits) {
options.c_cflag &= ~CSTOPB;
}
}
+
+void serial::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); }
+
+void serial::flushTxRxBuf(int fd) { tcflush(fd, TCIOFLUSH); }
diff --git a/src/fsfw_hal/linux/serial/helper.h b/src/fsfw_hal/linux/serial/helper.h
index 7f067d00..623612ad 100644
--- a/src/fsfw_hal/linux/serial/helper.h
+++ b/src/fsfw_hal/linux/serial/helper.h
@@ -45,7 +45,7 @@ enum class UartBaudRate {
RATE_4000000
};
-namespace uart {
+namespace serial {
void setMode(struct termios& options, UartModes mode);
/**
@@ -64,8 +64,11 @@ void setParity(struct termios& options, Parity parity);
void ignoreCtrlLines(struct termios& options);
+void flushRxBuf(int fd);
+void flushTxRxBuf(int fd);
+
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
-} // namespace uart
+} // namespace serial
#endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */
diff --git a/src/fsfw_hal/linux/spi/SpiComIF.cpp b/src/fsfw_hal/linux/spi/SpiComIF.cpp
index d285b120..f227c685 100644
--- a/src/fsfw_hal/linux/spi/SpiComIF.cpp
+++ b/src/fsfw_hal/linux/spi/SpiComIF.cpp
@@ -173,7 +173,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
int fileDescriptor = 0;
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
if (fileHelper.getOpenResult() != returnvalue::OK) {
- return OPENING_FILE_FAILED;
+ return spi::OPENING_FILE_FAILED;
}
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
uint32_t spiSpeed = 0;
@@ -234,7 +234,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
if (retval < 0) {
spiCookie->setTransferSize(0);
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
- result = FULL_DUPLEX_TRANSFER_FAILED;
+ result = spi::FULL_DUPLEX_TRANSFER_FAILED;
}
#if FSFW_HAL_SPI_WIRETAPPING == 1
performSpiWiretapping(spiCookie);
@@ -250,7 +250,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
sif::printWarning("SpiComIF::sendMessage: Half-Duplex write operation failed!\n");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
- result = HALF_DUPLEX_TRANSFER_FAILED;
+ result = spi::HALF_DUPLEX_TRANSFER_FAILED;
}
}
@@ -287,7 +287,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
int fileDescriptor = 0;
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
if (fileHelper.getOpenResult() != returnvalue::OK) {
- return OPENING_FILE_FAILED;
+ return spi::OPENING_FILE_FAILED;
}
uint8_t* rxBuf = nullptr;
@@ -327,7 +327,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
sif::printWarning("SpiComIF::sendMessage: Half-Duplex read operation failed!\n");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
- result = HALF_DUPLEX_TRANSFER_FAILED;
+ result = spi::HALF_DUPLEX_TRANSFER_FAILED;
}
if (gpioId != gpio::NO_GPIO and not csLockManual) {
diff --git a/src/fsfw_hal/linux/spi/SpiComIF.h b/src/fsfw_hal/linux/spi/SpiComIF.h
index 14a3355a..3b72a59d 100644
--- a/src/fsfw_hal/linux/spi/SpiComIF.h
+++ b/src/fsfw_hal/linux/spi/SpiComIF.h
@@ -22,15 +22,6 @@ class SpiCookie;
*/
class SpiComIF : public DeviceCommunicationIF, public SystemObject {
public:
- static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI;
- static constexpr ReturnValue_t OPENING_FILE_FAILED = returnvalue::makeCode(spiRetvalId, 0);
- /* Full duplex (ioctl) transfer failure */
- static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED =
- returnvalue::makeCode(spiRetvalId, 1);
- /* Half duplex (read/write) transfer failure */
- static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED =
- returnvalue::makeCode(spiRetvalId, 2);
-
SpiComIF(object_id_t objectId, std::string devname, GpioIF& gpioComIF);
ReturnValue_t initializeInterface(CookieIF* cookie) override;
diff --git a/src/fsfw_hal/linux/uio/UioMapper.cpp b/src/fsfw_hal/linux/uio/UioMapper.cpp
index 33e4fd97..c6da5488 100644
--- a/src/fsfw_hal/linux/uio/UioMapper.cpp
+++ b/src/fsfw_hal/linux/uio/UioMapper.cpp
@@ -36,7 +36,7 @@ UioMapper::~UioMapper() {}
ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permissions) {
ReturnValue_t result = returnvalue::OK;
- int fd = open(uioFile.c_str(), O_RDWR);
+ int fd = open(uioFile.c_str(), O_RDWR | O_SYNC);
if (fd < 1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "UioMapper::getMappedAdress: Invalid UIO device file " << uioFile << std::endl;
diff --git a/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp b/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp
index 724917bd..4d688bd5 100644
--- a/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp
+++ b/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp
@@ -357,13 +357,13 @@ ReturnValue_t SpiComIF::halErrorHandler(HAL_StatusTypeDef status, spi::TransferM
sif::printWarning("SpiComIF::handle%sSendOperation: HAL error %d occured\n", modeString, status);
switch (status) {
case (HAL_BUSY): {
- return spi::HAL_BUSY_RETVAL;
+ return spi::BUSY;
}
case (HAL_ERROR): {
- return spi::HAL_ERROR_RETVAL;
+ return spi::GENERIC_ERROR;
}
case (HAL_TIMEOUT): {
- return spi::HAL_TIMEOUT_RETVAL;
+ return spi::TIMEOUT;
}
default: {
return returnvalue::FAILED;
diff --git a/unittests/CatchFactory.cpp b/unittests/CatchFactory.cpp
index 0d855cb3..589e6887 100644
--- a/unittests/CatchFactory.cpp
+++ b/unittests/CatchFactory.cpp
@@ -30,9 +30,9 @@
*/
void Factory::produceFrameworkObjects(void* args) {
setStaticFrameworkObjectIds();
- new EventManager(objects::EVENT_MANAGER);
+ new EventManager(objects::EVENT_MANAGER, 120);
new HealthTable(objects::HEALTH_TABLE);
- new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
+ new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER, 20, false, 1.0);
{
PoolManager::LocalPoolConfig poolCfg = {{100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024}};
diff --git a/unittests/action/TestActionHelper.cpp b/unittests/action/TestActionHelper.cpp
index d99700d7..de021bb8 100644
--- a/unittests/action/TestActionHelper.cpp
+++ b/unittests/action/TestActionHelper.cpp
@@ -27,12 +27,7 @@ TEST_CASE("Action Helper", "[action]") {
CHECK(not testDhMock.executeActionCalled);
REQUIRE(actionHelper.handleActionMessage(&actionMessage) == returnvalue::OK);
CHECK(testDhMock.executeActionCalled);
- // No message is sent if everything is alright.
CHECK(not testMqMock.wasMessageSent());
- store_address_t invalidAddress;
- ActionMessage::setCommand(&actionMessage, testActionId, invalidAddress);
- actionHelper.handleActionMessage(&actionMessage);
- CHECK(testMqMock.wasMessageSent());
const uint8_t* ptr = nullptr;
size_t size = 0;
REQUIRE(ipcStore->getData(paramAddress, &ptr, &size) ==
@@ -44,6 +39,10 @@ TEST_CASE("Action Helper", "[action]") {
for (uint8_t i = 0; i < 3; i++) {
REQUIRE(ptr[i] == (i + 1));
}
+ // Action message without application data is also valid
+ store_address_t invalidAddress;
+ ActionMessage::setCommand(&actionMessage, testActionId, invalidAddress);
+ actionHelper.handleActionMessage(&actionMessage);
testDhMock.clearBuffer();
}
@@ -95,17 +94,5 @@ TEST_CASE("Action Helper", "[action]") {
REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
}
- SECTION("Missing IPC Data") {
- ActionMessage::setCommand(&actionMessage, testActionId, store_address_t::invalid());
- CHECK(not testDhMock.executeActionCalled);
- REQUIRE(actionHelper.handleActionMessage(&actionMessage) == returnvalue::OK);
- CommandMessage testMessage;
- REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK);
- REQUIRE(testMessage.getCommand() == static_cast(ActionMessage::STEP_FAILED));
- REQUIRE(ActionMessage::getReturnCode(&testMessage) ==
- static_cast(StorageManagerIF::ILLEGAL_STORAGE_ID));
- REQUIRE(ActionMessage::getStep(&testMessage) == 0);
- }
-
SECTION("Data Reply") {}
}
diff --git a/unittests/cfdp/pdu/testCfdpHeader.cpp b/unittests/cfdp/pdu/testCfdpHeader.cpp
index 5f81bec9..1fc7dfd4 100644
--- a/unittests/cfdp/pdu/testCfdpHeader.cpp
+++ b/unittests/cfdp/pdu/testCfdpHeader.cpp
@@ -97,7 +97,7 @@ TEST_CASE("CFDP Header", "[cfdp]") {
REQUIRE(creator.serialize(&serTarget, &serSize, serBuf.size(),
SerializeIF::Endianness::BIG) == returnvalue::OK);
CHECK(serBuf[0] == 0x3f);
- CHECK(serBuf[3] == 0x99);
+ CHECK(serBuf[3] == 0x88);
REQUIRE(creator.getCrcFlag() == true);
REQUIRE(creator.getDirection() == cfdp::Direction::TOWARDS_SENDER);
REQUIRE(creator.getLargeFileFlag() == true);
@@ -127,7 +127,7 @@ TEST_CASE("CFDP Header", "[cfdp]") {
REQUIRE(creator.getTransmissionMode() == cfdp::TransmissionMode::UNACKNOWLEDGED);
REQUIRE(creator.getSegmentationControl() == true);
// Last three bits are 2 now (length of seq number) and bit 1 to bit 3 is 4 (len entity IDs)
- REQUIRE(serBuf[3] == 0b11001010);
+ REQUIRE(serBuf[3] == 0b10111001);
uint32_t entityId = 0;
size_t deSerSize = 0;
SerializeAdapter::deSerialize(&entityId, serBuf.data() + 4, &deSerSize,
@@ -175,7 +175,7 @@ TEST_CASE("CFDP Header", "[cfdp]") {
REQUIRE(serBuf[1] == 0);
REQUIRE(serBuf[2] == 0);
// Entity and Transaction Sequence number are 1 byte large
- REQUIRE(serBuf[3] == 0b00010001);
+ REQUIRE(serBuf[3] == 0b00000000);
// Source ID
REQUIRE(serBuf[4] == 0);
// Transaction Seq Number
@@ -220,7 +220,7 @@ TEST_CASE("CFDP Header", "[cfdp]") {
REQUIRE(serBuf[1] == 0);
REQUIRE(serBuf[2] == 0);
// Entity and Transaction Sequence number are 1 byte large
- REQUIRE(serBuf[3] == 0b00010001);
+ REQUIRE(serBuf[3] == 0b00000000);
REQUIRE(serSize == 7);
// Deser call not strictly necessary
auto reader = PduHeaderReader(serBuf.data(), serBuf.size());
@@ -270,7 +270,7 @@ TEST_CASE("CFDP Header", "[cfdp]") {
REQUIRE(reader.parseData() == returnvalue::OK);
// Everything except version bit flipped to one now
REQUIRE(serBuf[0] == 0x3f);
- REQUIRE(serBuf[3] == 0b11001010);
+ REQUIRE(serBuf[3] == 0b10111001);
REQUIRE(reader.getWholePduSize() == 14);
REQUIRE(reader.getCrcFlag() == true);
diff --git a/unittests/cfdp/pdu/testFileData.cpp b/unittests/cfdp/pdu/testFileData.cpp
index 258ef9c1..39139378 100644
--- a/unittests/cfdp/pdu/testFileData.cpp
+++ b/unittests/cfdp/pdu/testFileData.cpp
@@ -68,7 +68,7 @@ TEST_CASE("File Data PDU", "[cfdp][pdu]") {
// Bits 1 to 3 length of enitity IDs is 2
// Bit 4: Segment metadata flag is set
// Bit 5 to seven: length of transaction seq num is 2
- REQUIRE(fileDataBuffer[3] == 0b10101010);
+ REQUIRE(fileDataBuffer[3] == 0b10011001);
REQUIRE((fileDataBuffer[10] >> 6) &
0b11 == cfdp::RecordContinuationState::CONTAINS_START_AND_END);
// Segment metadata length
diff --git a/unittests/cfdp/pdu/testFileDirective.cpp b/unittests/cfdp/pdu/testFileDirective.cpp
index e1158a1a..17e0d699 100644
--- a/unittests/cfdp/pdu/testFileDirective.cpp
+++ b/unittests/cfdp/pdu/testFileDirective.cpp
@@ -30,7 +30,7 @@ TEST_CASE("CFDP File Directive", "[cfdp][pdu]") {
REQUIRE(serBuf[1] == 0);
REQUIRE(serBuf[2] == 5);
// Entity and Transaction Sequence number are 1 byte large
- REQUIRE(serBuf[3] == 0b00010001);
+ REQUIRE(serBuf[3] == 0b00000000);
// Source ID
REQUIRE(serBuf[4] == 0);
// Transaction Seq Number
@@ -82,4 +82,4 @@ TEST_CASE("CFDP File Directive", "[cfdp][pdu]") {
// Invalid file directive
REQUIRE(fdDeser.parseData() == cfdp::INVALID_DIRECTIVE_FIELD);
}
-}
\ No newline at end of file
+}
diff --git a/unittests/cfdp/testCfdp.cpp b/unittests/cfdp/testCfdp.cpp
index eacc83de..467b5b2d 100644
--- a/unittests/cfdp/testCfdp.cpp
+++ b/unittests/cfdp/testCfdp.cpp
@@ -33,8 +33,8 @@ TEST_CASE("CFDP Base", "[cfdp]") {
// PDU data field length is 5 (4 + Directive code octet)
REQUIRE(serBuf[1] == 0);
REQUIRE(serBuf[2] == 5);
- // Entity and Transaction Sequence number are 1 byte large
- REQUIRE(serBuf[3] == 0b00010001);
+ // Entity and Transaction Sequence number are 1 byte large, value minus one is stored
+ REQUIRE(serBuf[3] == 0b00000000);
// Source ID
REQUIRE(serBuf[4] == 0);
// Transaction Seq Number
diff --git a/unittests/datapoollocal/testLocalPoolManager.cpp b/unittests/datapoollocal/testLocalPoolManager.cpp
index 91cd011d..e463a123 100644
--- a/unittests/datapoollocal/testLocalPoolManager.cpp
+++ b/unittests/datapoollocal/testLocalPoolManager.cpp
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include "CatchDefinitions.h"
@@ -309,9 +310,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") {
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
false);
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
- /* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the
- resulting collection interval should be 1.0 second */
- CHECK(poolOwner.dataset.getCollectionInterval() == 1.0);
+ CHECK_THAT(poolOwner.dataset.getCollectionInterval(), Catch::Matchers::WithinAbs(0.4, 0.01));
REQUIRE(poolOwnerMock.wasMessageSent());
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
@@ -348,14 +347,6 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") {
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
- HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
- false);
- CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) ==
- static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
- REQUIRE(poolOwnerMock.wasMessageSent());
- REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
- CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
-
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) ==
static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));