From f735c2e9d4f9d0c2f9803332f4b63b7e435b01eb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 11:51:51 +0100 Subject: [PATCH 01/60] assert size larger than 0 --- src/fsfw/container/FixedArrayList.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsfw/container/FixedArrayList.h b/src/fsfw/container/FixedArrayList.h index 97ade7e8..dde8eb16 100644 --- a/src/fsfw/container/FixedArrayList.h +++ b/src/fsfw/container/FixedArrayList.h @@ -12,6 +12,7 @@ template class FixedArrayList : public ArrayList { static_assert(MAX_SIZE <= std::numeric_limits::max(), "count_t is not large enough to hold MAX_SIZE"); + static_assert(MAX_SIZE > 0, "MAX_SIZE is 0"); private: T data[MAX_SIZE]; From 066dd0d397a4ff0d94f3d193e1ecb8e64f2e7541 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 11:52:20 +0100 Subject: [PATCH 02/60] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cc07f78..3a1ce06e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +## Changed + +- Assert than `FixedArrayList` is larger than 0 at compile time. + # [v6.0.0] 2023-02-10 ## Fixes From b057250bfb3bb87943797c4b32eb17f22558907a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 11:53:12 +0100 Subject: [PATCH 03/60] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a1ce06e..c56885d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Changed -- Assert than `FixedArrayList` is larger than 0 at compile time. +- Assert that `FixedArrayList` is larger than 0 at compile time. # [v6.0.0] 2023-02-10 From d98ed40e3d429c60f837e8d0763edb32b44c6f07 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 12:09:30 +0100 Subject: [PATCH 04/60] add CFDP subsystem ID --- src/fsfw/events/fwSubsystemIdRanges.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsfw/events/fwSubsystemIdRanges.h b/src/fsfw/events/fwSubsystemIdRanges.h index d8e4ade6..574ea070 100644 --- a/src/fsfw/events/fwSubsystemIdRanges.h +++ b/src/fsfw/events/fwSubsystemIdRanges.h @@ -33,6 +33,7 @@ enum : uint8_t { PUS_SERVICE_23 = 103, MGM_LIS3MDL = 106, MGM_RM3100 = 107, + CFDP = 108, FW_SUBSYSTEM_ID_RANGE }; From 6fc8f756a733e7887f5a101cfce0fe30c35834ec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 12:13:55 +0100 Subject: [PATCH 05/60] update power switch IF --- src/fsfw/events/fwSubsystemIdRanges.h | 2 +- src/fsfw/power/PowerSwitchIF.h | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fsfw/events/fwSubsystemIdRanges.h b/src/fsfw/events/fwSubsystemIdRanges.h index d8e4ade6..88958758 100644 --- a/src/fsfw/events/fwSubsystemIdRanges.h +++ b/src/fsfw/events/fwSubsystemIdRanges.h @@ -10,7 +10,7 @@ enum : uint8_t { CDH = 28, TCS_1 = 59, PCDU_1 = 42, - PCDU_2 = 43, + POWER_SWITCH_IF = 43, HEATER = 50, T_SENSORS = 52, FDIR = 70, diff --git a/src/fsfw/power/PowerSwitchIF.h b/src/fsfw/power/PowerSwitchIF.h index e8c9aff4..0b331e11 100644 --- a/src/fsfw/power/PowerSwitchIF.h +++ b/src/fsfw/power/PowerSwitchIF.h @@ -28,10 +28,12 @@ class PowerSwitchIF { static const ReturnValue_t SWITCH_TIMEOUT = MAKE_RETURN_CODE(2); static const ReturnValue_t FUSE_ON = MAKE_RETURN_CODE(3); static const ReturnValue_t FUSE_OFF = MAKE_RETURN_CODE(4); - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_2; - static const Event SWITCH_WENT_OFF = MAKE_EVENT( - 0, severity::LOW); //!< Someone detected that a switch went off which shouldn't. Severity: - //!< Low, Parameter1: switchId1, Parameter2: switchId2 + static const ReturnValue_t SWITCH_UNKNOWN = MAKE_RETURN_CODE(5); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::POWER_SWITCH_IF; + //!< Someone detected that a switch went off which shouldn't. Severity: + //!< Low, Parameter1: switchId1, Parameter2: switchId2 + static const Event SWITCH_WENT_OFF = MAKE_EVENT(0, severity::LOW); /** * send a direct command to the Power Unit to enable/disable the specified switch. * @@ -50,6 +52,7 @@ class PowerSwitchIF { * @return * - @c SWITCH_ON if the specified switch is on. * - @c SWITCH_OFF if the specified switch is off. + * - @c SWITCH_UNKNOWN if the state of the specified switch is unknown. * - @c returnvalue::FAILED if an error occured */ virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const = 0; From 8f63a0e747e3ab44d5a43c1e4d690d516f0e75a7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 12:15:21 +0100 Subject: [PATCH 06/60] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cc07f78..05a8743e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +## Changed + +- Renamed `PCDU_2` subsystem ID to `POWER_SWITCH_IF`. +- Add new `PowerSwitchIF::SWITCH_UNKNOWN` returnvalue. + # [v6.0.0] 2023-02-10 ## Fixes From aa84e93603f32ce5aaa7c308e80ae084c3d2d004 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 12:17:36 +0100 Subject: [PATCH 07/60] small tweak for version getter --- src/fsfw/version.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 050187a9..27d44c03 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -1,6 +1,7 @@ #include "version.h" #include +#include #include "fsfw/FSFWVersion.h" @@ -20,7 +21,7 @@ fsfw::Version::Version(int major, int minor, int revision, const char* addInfo) void fsfw::Version::getVersion(char* str, size_t maxLen) const { size_t len = snprintf(str, maxLen, "%d.%d.%d", major, minor, revision); - if (addInfo != nullptr) { + if (addInfo != nullptr and std::strcmp(addInfo, "") != 0) { snprintf(str + len, maxLen - len, "-%s", addInfo); } } @@ -30,7 +31,7 @@ namespace fsfw { #if FSFW_CPP_OSTREAM_ENABLED == 1 std::ostream& operator<<(std::ostream& os, const Version& v) { os << v.major << "." << v.minor << "." << v.revision; - if (v.addInfo != nullptr) { + if (v.addInfo != nullptr and std::strcmp(v.addInfo, "") != 0) { os << "-" << v.addInfo; } return os; From 1f36c082ef83a6c8a30992d319221c5b3bb5c70e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 12:21:50 +0100 Subject: [PATCH 08/60] bugfix and changelog for Linux getUptime --- CHANGELOG.md | 4 ++++ src/fsfw/osal/linux/Clock.cpp | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cc07f78..4a6f185b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +## Fixes + +- Linux OSAL `getUptime` fix: Check validity of `/proc/uptime` file before reading uptime. + # [v6.0.0] 2023-02-10 ## Fixes diff --git a/src/fsfw/osal/linux/Clock.cpp b/src/fsfw/osal/linux/Clock.cpp index bfdcf4e2..7dd960e5 100644 --- a/src/fsfw/osal/linux/Clock.cpp +++ b/src/fsfw/osal/linux/Clock.cpp @@ -76,14 +76,17 @@ 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; - if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) { + std::ifstream ifile("/proc/uptime"); + if (ifile.bad()) { + return returnvalue::FAILED; + } + if (ifile >> uptimeSeconds) { uptime->tv_sec = uptimeSeconds; uptime->tv_usec = uptimeSeconds * (double)1e6 - (uptime->tv_sec * 1e6); + return returnvalue::OK; } - return returnvalue::OK; + return returnvalue::FAILED; } // Wait for new FSFW Clock function delivering seconds uptime. From 5e3f5c4121317ab62a89a028301251ca59edbe33 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 12:25:39 +0100 Subject: [PATCH 09/60] fuse update --- src/fsfw/power/Fuse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/power/Fuse.h b/src/fsfw/power/Fuse.h index e8b86cfd..c1b35899 100644 --- a/src/fsfw/power/Fuse.h +++ b/src/fsfw/power/Fuse.h @@ -32,7 +32,7 @@ class Fuse : public SystemObject, gp_id_t poolIdPower; }; - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1; + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::POWER_SWITCH_IF; //! PSS detected that current on a fuse is totally out of bounds. static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(1, severity::LOW); //! PSS detected a fuse that went off. From 47503824d7ca4cf656b9f603c8e10daac85b3393 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Mar 2023 12:27:39 +0100 Subject: [PATCH 10/60] health service fixes and changelog --- CHANGELOG.md | 5 +++++ src/fsfw/pus/CServiceHealthCommanding.cpp | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cc07f78..f12aa90e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +## Fixes + +- PUS Health Service: Size check for set health command. +- PUS Health Service: Perform operation completion for announce health command. + # [v6.0.0] 2023-02-10 ## Fixes diff --git a/src/fsfw/pus/CServiceHealthCommanding.cpp b/src/fsfw/pus/CServiceHealthCommanding.cpp index 7faf8174..3ced4ffb 100644 --- a/src/fsfw/pus/CServiceHealthCommanding.cpp +++ b/src/fsfw/pus/CServiceHealthCommanding.cpp @@ -82,6 +82,9 @@ ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message, ReturnValue_t result = returnvalue::OK; switch (subservice) { case (Subservice::COMMAND_SET_HEALTH): { + if (tcDataLen != sizeof(object_id_t) + sizeof(HasHealthIF::HealthState)) { + return CommandingServiceBase::INVALID_TC; + } HealthSetCommand healthCommand; result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG); if (result != returnvalue::OK) { @@ -93,7 +96,7 @@ ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message, } case (Subservice::COMMAND_ANNOUNCE_HEALTH): { HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE); - break; + return CommandingServiceBase::EXECUTION_COMPLETE; } case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): { ReturnValue_t result = iterateHealthTable(true); From 227524a21da755d125bcb1a5ff67bcbc452f8cf9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 15:49:09 +0100 Subject: [PATCH 11/60] transition source submode is tricky --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } From 341437df1387aaf0128dd5304b5c0cc8ad734e69 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 21 Mar 2023 20:20:13 +0100 Subject: [PATCH 12/60] add flush functions for serial helpers --- src/fsfw_hal/linux/serial/helper.cpp | 4 ++++ src/fsfw_hal/linux/serial/helper.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/fsfw_hal/linux/serial/helper.cpp b/src/fsfw_hal/linux/serial/helper.cpp index ba975f2f..bc344608 100644 --- a/src/fsfw_hal/linux/serial/helper.cpp +++ b/src/fsfw_hal/linux/serial/helper.cpp @@ -161,3 +161,7 @@ void uart::setStopbits(struct termios& options, StopBits bits) { options.c_cflag &= ~CSTOPB; } } + +void uart::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); } + +void uart::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..833886b1 100644 --- a/src/fsfw_hal/linux/serial/helper.h +++ b/src/fsfw_hal/linux/serial/helper.h @@ -64,6 +64,9 @@ 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 From f8a7c1d4ed621a3375db0da9b9e9f8d5484abbc1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Mar 2023 01:03:49 +0100 Subject: [PATCH 13/60] rename namespace --- src/fsfw_hal/linux/serial/SerialComIF.cpp | 6 +++--- src/fsfw_hal/linux/serial/helper.cpp | 20 ++++++++++---------- src/fsfw_hal/linux/serial/helper.h | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) 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 bc344608..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; @@ -162,6 +162,6 @@ void uart::setStopbits(struct termios& options, StopBits bits) { } } -void uart::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); } +void serial::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); } -void uart::flushTxRxBuf(int fd) { tcflush(fd, TCIOFLUSH); } +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 833886b1..ee59ac66 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); /** From 33ac395072f0145b6e80e12deae978a5e0432f08 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Mar 2023 15:42:14 +0100 Subject: [PATCH 14/60] use RR sched instead of FIFO for Linux RT --- src/fsfw/osal/linux/PosixThread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/osal/linux/PosixThread.cpp b/src/fsfw/osal/linux/PosixThread.cpp index 811d58e2..9851876d 100644 --- a/src/fsfw/osal/linux/PosixThread.cpp +++ b/src/fsfw/osal/linux/PosixThread.cpp @@ -179,8 +179,8 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { #error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1" #endif #if FSFW_USE_REALTIME_FOR_LINUX == 1 - // FIFO -> This needs root privileges for the process - status = pthread_attr_setschedpolicy(&attributes, SCHED_FIFO); + // RR -> This needs root privileges for the process + status = pthread_attr_setschedpolicy(&attributes, SCHED_RR); if (status != 0) { utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy"); } From db4587bb59603bdc83e6720193fd1782649a0678 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Mar 2023 18:29:17 +0100 Subject: [PATCH 15/60] allow creating regular threads --- src/fsfw/osal/linux/PosixThread.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/fsfw/osal/linux/PosixThread.cpp b/src/fsfw/osal/linux/PosixThread.cpp index 9851876d..e90070bb 100644 --- a/src/fsfw/osal/linux/PosixThread.cpp +++ b/src/fsfw/osal/linux/PosixThread.cpp @@ -178,20 +178,32 @@ 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 (priority < 100) { + // RR -> This needs root privileges for the process #if FSFW_USE_REALTIME_FOR_LINUX == 1 - // RR -> This needs root privileges for the process - status = pthread_attr_setschedpolicy(&attributes, SCHED_RR); - 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"); + } +#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 + } else { + priority = 0; } sched_param scheduleParams; scheduleParams.__sched_priority = priority; status = pthread_attr_setschedparam(&attributes, &scheduleParams); if (status != 0) { - utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedparam"); - } +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "PosixThread: Setting priority failed" << std::endl; #endif + } // Set Signal Mask for suspend until startTask is called sigset_t waitSignal; sigemptyset(&waitSignal); From cf6150cc184656481eaeb2beff23cd8e92a6ada9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Mar 2023 00:57:44 +0100 Subject: [PATCH 16/60] add BUSY retval --- src/fsfw/devicehandlers/DeviceCommunicationIF.h | 1 + 1 file changed, 1 insertion(+) 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() {} From d16b3c7e6707276dcc5a7ce6b100a88b0ef84b74 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Mar 2023 11:53:41 +0100 Subject: [PATCH 17/60] try to do this cleanly --- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 11 ++++++++--- src/fsfw/osal/linux/FixedTimeslotTask.h | 3 ++- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 11 ++++++++--- src/fsfw/osal/linux/PeriodicPosixTask.h | 2 +- src/fsfw/osal/linux/PosixThread.cpp | 11 ++++++----- src/fsfw/osal/linux/PosixThread.h | 11 ++++++++++- src/fsfw/osal/linux/TaskFactory.cpp | 14 ++++++++------ src/fsfw/tasks/TaskFactory.h | 6 ++++-- src/fsfw_hal/linux/serial/helper.h | 2 +- 9 files changed, 48 insertions(+), 23 deletions(-) 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 e90070bb..385b4e1c 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,7 +179,7 @@ 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 (priority < 100) { + if (schedPolicy == SchedulingPolicy::RR) { // RR -> This needs root privileges for the process #if FSFW_USE_REALTIME_FOR_LINUX == 1 status = pthread_attr_setschedpolicy(&attributes, SCHED_RR); @@ -192,8 +193,6 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { << std::endl; #endif #endif - } else { - priority = 0; } sched_param scheduleParams; @@ -255,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..1ae0ec0c 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; +}; + 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/tasks/TaskFactory.h b/src/fsfw/tasks/TaskFactory.h index 828c533e..9198f100 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); /** * 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); /** * Function to be called to delete a task diff --git a/src/fsfw_hal/linux/serial/helper.h b/src/fsfw_hal/linux/serial/helper.h index ee59ac66..623612ad 100644 --- a/src/fsfw_hal/linux/serial/helper.h +++ b/src/fsfw_hal/linux/serial/helper.h @@ -69,6 +69,6 @@ void flushTxRxBuf(int fd); int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter); -} // namespace uart +} // namespace serial #endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */ From e704295cce76048d65bbb8893840b9ecedb05c94 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Mar 2023 11:58:23 +0100 Subject: [PATCH 18/60] default value --- src/fsfw/osal/linux/PosixThread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/osal/linux/PosixThread.h b/src/fsfw/osal/linux/PosixThread.h index 1ae0ec0c..133a9884 100644 --- a/src/fsfw/osal/linux/PosixThread.h +++ b/src/fsfw/osal/linux/PosixThread.h @@ -11,7 +11,7 @@ enum SchedulingPolicy { REGULAR, RR }; struct PosixThreadArgs { - SchedulingPolicy policy; + SchedulingPolicy policy = SchedulingPolicy::REGULAR; }; class PosixThread { From 4415dc24e1bee0252e5282b583fcade7f37a97bf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Mar 2023 13:25:34 +0100 Subject: [PATCH 19/60] fix host OSAL --- src/fsfw/osal/host/TaskFactory.cpp | 10 ++++++---- src/fsfw/tasks/TaskFactory.h | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) 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/tasks/TaskFactory.h b/src/fsfw/tasks/TaskFactory.h index 9198f100..e9b96a77 100644 --- a/src/fsfw/tasks/TaskFactory.h +++ b/src/fsfw/tasks/TaskFactory.h @@ -48,7 +48,7 @@ class TaskFactory { PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, - void* args); + void* args = nullptr); /** * The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks. @@ -64,7 +64,7 @@ class TaskFactory { TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, - void* args); + void* args = nullptr); /** * Function to be called to delete a task From a937b457f900a6a6b26bc0b42a5357f014840a67 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Mar 2023 14:10:47 +0100 Subject: [PATCH 20/60] this is so confusing --- src/fsfw/osal/linux/PosixThread.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fsfw/osal/linux/PosixThread.cpp b/src/fsfw/osal/linux/PosixThread.cpp index 385b4e1c..f420b326 100644 --- a/src/fsfw/osal/linux/PosixThread.cpp +++ b/src/fsfw/osal/linux/PosixThread.cpp @@ -186,6 +186,14 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { 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 @@ -195,14 +203,6 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { #endif } - 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 - } // Set Signal Mask for suspend until startTask is called sigset_t waitSignal; sigemptyset(&waitSignal); From b31e1037fb3d436e6a7f213050af8f64d194a85d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 26 Mar 2023 20:05:10 +0200 Subject: [PATCH 21/60] HK service configurable queue depth --- src/fsfw/pus/Service3Housekeeping.cpp | 5 +++-- src/fsfw/pus/Service3Housekeeping.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/fsfw/pus/Service3Housekeeping.cpp b/src/fsfw/pus/Service3Housekeeping.cpp index 0a51aa4b..485c83f4 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) +Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId, + uint32_t queueDepth) : CommandingServiceBase(objectId, apid, "PUS 3 HK", serviceId, NUM_OF_PARALLEL_COMMANDS, - COMMAND_TIMEOUT_SECONDS) {} + COMMAND_TIMEOUT_SECONDS, queueDepth) {} Service3Housekeeping::~Service3Housekeeping() {} diff --git a/src/fsfw/pus/Service3Housekeeping.h b/src/fsfw/pus/Service3Housekeeping.h index 70f15762..38f808f4 100644 --- a/src/fsfw/pus/Service3Housekeeping.h +++ b/src/fsfw/pus/Service3Housekeeping.h @@ -28,7 +28,7 @@ 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); virtual ~Service3Housekeeping(); protected: From 314f0fa2cde749ee1021d311e222bb0044cc2e5b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 15:27:48 +0200 Subject: [PATCH 22/60] start power switch component in undefined mode --- src/fsfw/power/PowerSwitcherComponent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 4f632e2c6866cee88dd9920a965aa0d079799aa3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 28 Mar 2023 19:37:47 +0200 Subject: [PATCH 23/60] ctrl base bugfix --- src/fsfw/controller/ControllerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); From e2e87b149d91c51196c76d6b84243fce1c77a28a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 3 Apr 2023 14:31:45 +0200 Subject: [PATCH 24/60] initialize switch state list --- src/fsfw/power/DummyPowerSwitcher.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fsfw/power/DummyPowerSwitcher.cpp b/src/fsfw/power/DummyPowerSwitcher.cpp index 952a5a57..51adde71 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; From 1e3c89b672e17700a9b50a312d9df29c54977685 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 3 Apr 2023 17:59:14 +0200 Subject: [PATCH 25/60] i dont think ths needs to be public --- src/fsfw/devicehandlers/HealthDevice.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fsfw/devicehandlers/HealthDevice.h b/src/fsfw/devicehandlers/HealthDevice.h index f4c3520f..00ea44c5 100644 --- a/src/fsfw/devicehandlers/HealthDevice.h +++ b/src/fsfw/devicehandlers/HealthDevice.h @@ -31,8 +31,6 @@ class HealthDevice : public SystemObject, public ExecutableObjectIF, public HasH MessageQueueId_t parentQueue; MessageQueueIF* commandQueue; - - public: HealthHelper healthHelper; }; From 7a392dc33a7e406986fa3684e114a41b0e91de9a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 3 Apr 2023 18:54:35 +0200 Subject: [PATCH 26/60] new register function --- src/fsfw/devicehandlers/HealthDevice.cpp | 5 ++-- src/fsfw/devicehandlers/HealthDevice.h | 2 +- src/fsfw/subsystem/SubsystemBase.cpp | 31 +++++++++++++----------- src/fsfw/subsystem/SubsystemBase.h | 2 ++ 4 files changed, 22 insertions(+), 18 deletions(-) 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 00ea44c5..a5c28cf7 100644 --- a/src/fsfw/devicehandlers/HealthDevice.h +++ b/src/fsfw/devicehandlers/HealthDevice.h @@ -29,7 +29,7 @@ class HealthDevice : public SystemObject, public ExecutableObjectIF, public HasH protected: HealthState lastHealth; - MessageQueueId_t parentQueue; + MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE; MessageQueueIF* commandQueue; HealthHelper healthHelper; }; diff --git a/src/fsfw/subsystem/SubsystemBase.cpp b/src/fsfw/subsystem/SubsystemBase.cpp index eccd447c..b8c09230 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; From 7966ede11b1eb038cbf0111f865bfbf830183c24 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 3 Apr 2023 21:57:18 +0200 Subject: [PATCH 27/60] add O_SYNC flag for UioMapper --- src/fsfw_hal/linux/uio/UioMapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 94cdf67a80e3379783df57954e354d858f2f8e03 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 4 Apr 2023 01:51:58 +0200 Subject: [PATCH 28/60] make health functions virtual --- src/fsfw/devicehandlers/DeviceHandlerBase.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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, From 4af90f99f3daf108ea123afc7c0f0372e5d0da5d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 4 Apr 2023 01:52:26 +0200 Subject: [PATCH 29/60] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3e03c4f..a841e38d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +## Changed + +- Health functions are virtual now. + # [v6.0.0] 2023-02-10 ## Fixes From 6650c293da09d8851c2bd6c4d6e6c5a8390d003e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 4 Apr 2023 15:59:26 +0200 Subject: [PATCH 30/60] change collection interval is public now --- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 12 +++--------- src/fsfw/datapoollocal/LocalDataPoolManager.h | 3 +-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index f66a328c..178d5654 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,7 @@ 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 +728,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); From 5a9304765f670685b6ca27cc9e6064012a17bab7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 6 Apr 2023 22:34:57 +0200 Subject: [PATCH 31/60] accepts action commands without ipc data --- src/fsfw/action/ActionHelper.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/fsfw/action/ActionHelper.cpp b/src/fsfw/action/ActionHelper.cpp index fd6c8afb..5e0a9a5f 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); From e97fa5ac84db7ab5c10a31c2c78b26057cfacb71 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 7 Apr 2023 11:03:46 +0200 Subject: [PATCH 32/60] add skip directive for retvals --- src/fsfw/globalfunctions/DleParser.h | 3 +++ 1 file changed, 3 insertions(+) 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 }; From 285d327b97514946f0714e477289f67ee8bd413f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 7 Apr 2023 17:42:44 +0200 Subject: [PATCH 33/60] clean up spi retval defs --- src/fsfw/action/ActionHelper.cpp | 4 ++-- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 3 ++- src/fsfw/power/DummyPowerSwitcher.cpp | 2 +- src/fsfw/subsystem/SubsystemBase.cpp | 2 +- src/fsfw_hal/common/spi/spiCommon.h | 12 +++++++++++- src/fsfw_hal/linux/spi/SpiComIF.cpp | 10 +++++----- src/fsfw_hal/linux/spi/SpiComIF.h | 9 --------- src/fsfw_hal/stm32h7/spi/SpiComIF.cpp | 6 +++--- 8 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/fsfw/action/ActionHelper.cpp b/src/fsfw/action/ActionHelper.cpp index 5e0a9a5f..81a1a727 100644 --- a/src/fsfw/action/ActionHelper.cpp +++ b/src/fsfw/action/ActionHelper.cpp @@ -63,7 +63,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act const uint8_t* dataPtr = nullptr; size_t size = 0; ReturnValue_t result; - if(dataAddress != store_address_t::invalid()) { + if (dataAddress != store_address_t::invalid()) { hasAdditionalData = true; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != returnvalue::OK) { @@ -74,7 +74,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act } } result = owner->executeAction(actionId, commandedBy, dataPtr, size); - if(hasAdditionalData) { + if (hasAdditionalData) { ipcStore->deleteData(dataAddress); } if (result == HasActionsIF::EXECUTION_FINISHED) { diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index 178d5654..32de8e6b 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -720,7 +720,8 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool ena return returnvalue::OK; } -ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float newCollectionInterval) { +ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, + float newCollectionInterval) { LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid); if (dataSet == nullptr) { printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval", diff --git a/src/fsfw/power/DummyPowerSwitcher.cpp b/src/fsfw/power/DummyPowerSwitcher.cpp index 51adde71..80b4cc4a 100644 --- a/src/fsfw/power/DummyPowerSwitcher.cpp +++ b/src/fsfw/power/DummyPowerSwitcher.cpp @@ -7,7 +7,7 @@ DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwit switcherList(numberOfSwitches), fuseList(numberOfFuses), switchDelayMs(switchDelayMs) { - for(auto &switchState: switcherList) { + for (auto &switchState : switcherList) { switchState = PowerSwitchIF::SWITCH_UNKNOWN; } } diff --git a/src/fsfw/subsystem/SubsystemBase.cpp b/src/fsfw/subsystem/SubsystemBase.cpp index b8c09230..4f62a889 100644 --- a/src/fsfw/subsystem/SubsystemBase.cpp +++ b/src/fsfw/subsystem/SubsystemBase.cpp @@ -325,7 +325,7 @@ 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; + ChildInfo info; // intentional to force an initial command during system startup info.commandQueue = childQueue; 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/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/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; From 894d1e3b8744bb59b498e8ac56f19065759af366 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 11 Apr 2023 16:36:54 +0200 Subject: [PATCH 34/60] move CFDP handler --- src/fsfw/cfdp.h | 1 - src/fsfw/cfdp/handler/CMakeLists.txt | 5 +- src/fsfw/cfdp/handler/CfdpHandler.cpp | 134 -------------------------- src/fsfw/cfdp/handler/CfdpHandler.h | 71 -------------- 4 files changed, 2 insertions(+), 209 deletions(-) delete mode 100644 src/fsfw/cfdp/handler/CfdpHandler.cpp delete mode 100644 src/fsfw/cfdp/handler/CfdpHandler.h 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 From 7f61d17ceeee76ffd2206831a9288e5c8da5b6f0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 21:08:44 +0200 Subject: [PATCH 35/60] even better event manager printout --- src/fsfw/events/EventManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fsfw/events/EventManager.cpp b/src/fsfw/events/EventManager.cpp index f2a099ed..045b2416 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 " << 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); From 5eb9ee8bc1e6f8640cbea46febd11e4b92241881 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 21:22:24 +0200 Subject: [PATCH 36/60] DHB fdir: event queue depth confgurable --- src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.cpp | 5 +++-- src/fsfw/devicehandlers/DeviceHandlerFailureIsolation.h | 3 ++- src/fsfw/events/EventManager.cpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) 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/events/EventManager.cpp b/src/fsfw/events/EventManager.cpp index 045b2416..f5cc99c6 100644 --- a/src/fsfw/events/EventManager.cpp +++ b/src/fsfw/events/EventManager.cpp @@ -55,7 +55,7 @@ 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 << " for event " << std::setw(4) + << 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 From 258f0d331329d67e13eec9d7f4053fd269e3f9b6 Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 19 Apr 2023 15:25:14 +0200 Subject: [PATCH 37/60] use both LPFs --- .../devicehandlers/devicedefinitions/gyroL3gHelpers.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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; From 025b379e8bc053c7daa9267e3fa77c33749ef3c9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 4 May 2023 14:04:55 +0200 Subject: [PATCH 38/60] bump ETL version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From 4518fec65ce92c0cc0f569036da8cbcf1b1a3d1e Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Mon, 8 May 2023 15:25:47 +0200 Subject: [PATCH 39/60] CHANGELOG --- CHANGELOG.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01420436..693e59e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,15 +10,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Fixes -- Linux OSAL `getUptime` fix: Check validity of `/proc/uptime` file before reading uptime. - PUS Health Service: Size check for set health command. -- PUS Health Service: Perform operation completion for announce 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 ## Changed - +- 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 # [v6.0.0] 2023-02-10 From cae131edcf95e6ab8c6415abb31e529aea553ba7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 15 May 2023 16:02:55 +0200 Subject: [PATCH 40/60] CFDP and unittest bugfixes --- src/fsfw/cfdp/pdu/HeaderCreator.cpp | 4 ++-- src/fsfw/cfdp/pdu/HeaderReader.cpp | 4 ++-- unittests/CatchFactory.cpp | 2 +- unittests/action/TestActionHelper.cpp | 22 +++++----------------- unittests/cfdp/pdu/testCfdpHeader.cpp | 10 +++++----- unittests/cfdp/pdu/testFileData.cpp | 2 +- unittests/cfdp/pdu/testFileDirective.cpp | 4 ++-- unittests/cfdp/testCfdp.cpp | 4 ++-- 8 files changed, 20 insertions(+), 32 deletions(-) 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/unittests/CatchFactory.cpp b/unittests/CatchFactory.cpp index 0d855cb3..37c62f94 100644 --- a/unittests/CatchFactory.cpp +++ b/unittests/CatchFactory.cpp @@ -30,7 +30,7 @@ */ 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); diff --git a/unittests/action/TestActionHelper.cpp b/unittests/action/TestActionHelper.cpp index d99700d7..57166d5e 100644 --- a/unittests/action/TestActionHelper.cpp +++ b/unittests/action/TestActionHelper.cpp @@ -27,12 +27,8 @@ 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()); + CHECK(not testMqMock.wasMessageSent()); const uint8_t* ptr = nullptr; size_t size = 0; REQUIRE(ipcStore->getData(paramAddress, &ptr, &size) == @@ -44,6 +40,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 +95,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 From 1a77e6bb095b275f8223d7f71f74eb6de188ec54 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 15 May 2023 16:13:05 +0200 Subject: [PATCH 41/60] proper floating point comparison --- unittests/datapoollocal/testLocalPoolManager.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) 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)); From 4391823f01d792bcc078d47b60f7df7624f8cbe4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 15 May 2023 16:14:36 +0200 Subject: [PATCH 42/60] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a841e38d..2250a301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +## Fixed + +- 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. + ## Changed - Health functions are virtual now. From e0adb3325f4a26f6c112ef4b83114319b67cdbff Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 May 2023 10:37:26 +0200 Subject: [PATCH 43/60] werks --- unittests/action/TestActionHelper.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/unittests/action/TestActionHelper.cpp b/unittests/action/TestActionHelper.cpp index 57166d5e..de021bb8 100644 --- a/unittests/action/TestActionHelper.cpp +++ b/unittests/action/TestActionHelper.cpp @@ -28,7 +28,6 @@ TEST_CASE("Action Helper", "[action]") { REQUIRE(actionHelper.handleActionMessage(&actionMessage) == returnvalue::OK); CHECK(testDhMock.executeActionCalled); CHECK(not testMqMock.wasMessageSent()); - CHECK(not testMqMock.wasMessageSent()); const uint8_t* ptr = nullptr; size_t size = 0; REQUIRE(ipcStore->getData(paramAddress, &ptr, &size) == From b442ca09b91d0cfdc6acd5a30349a25c4051972c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 11:58:31 +0200 Subject: [PATCH 44/60] configurable queue depth --- src/fsfw/pus/Service8FunctionManagement.cpp | 4 ++-- src/fsfw/pus/Service8FunctionManagement.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) 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: From 74b164b1da9958a5b34a8c3cea05e74d111a6d4d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Jun 2023 18:02:27 +0200 Subject: [PATCH 45/60] make number of parallel cmds configurable --- src/fsfw/pus/Service3Housekeeping.cpp | 4 ++-- src/fsfw/pus/Service3Housekeeping.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/fsfw/pus/Service3Housekeeping.cpp b/src/fsfw/pus/Service3Housekeeping.cpp index 485c83f4..c6fac20c 100644 --- a/src/fsfw/pus/Service3Housekeeping.cpp +++ b/src/fsfw/pus/Service3Housekeeping.cpp @@ -5,8 +5,8 @@ #include "fsfw/pus/servicepackets/Service3Packets.h" Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId, - uint32_t queueDepth) - : CommandingServiceBase(objectId, apid, "PUS 3 HK", serviceId, NUM_OF_PARALLEL_COMMANDS, + 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 38f808f4..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, uint32_t queueDepth); + Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId, uint32_t queueDepth, + uint8_t numParallelCommands); virtual ~Service3Housekeeping(); protected: From f2947bc78e91802e93eee970817b6ca47356225a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 18 Jun 2023 19:04:36 +0200 Subject: [PATCH 46/60] specify truncate flag explicitely --- src/fsfw_hal/host/HostFilesystem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fsfw_hal/host/HostFilesystem.cpp b/src/fsfw_hal/host/HostFilesystem.cpp index 315ba422..f9f3bdd6 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 truncaion flug explicitely. + ofstream of(path, std::ios::out | std::ios::trunc); return returnvalue::OK; } From f80c5980ea5bf84828a22dc6b4985a8747f85df4 Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 17:04:45 +0200 Subject: [PATCH 47/60] max value calc fix --- src/fsfw/globalfunctions/math/VectorOperations.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/globalfunctions/math/VectorOperations.h b/src/fsfw/globalfunctions/math/VectorOperations.h index 197cd46a..1e84330e 100644 --- a/src/fsfw/globalfunctions/math/VectorOperations.h +++ b/src/fsfw/globalfunctions/math/VectorOperations.h @@ -54,7 +54,7 @@ class VectorOperations { } static T maxAbsValue(const T *vector, uint8_t size, uint8_t *index = 0) { - T max = -1; + T max = vector[size - 1]; for (; size > 0; size--) { T abs = vector[size - 1]; @@ -72,7 +72,7 @@ class VectorOperations { } static T maxValue(const T *vector, uint8_t size, uint8_t *index = 0) { - T max = -1; + T max = vector[size - 1]; for (; size > 0; size--) { if (vector[size - 1] > max) { From c7037d417a8dbc0e0b7d2c5244c02bb1fc3c1312 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Tue, 20 Jun 2023 11:54:15 +0200 Subject: [PATCH 48/60] nullptr check for optional argument --- .../globalfunctions/math/VectorOperations.h | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/fsfw/globalfunctions/math/VectorOperations.h b/src/fsfw/globalfunctions/math/VectorOperations.h index 1e84330e..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) { + 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) { + 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; } From 0f76cdb3ba54f5e90a8eee4316c49cf0f581f996 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:36:03 +0200 Subject: [PATCH 49/60] typo --- src/fsfw_hal/host/HostFilesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw_hal/host/HostFilesystem.cpp b/src/fsfw_hal/host/HostFilesystem.cpp index f9f3bdd6..20984f77 100644 --- a/src/fsfw_hal/host/HostFilesystem.cpp +++ b/src/fsfw_hal/host/HostFilesystem.cpp @@ -165,7 +165,7 @@ ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) { if (not filesystem::exists(path, e)) { return FILE_DOES_NOT_EXIST; } - // Specify truncaion flug explicitely. + // Specify truncation flug explicitely. ofstream of(path, std::ios::out | std::ios::trunc); return returnvalue::OK; } From a85a38c882af968200a0dd54ded9fd99b3961e7a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 22 Jun 2023 16:08:29 +0200 Subject: [PATCH 50/60] some thnings are configurable now --- src/fsfw/internalerror/InternalErrorReporter.cpp | 10 ++++++---- src/fsfw/internalerror/InternalErrorReporter.h | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-) 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..210f2cb1 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 generatonFrequency); /** * 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; From 2293e7f2bb31c4bf81ad8e41c358c94fc9a5f921 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 22 Jun 2023 16:12:41 +0200 Subject: [PATCH 51/60] typo --- src/fsfw/internalerror/InternalErrorReporter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/internalerror/InternalErrorReporter.h b/src/fsfw/internalerror/InternalErrorReporter.h index 210f2cb1..f845410b 100644 --- a/src/fsfw/internalerror/InternalErrorReporter.h +++ b/src/fsfw/internalerror/InternalErrorReporter.h @@ -22,7 +22,7 @@ class InternalErrorReporter : public SystemObject, public HasLocalDataPoolIF { public: InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth, - bool enableSetByDefault, float generatonFrequency); + bool enableSetByDefault, float generationFrequency); /** * Enable diagnostic printout. Please note that this feature will From c3572e31a8d6845442cf8e54802d94477b2db64e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 25 Jun 2023 12:35:50 +0200 Subject: [PATCH 52/60] add API to set msg counter --- CHANGELOG.md | 2 +- src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.cpp | 6 ++++++ src/fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 487f3736..b4e9ab8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Fixes - - 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. @@ -26,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - add CFDP subsystem ID https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/742 +- `PusTmZcWriter` now exposes API to set message counter field. ## Changed - Bump ETL version to 20.35.14 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: From 110cb903a609586c77e3bc093851b8d739ddedc3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 10 Jul 2023 14:14:31 +0200 Subject: [PATCH 53/60] countdown based HK generation --- CHANGELOG.md | 2 + .../PeriodicHousekeepingHelper.cpp | 47 ++++--------------- .../housekeeping/PeriodicHousekeepingHelper.h | 8 ++-- 3 files changed, 14 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e9ab8e..c5e05a91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `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`. diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp index b39e45c3..852032fa 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,21 @@ 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; -} - -float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() const { - return intervalTicksToSeconds(collectionIntervalTicks); + changeCollectionInterval(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; + } + hkGenerationCd.setTimeout(intervalMs); } diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h index 1ec0febf..2e168c85 100644 --- a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h +++ b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h @@ -1,6 +1,8 @@ #ifndef FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ #define FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ +#include + #include #include "fsfw/timemanager/Clock.h" @@ -19,13 +21,9 @@ class PeriodicHousekeepingHelper { private: LocalPoolDataSetBase* owner = nullptr; - - uint32_t intervalSecondsToIntervalTicks(float collectionIntervalSeconds); - float intervalTicksToSeconds(uint32_t collectionInterval) const; + Countdown hkGenerationCd; dur_millis_t minimumPeriodicInterval = 0; - uint32_t internalTickCounter = 1; - uint32_t collectionIntervalTicks = 0; }; #endif /* FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ */ From 9c8b1c697b3812958e7d00326ee12285e0484caf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 10 Jul 2023 14:20:02 +0200 Subject: [PATCH 54/60] added back missing function --- src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp | 6 ++++++ src/fsfw/housekeeping/PeriodicHousekeepingHelper.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp index 852032fa..da3b6b8d 100644 --- a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp +++ b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp @@ -14,6 +14,10 @@ void PeriodicHousekeepingHelper::initialize(float collectionInterval, changeCollectionInterval(collectionInterval); } +float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() const { + return collectionInterval; +} + bool PeriodicHousekeepingHelper::checkOpNecessary() { if (hkGenerationCd.hasTimedOut()) { hkGenerationCd.resetTimer(); @@ -26,6 +30,8 @@ void PeriodicHousekeepingHelper::changeCollectionInterval(float newIntervalSecon uint32_t intervalMs = newIntervalSeconds * 1000; if (newIntervalSeconds <= 0) { intervalMs = minimumPeriodicInterval; + newIntervalSeconds = static_cast(minimumPeriodicInterval) / 1000.0; } + collectionInterval = newIntervalSeconds; hkGenerationCd.setTimeout(intervalMs); } diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h index 2e168c85..19418977 100644 --- a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h +++ b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h @@ -22,6 +22,7 @@ class PeriodicHousekeepingHelper { private: LocalPoolDataSetBase* owner = nullptr; Countdown hkGenerationCd; + float collectionInterval = 0.0; dur_millis_t minimumPeriodicInterval = 0; }; From 88e8665280a0381c41b724ab035a8c3eff1a23c1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 10 Jul 2023 17:45:02 +0200 Subject: [PATCH 55/60] important bugfix for PUS TM creator --- CHANGELOG.md | 2 ++ src/fsfw/tmtcpacket/pus/tm/PusTmCreator.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e9ab8e..c8e399ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## 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. 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; }; From 988e07f0bece2f1ccf7b26c9e80965440c667409 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 11 Jul 2023 15:40:43 +0200 Subject: [PATCH 56/60] countdown --- src/fsfw/housekeeping/PeriodicHousekeepingHelper.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h index 19418977..1586649c 100644 --- a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h +++ b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.h @@ -1,11 +1,10 @@ #ifndef FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ #define FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ -#include - #include #include "fsfw/timemanager/Clock.h" +#include "fsfw/timemanager/Countdown.h" class LocalPoolDataSetBase; From a26b0c38ac2631804fac8b27eb11f749748b12dd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 10:31:02 +0200 Subject: [PATCH 57/60] small tweak to allow immediate HK generation --- src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp index da3b6b8d..ec34330a 100644 --- a/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp +++ b/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp @@ -34,4 +34,6 @@ void PeriodicHousekeepingHelper::changeCollectionInterval(float newIntervalSecon } collectionInterval = newIntervalSeconds; hkGenerationCd.setTimeout(intervalMs); + // We want an immediate HK packet at the start, so time out the generation CD immediately. + hkGenerationCd.timeOut(); } From aac74fae3889cc1f5184ef81d65fd7e4c56b8caf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 10:34:19 +0200 Subject: [PATCH 58/60] shared cmake file --- .idea/cmake.xml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .idea/cmake.xml 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 From 62ace649a758aa19d510e95c3c68bb50660d299e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 10:35:35 +0200 Subject: [PATCH 59/60] fix unittest --- unittests/CatchFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/CatchFactory.cpp b/unittests/CatchFactory.cpp index 37c62f94..589e6887 100644 --- a/unittests/CatchFactory.cpp +++ b/unittests/CatchFactory.cpp @@ -32,7 +32,7 @@ void Factory::produceFrameworkObjects(void* args) { setStaticFrameworkObjectIds(); 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}}; From 796c7a9e377fa197e7e79b9a757d1b8e97419b8f Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 9 Aug 2023 11:42:11 +0200 Subject: [PATCH 60/60] tle is too old after 30 days now --- src/fsfw/coordinates/Sgp4Propagator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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; }