From 9ce59d3c750e74e81c04a0a740c6994c48674b5c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Mar 2022 17:54:09 +0100 Subject: [PATCH 001/198] added an additional conversion function - timeval to TimeOfDay_t --- src/fsfw/timemanager/Clock.h | 7 +++++++ src/fsfw/timemanager/ClockCommon.cpp | 21 ++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/fsfw/timemanager/Clock.h b/src/fsfw/timemanager/Clock.h index 99e8a56a..e9afff2e 100644 --- a/src/fsfw/timemanager/Clock.h +++ b/src/fsfw/timemanager/Clock.h @@ -99,6 +99,13 @@ class Clock { */ static ReturnValue_t getDateAndTime(TimeOfDay_t *time); + /** + * Convert to time of day struct given the POSIX timeval struct + * @param from + * @param to + * @return + */ + static ReturnValue_t convertTimevalToTimeOfDay(const timeval *from, TimeOfDay_t *to); /** * Converts a time of day struct to POSIX seconds. * @param time The time of day as input diff --git a/src/fsfw/timemanager/ClockCommon.cpp b/src/fsfw/timemanager/ClockCommon.cpp index e5749b19..18407362 100644 --- a/src/fsfw/timemanager/ClockCommon.cpp +++ b/src/fsfw/timemanager/ClockCommon.cpp @@ -1,7 +1,9 @@ +#include + #include "fsfw/ipc/MutexGuard.h" #include "fsfw/timemanager/Clock.h" -ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval *tt) { +ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { uint16_t leapSeconds; ReturnValue_t result = getLeapSeconds(&leapSeconds); if (result != HasReturnvaluesIF::RETURN_OK) { @@ -31,7 +33,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t Clock::getLeapSeconds(uint16_t *leapSeconds_) { +ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if (timeMutex == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -42,9 +44,22 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t *leapSeconds_) { return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) { + struct tm* timeInfo; + timeInfo = gmtime(&from->tv_sec); + to->year = timeInfo->tm_year + 1900; + to->month = timeInfo->tm_mon + 1; + to->day = timeInfo->tm_mday; + to->hour = timeInfo->tm_hour; + to->minute = timeInfo->tm_min; + to->second = timeInfo->tm_sec; + to->usecond = from->tv_usec; + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t Clock::checkOrCreateClockMutex() { if (timeMutex == nullptr) { - MutexFactory *mutexFactory = MutexFactory::instance(); + MutexFactory* mutexFactory = MutexFactory::instance(); if (mutexFactory == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } From 7ffb4107d246446c468ca10c49a60a939e39e29f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 25 Mar 2022 13:32:29 +0100 Subject: [PATCH 002/198] added missing docs --- src/fsfw/timemanager/ClockCommon.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/fsfw/timemanager/ClockCommon.cpp b/src/fsfw/timemanager/ClockCommon.cpp index 18407362..87b88497 100644 --- a/src/fsfw/timemanager/ClockCommon.cpp +++ b/src/fsfw/timemanager/ClockCommon.cpp @@ -46,6 +46,9 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) { struct tm* timeInfo; + // According to https://en.cppreference.com/w/c/chrono/gmtime, the implementation of gmtime_s + // in the Windows CRT is incompatible with the C standard but this should not be an issue for + // this implementation timeInfo = gmtime(&from->tv_sec); to->year = timeInfo->tm_year + 1900; to->month = timeInfo->tm_mon + 1; From 7095999bd2a412a475362bce19f6f1eb9d1cfec6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 25 Mar 2022 13:34:35 +0100 Subject: [PATCH 003/198] remove CCSDSTime function --- src/fsfw/timemanager/CCSDSTime.cpp | 5 ----- src/fsfw/timemanager/CCSDSTime.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/fsfw/timemanager/CCSDSTime.cpp b/src/fsfw/timemanager/CCSDSTime.cpp index c5132cbb..6a0a8e77 100644 --- a/src/fsfw/timemanager/CCSDSTime.cpp +++ b/src/fsfw/timemanager/CCSDSTime.cpp @@ -489,11 +489,6 @@ ReturnValue_t CCSDSTime::checkTimeOfDay(const Clock::TimeOfDay_t* time) { return RETURN_OK; } -ReturnValue_t CCSDSTime::convertTimevalToTimeOfDay(Clock::TimeOfDay_t* to, timeval* from) { - // This is rather tricky. Implement only if needed. Also, if so, move to OSAL. - return UNSUPPORTED_TIME_FORMAT; -} - ReturnValue_t CCSDSTime::convertFromCDS(timeval* to, const uint8_t* from, size_t* foundLength, size_t maxLength) { uint8_t pField = *from; diff --git a/src/fsfw/timemanager/CCSDSTime.h b/src/fsfw/timemanager/CCSDSTime.h index 9de41e09..19c980d0 100644 --- a/src/fsfw/timemanager/CCSDSTime.h +++ b/src/fsfw/timemanager/CCSDSTime.h @@ -223,7 +223,6 @@ class CCSDSTime : public HasReturnvaluesIF { uint8_t *day); static bool isLeapYear(uint32_t year); - static ReturnValue_t convertTimevalToTimeOfDay(Clock::TimeOfDay_t *to, timeval *from); }; #endif /* FSFW_TIMEMANAGER_CCSDSTIME_H_ */ From 59ab54b2fb0ff75d253cbbb6bb4ea59dbce37bbf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 25 Mar 2022 13:41:37 +0100 Subject: [PATCH 004/198] call corrections --- src/fsfw/timemanager/CCSDSTime.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/timemanager/CCSDSTime.cpp b/src/fsfw/timemanager/CCSDSTime.cpp index 6a0a8e77..d4f4f331 100644 --- a/src/fsfw/timemanager/CCSDSTime.cpp +++ b/src/fsfw/timemanager/CCSDSTime.cpp @@ -91,7 +91,7 @@ ReturnValue_t CCSDSTime::convertFromCDS(Clock::TimeOfDay_t* to, const uint8_t* f if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return convertTimevalToTimeOfDay(to, &time); + return Clock::convertTimevalToTimeOfDay(to, &time); } ReturnValue_t CCSDSTime::convertFromCCS(Clock::TimeOfDay_t* to, const uint8_t* from, @@ -578,7 +578,7 @@ ReturnValue_t CCSDSTime::convertFromCDS(Clock::TimeOfDay_t* to, const CCSDSTime: if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return CCSDSTime::convertTimevalToTimeOfDay(to, &tempTimeval); + return Clock::convertTimevalToTimeOfDay(to, &tempTimeval); } ReturnValue_t CCSDSTime::convertFromCUC(timeval* to, uint8_t pField, const uint8_t* from, From d0fec93dc34007aafb988e04106f01524670cb8a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 25 Mar 2022 13:42:49 +0100 Subject: [PATCH 005/198] argument order inversion --- src/fsfw/timemanager/CCSDSTime.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/timemanager/CCSDSTime.cpp b/src/fsfw/timemanager/CCSDSTime.cpp index d4f4f331..9ebd1d79 100644 --- a/src/fsfw/timemanager/CCSDSTime.cpp +++ b/src/fsfw/timemanager/CCSDSTime.cpp @@ -91,7 +91,7 @@ ReturnValue_t CCSDSTime::convertFromCDS(Clock::TimeOfDay_t* to, const uint8_t* f if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return Clock::convertTimevalToTimeOfDay(to, &time); + return Clock::convertTimevalToTimeOfDay(&time, to); } ReturnValue_t CCSDSTime::convertFromCCS(Clock::TimeOfDay_t* to, const uint8_t* from, @@ -578,7 +578,7 @@ ReturnValue_t CCSDSTime::convertFromCDS(Clock::TimeOfDay_t* to, const CCSDSTime: if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return Clock::convertTimevalToTimeOfDay(to, &tempTimeval); + return Clock::convertTimevalToTimeOfDay(&tempTimeval, to); } ReturnValue_t CCSDSTime::convertFromCUC(timeval* to, uint8_t pField, const uint8_t* from, From 10398855a9aeddfc808f511f24d3e363846bc756 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Fri, 25 Mar 2022 18:47:31 +0100 Subject: [PATCH 006/198] Added more unittest coverage Added Mutex for gmtime functions Moved Statics used in ClockCommon to ClockCommon --- src/fsfw/osal/freertos/Clock.cpp | 3 - src/fsfw/osal/host/Clock.cpp | 11 +- src/fsfw/osal/linux/Clock.cpp | 12 +- src/fsfw/osal/rtems/Clock.cpp | 2 - src/fsfw/timemanager/Clock.h | 1 + src/fsfw/timemanager/ClockCommon.cpp | 17 ++- .../unit/globalfunctions/CMakeLists.txt | 1 + .../globalfunctions/testTimevalOperations.cpp | 125 ++++++++++++++++++ tests/src/fsfw_tests/unit/osal/CMakeLists.txt | 1 + tests/src/fsfw_tests/unit/osal/TestClock.cpp | 92 +++++++++++++ .../unit/timemanager/TestCCSDSTime.cpp | 14 ++ 11 files changed, 266 insertions(+), 13 deletions(-) create mode 100644 tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp create mode 100644 tests/src/fsfw_tests/unit/osal/TestClock.cpp diff --git a/src/fsfw/osal/freertos/Clock.cpp b/src/fsfw/osal/freertos/Clock.cpp index 05083968..cabf7d81 100644 --- a/src/fsfw/osal/freertos/Clock.cpp +++ b/src/fsfw/osal/freertos/Clock.cpp @@ -11,9 +11,6 @@ // TODO sanitize input? // TODO much of this code can be reused for tick-only systems -uint16_t Clock::leapSeconds = 0; -MutexIF* Clock::timeMutex = nullptr; - uint32_t Clock::getTicksPerSecond(void) { return 1000; } ReturnValue_t Clock::setClock(const TimeOfDay_t* time) { diff --git a/src/fsfw/osal/host/Clock.cpp b/src/fsfw/osal/host/Clock.cpp index d0acdfdf..b4fd73f6 100644 --- a/src/fsfw/osal/host/Clock.cpp +++ b/src/fsfw/osal/host/Clock.cpp @@ -4,6 +4,7 @@ #include "fsfw/platform.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/ipc/MutexGuard.h" #if defined(PLATFORM_WIN) #include @@ -11,9 +12,6 @@ #include #endif -uint16_t Clock::leapSeconds = 0; -MutexIF* Clock::timeMutex = NULL; - using SystemClock = std::chrono::system_clock; uint32_t Clock::getTicksPerSecond(void) { @@ -127,6 +125,13 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { auto seconds = std::chrono::time_point_cast(now); auto fraction = now - seconds; time_t tt = SystemClock::to_time_t(now); + ReturnValue_t result = checkOrCreateClockMutex(); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + MutexGuard helper(timeMutex); + // gmtime writes its output in a global buffer which is not Thread Safe + // Therefore we have to use a Mutex here struct tm* timeInfo; timeInfo = gmtime(&tt); time->year = timeInfo->tm_year + 1900; diff --git a/src/fsfw/osal/linux/Clock.cpp b/src/fsfw/osal/linux/Clock.cpp index 61eb970f..a3480b56 100644 --- a/src/fsfw/osal/linux/Clock.cpp +++ b/src/fsfw/osal/linux/Clock.cpp @@ -9,9 +9,7 @@ #include #include "fsfw/serviceinterface/ServiceInterface.h" - -uint16_t Clock::leapSeconds = 0; -MutexIF* Clock::timeMutex = NULL; +#include "fsfw/ipc/MutexGuard.h" uint32_t Clock::getTicksPerSecond(void) { uint32_t ticks = sysconf(_SC_CLK_TCK); @@ -117,7 +115,13 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { // TODO errno return HasReturnvaluesIF::RETURN_FAILED; } - + ReturnValue_t result = checkOrCreateClockMutex(); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + MutexGuard helper(timeMutex); + // gmtime writes its output in a global buffer which is not Thread Safe + // Therefore we have to use a Mutex here struct tm* timeInfo; timeInfo = gmtime(&timeUnix.tv_sec); time->year = timeInfo->tm_year + 1900; diff --git a/src/fsfw/osal/rtems/Clock.cpp b/src/fsfw/osal/rtems/Clock.cpp index 06b0c1d8..fe0afb46 100644 --- a/src/fsfw/osal/rtems/Clock.cpp +++ b/src/fsfw/osal/rtems/Clock.cpp @@ -6,8 +6,6 @@ #include "fsfw/ipc/MutexGuard.h" #include "fsfw/osal/rtems/RtemsBasic.h" -uint16_t Clock::leapSeconds = 0; -MutexIF* Clock::timeMutex = nullptr; uint32_t Clock::getTicksPerSecond(void) { rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second(); diff --git a/src/fsfw/timemanager/Clock.h b/src/fsfw/timemanager/Clock.h index e9afff2e..75c898e5 100644 --- a/src/fsfw/timemanager/Clock.h +++ b/src/fsfw/timemanager/Clock.h @@ -173,6 +173,7 @@ class Clock { static MutexIF *timeMutex; static uint16_t leapSeconds; + static bool leapSecondsSet; }; #endif /* FSFW_TIMEMANAGER_CLOCK_H_ */ diff --git a/src/fsfw/timemanager/ClockCommon.cpp b/src/fsfw/timemanager/ClockCommon.cpp index 87b88497..c24dd781 100644 --- a/src/fsfw/timemanager/ClockCommon.cpp +++ b/src/fsfw/timemanager/ClockCommon.cpp @@ -3,6 +3,10 @@ #include "fsfw/ipc/MutexGuard.h" #include "fsfw/timemanager/Clock.h" +uint16_t Clock::leapSeconds = 0; +MutexIF* Clock::timeMutex = nullptr; +bool Clock::leapSecondsSet = false; + ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { uint16_t leapSeconds; ReturnValue_t result = getLeapSeconds(&leapSeconds); @@ -29,12 +33,16 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { MutexGuard helper(timeMutex); leapSeconds = leapSeconds_; + leapSecondsSet = true; return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { - if (timeMutex == nullptr) { + if(not leapSecondsSet){ + return HasReturnvaluesIF::RETURN_FAILED; + } + if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) { return HasReturnvaluesIF::RETURN_FAILED; } MutexGuard helper(timeMutex); @@ -49,6 +57,13 @@ ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* // According to https://en.cppreference.com/w/c/chrono/gmtime, the implementation of gmtime_s // in the Windows CRT is incompatible with the C standard but this should not be an issue for // this implementation + ReturnValue_t result = checkOrCreateClockMutex(); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + MutexGuard helper(timeMutex); + // gmtime writes its output in a global buffer which is not Thread Safe + // Therefore we have to use a Mutex here timeInfo = gmtime(&from->tv_sec); to->year = timeInfo->tm_year + 1900; to->month = timeInfo->tm_mon + 1; diff --git a/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt b/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt index 79f847bf..348b99fc 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt @@ -3,4 +3,5 @@ target_sources(${FSFW_TEST_TGT} PRIVATE testOpDivider.cpp testBitutil.cpp testCRC.cpp + testTimevalOperations.cpp ) diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp new file mode 100644 index 00000000..92242ed9 --- /dev/null +++ b/tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp @@ -0,0 +1,125 @@ +#include +#include + +#include + +#include "fsfw_tests/unit/CatchDefinitions.h" + +TEST_CASE("TimevalTest", "[timevalOperations]"){ + SECTION("Comparison"){ + timeval t1; + t1.tv_sec = 1648227422; + t1.tv_usec = 123456; + timeval t2; + t2.tv_sec = 1648227422; + t2.tv_usec = 123456; + REQUIRE(t1 == t2); + REQUIRE(t2 == t1); + REQUIRE_FALSE(t1 != t2); + REQUIRE_FALSE(t2 != t1); + REQUIRE(t1 <= t2); + REQUIRE(t2 <= t1); + REQUIRE(t1 >= t2); + REQUIRE(t2 >= t1); + REQUIRE_FALSE(t1 < t2); + REQUIRE_FALSE(t2 < t1); + REQUIRE_FALSE(t1 > t2); + REQUIRE_FALSE(t2 > t1); + + timeval t3; + t3.tv_sec = 1648227422; + t3.tv_usec = 123457; + REQUIRE_FALSE(t1 == t3); + REQUIRE(t1 != t3); + REQUIRE(t1 <= t3); + REQUIRE_FALSE(t3 <= t1); + REQUIRE_FALSE(t1 >= t3); + REQUIRE(t3 >= t1); + REQUIRE(t1 < t3); + REQUIRE_FALSE(t3 < t1); + REQUIRE_FALSE(t1 > t3); + REQUIRE(t3 > t1); + + timeval t4; + t4.tv_sec = 1648227423; + t4.tv_usec = 123456; + REQUIRE_FALSE(t1 == t4); + REQUIRE(t1 != t4); + REQUIRE(t1 <= t4); + REQUIRE_FALSE(t4 <= t1); + REQUIRE_FALSE(t1 >= t4); + REQUIRE(t4 >= t1); + REQUIRE(t1 < t4); + REQUIRE_FALSE(t4 < t1); + REQUIRE_FALSE(t1 > t4); + REQUIRE(t4 > t1); + } + SECTION("Operators"){ + timeval t1; + t1.tv_sec = 1648227422; + t1.tv_usec = 123456; + timeval t2; + t2.tv_sec = 1648227422; + t2.tv_usec = 123456; + timeval t3 = t1 - t2; + REQUIRE(t3.tv_sec == 0); + REQUIRE(t3.tv_usec == 0); + timeval t4 = t1 - t3; + REQUIRE(t4.tv_sec == 1648227422); + REQUIRE(t4.tv_usec == 123456); + timeval t5 = t3 - t1; + REQUIRE(t5.tv_sec == -1648227422); + REQUIRE(t5.tv_usec == -123456); + + timeval t6; + t6.tv_sec = 1648227400; + t6.tv_usec = 999999; + + timeval t7 = t6 + t1; + REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull)); + REQUIRE(t7.tv_usec == 123455); + + timeval t8 = t1 - t6; + REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1); + REQUIRE(t8.tv_usec == 123457); + + double scalar = 2; + timeval t9 = t1 * scalar; + REQUIRE(t9.tv_sec == 3296454844); + REQUIRE(t9.tv_usec == 246912); + timeval t10 = scalar * t1; + REQUIRE(t10.tv_sec == 3296454844); + REQUIRE(t10.tv_usec == 246912); + timeval t11 = t6 * scalar; + REQUIRE(t11.tv_sec == (3296454800 + 1)); + REQUIRE(t11.tv_usec == 999998); + + timeval t12 = t1 / scalar; + REQUIRE(t12.tv_sec == 824113711); + REQUIRE(t12.tv_usec == 61728); + + timeval t13 = t6 / scalar; + REQUIRE(t13.tv_sec == 824113700); + // Rounding issue + REQUIRE(t13.tv_usec == 499999); + + double scalar2 = t9 / t1; + REQUIRE(scalar2 == Catch::Approx(2.0)); + double scalar3 = t1 / t6; + REQUIRE(scalar3 == Catch::Approx(1.000000013)); + double scalar4 = t3 / t1; + REQUIRE(scalar4 == Catch::Approx(0)); + double scalar5 = t12 / t1; + REQUIRE(scalar5 == Catch::Approx(0.5)); + } + + SECTION("timevalOperations::toTimeval"){ + double seconds = 1648227422.123456; + timeval t1 = timevalOperations::toTimeval(seconds); + REQUIRE(t1.tv_sec == 1648227422); + // Allow 1 usec rounding tolerance + REQUIRE(t1.tv_usec >= 123455); + REQUIRE(t1.tv_usec <= 123457); + } + +} \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/osal/CMakeLists.txt b/tests/src/fsfw_tests/unit/osal/CMakeLists.txt index 293be2e8..030d363b 100644 --- a/tests/src/fsfw_tests/unit/osal/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/osal/CMakeLists.txt @@ -1,4 +1,5 @@ target_sources(${FSFW_TEST_TGT} PRIVATE TestMessageQueue.cpp TestSemaphore.cpp + TestClock.cpp ) diff --git a/tests/src/fsfw_tests/unit/osal/TestClock.cpp b/tests/src/fsfw_tests/unit/osal/TestClock.cpp new file mode 100644 index 00000000..ff530832 --- /dev/null +++ b/tests/src/fsfw_tests/unit/osal/TestClock.cpp @@ -0,0 +1,92 @@ +#include +#include + +#include +#include +#include + +#include "fsfw_tests/unit/CatchDefinitions.h" + +TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]"){ + SECTION("Test getClock"){ + timeval time; + ReturnValue_t result = Clock::getClock_timeval(&time); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + Clock::TimeOfDay_t timeOfDay; + result = Clock::getDateAndTime(&timeOfDay); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + timeval timeOfDayAsTimeval; + result = Clock::convertTimeOfDayToTimeval(&timeOfDay, &timeOfDayAsTimeval); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + // We require timeOfDayAsTimeval to be larger than time as it + // was request a few ns later + double difference = timevalOperations::toDouble(timeOfDayAsTimeval-time); + CHECK(difference>=0.0); + CHECK(difference<=0.005); + + // Conversion in the other direction + Clock::TimeOfDay_t timevalAsTimeOfDay; + result = Clock::convertTimevalToTimeOfDay(&time, &timevalAsTimeOfDay); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + CHECK(timevalAsTimeOfDay.year <= timeOfDay.year); + // TODO We should write TimeOfDay operators! + } + SECTION("Leap seconds"){ + uint16_t leapSeconds = 0; + ReturnValue_t result = Clock::getLeapSeconds(&leapSeconds); + REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED); + REQUIRE(leapSeconds == 0); + result = Clock::setLeapSeconds(18); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + result = Clock::getLeapSeconds(&leapSeconds); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(leapSeconds == 18); + } + SECTION("usec Test"){ + timeval timeAsTimeval; + ReturnValue_t result = Clock::getClock_timeval(&timeAsTimeval); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + uint64_t timeAsUsec = 0; + result = Clock::getClock_usecs(&timeAsUsec); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + double timeAsUsecDouble = static_cast(timeAsUsec)/1000000.0; + timeval timeAsUsecTimeval = timevalOperations::toTimeval(timeAsUsecDouble); + double difference = timevalOperations::toDouble(timeAsTimeval - timeAsUsecTimeval); + // We accept 5 ms difference + CHECK(abs(difference) <= 0.005); + uint64_t timevalAsUint64 = static_cast(timeAsTimeval.tv_sec)*1000000ull + static_cast(timeAsTimeval.tv_usec); + if(timeAsUsec > timevalAsUint64){ + // This should not be the case but we can see some rounding issue sometimes + // This is the case if used in valgrind. This might indicate an other issue + CHECK((timeAsUsec - timevalAsUint64)>=0); + CHECK((timeAsUsec - timevalAsUint64)<=(5*1000)); + }else{ + CHECK((timevalAsUint64 - timeAsUsec)>=0); + CHECK((timevalAsUint64 - timeAsUsec)<=(5*1000)); + } + + } + SECTION("Test j2000"){ + double j2000; + timeval time; + time.tv_sec = 1648208539; + time.tv_usec = 0; + ReturnValue_t result = Clock::convertTimevalToJD2000(time, &j2000); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + double correctJ2000 = 2459663.98772 - 2451545.0; + CHECK(j2000 == Catch::Approx(correctJ2000).margin(1.2*1e-8)); + } + SECTION("Convert to TT"){ + timeval utcTime; + utcTime.tv_sec = 1648208539; + utcTime.tv_usec = 999000; + timeval tt; + ReturnValue_t result = Clock::setLeapSeconds(27); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + result = Clock::convertUTCToTT(utcTime, &tt); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + CHECK(tt.tv_usec == 183000); + // The plus 1 is a own forced overflow of usecs + CHECK(tt.tv_sec == (1648208539 + 27 + 10 + 32 + 1)); + } +} \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp index 2e80487a..2bf6aaf0 100644 --- a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp +++ b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp @@ -120,6 +120,8 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { CHECK(cdsTime.msDay_l == 0xC5); CHECK(cdsTime.msDay_ll == 0xC3); + + // Conversion back to timeval timeval timeReturnAsTimeval; result = CCSDSTime::convertFromCDS(&timeReturnAsTimeval, &cdsTime); @@ -128,5 +130,17 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { timeval difference = timeAsTimeval - timeReturnAsTimeval; CHECK(difference.tv_usec == 456); CHECK(difference.tv_sec == 0); + + Clock::TimeOfDay_t timeReturnAsTimeOfDay; + result = CCSDSTime::convertFromCDS(&timeReturnAsTimeOfDay, &cdsTime); + CHECK(result == HasReturnvaluesIF::RETURN_OK); + CHECK(timeReturnAsTimeOfDay.year == 2020); + CHECK(timeReturnAsTimeOfDay.month == 2); + CHECK(timeReturnAsTimeOfDay.day == 29); + CHECK(timeReturnAsTimeOfDay.hour == 13); + CHECK(timeReturnAsTimeOfDay.minute == 24); + CHECK(timeReturnAsTimeOfDay.second == 45); + // micro seconds precision is lost + CHECK(timeReturnAsTimeOfDay.usecond == 123000); } } \ No newline at end of file From 665d8cd4792310f01236b4c7ef7413d3ac340a9a Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Fri, 25 Mar 2022 18:48:53 +0100 Subject: [PATCH 007/198] Applied clang format --- src/fsfw/osal/host/Clock.cpp | 6 +- src/fsfw/osal/linux/Clock.cpp | 4 +- src/fsfw/osal/rtems/Clock.cpp | 1 - src/fsfw/timemanager/ClockCommon.cpp | 4 +- src/fsfw/version.cpp | 3 +- src/fsfw/version.h | 2 +- .../globalfunctions/testTimevalOperations.cpp | 219 +++++++++--------- tests/src/fsfw_tests/unit/osal/TestClock.cpp | 164 ++++++------- .../unit/timemanager/TestCCSDSTime.cpp | 2 - tests/src/fsfw_tests/unit/version.cpp | 50 ++-- 10 files changed, 226 insertions(+), 229 deletions(-) diff --git a/src/fsfw/osal/host/Clock.cpp b/src/fsfw/osal/host/Clock.cpp index b4fd73f6..19e120b3 100644 --- a/src/fsfw/osal/host/Clock.cpp +++ b/src/fsfw/osal/host/Clock.cpp @@ -2,9 +2,9 @@ #include +#include "fsfw/ipc/MutexGuard.h" #include "fsfw/platform.h" #include "fsfw/serviceinterface/ServiceInterface.h" -#include "fsfw/ipc/MutexGuard.h" #if defined(PLATFORM_WIN) #include @@ -125,8 +125,8 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { auto seconds = std::chrono::time_point_cast(now); auto fraction = now - seconds; time_t tt = SystemClock::to_time_t(now); - ReturnValue_t result = checkOrCreateClockMutex(); - if(result != HasReturnvaluesIF::RETURN_OK){ + ReturnValue_t result = checkOrCreateClockMutex(); + if (result != HasReturnvaluesIF::RETURN_OK) { return result; } MutexGuard helper(timeMutex); diff --git a/src/fsfw/osal/linux/Clock.cpp b/src/fsfw/osal/linux/Clock.cpp index a3480b56..534e7e22 100644 --- a/src/fsfw/osal/linux/Clock.cpp +++ b/src/fsfw/osal/linux/Clock.cpp @@ -8,8 +8,8 @@ #include -#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/ipc/MutexGuard.h" +#include "fsfw/serviceinterface/ServiceInterface.h" uint32_t Clock::getTicksPerSecond(void) { uint32_t ticks = sysconf(_SC_CLK_TCK); @@ -116,7 +116,7 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t result = checkOrCreateClockMutex(); - if(result != HasReturnvaluesIF::RETURN_OK){ + if (result != HasReturnvaluesIF::RETURN_OK) { return result; } MutexGuard helper(timeMutex); diff --git a/src/fsfw/osal/rtems/Clock.cpp b/src/fsfw/osal/rtems/Clock.cpp index fe0afb46..831c67d4 100644 --- a/src/fsfw/osal/rtems/Clock.cpp +++ b/src/fsfw/osal/rtems/Clock.cpp @@ -6,7 +6,6 @@ #include "fsfw/ipc/MutexGuard.h" #include "fsfw/osal/rtems/RtemsBasic.h" - uint32_t Clock::getTicksPerSecond(void) { rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second(); return static_cast(ticks_per_second); diff --git a/src/fsfw/timemanager/ClockCommon.cpp b/src/fsfw/timemanager/ClockCommon.cpp index c24dd781..ca8b12a4 100644 --- a/src/fsfw/timemanager/ClockCommon.cpp +++ b/src/fsfw/timemanager/ClockCommon.cpp @@ -39,7 +39,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { } ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { - if(not leapSecondsSet){ + if (not leapSecondsSet) { return HasReturnvaluesIF::RETURN_FAILED; } if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) { @@ -58,7 +58,7 @@ ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* // in the Windows CRT is incompatible with the C standard but this should not be an issue for // this implementation ReturnValue_t result = checkOrCreateClockMutex(); - if(result != HasReturnvaluesIF::RETURN_OK){ + if (result != HasReturnvaluesIF::RETURN_OK) { return result; } MutexGuard helper(timeMutex); diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 926e465f..e4a62002 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -1,8 +1,9 @@ #include "version.h" -#include "fsfw/FSFWVersion.h" #include +#include "fsfw/FSFWVersion.h" + #ifdef major #undef major #endif diff --git a/src/fsfw/version.h b/src/fsfw/version.h index 7cddf193..bb4d0399 100644 --- a/src/fsfw/version.h +++ b/src/fsfw/version.h @@ -29,7 +29,7 @@ class Version { } friend bool operator>(const Version& v1, const Version& v2) { - return not (v1 < v2) and not (v1 == v2); + return not(v1 < v2) and not(v1 == v2); } friend bool operator<=(const Version& v1, const Version& v2) { return ((v1 == v2) or (v1 < v2)); } diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp index 92242ed9..347d2204 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp +++ b/tests/src/fsfw_tests/unit/globalfunctions/testTimevalOperations.cpp @@ -1,125 +1,124 @@ -#include -#include - #include +#include +#include + #include "fsfw_tests/unit/CatchDefinitions.h" -TEST_CASE("TimevalTest", "[timevalOperations]"){ - SECTION("Comparison"){ - timeval t1; - t1.tv_sec = 1648227422; - t1.tv_usec = 123456; - timeval t2; - t2.tv_sec = 1648227422; - t2.tv_usec = 123456; - REQUIRE(t1 == t2); - REQUIRE(t2 == t1); - REQUIRE_FALSE(t1 != t2); - REQUIRE_FALSE(t2 != t1); - REQUIRE(t1 <= t2); - REQUIRE(t2 <= t1); - REQUIRE(t1 >= t2); - REQUIRE(t2 >= t1); - REQUIRE_FALSE(t1 < t2); - REQUIRE_FALSE(t2 < t1); - REQUIRE_FALSE(t1 > t2); - REQUIRE_FALSE(t2 > t1); +TEST_CASE("TimevalTest", "[timevalOperations]") { + SECTION("Comparison") { + timeval t1; + t1.tv_sec = 1648227422; + t1.tv_usec = 123456; + timeval t2; + t2.tv_sec = 1648227422; + t2.tv_usec = 123456; + REQUIRE(t1 == t2); + REQUIRE(t2 == t1); + REQUIRE_FALSE(t1 != t2); + REQUIRE_FALSE(t2 != t1); + REQUIRE(t1 <= t2); + REQUIRE(t2 <= t1); + REQUIRE(t1 >= t2); + REQUIRE(t2 >= t1); + REQUIRE_FALSE(t1 < t2); + REQUIRE_FALSE(t2 < t1); + REQUIRE_FALSE(t1 > t2); + REQUIRE_FALSE(t2 > t1); - timeval t3; - t3.tv_sec = 1648227422; - t3.tv_usec = 123457; - REQUIRE_FALSE(t1 == t3); - REQUIRE(t1 != t3); - REQUIRE(t1 <= t3); - REQUIRE_FALSE(t3 <= t1); - REQUIRE_FALSE(t1 >= t3); - REQUIRE(t3 >= t1); - REQUIRE(t1 < t3); - REQUIRE_FALSE(t3 < t1); - REQUIRE_FALSE(t1 > t3); - REQUIRE(t3 > t1); + timeval t3; + t3.tv_sec = 1648227422; + t3.tv_usec = 123457; + REQUIRE_FALSE(t1 == t3); + REQUIRE(t1 != t3); + REQUIRE(t1 <= t3); + REQUIRE_FALSE(t3 <= t1); + REQUIRE_FALSE(t1 >= t3); + REQUIRE(t3 >= t1); + REQUIRE(t1 < t3); + REQUIRE_FALSE(t3 < t1); + REQUIRE_FALSE(t1 > t3); + REQUIRE(t3 > t1); - timeval t4; - t4.tv_sec = 1648227423; - t4.tv_usec = 123456; - REQUIRE_FALSE(t1 == t4); - REQUIRE(t1 != t4); - REQUIRE(t1 <= t4); - REQUIRE_FALSE(t4 <= t1); - REQUIRE_FALSE(t1 >= t4); - REQUIRE(t4 >= t1); - REQUIRE(t1 < t4); - REQUIRE_FALSE(t4 < t1); - REQUIRE_FALSE(t1 > t4); - REQUIRE(t4 > t1); - } - SECTION("Operators"){ - timeval t1; - t1.tv_sec = 1648227422; - t1.tv_usec = 123456; - timeval t2; - t2.tv_sec = 1648227422; - t2.tv_usec = 123456; - timeval t3 = t1 - t2; - REQUIRE(t3.tv_sec == 0); - REQUIRE(t3.tv_usec == 0); - timeval t4 = t1 - t3; - REQUIRE(t4.tv_sec == 1648227422); - REQUIRE(t4.tv_usec == 123456); - timeval t5 = t3 - t1; - REQUIRE(t5.tv_sec == -1648227422); - REQUIRE(t5.tv_usec == -123456); + timeval t4; + t4.tv_sec = 1648227423; + t4.tv_usec = 123456; + REQUIRE_FALSE(t1 == t4); + REQUIRE(t1 != t4); + REQUIRE(t1 <= t4); + REQUIRE_FALSE(t4 <= t1); + REQUIRE_FALSE(t1 >= t4); + REQUIRE(t4 >= t1); + REQUIRE(t1 < t4); + REQUIRE_FALSE(t4 < t1); + REQUIRE_FALSE(t1 > t4); + REQUIRE(t4 > t1); + } + SECTION("Operators") { + timeval t1; + t1.tv_sec = 1648227422; + t1.tv_usec = 123456; + timeval t2; + t2.tv_sec = 1648227422; + t2.tv_usec = 123456; + timeval t3 = t1 - t2; + REQUIRE(t3.tv_sec == 0); + REQUIRE(t3.tv_usec == 0); + timeval t4 = t1 - t3; + REQUIRE(t4.tv_sec == 1648227422); + REQUIRE(t4.tv_usec == 123456); + timeval t5 = t3 - t1; + REQUIRE(t5.tv_sec == -1648227422); + REQUIRE(t5.tv_usec == -123456); - timeval t6; - t6.tv_sec = 1648227400; - t6.tv_usec = 999999; + timeval t6; + t6.tv_sec = 1648227400; + t6.tv_usec = 999999; - timeval t7 = t6 + t1; - REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull)); - REQUIRE(t7.tv_usec == 123455); + timeval t7 = t6 + t1; + REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull)); + REQUIRE(t7.tv_usec == 123455); - timeval t8 = t1 - t6; - REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1); - REQUIRE(t8.tv_usec == 123457); + timeval t8 = t1 - t6; + REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1); + REQUIRE(t8.tv_usec == 123457); - double scalar = 2; - timeval t9 = t1 * scalar; - REQUIRE(t9.tv_sec == 3296454844); - REQUIRE(t9.tv_usec == 246912); - timeval t10 = scalar * t1; - REQUIRE(t10.tv_sec == 3296454844); - REQUIRE(t10.tv_usec == 246912); - timeval t11 = t6 * scalar; - REQUIRE(t11.tv_sec == (3296454800 + 1)); - REQUIRE(t11.tv_usec == 999998); + double scalar = 2; + timeval t9 = t1 * scalar; + REQUIRE(t9.tv_sec == 3296454844); + REQUIRE(t9.tv_usec == 246912); + timeval t10 = scalar * t1; + REQUIRE(t10.tv_sec == 3296454844); + REQUIRE(t10.tv_usec == 246912); + timeval t11 = t6 * scalar; + REQUIRE(t11.tv_sec == (3296454800 + 1)); + REQUIRE(t11.tv_usec == 999998); - timeval t12 = t1 / scalar; - REQUIRE(t12.tv_sec == 824113711); - REQUIRE(t12.tv_usec == 61728); + timeval t12 = t1 / scalar; + REQUIRE(t12.tv_sec == 824113711); + REQUIRE(t12.tv_usec == 61728); - timeval t13 = t6 / scalar; - REQUIRE(t13.tv_sec == 824113700); - // Rounding issue - REQUIRE(t13.tv_usec == 499999); + timeval t13 = t6 / scalar; + REQUIRE(t13.tv_sec == 824113700); + // Rounding issue + REQUIRE(t13.tv_usec == 499999); - double scalar2 = t9 / t1; - REQUIRE(scalar2 == Catch::Approx(2.0)); - double scalar3 = t1 / t6; - REQUIRE(scalar3 == Catch::Approx(1.000000013)); - double scalar4 = t3 / t1; - REQUIRE(scalar4 == Catch::Approx(0)); - double scalar5 = t12 / t1; - REQUIRE(scalar5 == Catch::Approx(0.5)); - } - - SECTION("timevalOperations::toTimeval"){ - double seconds = 1648227422.123456; - timeval t1 = timevalOperations::toTimeval(seconds); - REQUIRE(t1.tv_sec == 1648227422); - // Allow 1 usec rounding tolerance - REQUIRE(t1.tv_usec >= 123455); - REQUIRE(t1.tv_usec <= 123457); - } + double scalar2 = t9 / t1; + REQUIRE(scalar2 == Catch::Approx(2.0)); + double scalar3 = t1 / t6; + REQUIRE(scalar3 == Catch::Approx(1.000000013)); + double scalar4 = t3 / t1; + REQUIRE(scalar4 == Catch::Approx(0)); + double scalar5 = t12 / t1; + REQUIRE(scalar5 == Catch::Approx(0.5)); + } + SECTION("timevalOperations::toTimeval") { + double seconds = 1648227422.123456; + timeval t1 = timevalOperations::toTimeval(seconds); + REQUIRE(t1.tv_sec == 1648227422); + // Allow 1 usec rounding tolerance + REQUIRE(t1.tv_usec >= 123455); + REQUIRE(t1.tv_usec <= 123457); + } } \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/osal/TestClock.cpp b/tests/src/fsfw_tests/unit/osal/TestClock.cpp index ff530832..f7c63cce 100644 --- a/tests/src/fsfw_tests/unit/osal/TestClock.cpp +++ b/tests/src/fsfw_tests/unit/osal/TestClock.cpp @@ -1,92 +1,92 @@ -#include #include +#include #include -#include #include +#include #include "fsfw_tests/unit/CatchDefinitions.h" -TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]"){ - SECTION("Test getClock"){ - timeval time; - ReturnValue_t result = Clock::getClock_timeval(&time); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - Clock::TimeOfDay_t timeOfDay; - result = Clock::getDateAndTime(&timeOfDay); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - timeval timeOfDayAsTimeval; - result = Clock::convertTimeOfDayToTimeval(&timeOfDay, &timeOfDayAsTimeval); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - // We require timeOfDayAsTimeval to be larger than time as it - // was request a few ns later - double difference = timevalOperations::toDouble(timeOfDayAsTimeval-time); - CHECK(difference>=0.0); - CHECK(difference<=0.005); +TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]") { + SECTION("Test getClock") { + timeval time; + ReturnValue_t result = Clock::getClock_timeval(&time); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + Clock::TimeOfDay_t timeOfDay; + result = Clock::getDateAndTime(&timeOfDay); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + timeval timeOfDayAsTimeval; + result = Clock::convertTimeOfDayToTimeval(&timeOfDay, &timeOfDayAsTimeval); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + // We require timeOfDayAsTimeval to be larger than time as it + // was request a few ns later + double difference = timevalOperations::toDouble(timeOfDayAsTimeval - time); + CHECK(difference >= 0.0); + CHECK(difference <= 0.005); - // Conversion in the other direction - Clock::TimeOfDay_t timevalAsTimeOfDay; - result = Clock::convertTimevalToTimeOfDay(&time, &timevalAsTimeOfDay); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - CHECK(timevalAsTimeOfDay.year <= timeOfDay.year); - // TODO We should write TimeOfDay operators! - } - SECTION("Leap seconds"){ - uint16_t leapSeconds = 0; - ReturnValue_t result = Clock::getLeapSeconds(&leapSeconds); - REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED); - REQUIRE(leapSeconds == 0); - result = Clock::setLeapSeconds(18); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - result = Clock::getLeapSeconds(&leapSeconds); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - REQUIRE(leapSeconds == 18); - } - SECTION("usec Test"){ - timeval timeAsTimeval; - ReturnValue_t result = Clock::getClock_timeval(&timeAsTimeval); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - uint64_t timeAsUsec = 0; - result = Clock::getClock_usecs(&timeAsUsec); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - double timeAsUsecDouble = static_cast(timeAsUsec)/1000000.0; - timeval timeAsUsecTimeval = timevalOperations::toTimeval(timeAsUsecDouble); - double difference = timevalOperations::toDouble(timeAsTimeval - timeAsUsecTimeval); - // We accept 5 ms difference - CHECK(abs(difference) <= 0.005); - uint64_t timevalAsUint64 = static_cast(timeAsTimeval.tv_sec)*1000000ull + static_cast(timeAsTimeval.tv_usec); - if(timeAsUsec > timevalAsUint64){ - // This should not be the case but we can see some rounding issue sometimes - // This is the case if used in valgrind. This might indicate an other issue - CHECK((timeAsUsec - timevalAsUint64)>=0); - CHECK((timeAsUsec - timevalAsUint64)<=(5*1000)); - }else{ - CHECK((timevalAsUint64 - timeAsUsec)>=0); - CHECK((timevalAsUint64 - timeAsUsec)<=(5*1000)); - } - - } - SECTION("Test j2000"){ - double j2000; - timeval time; - time.tv_sec = 1648208539; - time.tv_usec = 0; - ReturnValue_t result = Clock::convertTimevalToJD2000(time, &j2000); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - double correctJ2000 = 2459663.98772 - 2451545.0; - CHECK(j2000 == Catch::Approx(correctJ2000).margin(1.2*1e-8)); - } - SECTION("Convert to TT"){ - timeval utcTime; - utcTime.tv_sec = 1648208539; - utcTime.tv_usec = 999000; - timeval tt; - ReturnValue_t result = Clock::setLeapSeconds(27); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - result = Clock::convertUTCToTT(utcTime, &tt); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - CHECK(tt.tv_usec == 183000); - // The plus 1 is a own forced overflow of usecs - CHECK(tt.tv_sec == (1648208539 + 27 + 10 + 32 + 1)); + // Conversion in the other direction + Clock::TimeOfDay_t timevalAsTimeOfDay; + result = Clock::convertTimevalToTimeOfDay(&time, &timevalAsTimeOfDay); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + CHECK(timevalAsTimeOfDay.year <= timeOfDay.year); + // TODO We should write TimeOfDay operators! + } + SECTION("Leap seconds") { + uint16_t leapSeconds = 0; + ReturnValue_t result = Clock::getLeapSeconds(&leapSeconds); + REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED); + REQUIRE(leapSeconds == 0); + result = Clock::setLeapSeconds(18); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + result = Clock::getLeapSeconds(&leapSeconds); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(leapSeconds == 18); + } + SECTION("usec Test") { + timeval timeAsTimeval; + ReturnValue_t result = Clock::getClock_timeval(&timeAsTimeval); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + uint64_t timeAsUsec = 0; + result = Clock::getClock_usecs(&timeAsUsec); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + double timeAsUsecDouble = static_cast(timeAsUsec) / 1000000.0; + timeval timeAsUsecTimeval = timevalOperations::toTimeval(timeAsUsecDouble); + double difference = timevalOperations::toDouble(timeAsTimeval - timeAsUsecTimeval); + // We accept 5 ms difference + CHECK(abs(difference) <= 0.005); + uint64_t timevalAsUint64 = static_cast(timeAsTimeval.tv_sec) * 1000000ull + + static_cast(timeAsTimeval.tv_usec); + if (timeAsUsec > timevalAsUint64) { + // This should not be the case but we can see some rounding issue sometimes + // This is the case if used in valgrind. This might indicate an other issue + CHECK((timeAsUsec - timevalAsUint64) >= 0); + CHECK((timeAsUsec - timevalAsUint64) <= (5 * 1000)); + } else { + CHECK((timevalAsUint64 - timeAsUsec) >= 0); + CHECK((timevalAsUint64 - timeAsUsec) <= (5 * 1000)); } + } + SECTION("Test j2000") { + double j2000; + timeval time; + time.tv_sec = 1648208539; + time.tv_usec = 0; + ReturnValue_t result = Clock::convertTimevalToJD2000(time, &j2000); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + double correctJ2000 = 2459663.98772 - 2451545.0; + CHECK(j2000 == Catch::Approx(correctJ2000).margin(1.2 * 1e-8)); + } + SECTION("Convert to TT") { + timeval utcTime; + utcTime.tv_sec = 1648208539; + utcTime.tv_usec = 999000; + timeval tt; + ReturnValue_t result = Clock::setLeapSeconds(27); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + result = Clock::convertUTCToTT(utcTime, &tt); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + CHECK(tt.tv_usec == 183000); + // The plus 1 is a own forced overflow of usecs + CHECK(tt.tv_sec == (1648208539 + 27 + 10 + 32 + 1)); + } } \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp index 2bf6aaf0..6970b193 100644 --- a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp +++ b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp @@ -120,8 +120,6 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { CHECK(cdsTime.msDay_l == 0xC5); CHECK(cdsTime.msDay_ll == 0xC3); - - // Conversion back to timeval timeval timeReturnAsTimeval; result = CCSDSTime::convertFromCDS(&timeReturnAsTimeval, &cdsTime); diff --git a/tests/src/fsfw_tests/unit/version.cpp b/tests/src/fsfw_tests/unit/version.cpp index 92a930dc..2967dfa5 100644 --- a/tests/src/fsfw_tests/unit/version.cpp +++ b/tests/src/fsfw_tests/unit/version.cpp @@ -17,15 +17,15 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { fsfw::Version v1 = fsfw::Version(1, 1, 1); fsfw::Version v2 = fsfw::Version(1, 1, 1); REQUIRE(v1 == v2); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 > v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 > v2)); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); v1.revision -= 1; REQUIRE(v1 != v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); v1.revision += 1; @@ -33,60 +33,60 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.minor += 1; v1.major -= 1; REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.major += 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 < v2)); + REQUIRE(not(v1 != v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 < v2)); v1.major += 1; v1.minor -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.major -= 1; v1.minor += 2; v1.revision -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.minor -= 1; v1.revision += 2; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.revision -= 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); + REQUIRE(not(v1 != v2)); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "v" << fsfw::FSFW_VERSION << std::endl; #endif char verString[10] = {}; fsfw::FSFW_VERSION.getVersion(verString, sizeof(verString)); #if FSFW_DISABLE_PRINTOUT == 0 - printf("v%s\n",verString); + printf("v%s\n", verString); #endif } From 0b3255e463f45d58c555481482567f45c753451a Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 28 Mar 2022 15:17:59 +0200 Subject: [PATCH 008/198] Fixed tests --- tests/src/fsfw_tests/unit/osal/TestClock.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/tests/src/fsfw_tests/unit/osal/TestClock.cpp b/tests/src/fsfw_tests/unit/osal/TestClock.cpp index f7c63cce..38ec3915 100644 --- a/tests/src/fsfw_tests/unit/osal/TestClock.cpp +++ b/tests/src/fsfw_tests/unit/osal/TestClock.cpp @@ -51,20 +51,14 @@ TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]") { REQUIRE(result == HasReturnvaluesIF::RETURN_OK); double timeAsUsecDouble = static_cast(timeAsUsec) / 1000000.0; timeval timeAsUsecTimeval = timevalOperations::toTimeval(timeAsUsecDouble); - double difference = timevalOperations::toDouble(timeAsTimeval - timeAsUsecTimeval); + double difference = timevalOperations::toDouble(timeAsUsecTimeval - timeAsTimeval); // We accept 5 ms difference - CHECK(abs(difference) <= 0.005); + CHECK(difference >= 0.0); + CHECK(difference <= 0.005); uint64_t timevalAsUint64 = static_cast(timeAsTimeval.tv_sec) * 1000000ull + static_cast(timeAsTimeval.tv_usec); - if (timeAsUsec > timevalAsUint64) { - // This should not be the case but we can see some rounding issue sometimes - // This is the case if used in valgrind. This might indicate an other issue - CHECK((timeAsUsec - timevalAsUint64) >= 0); - CHECK((timeAsUsec - timevalAsUint64) <= (5 * 1000)); - } else { - CHECK((timevalAsUint64 - timeAsUsec) >= 0); - CHECK((timevalAsUint64 - timeAsUsec) <= (5 * 1000)); - } + CHECK((timeAsUsec - timevalAsUint64) >= 0); + CHECK((timeAsUsec - timevalAsUint64) <= (5 * 1000)); } SECTION("Test j2000") { double j2000; From e6e71436c280bcf688cfdffde1b0971955fea20d Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 28 Mar 2022 18:32:51 +0200 Subject: [PATCH 009/198] Added more tests --- .../unit/timemanager/TestCCSDSTime.cpp | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp index 6970b193..ce54d2f1 100644 --- a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp +++ b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp @@ -81,7 +81,8 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { std::string timeAscii = "2022-12-31T23:59:59.123Z"; Clock::TimeOfDay_t timeTo; const uint8_t* timeChar = reinterpret_cast(timeAscii.c_str()); - CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length()); + auto result = CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length()); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); REQUIRE(timeTo.year == 2022); REQUIRE(timeTo.month == 12); REQUIRE(timeTo.day == 31); @@ -89,6 +90,19 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { REQUIRE(timeTo.minute == 59); REQUIRE(timeTo.second == 59); REQUIRE(timeTo.usecond == Catch::Approx(123000)); + + std::string timeAscii2 = "2022-365T23:59:59.123Z"; + const uint8_t* timeChar2 = reinterpret_cast(timeAscii2.c_str()); + Clock::TimeOfDay_t timeTo2; + result = CCSDSTime::convertFromCcsds(&timeTo2, timeChar2, timeAscii2.length()); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(timeTo2.year == 2022); + REQUIRE(timeTo2.month == 12); + REQUIRE(timeTo2.day == 31); + REQUIRE(timeTo2.hour == 23); + REQUIRE(timeTo2.minute == 59); + REQUIRE(timeTo2.second == 59); + REQUIRE(timeTo2.usecond == Catch::Approx(123000)); } SECTION("CDS Conversions") { @@ -119,6 +133,7 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { CHECK(cdsTime.msDay_h == 0xE0); CHECK(cdsTime.msDay_l == 0xC5); CHECK(cdsTime.msDay_ll == 0xC3); + CHECK(cdsTime.pField == CCSDSTime::P_FIELD_CDS_SHORT); // Conversion back to timeval timeval timeReturnAsTimeval; @@ -140,5 +155,45 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { CHECK(timeReturnAsTimeOfDay.second == 45); // micro seconds precision is lost CHECK(timeReturnAsTimeOfDay.usecond == 123000); + + Clock::TimeOfDay_t timeReturnAsTodFromBuffer; + const uint8_t* buffer = reinterpret_cast(&cdsTime); + result = CCSDSTime::convertFromCDS(&timeReturnAsTodFromBuffer, buffer, sizeof(cdsTime)); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + CHECK(timeReturnAsTodFromBuffer.year == time.year); + CHECK(timeReturnAsTodFromBuffer.month == time.month); + CHECK(timeReturnAsTodFromBuffer.day == time.day); + CHECK(timeReturnAsTodFromBuffer.hour == time.hour); + CHECK(timeReturnAsTodFromBuffer.minute == time.minute); + CHECK(timeReturnAsTodFromBuffer.second == time.second); + CHECK(timeReturnAsTodFromBuffer.usecond == 123000); + + + Clock::TimeOfDay_t todFromCCSDS; + result = CCSDSTime::convertFromCcsds(&todFromCCSDS, buffer, sizeof(cdsTime)); + CHECK(result == HasReturnvaluesIF::RETURN_OK); + CHECK(todFromCCSDS.year == time.year); + CHECK(todFromCCSDS.month == time.month); + CHECK(todFromCCSDS.day == time.day); + CHECK(todFromCCSDS.hour == time.hour); + CHECK(todFromCCSDS.minute == time.minute); + CHECK(todFromCCSDS.second == time.second); + CHECK(todFromCCSDS.usecond == 123000); + } + SECTION("CCSDS Failures"){ + Clock::TimeOfDay_t time; + time.year = 2020; + time.month = 12; + time.day = 32; + time.hour = 13; + time.minute = 24; + time.second = 45; + time.usecond = 123456; + CCSDSTime::Ccs_mseconds to; + auto result = CCSDSTime::convertToCcsds(&to, &time); + REQUIRE(result == CCSDSTime::INVALID_TIME_FORMAT); + CCSDSTime::Ccs_seconds to2; + result = CCSDSTime::convertToCcsds(&to2, &time); + REQUIRE(result == CCSDSTime::INVALID_TIME_FORMAT); } } \ No newline at end of file From b4effe7a46fcb64647846a42509516f1f5eb8043 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 28 Mar 2022 18:33:24 +0200 Subject: [PATCH 010/198] Clang format --- tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp index ce54d2f1..a43ff8ab 100644 --- a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp +++ b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp @@ -168,7 +168,6 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { CHECK(timeReturnAsTodFromBuffer.second == time.second); CHECK(timeReturnAsTodFromBuffer.usecond == 123000); - Clock::TimeOfDay_t todFromCCSDS; result = CCSDSTime::convertFromCcsds(&todFromCCSDS, buffer, sizeof(cdsTime)); CHECK(result == HasReturnvaluesIF::RETURN_OK); @@ -180,7 +179,7 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { CHECK(todFromCCSDS.second == time.second); CHECK(todFromCCSDS.usecond == 123000); } - SECTION("CCSDS Failures"){ + SECTION("CCSDS Failures") { Clock::TimeOfDay_t time; time.year = 2020; time.month = 12; From 2800d6f28c6c3f5b890746f28279ff0ec1c94ab5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 20:16:11 +0200 Subject: [PATCH 011/198] add ETL dependency --- CMakeLists.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9786d572..137d6cb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,26 @@ if(FSFW_BUILD_UNITTESTS) endif() endif() +message(STATUS "Finding and/or providing ETL library") +# Check whether the user has already installed Catch2 first +find_package(etl QUIET) +# Not installed, so use FetchContent to download and provide etl +if(NOT etl_FOUND) + message(STATUS + "No ETL installation was found with find_package. Installing and providing " + "etl with FindPackage" + ) + include(FetchContent) + + FetchContent_Declare( + etl + GIT_REPOSITORY https://github.com/ETLCPP/etl + GIT_TAG 20.26.0 + ) + + FetchContent_MakeAvailable(etl) +endif() + set(FSFW_CORE_INC_PATH "inc") set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux rtems freertos) From 082c86ea181c42f52200cd5d3ae2b73b7cb48e24 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 20:18:49 +0200 Subject: [PATCH 012/198] link ETL lib as well --- CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 137d6cb9..282cf564 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ set(FSFW_REVISION 0) # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +set(FSFW_ETL_LIB_NAME etl) option(FSFW_GENERATE_SECTIONS "Generate function and data sections. Required to remove unused code" ON @@ -90,9 +91,9 @@ endif() message(STATUS "Finding and/or providing ETL library") # Check whether the user has already installed Catch2 first -find_package(etl QUIET) +find_package(${FSFW_ETL_LIB_NAME} QUIET) # Not installed, so use FetchContent to download and provide etl -if(NOT etl_FOUND) +if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) message(STATUS "No ETL installation was found with find_package. Installing and providing " "etl with FindPackage" @@ -100,7 +101,7 @@ if(NOT etl_FOUND) include(FetchContent) FetchContent_Declare( - etl + ${FSFW_ETL_LIB_NAME} GIT_REPOSITORY https://github.com/ETLCPP/etl GIT_TAG 20.26.0 ) @@ -369,6 +370,7 @@ target_compile_options(${LIB_FSFW_NAME} PRIVATE ) target_link_libraries(${LIB_FSFW_NAME} PRIVATE + ${FSFW_ETL_LIB_NAME} ${FSFW_ADDITIONAL_LINK_LIBS} ) From 8ff9eadf308b3507529fcc8f37b41c4fecee3637 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 20:43:36 +0200 Subject: [PATCH 013/198] update changelog, add basic instructions for etl --- CHANGELOG.md | 2 ++ CMakeLists.txt | 3 ++- README.md | 26 ++++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3eb6942..c7b510f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information inside `fsfw/version.h` PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 +- Added ETL dependency + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592 # [v4.0.0] diff --git a/CMakeLists.txt b/CMakeLists.txt index 282cf564..a0fe9859 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ set(FSFW_REVISION 0) # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +set(FSFW_ETL_LIB_VERSION 20.26.0) set(FSFW_ETL_LIB_NAME etl) option(FSFW_GENERATE_SECTIONS @@ -103,7 +104,7 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) FetchContent_Declare( ${FSFW_ETL_LIB_NAME} GIT_REPOSITORY https://github.com/ETLCPP/etl - GIT_TAG 20.26.0 + GIT_TAG ${FSFW_ETL_LIB_VERSION} ) FetchContent_MakeAvailable(etl) diff --git a/README.md b/README.md index dff87b2e..c8a6c874 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,15 @@ with Airbus Defence and Space GmbH. ## Quick facts -The framework is designed for systems, which communicate with external devices, perform control loops, receive telecommands and send telemetry, and need to maintain a high level of availability. Therefore, a mode and health system provides control over the states of the software and the controlled devices. In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well. +The framework is designed for systems, which communicate with external devices, perform control loops, +receive telecommands and send telemetry, and need to maintain a high level of availability. Therefore, +a mode and health system provides control over the states of the software and the controlled devices. +In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well. -The FSFW provides abstraction layers for operating systems to provide a uniform operating system abstraction layer (OSAL). Some components of this OSAL are required internally by the FSFW but is also very useful for developers to implement the same application logic on different operating systems with a uniform interface. +The FSFW provides abstraction layers for operating systems to provide a uniform operating system +abstraction layer (OSAL). Some components of this OSAL are required internally by the FSFW but is +also very useful for developers to implement the same application logic on different operating +systems with a uniform interface. Currently, the FSFW provides the following OSALs: @@ -45,6 +51,22 @@ A template configuration folder was provided and can be copied into the project a starting point. The [configuration section](docs/README-config.md#top) provides more specific information about the possible options. +## Prerequisites + +The Embedded Template Library (etl) is a dependency of the FSFW which is automatically +installed and provided by the build system unless the correction version was installed. + +You can install the ETL library like this: + +```cpp +git clone https://github.com/ETLCPP/etl +cd etl +git checkout +mkdir build && cd build +cmake .. +cmake --install . +``` + ## Adding the library The following steps show how to add and use FSFW components. It is still recommended to From 05495077ecf0c202ec95f47b9a58e966236bcb5b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 20:53:39 +0200 Subject: [PATCH 014/198] doc update --- CMakeLists.txt | 10 ++++++++-- README.md | 20 ++++++++++++++++++++ docs/getting_started.rst | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0fe9859..b2d6714c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,13 @@ set(FSFW_REVISION 0) # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) -set(FSFW_ETL_LIB_VERSION 20.26.0) + +set(FSFW_ETL_LIB_MAJOR_VERSION 20) +set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.26.0) + +set(FSFW_CATCH2_LIB_MAJOR_VERSION 3) +set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview4) + set(FSFW_ETL_LIB_NAME etl) option(FSFW_GENERATE_SECTIONS @@ -58,7 +64,7 @@ if(FSFW_BUILD_UNITTESTS) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v3.0.0-preview4 + GIT_TAG ${FSFW_CATCH2_LIB_VERSION} ) FetchContent_MakeAvailable(Catch2) diff --git a/README.md b/README.md index c8a6c874..51d78b25 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ information about the possible options. The Embedded Template Library (etl) is a dependency of the FSFW which is automatically installed and provided by the build system unless the correction version was installed. +The current recommended version can be found inside the fsfw `CMakeLists.txt` file or by using +`ccmake` and looking up the `FSFW_ETL_LIB_VERSION` variable. You can install the ETL library like this: @@ -67,6 +69,11 @@ cmake .. cmake --install . ``` +Right now, the version provision feature by the ETL library has not been implemented +yet so `CMake` is unable to determine and check the major version of the ETL +library. You have to ensure that the ETL library has been installed with the +correct major version. + ## Adding the library The following steps show how to add and use FSFW components. It is still recommended to @@ -105,6 +112,19 @@ The FSFW also has unittests which use the [Catch2 library](https://github.com/ca These are built by setting the CMake option `FSFW_BUILD_UNITTESTS` to `ON` or `TRUE` from your project `CMakeLists.txt` file or from the command line. +You can install the Catch2 library, which prevents the build system to avoid re-downloading +the dependency if the unit tests are completely rebuilt. The current recommended version +can be found inside the fsfw `CMakeLists.txt` file or by using `ccmake` and looking up +the `FSFW_CATCH2_LIB_VERSION` variable. + +```sh +git clone https://github.com/catchorg/Catch2.git +cd Catch2 +git checkout +cmake -Bbuild -H. -DBUILD_TESTING=OFF +sudo cmake --build build/ --target install +``` + The fsfw-tests binary will be built as part of the static library and dropped alongside it. If the unittests are built, the library and the tests will be built with coverage information by default. This can be disabled by setting the `FSFW_TESTS_COV_GEN` option to `OFF` or `FALSE`. diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 34547211..fb316a97 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -19,6 +19,30 @@ A template configuration folder was provided and can be copied into the project a starting point. The [configuration section](docs/README-config.md#top) provides more specific information about the possible options. +Prerequisites +------------------- + +The Embedded Template Library (etl) is a dependency of the FSFW which is automatically +installed and provided by the build system unless the correction version was installed. +The current recommended version can be found inside the fsfw ``CMakeLists.txt`` file or by using +``ccmake`` and looking up the ``FSFW_ETL_LIB_VERSION`` variable. + +You can install the ETL library like this: + +.. code-block:: console + + git clone https://github.com/ETLCPP/etl + cd etl + git checkout + mkdir build && cd build + cmake .. + cmake --install . + +Right now, the version provision feature by the ETL library has not been implemented +yet so ``CMake`` is unable to determine and check the major version of the ETL +library. You have to ensure that the ETL library has been installed with the +correct major version. + Adding the library ------------------- @@ -60,6 +84,20 @@ The FSFW also has unittests which use the `Catch2 library`_. These are built by setting the CMake option ``FSFW_BUILD_UNITTESTS`` to ``ON`` or `TRUE` from your project `CMakeLists.txt` file or from the command line. +You can install the Catch2 library, which prevents the build system to avoid re-downloading +the dependency if the unit tests are completely rebuilt. The current recommended version +can be found inside the fsfw ``CMakeLists.txt`` file or by using ``ccmake`` and looking up +the ``FSFW_CATCH2_LIB_VERSION`` variable. + +.. code-block:: console + + git clone https://github.com/catchorg/Catch2.git + cd Catch2 + git checkout + cmake -Bbuild -H. -DBUILD_TESTING=OFF + sudo cmake --build build/ --target install + + The fsfw-tests binary will be built as part of the static library and dropped alongside it. If the unittests are built, the library and the tests will be built with coverage information by default. This can be disabled by setting the `FSFW_TESTS_COV_GEN` option to `OFF` or `FALSE`. From 8dd0b2608d7e3c27bbd8eae80dad669a8bbf8f08 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 20:55:34 +0200 Subject: [PATCH 015/198] cache version variables --- CMakeLists.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2d6714c..903133a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,11 +7,19 @@ set(FSFW_REVISION 0) # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) -set(FSFW_ETL_LIB_MAJOR_VERSION 20) -set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.26.0) +set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE + "ETL library major version requirement" +) +set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.26.0 CACHE + "ETL library exact version requirement" +) -set(FSFW_CATCH2_LIB_MAJOR_VERSION 3) -set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview4) +set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE + "Catch2 library major version requirement" +) +set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview4 CACHE + "Catch2 library exact version requirement" +) set(FSFW_ETL_LIB_NAME etl) From c2a89bf709ccdd022399ecd6b6a68da209a481ac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 20:57:13 +0200 Subject: [PATCH 016/198] bugfix --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 903133a1..82466481 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,17 +7,17 @@ set(FSFW_REVISION 0) # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) -set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE +set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING "ETL library major version requirement" ) -set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.26.0 CACHE +set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.26.0 CACHE STRING "ETL library exact version requirement" ) -set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE +set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE STRING "Catch2 library major version requirement" ) -set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview4 CACHE +set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview4 CACHE STRING "Catch2 library exact version requirement" ) From 5525466b5247c949770406f1f2deac850497e760 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 20:57:30 +0200 Subject: [PATCH 017/198] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7b510f2..39c52139 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information inside `fsfw/version.h` PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 -- Added ETL dependency +- Added ETL dependency and improved library dependency management PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592 # [v4.0.0] From d07e0e55765d2b1f9e9cb48b19cb5d6da87b63bf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 21:01:26 +0200 Subject: [PATCH 018/198] trying something --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82466481..54db77ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,7 @@ add_library(${LIB_FSFW_NAME}) if(FSFW_BUILD_UNITTESTS) message(STATUS "Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first - find_package(Catch2 3) + find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION}) # Not installed, so use FetchContent to download and provide Catch2 if(NOT Catch2_FOUND) include(FetchContent) @@ -106,7 +106,7 @@ endif() message(STATUS "Finding and/or providing ETL library") # Check whether the user has already installed Catch2 first -find_package(${FSFW_ETL_LIB_NAME} QUIET) +find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide etl if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) message(STATUS From 8037e8074b544ab1587fc355adda20ad09dcd36f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 21:03:18 +0200 Subject: [PATCH 019/198] more docs --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54db77ce..9d9c4f70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,7 +106,10 @@ endif() message(STATUS "Finding and/or providing ETL library") # Check whether the user has already installed Catch2 first -find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) +# I think the version provisioning feature of CMake has not been implemented for the ETL library +# yet. Therefore we can not specify any (not even the major) version here and we have to rely +# on the user having installed the correct version for now +find_package(${FSFW_ETL_LIB_NAME} QUIET) # Not installed, so use FetchContent to download and provide etl if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) message(STATUS From 1a530633ca5deef06f9eb7ffb2e008ad59051ec5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 28 Mar 2022 21:10:51 +0200 Subject: [PATCH 020/198] small fix --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d9c4f70..fc797084 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,7 @@ if(FSFW_BUILD_UNITTESTS) endif() message(STATUS "Finding and/or providing ETL library") -# Check whether the user has already installed Catch2 first +# Check whether the user has already installed ETL first # I think the version provisioning feature of CMake has not been implemented for the ETL library # yet. Therefore we can not specify any (not even the major) version here and we have to rely # on the user having installed the correct version for now From 4f9797af3b4432a7e26279e039709b7cee5ca06e Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 28 Mar 2022 21:24:33 +0200 Subject: [PATCH 021/198] Updated CCSDS CuC Functions --- src/fsfw/timemanager/CCSDSTime.cpp | 12 ++++----- src/fsfw/timemanager/CCSDSTime.h | 27 ++++++++++++++++--- .../unit/timemanager/TestCCSDSTime.cpp | 21 +++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/fsfw/timemanager/CCSDSTime.cpp b/src/fsfw/timemanager/CCSDSTime.cpp index 9ebd1d79..ff20142f 100644 --- a/src/fsfw/timemanager/CCSDSTime.cpp +++ b/src/fsfw/timemanager/CCSDSTime.cpp @@ -428,7 +428,7 @@ ReturnValue_t CCSDSTime::convertFromCUC(timeval* to, const uint8_t* from, size_t from++; ReturnValue_t result = convertFromCUC(to, pField, from, foundLength, maxLength - 1); if (result == HasReturnvaluesIF::RETURN_OK) { - if (foundLength != NULL) { + if (foundLength != nullptr) { *foundLength += 1; } } @@ -588,18 +588,18 @@ ReturnValue_t CCSDSTime::convertFromCUC(timeval* to, uint8_t pField, const uint8 uint8_t nCoarse = ((pField & 0b1100) >> 2) + 1; uint8_t nFine = (pField & 0b11); size_t totalLength = nCoarse + nFine; - if (foundLength != NULL) { + if (foundLength != nullptr) { *foundLength = totalLength; } if (totalLength > maxLength) { return LENGTH_MISMATCH; } - for (int count = 0; count < nCoarse; count++) { - secs += *from << ((nCoarse * 8 - 8) * (1 + count)); + for (int count = nCoarse; count > 0; count--) { + secs += *from << (count * 8 - 8); from++; } - for (int count = 0; count < nFine; count++) { - subSeconds += *from << ((nFine * 8 - 8) * (1 + count)); + for (int count = nFine; count > 0; count--) { + subSeconds += *from << (count * 8 - 8); from++; } // Move to POSIX epoch. diff --git a/src/fsfw/timemanager/CCSDSTime.h b/src/fsfw/timemanager/CCSDSTime.h index 19c980d0..59e16a1c 100644 --- a/src/fsfw/timemanager/CCSDSTime.h +++ b/src/fsfw/timemanager/CCSDSTime.h @@ -161,18 +161,37 @@ class CCSDSTime : public HasReturnvaluesIF { */ static ReturnValue_t convertFromCcsds(timeval *to, uint8_t const *from, size_t *foundLength, size_t maxLength); - + /** + * @brief Currently unsupported conversion due to leapseconds + * + * @param to Time Of Day (UTC) + * @param from Buffer to take the CUC from + * @param length Length of buffer + * @return ReturnValue_t UNSUPPORTED_TIME_FORMAT in any case ATM + */ static ReturnValue_t convertFromCUC(Clock::TimeOfDay_t *to, uint8_t const *from, uint8_t length); - + /** + * @brief Converts from CCSDS CUC to timeval + * + * If input is CCSDS Epoch this is TAI! -> No leapsecond support. + * + * Currently, it only supports seconds + 2 Byte Subseconds (1/65536 seconds) + * + * + * @param to Timeval to write the result to + * @param from Buffer to read from + * @param foundLength Length found by this function (can be nullptr if unused) + * @param maxLength Max length of the buffer to be read + * @return ReturnValue_t - RETURN_OK if successful + * - LENGTH_MISMATCH if expected length is larger than maxLength + */ static ReturnValue_t convertFromCUC(timeval *to, uint8_t const *from, size_t *foundLength, size_t maxLength); - static ReturnValue_t convertFromCUC(timeval *to, uint8_t pField, uint8_t const *from, size_t *foundLength, size_t maxLength); static ReturnValue_t convertFromCCS(timeval *to, uint8_t const *from, size_t *foundLength, size_t maxLength); - static ReturnValue_t convertFromCCS(timeval *to, uint8_t pField, uint8_t const *from, size_t *foundLength, size_t maxLength); diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp index a43ff8ab..e96ddfc9 100644 --- a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp +++ b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp @@ -179,6 +179,27 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { CHECK(todFromCCSDS.second == time.second); CHECK(todFromCCSDS.usecond == 123000); } + SECTION("CUC") { + timeval to; + // seconds = 0x771E960F, microseconds = 0x237 + // microseconds = 567000 + // This gives 37158.912 1/65536 seconds -> rounded to 37159 -> 0x9127 + // This results in -> 567001 us + std::array cucBuffer = { + CCSDSTime::P_FIELD_CUC_6B_CCSDS, 0x77, 0x1E, 0x96, 0x0F, 0x91, 0x27}; + size_t foundLength = 0; + auto result = CCSDSTime::convertFromCUC(&to, cucBuffer.data(), &foundLength, cucBuffer.size()); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(foundLength == 7); + REQUIRE(to.tv_sec == 1619801999); // TAI (no leap seconds) + REQUIRE(to.tv_usec == 567001); + + Clock::TimeOfDay_t tod; + result = CCSDSTime::convertFromCUC(&tod, cucBuffer.data(), cucBuffer.size()); + // This test must be changed if this is ever going to be implemented + REQUIRE(result == CCSDSTime::UNSUPPORTED_TIME_FORMAT); + } + SECTION("CCSDS Failures") { Clock::TimeOfDay_t time; time.year = 2020; From a3930dafc59bca2faf49e133b8c6f03f01ff8d4f Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 28 Mar 2022 21:37:25 +0200 Subject: [PATCH 022/198] Moved unused constructors --- src/fsfw/timemanager/CCSDSTime.cpp | 4 ---- src/fsfw/timemanager/CCSDSTime.h | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/fsfw/timemanager/CCSDSTime.cpp b/src/fsfw/timemanager/CCSDSTime.cpp index ff20142f..1f84dd03 100644 --- a/src/fsfw/timemanager/CCSDSTime.cpp +++ b/src/fsfw/timemanager/CCSDSTime.cpp @@ -6,10 +6,6 @@ #include "fsfw/FSFW.h" -CCSDSTime::CCSDSTime() {} - -CCSDSTime::~CCSDSTime() {} - ReturnValue_t CCSDSTime::convertToCcsds(Ccs_seconds* to, const Clock::TimeOfDay_t* from) { ReturnValue_t result = checkTimeOfDay(from); if (result != RETURN_OK) { diff --git a/src/fsfw/timemanager/CCSDSTime.h b/src/fsfw/timemanager/CCSDSTime.h index 59e16a1c..2a2316af 100644 --- a/src/fsfw/timemanager/CCSDSTime.h +++ b/src/fsfw/timemanager/CCSDSTime.h @@ -211,8 +211,8 @@ class CCSDSTime : public HasReturnvaluesIF { static uint32_t subsecondsToMicroseconds(uint16_t subseconds); private: - CCSDSTime(); - virtual ~CCSDSTime(); + CCSDSTime(){}; + virtual ~CCSDSTime(){}; /** * checks a ccs time stream for validity * From bfa77cf810060a2254b0b341048cc7ce4c3fee24 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 29 Mar 2022 15:07:29 +0200 Subject: [PATCH 023/198] Add TC scheduler service - Written by David Woodward as part of the SOURCE project - Adaptions to make it more generic and compatible to FSFW --- src/fsfw/pus/Service11TelecommandScheduling.h | 191 ++++++ .../pus/Service11TelecommandScheduling.tpp | 608 ++++++++++++++++++ 2 files changed, 799 insertions(+) create mode 100644 src/fsfw/pus/Service11TelecommandScheduling.h create mode 100644 src/fsfw/pus/Service11TelecommandScheduling.tpp diff --git a/src/fsfw/pus/Service11TelecommandScheduling.h b/src/fsfw/pus/Service11TelecommandScheduling.h new file mode 100644 index 00000000..97a343a7 --- /dev/null +++ b/src/fsfw/pus/Service11TelecommandScheduling.h @@ -0,0 +1,191 @@ +#ifndef MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_ +#define MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_ + +#include +#include +#include + +#include "fsfw/FSFW.h" + +/** + * @brief: PUS-Service 11 - Telecommand scheduling. + * @details: + * PUS-Service 11 - Telecommand scheduling. + * Full documentation: ECSS-E-ST-70-41C, p. 168: + * ST[11] time-based scheduling + * + * This service provides the capability to command pre-loaded + * application processes (telecommands) by releasing them at their + * due-time. + * References to telecommands are stored together with their due-timepoints + * and are released at their corresponding due-time. + * + * Necessary subservice functionalities are implemented. + * Those are: + * TC[11,4] activity insertion + * TC[11,5] activity deletion + * TC[11,6] filter-based activity deletion + * TC[11,7] activity time-shift + * TC[11,8] filter-based activity time-shift + * + * Groups are not supported. + * This service remains always enabled. Sending a disable-request has no effect. + */ +template +class Service11TelecommandScheduling final : public PusServiceBase { + public: + // The types of PUS-11 subservices + enum Subservice { + ENABLE_SCHEDULING = 1, + DISABLE_SCHEDULING = 2, + RESET_SCHEDULING = 3, + INSERT_ACTIVITY = 4, + DELETE_ACTIVITY = 5, + FILTER_DELETE_ACTIVITY = 6, + TIMESHIFT_ACTIVITY = 7, + FILTER_TIMESHIFT_ACTIVITY = 8, + DETAIL_REPORT = 9, + TIMEBASE_SCHEDULE_DETAIL_REPORT = 10, + TIMESHIFT_ALL_SCHEDULE_ACTIVITIES = 15 + }; + + // The types of time windows for TC[11,6] and TC[11,8], as defined in ECSS-E-ST-70-41C, + // requirement 8.11.3c (p. 507) + enum TypeOfTimeWindow : uint32_t { + SELECT_ALL = 0, + FROM_TIMETAG_TO_TIMETAG = 1, + FROM_TIMETAG = 2, + TO_TIMETAG = 3 + }; + + Service11TelecommandScheduling(object_id_t objectId, uint16_t apid, uint8_t serviceId, + AcceptsTelecommandsIF* tcRecipient, + uint16_t releaseTimeMarginSeconds = DEFAULT_RELEASE_TIME_MARGIN, + bool debugMode = false); + + ~Service11TelecommandScheduling(); + + /** PusServiceBase overrides */ + ReturnValue_t handleRequest(uint8_t subservice) override; + ReturnValue_t performService() override; + ReturnValue_t initialize() override; + + private: + struct TelecommandStruct { + uint64_t requestId; + uint32_t seconds; + store_address_t storeAddr; // uint16 + }; + + static constexpr uint16_t DEFAULT_RELEASE_TIME_MARGIN = 5; + + // minimum release time offset to insert into schedule + const uint16_t RELEASE_TIME_MARGIN_SECONDS = 5; + + // the maximum amount of stored TCs is defined here + static constexpr uint16_t MAX_STORED_TELECOMMANDS = 500; + + bool debugMode = false; + StorageManagerIF* tcStore = nullptr; + AcceptsTelecommandsIF* tcRecipient = nullptr; + MessageQueueId_t recipientMsgQueueId = 0; + + /** + * The telecommand map uses the exectution time as a Unix time stamp as + * the key. This is mapped to a generic telecommand struct. + */ + using TelecommandMap = etl::multimap; + using TcMapIter = typename TelecommandMap::iterator; + + TelecommandMap telecommandMap; + + /** + * @brief Logic to be performed on an incoming TC[11,4]. + * @return RETURN_OK if successful + */ + ReturnValue_t doInsertActivity(void); + + /** + * @brief Logic to be performed on an incoming TC[11,5]. + * @return RETURN_OK if successful + */ + ReturnValue_t doDeleteActivity(void); + + /** + * @brief Logic to be performed on an incoming TC[11,6]. + * @return RETURN_OK if successful + */ + ReturnValue_t doFilterDeleteActivity(void); + + /** + * @brief Logic to be performed on an incoming TC[11,7]. + * @return RETURN_OK if successful + */ + ReturnValue_t doTimeshiftActivity(void); + + /** + * @brief Logic to be performed on an incoming TC[11,8]. + * @return RETURN_OK if successful + */ + ReturnValue_t doFilterTimeshiftActivity(void); + + /** + * @brief Deserializes a generic type from a payload buffer by using the FSFW + * SerializeAdapter Interface. + * @param output Output to be deserialized + * @param buf Payload buffer (application data) + * @param bufsize Remaining size of payload buffer (application data size) + * @return RETURN_OK if successful + */ + template + ReturnValue_t deserializeViaFsfwInterface(T& output, const uint8_t* buf, size_t bufsize); + + /** + * @brief Extracts the Request ID from the Application Data of a TC by utilizing a ctor of the + * class TcPacketPus. + * NOTE: This only works if the payload data is a TC (e.g. not for TC[11,5] which does not + * send a TC as payload)! + * @param data The Application data of the TC (get via getApplicationData()). + * @return requestId + */ + uint64_t getRequestIdFromDataTC(const uint8_t* data) const; + + /** + * @brief Extracts the Request ID from the Application Data directly, assuming it is packed + * as follows (acc. to ECSS): | source ID (uint32) | apid (uint32) | ssc (uint32) |. + * @param data Pointer to first byte described data + * @param dataSize Remaining size of data NOTE: non-const, this is modified by the function + * @param [out] requestId Request ID + * @return RETURN_OK if successful + */ + ReturnValue_t getRequestIdFromData(const uint8_t* data, size_t& dataSize, uint64_t& requestId); + + /** + * @brief Builds the Request ID from its three elements. + * @param sourceId Source ID + * @param apid Application Process ID (APID) + * @param ssc Source Sequence Count + * @return Request ID + */ + uint64_t buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const; + + /** + * @brief Gets the filter range for filter TCs from a data packet + * @param data TC data + * @param dataSize TC data size + * @param [out] itBegin Begin of filter range + * @param [out] itEnd End of filter range + * @return RETURN_OK if successful + */ + ReturnValue_t getMapFilterFromData(const uint8_t* data, size_t dataSize, TcMapIter& itBegin, + TcMapIter& itEnd); + + /** + * @brief Prints content of multimap. Use for simple debugging only. + */ + void debugPrintMultimapContent(void) const; +}; + +#include "Service11TelecommandScheduling.tpp" + +#endif /* MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_ */ diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp new file mode 100644 index 00000000..bfd9e96f --- /dev/null +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -0,0 +1,608 @@ +#pragma once + +#include +#include +#include + +#include + +template +inline Service11TelecommandScheduling::Service11TelecommandScheduling( + object_id_t objectId, uint16_t apid, uint8_t serviceId, AcceptsTelecommandsIF *tcRecipient, + uint16_t releaseTimeMarginSeconds, bool debugMode) + : PusServiceBase(objectId, apid, serviceId), + RELEASE_TIME_MARGIN_SECONDS(releaseTimeMarginSeconds), + debugMode(debugMode), + tcRecipient(tcRecipient) {} + +template +inline Service11TelecommandScheduling::~Service11TelecommandScheduling() {} + +template +inline ReturnValue_t Service11TelecommandScheduling::handleRequest( + uint8_t subservice) { + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::handleRequest: Handling request " << static_cast(subservice); +#else + sif::printInfo("PUS11::handleRequest: Handling request %d\n", subservice); +#endif + } + switch (subservice) { + case Subservice::INSERT_ACTIVITY: + return doInsertActivity(); + case Subservice::DELETE_ACTIVITY: + return doDeleteActivity(); + case Subservice::FILTER_DELETE_ACTIVITY: + return doFilterDeleteActivity(); + case Subservice::TIMESHIFT_ACTIVITY: + return doTimeshiftActivity(); + case Subservice::FILTER_TIMESHIFT_ACTIVITY: + return doFilterTimeshiftActivity(); + default: + break; + } + + return HasReturnvaluesIF::RETURN_FAILED; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::performService() { + // DEBUG + // DebugPrintMultimapContent(); + + // get current time as UNIX timestamp + timeval tNow = {}; + Clock::getClock_timeval(&tNow); + + // NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg + // does not work in this case as we are deleting the current element here. + for (auto it = telecommandMap.begin(); it != telecommandMap.end();) { + if (it->first <= tNow.tv_sec) { + // release tc + TmTcMessage releaseMsg(it->second.storeAddr); + auto sendRet = this->requestQueue->sendMessage(recipientMsgQueueId, &releaseMsg, false); + + if (sendRet != HasReturnvaluesIF::RETURN_OK) { + return sendRet; + } + + telecommandMap.erase(it++); + + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Released TC & erased it from TC map" << std::endl; +#else + sif::printInfo("Released TC & erased it from TC map\n"); +#endif + } + continue; + } + it++; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::initialize() { + ReturnValue_t res = PusServiceBase::initialize(); + if (res != HasReturnvaluesIF::RETURN_OK) { + return res; + } + + tcStore = ObjectManager::instance()->get(objects::TC_STORE); + if (!tcStore) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + if (tcRecipient == nullptr) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + recipientMsgQueueId = tcRecipient->getRequestQueue(); + + return res; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::doInsertActivity(void) { + // Get de-serialized Timestamp + const uint8_t *data = currentPacket.getApplicationData(); + size_t dataSize = currentPacket.getApplicationDataSize(); + + uint32_t timestamp = 0; + if (deserializeViaFsfwInterface(timestamp, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + data += sizeof(uint32_t); // move ptr past timestamp (for later) + dataSize -= sizeof(uint32_t); // and reduce size accordingly + + // Insert possible if sched. time is above margin + // (See requirement for Time margin) + timeval tNow = {}; + Clock::getClock_timeval(&tNow); + if (timestamp - tNow.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to " + "current time" + << std::endl; +#else + sif::printWarning( + "Service11TelecommandScheduling::doInsertActivity: Release time too close to current " + "time\n"); +#endif + return RETURN_FAILED; + } + + // store currentPacket and receive the store address + store_address_t addr; + if (tcStore->addData(&addr, data, dataSize) != RETURN_OK || + addr.raw == storeId::INVALID_STORE_ADDRESS) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "Service11TelecommandScheduling::doInsertActivity: Adding data to TC Store failed" + << std::endl; +#else + sif::printError( + "Service11TelecommandScheduling::doInsertActivity: Adding data to TC Store failed\n"); +#endif + return RETURN_FAILED; + } + + // insert into multimap with new store address + TelecommandStruct tc; + tc.seconds = timestamp; + tc.storeAddr = addr; + tc.requestId = + getRequestIdFromDataTC(data); // TODO: Missing sanity check of the returned request id + + auto it = telecommandMap.insert(std::pair(timestamp, tc)); + if (it == telecommandMap.end()) { + return RETURN_FAILED; + } + + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::doInsertActivity: Inserted into Multimap:" << std::endl; +#else + sif::printInfo("PUS11::doInsertActivity: Inserted into Multimap:\n"); +#endif + debugPrintMultimapContent(); + } + return HasReturnvaluesIF::RETURN_OK; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::doDeleteActivity(void) { + const uint8_t *data = currentPacket.getApplicationData(); + size_t dataSize = currentPacket.getApplicationDataSize(); + + // Get request ID + uint64_t requestId; + if (getRequestIdFromData(data, dataSize, requestId) != RETURN_OK) { + return RETURN_FAILED; + } + + // DEBUG + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::doDeleteActivity: requestId: " << requestId << std::endl; +#else + sif::printInfo("PUS11::doDeleteActivity: requestId: %d\n", requestId); +#endif + } + + TcMapIter tcToDelete; // handle to the TC to be deleted, can be used if counter is valid + int tcToDeleteCount = 0; // counter of all found TCs. Should be 1. + + for (auto it = telecommandMap.begin(); it != telecommandMap.end(); it++) { + if (it->second.requestId == requestId) { + tcToDelete = it; + tcToDeleteCount++; + } + } + + // check if 1 explicit TC is found via request ID + if (tcToDeleteCount == 0 || tcToDeleteCount > 1) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "Service11TelecommandScheduling::doDeleteActivity: No or more than 1 TC found. " + "Cannot explicitly delete TC" + << std::endl; +#else + sif::printWarning( + "Service11TelecommandScheduling::doDeleteActivity: No or more than 1 TC found. " + "Cannot explicitly delete TC"); +#endif + return RETURN_FAILED; + } + + // delete packet from store + if (tcStore->deleteData(tcToDelete->second.storeAddr) != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "Service11TelecommandScheduling::doDeleteActivity: Could not delete TC from Store" + << std::endl; +#else + sif::printError( + "Service11TelecommandScheduling::doDeleteActivity: Could not delete TC from Store\n"); +#endif + return RETURN_FAILED; + } + + telecommandMap.erase(tcToDelete); + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::doDeleteActivity: Deleted TC from map" << std::endl; +#else + sif::printInfo("PUS11::doDeleteActivity: Deleted TC from map\n"); +#endif + } + + return RETURN_OK; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::doFilterDeleteActivity(void) { + const uint8_t *data = currentPacket.getApplicationData(); + size_t dataSize = currentPacket.getApplicationDataSize(); + + TcMapIter itBegin; + TcMapIter itEnd; + + // get the filter window as map range via dedicated method + if (getMapFilterFromData(data, dataSize, itBegin, itEnd) != RETURN_OK) { + return RETURN_FAILED; + } + + int deletedTCs = 0; + for (TcMapIter it = itBegin; it != itEnd; it++) { + // delete packet from store + if (tcStore->deleteData(it->second.storeAddr) != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "Service11TelecommandScheduling::doFilterDeleteActivity: Could not delete TC " + "from Store" + << std::endl; +#else + sif::printError( + "Service11TelecommandScheduling::doFilterDeleteActivity: Could not delete TC from " + "Store\n"); +#endif + continue; + } + deletedTCs++; + } + + // NOTE: Spec says this function erases all elements including itBegin but not itEnd, + // see here: https://www.cplusplus.com/reference/map/multimap/erase/ + // Therefore we need to increase itEnd by 1. (Note that end() returns the "past-the-end" iterator) + if (itEnd != telecommandMap.end()) { + itEnd++; + } + + telecommandMap.erase(itBegin, itEnd); + + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::doFilterDeleteActivity: Deleted " << deletedTCs << " TCs" << std::endl; +#else + sif::printInfo("PUS11::doFilterDeleteActivity: Deleted %d TCs\n", deletedTCs); +#endif + } + return RETURN_OK; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::doTimeshiftActivity(void) { + const uint8_t *data = currentPacket.getApplicationData(); + size_t dataSize = currentPacket.getApplicationDataSize(); + + // Get relative time + uint32_t relativeTime = 0; + if (deserializeViaFsfwInterface(relativeTime, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + if (relativeTime == 0) { + return RETURN_FAILED; + } + // TODO further check sanity of the relative time? + + data += sizeof(uint32_t); + dataSize -= sizeof(uint32_t); + + // Get request ID + uint64_t requestId; + if (getRequestIdFromData(data, dataSize, requestId) != RETURN_OK) { + return RETURN_FAILED; + } + + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::doTimeshiftActivity: requestId: " << requestId << std::endl; +#else + sif::printInfo("PUS11::doTimeshiftActivity: requestId: %d\n", requestId); +#endif + } + + // NOTE: Despite having C++17 ETL multimap has no member function extract :( + + TcMapIter tcToTimeshiftIt; + int tcToTimeshiftCount = 0; + + for (auto it = telecommandMap.begin(); it != telecommandMap.end(); it++) { + if (it->second.requestId == requestId) { + tcToTimeshiftIt = it; + tcToTimeshiftCount++; + } + } + + if (tcToTimeshiftCount == 0 || tcToTimeshiftCount > 1) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "Service11TelecommandScheduling::doTimeshiftActivity: Either 0 or more than 1 " + "TCs found. No explicit timeshifting " + "possible" + << std::endl; + +#else + sif::printWarning( + "Service11TelecommandScheduling::doTimeshiftActivity: Either 0 or more than 1 TCs found. " + "No explicit timeshifting possible\n"); +#endif + return RETURN_FAILED; + } + + // temporarily hold the item + TelecommandStruct tempTc(tcToTimeshiftIt->second); + uint32_t tempKey = tcToTimeshiftIt->first + relativeTime; + + // delete old entry from the mm + telecommandMap.erase(tcToTimeshiftIt); + + // and then insert it again as new entry + telecommandMap.insert(std::make_pair(tempKey, tempTc)); + + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::doTimeshiftActivity: Shifted TC" << std::endl; +#else + sif::printDebug("PUS11::doTimeshiftActivity: Shifted TC\n"); +#endif + debugPrintMultimapContent(); + } + + return RETURN_OK; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::doFilterTimeshiftActivity(void) { + const uint8_t *data = currentPacket.getApplicationData(); + uint32_t dataSize = currentPacket.getApplicationDataSize(); + + // Get relative time + uint32_t relativeTime = 0; + if (deserializeViaFsfwInterface(relativeTime, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + if (relativeTime == 0) { + return RETURN_FAILED; + } + data += sizeof(uint32_t); + dataSize -= sizeof(uint32_t); + + // Do time window + TcMapIter itBegin; + TcMapIter itEnd; + if (getMapFilterFromData(data, dataSize, itBegin, itEnd) != RETURN_OK) { + return RETURN_FAILED; + } + + int shiftedItemsCount = 0; + for (auto it = itBegin; it != itEnd;) { + // temporarily hold the item + TelecommandStruct tempTc(it->second); + uint32_t tempKey = it->first + relativeTime; + + // delete the old entry from the mm + telecommandMap.erase(it++); + + // and then insert it again as new entry + telecommandMap.insert(std::make_pair(tempKey, tempTc)); + shiftedItemsCount++; + continue; + } + + if (debugMode) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "PUS11::doFilterTimeshiftActivity: shiftedItemsCount: " << shiftedItemsCount + << std::endl; +#else + sif::printInfo("PUS11::doFilterTimeshiftActivity: shiftedItemsCount: %d\n", shiftedItemsCount); +#endif + debugPrintMultimapContent(); + } + + if (shiftedItemsCount > 0) { + return RETURN_OK; + } + return RETURN_FAILED; +} + +template +inline uint64_t Service11TelecommandScheduling::getRequestIdFromDataTC( + const uint8_t *data) const { + TcPacketPus mask(data); + + uint32_t sourceId = mask.getSourceId(); + uint16_t apid = mask.getAPID(); + uint16_t sequenceCount = mask.getPacketSequenceCount(); + + return buildRequestId(sourceId, apid, sequenceCount); +} + +template +inline ReturnValue_t Service11TelecommandScheduling::getRequestIdFromData( + const uint8_t *data, size_t &dataSize, uint64_t &requestId) { + uint32_t srcId = 0; + uint16_t apid = 0; + uint16_t ssc = 0; + + if (deserializeViaFsfwInterface(srcId, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + + data += sizeof(uint32_t); + dataSize -= sizeof(uint32_t); + if (deserializeViaFsfwInterface(apid, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + + data += sizeof(uint32_t); + dataSize -= sizeof(uint32_t); + if (deserializeViaFsfwInterface(ssc, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + + requestId = buildRequestId(srcId, apid, ssc); + + return RETURN_OK; +} + +template +inline uint64_t Service11TelecommandScheduling::buildRequestId(uint32_t sourceId, + uint16_t apid, + uint16_t ssc) const { + uint64_t sourceId64 = static_cast(sourceId); + uint64_t apid64 = static_cast(apid); + uint64_t ssc64 = static_cast(ssc); + + return (sourceId64 << 32) | (apid64 << 16) | ssc64; +} + +template +inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFromData( + const uint8_t *data, size_t dataSize, TcMapIter &itBegin, TcMapIter &itEnd) { + // get filter type first + uint32_t typeRaw; + if (deserializeViaFsfwInterface(typeRaw, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + // can be modified as the uint8_t pointer is passed by value (copy of ptr is modified) + data += sizeof(uint32_t); + dataSize -= sizeof(uint32_t); + + TypeOfTimeWindow type = static_cast(typeRaw); + + // we now have the type of delete activity - so now we set the range to delete, + // according to the type of time window. + // NOTE: Blocks are used in this switch-case statement so that timestamps can be + // cleanly redefined for each case. + switch (type) { + case TypeOfTimeWindow::SELECT_ALL: { + itBegin = telecommandMap.begin(); + itEnd = telecommandMap.end(); + break; + } + + case TypeOfTimeWindow::FROM_TIMETAG: { + uint32_t fromTimestamp; + if (deserializeViaFsfwInterface(fromTimestamp, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + + itBegin = telecommandMap.begin(); + while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) { + itBegin++; + } + + itEnd = telecommandMap.end(); + break; + } + + case TypeOfTimeWindow::TO_TIMETAG: { + uint32_t toTimestamp; + if (deserializeViaFsfwInterface(toTimestamp, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + itBegin = telecommandMap.begin(); + itEnd = telecommandMap.begin(); + while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) { + itEnd++; + } + break; + } + + case TypeOfTimeWindow::FROM_TIMETAG_TO_TIMETAG: { + uint32_t fromTimestamp; + uint32_t toTimestamp; + + if (deserializeViaFsfwInterface(fromTimestamp, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + data += sizeof(uint32_t); + dataSize -= sizeof(uint32_t); + + if (deserializeViaFsfwInterface(toTimestamp, data, dataSize) != RETURN_OK) { + return RETURN_FAILED; + } + itBegin = telecommandMap.begin(); + itEnd = telecommandMap.begin(); + + while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) { + itBegin++; + } + while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) { + itEnd++; + } + break; + } + + default: + return RETURN_FAILED; + } + + // additional security check, this should never be true + if (itBegin->first > itEnd->first) { + sif::printError("11::GetMapFilterFromData: itBegin > itEnd\n"); + return RETURN_FAILED; + } + + // the map range should now be set according to the sent filter. + return RETURN_OK; +} + +template +template +inline ReturnValue_t Service11TelecommandScheduling::deserializeViaFsfwInterface( + T &output, const uint8_t *buf, size_t bufsize) { + if (buf == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "Service11TelecommandScheduling::deserializeViaFsfwInterface: " + "Invalid buffer" + << std::endl; +#else + sif::printWarning( + "Service11TelecommandScheduling::deserializeViaFsfwInterface: " + "Invalid buffer\n"); +#endif +#endif + return RETURN_FAILED; + } + + return SerializeAdapter::deSerialize(&output, &buf, &bufsize, SerializeIF::Endianness::BIG); +} + +template +inline void Service11TelecommandScheduling::debugPrintMultimapContent(void) const { +#if FSFW_DISABLE_PRINTOUT == 0 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content" + << std::endl; + sif::debug << "[" << dit->first << "]: Request ID: " << dit->second.requestId << " | " + << "Store Address: " << dit->second.storeAddr << std::endl; +#else + sif::printDebug("Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content\n"); + for (auto dit = telecommandMap.begin(); dit != telecommandMap.end(); ++dit) { + sif::printDebug("[%d]: Request ID: %d | Store Address: %d\n", dit->first, + dit->second.requestId, dit->second.storeAddr); + } +#endif +#endif +} From 82fc7f33a8b27b985f279b8213bc9df7340865f2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 29 Mar 2022 15:11:41 +0200 Subject: [PATCH 024/198] update afmt scripts to format *.tpp files --- .../devicehandlers/MgmLIS3MDLHandler.cpp | 4 +- hal/src/fsfw_hal/linux/uart/UartCookie.cpp | 4 +- scripts/apply-clang-format.sh | 6 +- src/fsfw/container/FIFOBase.tpp | 105 ++++--- src/fsfw/container/FixedOrderedMultimap.tpp | 158 +++++----- src/fsfw/datapoollocal/LocalPoolVariable.tpp | 286 +++++++++--------- src/fsfw/datapoollocal/LocalPoolVector.tpp | 280 +++++++++-------- src/fsfw/osal/rtems/PeriodicTask.h | 5 +- src/fsfw/version.cpp | 3 +- src/fsfw/version.h | 2 +- tests/src/fsfw_tests/unit/version.cpp | 50 +-- 11 files changed, 441 insertions(+), 462 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 52b6dc07..644b488d 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -1,9 +1,9 @@ #include "MgmLIS3MDLHandler.h" -#include "fsfw/datapool/PoolReadGuard.h" - #include +#include "fsfw/datapool/PoolReadGuard.h" + MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie, uint32_t transitionDelay) : DeviceHandlerBase(objectId, deviceCommunication, comCookie), diff --git a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp index aa2dd214..3fedc9d4 100644 --- a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp @@ -24,9 +24,7 @@ void UartCookie::setParityEven() { parity = Parity::EVEN; } Parity UartCookie::getParity() const { return parity; } -void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { - bitsPerWord = bitsPerWord_; -} +void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; } BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; } diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index 27202324..ca63ac12 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -3,6 +3,6 @@ if [[ ! -f README.md ]]; then cd .. fi -find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i +find ./src -iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp | xargs clang-format --style=file -i +find ./hal -iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp | xargs clang-format --style=file -i +find ./tests -iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp | xargs clang-format --style=file -i diff --git a/src/fsfw/container/FIFOBase.tpp b/src/fsfw/container/FIFOBase.tpp index 2e6a3829..91804b6c 100644 --- a/src/fsfw/container/FIFOBase.tpp +++ b/src/fsfw/container/FIFOBase.tpp @@ -5,89 +5,88 @@ #error Include FIFOBase.h before FIFOBase.tpp! #endif -template -inline FIFOBase::FIFOBase(T* values, const size_t maxCapacity): - maxCapacity(maxCapacity), values(values){}; +template +inline FIFOBase::FIFOBase(T* values, const size_t maxCapacity) + : maxCapacity(maxCapacity), values(values){}; -template +template inline ReturnValue_t FIFOBase::insert(T value) { - if (full()) { - return FULL; - } else { - values[writeIndex] = value; - writeIndex = next(writeIndex); - ++currentSize; - return HasReturnvaluesIF::RETURN_OK; - } + if (full()) { + return FULL; + } else { + values[writeIndex] = value; + writeIndex = next(writeIndex); + ++currentSize; + return HasReturnvaluesIF::RETURN_OK; + } }; -template +template inline ReturnValue_t FIFOBase::retrieve(T* value) { - if (empty()) { - return EMPTY; - } else { - if (value == nullptr){ - return HasReturnvaluesIF::RETURN_FAILED; - } - *value = values[readIndex]; - readIndex = next(readIndex); - --currentSize; - return HasReturnvaluesIF::RETURN_OK; + if (empty()) { + return EMPTY; + } else { + if (value == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; } + *value = values[readIndex]; + readIndex = next(readIndex); + --currentSize; + return HasReturnvaluesIF::RETURN_OK; + } }; -template +template inline ReturnValue_t FIFOBase::peek(T* value) { - if(empty()) { - return EMPTY; - } else { - if (value == nullptr){ - return HasReturnvaluesIF::RETURN_FAILED; - } - *value = values[readIndex]; - return HasReturnvaluesIF::RETURN_OK; + if (empty()) { + return EMPTY; + } else { + if (value == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; } + *value = values[readIndex]; + return HasReturnvaluesIF::RETURN_OK; + } }; -template +template inline ReturnValue_t FIFOBase::pop() { - T value; - return this->retrieve(&value); + T value; + return this->retrieve(&value); }; -template +template inline bool FIFOBase::empty() { - return (currentSize == 0); + return (currentSize == 0); }; -template +template inline bool FIFOBase::full() { - return (currentSize == maxCapacity); + return (currentSize == maxCapacity); } -template +template inline size_t FIFOBase::size() { - return currentSize; + return currentSize; } -template +template inline size_t FIFOBase::next(size_t current) { - ++current; - if (current == maxCapacity) { - current = 0; - } - return current; + ++current; + if (current == maxCapacity) { + current = 0; + } + return current; } -template +template inline size_t FIFOBase::getMaxCapacity() const { - return maxCapacity; + return maxCapacity; } - -template -inline void FIFOBase::setContainer(T *data) { - this->values = data; +template +inline void FIFOBase::setContainer(T* data) { + this->values = data; } #endif diff --git a/src/fsfw/container/FixedOrderedMultimap.tpp b/src/fsfw/container/FixedOrderedMultimap.tpp index 294a161f..fd58bc44 100644 --- a/src/fsfw/container/FixedOrderedMultimap.tpp +++ b/src/fsfw/container/FixedOrderedMultimap.tpp @@ -1,109 +1,109 @@ #ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ #define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ - -template -inline ReturnValue_t FixedOrderedMultimap::insert(key_t key, T value, Iterator *storedValue) { - if (_size == theMap.maxSize()) { - return MAP_FULL; - } - size_t position = findNicePlace(key); - memmove(static_cast(&theMap[position + 1]),static_cast(&theMap[position]), - (_size - position) * sizeof(std::pair)); - theMap[position].first = key; - theMap[position].second = value; - ++_size; - if (storedValue != nullptr) { - *storedValue = Iterator(&theMap[position]); - } - return HasReturnvaluesIF::RETURN_OK; +template +inline ReturnValue_t FixedOrderedMultimap::insert(key_t key, T value, + Iterator *storedValue) { + if (_size == theMap.maxSize()) { + return MAP_FULL; + } + size_t position = findNicePlace(key); + memmove(static_cast(&theMap[position + 1]), static_cast(&theMap[position]), + (_size - position) * sizeof(std::pair)); + theMap[position].first = key; + theMap[position].second = value; + ++_size; + if (storedValue != nullptr) { + *storedValue = Iterator(&theMap[position]); + } + return HasReturnvaluesIF::RETURN_OK; } -template +template inline ReturnValue_t FixedOrderedMultimap::insert(std::pair pair) { - return insert(pair.first, pair.second); + return insert(pair.first, pair.second); } -template +template inline ReturnValue_t FixedOrderedMultimap::exists(key_t key) const { - ReturnValue_t result = KEY_DOES_NOT_EXIST; - if (findFirstIndex(key) < _size) { - result = HasReturnvaluesIF::RETURN_OK; - } - return result; + ReturnValue_t result = KEY_DOES_NOT_EXIST; + if (findFirstIndex(key) < _size) { + result = HasReturnvaluesIF::RETURN_OK; + } + return result; } -template +template inline ReturnValue_t FixedOrderedMultimap::erase(Iterator *iter) { - size_t i; - if ((i = findFirstIndex((*iter).value->first)) >= _size) { - return KEY_DOES_NOT_EXIST; - } - removeFromPosition(i); - if (*iter != begin()) { - (*iter)--; - } else { - *iter = begin(); - } - return HasReturnvaluesIF::RETURN_OK; + size_t i; + if ((i = findFirstIndex((*iter).value->first)) >= _size) { + return KEY_DOES_NOT_EXIST; + } + removeFromPosition(i); + if (*iter != begin()) { + (*iter)--; + } else { + *iter = begin(); + } + return HasReturnvaluesIF::RETURN_OK; } -template +template inline ReturnValue_t FixedOrderedMultimap::erase(key_t key) { - size_t i; - if ((i = findFirstIndex(key)) >= _size) { - return KEY_DOES_NOT_EXIST; - } - do { - removeFromPosition(i); - i = findFirstIndex(key, i); - } while (i < _size); - return HasReturnvaluesIF::RETURN_OK; + size_t i; + if ((i = findFirstIndex(key)) >= _size) { + return KEY_DOES_NOT_EXIST; + } + do { + removeFromPosition(i); + i = findFirstIndex(key, i); + } while (i < _size); + return HasReturnvaluesIF::RETURN_OK; } -template +template inline ReturnValue_t FixedOrderedMultimap::find(key_t key, T **value) const { - ReturnValue_t result = exists(key); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - *value = &theMap[findFirstIndex(key)].second; - return HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = exists(key); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + *value = &theMap[findFirstIndex(key)].second; + return HasReturnvaluesIF::RETURN_OK; } -template -inline size_t FixedOrderedMultimap::findFirstIndex(key_t key, size_t startAt) const { - if (startAt >= _size) { - return startAt + 1; +template +inline size_t FixedOrderedMultimap::findFirstIndex(key_t key, + size_t startAt) const { + if (startAt >= _size) { + return startAt + 1; + } + size_t i = startAt; + for (i = startAt; i < _size; ++i) { + if (theMap[i].first == key) { + return i; } - size_t i = startAt; - for (i = startAt; i < _size; ++i) { - if (theMap[i].first == key) { - return i; - } - } - return i; + } + return i; } -template +template inline size_t FixedOrderedMultimap::findNicePlace(key_t key) const { - size_t i = 0; - for (i = 0; i < _size; ++i) { - if (myComp(key, theMap[i].first)) { - return i; - } + size_t i = 0; + for (i = 0; i < _size; ++i) { + if (myComp(key, theMap[i].first)) { + return i; } - return i; + } + return i; } -template +template inline void FixedOrderedMultimap::removeFromPosition(size_t position) { - if (_size <= position) { - return; - } - memmove(static_cast(&theMap[position]), static_cast(&theMap[position + 1]), - (_size - position - 1) * sizeof(std::pair)); - --_size; + if (_size <= position) { + return; + } + memmove(static_cast(&theMap[position]), static_cast(&theMap[position + 1]), + (_size - position - 1) * sizeof(std::pair)); + --_size; } - #endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ */ diff --git a/src/fsfw/datapoollocal/LocalPoolVariable.tpp b/src/fsfw/datapoollocal/LocalPoolVariable.tpp index 9bb30611..f800dfd3 100644 --- a/src/fsfw/datapoollocal/LocalPoolVariable.tpp +++ b/src/fsfw/datapoollocal/LocalPoolVariable.tpp @@ -5,205 +5,189 @@ #error Include LocalPoolVariable.h before LocalPoolVariable.tpp! #endif -template -inline LocalPoolVariable::LocalPoolVariable(HasLocalDataPoolIF* hkOwner, - lp_id_t poolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode): - LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {} +template +inline LocalPoolVariable::LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId, + DataSetIF* dataSet, pool_rwm_t setReadWriteMode) + : LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {} -template -inline LocalPoolVariable::LocalPoolVariable(object_id_t poolOwner, - lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode): - LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {} +template +inline LocalPoolVariable::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId, + DataSetIF* dataSet, pool_rwm_t setReadWriteMode) + : LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {} +template +inline LocalPoolVariable::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet, + pool_rwm_t setReadWriteMode) + : LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet, + setReadWriteMode) {} -template -inline LocalPoolVariable::LocalPoolVariable(gp_id_t globalPoolId, - DataSetIF *dataSet, pool_rwm_t setReadWriteMode): - LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, - dataSet, setReadWriteMode){} - - -template -inline ReturnValue_t LocalPoolVariable::read( - MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - if(hkManager == nullptr) { - return readWithoutLock(); - } - MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager); - ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = readWithoutLock(); - mutex->unlockMutex(); +template +inline ReturnValue_t LocalPoolVariable::read(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + if (hkManager == nullptr) { + return readWithoutLock(); + } + MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager); + ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs); + if (result != HasReturnvaluesIF::RETURN_OK) { return result; + } + result = readWithoutLock(); + mutex->unlockMutex(); + return result; } -template +template inline ReturnValue_t LocalPoolVariable::readWithoutLock() { - if(readWriteMode == pool_rwm_t::VAR_WRITE) { - object_id_t targetObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVector", - PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId, - localPoolId); - return PoolVariableIF::INVALID_READ_WRITE_MODE; - } + if (readWriteMode == pool_rwm_t::VAR_WRITE) { + object_id_t targetObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, true, + targetObjectId, localPoolId); + return PoolVariableIF::INVALID_READ_WRITE_MODE; + } - PoolEntry* poolEntry = nullptr; - ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, - &poolEntry); - if(result != RETURN_OK) { - object_id_t ownerObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVariable", result, - false, ownerObjectId, localPoolId); - return result; - } - - this->value = *(poolEntry->getDataPtr()); - this->valid = poolEntry->getValid(); - return RETURN_OK; -} - -template -inline ReturnValue_t LocalPoolVariable::commit(bool setValid, - MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - this->setValid(setValid); - return commit(timeoutType, timeoutMs); -} - -template -inline ReturnValue_t LocalPoolVariable::commit( - MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - if(hkManager == nullptr) { - return commitWithoutLock(); - } - MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager); - ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - result = commitWithoutLock(); - mutex->unlockMutex(); + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = + LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry); + if (result != RETURN_OK) { + object_id_t ownerObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVariable", result, false, ownerObjectId, localPoolId); return result; + } + + this->value = *(poolEntry->getDataPtr()); + this->valid = poolEntry->getValid(); + return RETURN_OK; } -template +template +inline ReturnValue_t LocalPoolVariable::commit(bool setValid, MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + this->setValid(setValid); + return commit(timeoutType, timeoutMs); +} + +template +inline ReturnValue_t LocalPoolVariable::commit(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + if (hkManager == nullptr) { + return commitWithoutLock(); + } + MutexIF* mutex = LocalDpManagerAttorney::getMutexHandle(*hkManager); + ReturnValue_t result = mutex->lockMutex(timeoutType, timeoutMs); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commitWithoutLock(); + mutex->unlockMutex(); + return result; +} + +template inline ReturnValue_t LocalPoolVariable::commitWithoutLock() { - if(readWriteMode == pool_rwm_t::VAR_READ) { - object_id_t targetObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVector", - PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId, - localPoolId); - return PoolVariableIF::INVALID_READ_WRITE_MODE; - } + if (readWriteMode == pool_rwm_t::VAR_READ) { + object_id_t targetObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, false, + targetObjectId, localPoolId); + return PoolVariableIF::INVALID_READ_WRITE_MODE; + } - PoolEntry* poolEntry = nullptr; - ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, - &poolEntry); - if(result != RETURN_OK) { - object_id_t ownerObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVariable", result, - false, ownerObjectId, localPoolId); - return result; - } + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = + LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry); + if (result != RETURN_OK) { + object_id_t ownerObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVariable", result, false, ownerObjectId, localPoolId); + return result; + } - *(poolEntry->getDataPtr()) = this->value; - poolEntry->setValid(this->valid); - return RETURN_OK; + *(poolEntry->getDataPtr()) = this->value; + poolEntry->setValid(this->valid); + return RETURN_OK; } -template -inline ReturnValue_t LocalPoolVariable::serialize(uint8_t** buffer, - size_t* size, const size_t max_size, - SerializeIF::Endianness streamEndianness) const { - return SerializeAdapter::serialize(&value, - buffer, size ,max_size, streamEndianness); +template +inline ReturnValue_t LocalPoolVariable::serialize( + uint8_t** buffer, size_t* size, const size_t max_size, + SerializeIF::Endianness streamEndianness) const { + return SerializeAdapter::serialize(&value, buffer, size, max_size, streamEndianness); } -template +template inline size_t LocalPoolVariable::getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&value); + return SerializeAdapter::getSerializedSize(&value); } -template -inline ReturnValue_t LocalPoolVariable::deSerialize(const uint8_t** buffer, - size_t* size, SerializeIF::Endianness streamEndianness) { - return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); +template +inline ReturnValue_t LocalPoolVariable::deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); } #if FSFW_CPP_OSTREAM_ENABLED == 1 -template -inline std::ostream& operator<< (std::ostream &out, - const LocalPoolVariable &var) { - out << var.value; - return out; +template +inline std::ostream& operator<<(std::ostream& out, const LocalPoolVariable& var) { + out << var.value; + return out; } #endif -template +template inline LocalPoolVariable::operator T() const { - return value; + return value; } -template -inline LocalPoolVariable & LocalPoolVariable::operator=( - const T& newValue) { - value = newValue; - return *this; +template +inline LocalPoolVariable& LocalPoolVariable::operator=(const T& newValue) { + value = newValue; + return *this; } -template -inline LocalPoolVariable& LocalPoolVariable::operator =( - const LocalPoolVariable& newPoolVariable) { - value = newPoolVariable.value; - return *this; +template +inline LocalPoolVariable& LocalPoolVariable::operator=( + const LocalPoolVariable& newPoolVariable) { + value = newPoolVariable.value; + return *this; } -template -inline bool LocalPoolVariable::operator ==( - const LocalPoolVariable &other) const { - return this->value == other.value; +template +inline bool LocalPoolVariable::operator==(const LocalPoolVariable& other) const { + return this->value == other.value; } -template -inline bool LocalPoolVariable::operator ==(const T &other) const { - return this->value == other; +template +inline bool LocalPoolVariable::operator==(const T& other) const { + return this->value == other; } - -template -inline bool LocalPoolVariable::operator !=( - const LocalPoolVariable &other) const { - return not (*this == other); +template +inline bool LocalPoolVariable::operator!=(const LocalPoolVariable& other) const { + return not(*this == other); } -template -inline bool LocalPoolVariable::operator !=(const T &other) const { - return not (*this == other); +template +inline bool LocalPoolVariable::operator!=(const T& other) const { + return not(*this == other); } - -template -inline bool LocalPoolVariable::operator <( - const LocalPoolVariable &other) const { - return this->value < other.value; +template +inline bool LocalPoolVariable::operator<(const LocalPoolVariable& other) const { + return this->value < other.value; } -template -inline bool LocalPoolVariable::operator <(const T &other) const { - return this->value < other; +template +inline bool LocalPoolVariable::operator<(const T& other) const { + return this->value < other; } - -template -inline bool LocalPoolVariable::operator >( - const LocalPoolVariable &other) const { - return not (*this < other); +template +inline bool LocalPoolVariable::operator>(const LocalPoolVariable& other) const { + return not(*this < other); } -template -inline bool LocalPoolVariable::operator >(const T &other) const { - return not (*this < other); +template +inline bool LocalPoolVariable::operator>(const T& other) const { + return not(*this < other); } #endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ */ diff --git a/src/fsfw/datapoollocal/LocalPoolVector.tpp b/src/fsfw/datapoollocal/LocalPoolVector.tpp index 044b8fa7..a2c2b752 100644 --- a/src/fsfw/datapoollocal/LocalPoolVector.tpp +++ b/src/fsfw/datapoollocal/LocalPoolVector.tpp @@ -5,174 +5,172 @@ #error Include LocalPoolVector.h before LocalPoolVector.tpp! #endif -template -inline LocalPoolVector::LocalPoolVector( - HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet, - pool_rwm_t setReadWriteMode): - LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {} +template +inline LocalPoolVector::LocalPoolVector(HasLocalDataPoolIF* hkOwner, lp_id_t poolId, + DataSetIF* dataSet, + pool_rwm_t setReadWriteMode) + : LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {} -template -inline LocalPoolVector::LocalPoolVector(object_id_t poolOwner, - lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode): - LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {} +template +inline LocalPoolVector::LocalPoolVector(object_id_t poolOwner, lp_id_t poolId, + DataSetIF* dataSet, + pool_rwm_t setReadWriteMode) + : LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {} -template -inline LocalPoolVector::LocalPoolVector(gp_id_t globalPoolId, - DataSetIF *dataSet, pool_rwm_t setReadWriteMode): - LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, - dataSet, setReadWriteMode) {} +template +inline LocalPoolVector::LocalPoolVector(gp_id_t globalPoolId, DataSetIF* dataSet, + pool_rwm_t setReadWriteMode) + : LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet, + setReadWriteMode) {} -template -inline ReturnValue_t LocalPoolVector::read( - MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); - return readWithoutLock(); +template +inline ReturnValue_t LocalPoolVector::read(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); + return readWithoutLock(); } -template +template inline ReturnValue_t LocalPoolVector::readWithoutLock() { - if(readWriteMode == pool_rwm_t::VAR_WRITE) { - object_id_t targetObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVector", - PoolVariableIF::INVALID_READ_WRITE_MODE, true, targetObjectId, - localPoolId); - return PoolVariableIF::INVALID_READ_WRITE_MODE; - } + if (readWriteMode == pool_rwm_t::VAR_WRITE) { + object_id_t targetObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, true, + targetObjectId, localPoolId); + return PoolVariableIF::INVALID_READ_WRITE_MODE; + } - PoolEntry* poolEntry = nullptr; - ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, - &poolEntry); - memset(this->value, 0, vectorSize * sizeof(T)); + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = + LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry); + memset(this->value, 0, vectorSize * sizeof(T)); - if(result != RETURN_OK) { - object_id_t targetObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVector", result, true, targetObjectId, - localPoolId); - return result; - } - std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize()); - this->valid = poolEntry->getValid(); - return RETURN_OK; + if (result != RETURN_OK) { + object_id_t targetObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVector", result, true, targetObjectId, localPoolId); + return result; + } + std::memcpy(this->value, poolEntry->getDataPtr(), poolEntry->getByteSize()); + this->valid = poolEntry->getValid(); + return RETURN_OK; } -template +template inline ReturnValue_t LocalPoolVector::commit(bool valid, - MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - this->setValid(valid); - return commit(timeoutType, timeoutMs); + MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + this->setValid(valid); + return commit(timeoutType, timeoutMs); } -template -inline ReturnValue_t LocalPoolVector::commit( - MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) { - MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); - return commitWithoutLock(); +template +inline ReturnValue_t LocalPoolVector::commit(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + MutexGuard(LocalDpManagerAttorney::getMutexHandle(*hkManager), timeoutType, timeoutMs); + return commitWithoutLock(); } -template +template inline ReturnValue_t LocalPoolVector::commitWithoutLock() { - if(readWriteMode == pool_rwm_t::VAR_READ) { - object_id_t targetObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVector", - PoolVariableIF::INVALID_READ_WRITE_MODE, false, targetObjectId, - localPoolId); - return PoolVariableIF::INVALID_READ_WRITE_MODE; - } - PoolEntry* poolEntry = nullptr; - ReturnValue_t result = LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, - &poolEntry); - if(result != RETURN_OK) { - object_id_t targetObjectId = hkManager->getCreatorObjectId(); - reportReadCommitError("LocalPoolVector", result, false, targetObjectId, - localPoolId); - return result; - } - std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize()); - poolEntry->setValid(this->valid); - return RETURN_OK; -} - -template -inline T& LocalPoolVector::operator [](size_t i) { - if(i < vectorSize) { - return value[i]; - } - // If this happens, I have to set some value. I consider this - // a configuration error, but I wont exit here. -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "LocalPoolVector: Invalid index. Setting or returning" - " last value!" << std::endl; -#else - sif::printWarning("LocalPoolVector: Invalid index. Setting or returning" - " last value!\n"); -#endif - return value[vectorSize - 1]; -} - -template -inline const T& LocalPoolVector::operator [](size_t i) const { - if(i < vectorSize) { - return value[i]; - } - // If this happens, I have to set some value. I consider this - // a configuration error, but I wont exit here. -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "LocalPoolVector: Invalid index. Setting or returning" - " last value!" << std::endl; -#else - sif::printWarning("LocalPoolVector: Invalid index. Setting or returning" - " last value!\n"); -#endif - return value[vectorSize - 1]; -} - -template -inline ReturnValue_t LocalPoolVector::serialize(uint8_t** buffer, - size_t* size, size_t maxSize, - SerializeIF::Endianness streamEndianness) const { - ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; - for (uint16_t i = 0; i < vectorSize; i++) { - result = SerializeAdapter::serialize(&(value[i]), buffer, size, - maxSize, streamEndianness); - if (result != HasReturnvaluesIF::RETURN_OK) { - break; - } - } + if (readWriteMode == pool_rwm_t::VAR_READ) { + object_id_t targetObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVector", PoolVariableIF::INVALID_READ_WRITE_MODE, false, + targetObjectId, localPoolId); + return PoolVariableIF::INVALID_READ_WRITE_MODE; + } + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = + LocalDpManagerAttorney::fetchPoolEntry(*hkManager, localPoolId, &poolEntry); + if (result != RETURN_OK) { + object_id_t targetObjectId = hkManager->getCreatorObjectId(); + reportReadCommitError("LocalPoolVector", result, false, targetObjectId, localPoolId); return result; + } + std::memcpy(poolEntry->getDataPtr(), this->value, poolEntry->getByteSize()); + poolEntry->setValid(this->valid); + return RETURN_OK; } -template +template +inline T& LocalPoolVector::operator[](size_t i) { + if (i < vectorSize) { + return value[i]; + } + // If this happens, I have to set some value. I consider this + // a configuration error, but I wont exit here. +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "LocalPoolVector: Invalid index. Setting or returning" + " last value!" + << std::endl; +#else + sif::printWarning( + "LocalPoolVector: Invalid index. Setting or returning" + " last value!\n"); +#endif + return value[vectorSize - 1]; +} + +template +inline const T& LocalPoolVector::operator[](size_t i) const { + if (i < vectorSize) { + return value[i]; + } + // If this happens, I have to set some value. I consider this + // a configuration error, but I wont exit here. +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "LocalPoolVector: Invalid index. Setting or returning" + " last value!" + << std::endl; +#else + sif::printWarning( + "LocalPoolVector: Invalid index. Setting or returning" + " last value!\n"); +#endif + return value[vectorSize - 1]; +} + +template +inline ReturnValue_t LocalPoolVector::serialize( + uint8_t** buffer, size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + for (uint16_t i = 0; i < vectorSize; i++) { + result = SerializeAdapter::serialize(&(value[i]), buffer, size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; + } + } + return result; +} + +template inline size_t LocalPoolVector::getSerializedSize() const { - return vectorSize * SerializeAdapter::getSerializedSize(value); + return vectorSize * SerializeAdapter::getSerializedSize(value); } -template +template inline ReturnValue_t LocalPoolVector::deSerialize( - const uint8_t** buffer, size_t* size, - SerializeIF::Endianness streamEndianness) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; - for (uint16_t i = 0; i < vectorSize; i++) { - result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, - streamEndianness); - if (result != HasReturnvaluesIF::RETURN_OK) { - break; - } + const uint8_t** buffer, size_t* size, SerializeIF::Endianness streamEndianness) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + for (uint16_t i = 0; i < vectorSize; i++) { + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; } - return result; + } + return result; } #if FSFW_CPP_OSTREAM_ENABLED == 1 -template -inline std::ostream& operator<< (std::ostream &out, - const LocalPoolVector &var) { - out << "Vector: ["; - for(int i = 0;i < vectorSize; i++) { - out << var.value[i]; - if(i < vectorSize - 1) { - out << ", "; - } +template +inline std::ostream& operator<<(std::ostream& out, const LocalPoolVector& var) { + out << "Vector: ["; + for (int i = 0; i < vectorSize; i++) { + out << var.value[i]; + if (i < vectorSize - 1) { + out << ", "; } - out << "]"; - return out; + } + out << "]"; + return out; } #endif diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index 24ce4af1..9f47dfc6 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -59,14 +59,13 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; -/** + /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. * @param object pointer to the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(ExecutableObjectIF* object) override; - + ReturnValue_t addComponent(ExecutableObjectIF *object) override; uint32_t getPeriodMs() const override; diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 926e465f..e4a62002 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -1,8 +1,9 @@ #include "version.h" -#include "fsfw/FSFWVersion.h" #include +#include "fsfw/FSFWVersion.h" + #ifdef major #undef major #endif diff --git a/src/fsfw/version.h b/src/fsfw/version.h index 7cddf193..bb4d0399 100644 --- a/src/fsfw/version.h +++ b/src/fsfw/version.h @@ -29,7 +29,7 @@ class Version { } friend bool operator>(const Version& v1, const Version& v2) { - return not (v1 < v2) and not (v1 == v2); + return not(v1 < v2) and not(v1 == v2); } friend bool operator<=(const Version& v1, const Version& v2) { return ((v1 == v2) or (v1 < v2)); } diff --git a/tests/src/fsfw_tests/unit/version.cpp b/tests/src/fsfw_tests/unit/version.cpp index 92a930dc..2967dfa5 100644 --- a/tests/src/fsfw_tests/unit/version.cpp +++ b/tests/src/fsfw_tests/unit/version.cpp @@ -17,15 +17,15 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { fsfw::Version v1 = fsfw::Version(1, 1, 1); fsfw::Version v2 = fsfw::Version(1, 1, 1); REQUIRE(v1 == v2); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 > v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 > v2)); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); v1.revision -= 1; REQUIRE(v1 != v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); v1.revision += 1; @@ -33,60 +33,60 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.minor += 1; v1.major -= 1; REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.major += 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 < v2)); + REQUIRE(not(v1 != v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 < v2)); v1.major += 1; v1.minor -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.major -= 1; v1.minor += 2; v1.revision -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.minor -= 1; v1.revision += 2; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.revision -= 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); + REQUIRE(not(v1 != v2)); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "v" << fsfw::FSFW_VERSION << std::endl; #endif char verString[10] = {}; fsfw::FSFW_VERSION.getVersion(verString, sizeof(verString)); #if FSFW_DISABLE_PRINTOUT == 0 - printf("v%s\n",verString); + printf("v%s\n", verString); #endif } From 6c1db8473bdd7639065e230341d52007c58ecf49 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 31 Mar 2022 14:36:45 +0200 Subject: [PATCH 025/198] get alternative reply from device command info --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 31 ++++++++++++++----- src/fsfw/devicehandlers/DeviceHandlerBase.h | 6 +++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 08a15d5f..0e2802ac 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -410,7 +410,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet, size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) { // No need to check, as we may try to insert multiple times. - insertInCommandMap(deviceCommand); + insertInCommandMap(deviceCommand, hasDifferentReplyId, replyId); if (hasDifferentReplyId) { return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic); } else { @@ -437,11 +437,15 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, } } -ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) { +ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand, + bool useAlternativeReply, + DeviceCommandId_t alternativeReplyId) { DeviceCommandInfo info; info.expectedReplies = 0; info.isExecuting = false; info.sendReplyTo = NO_COMMANDER; + info.useAlternativeReplyId = alternativeReplyId; + info.alternativeReplyId = alternativeReplyId; auto resultPair = deviceCommandMap.emplace(deviceCommand, info); if (resultPair.second) { return RETURN_OK; @@ -451,12 +455,21 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm } size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) { - DeviceReplyIter iter = deviceReplyMap.find(commandId); - if (iter != deviceReplyMap.end()) { - return iter->second.replyLen; - } else { - return 0; + DeviceCommandId_t replyId = NO_COMMAND_ID; + DeviceCommandMap::iterator command = cookieInfo.pendingCommand; + if (command->second.useAlternativeReplyId) { + replyId = command->second.alternativeReplyId; } + else { + replyId = commandId; + } + DeviceReplyIter iter = deviceReplyMap.find(replyId); + if (iter != deviceReplyMap.end()) { + if (iter->second.delayCycles != 0) { + return iter->second.replyLen; + } + } + return 0; } ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, @@ -651,7 +664,9 @@ void DeviceHandlerBase::doGetWrite() { // We need to distinguish here, because a raw command never expects a reply. //(Could be done in eRIRM, but then child implementations need to be careful. - result = enableReplyInReplyMap(cookieInfo.pendingCommand); + DeviceCommandMap::iterator command = cookieInfo.pendingCommand; + result = enableReplyInReplyMap(command, 1, command->second.useAlternativeReplyId, + command->second.alternativeReplyId); } else { // always generate a failure event, so that FDIR knows what's up triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first); diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index c8b8b86d..5e974831 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -478,7 +478,9 @@ class DeviceHandlerBase : public DeviceHandlerIF, * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ - ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); + ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand, + bool useAlternativeReply = false, + DeviceCommandId_t alternativeReplyId = 0); /** * Enables a periodic reply for a given command. It sets to delay cycles to the specified @@ -751,6 +753,8 @@ class DeviceHandlerBase : public DeviceHandlerIF, //! if this is != NO_COMMANDER, DHB was commanded externally and shall //! report everything to commander. MessageQueueId_t sendReplyTo; + bool useAlternativeReplyId; + DeviceCommandId_t alternativeReplyId; }; using DeviceCommandMap = std::map; /** From c20be13733b0731c30c1d44eb08caf5e5862eb06 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Apr 2022 16:40:13 +0200 Subject: [PATCH 026/198] change switch type in header as well --- src/fsfw/power/PowerSwitcher.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fsfw/power/PowerSwitcher.h b/src/fsfw/power/PowerSwitcher.h index 853bbb40..279ffacf 100644 --- a/src/fsfw/power/PowerSwitcher.h +++ b/src/fsfw/power/PowerSwitcher.h @@ -18,7 +18,8 @@ class PowerSwitcher : public HasReturnvaluesIF { static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER; static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1); static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2); - PowerSwitcher(PowerSwitchIF* switcher, uint8_t setSwitch1, uint8_t setSwitch2 = power::NO_SWITCH, + PowerSwitcher(PowerSwitchIF* switcher, power::Switch_t setSwitch1, + power::Switch_t setSwitch2 = power::NO_SWITCH, State_t setStartState = SWITCH_IS_OFF); void turnOn(bool checkCurrentState = true); void turnOff(bool checkCurrentState = true); From c7daf697a89871dd5a641404d5e7de2369083fd0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Apr 2022 17:27:53 +0200 Subject: [PATCH 027/198] add new power switcher component --- src/fsfw/power/CMakeLists.txt | 1 + src/fsfw/power/PowerSwitcherComponent.cpp | 108 ++++++++++++++++++++++ src/fsfw/power/PowerSwitcherComponent.h | 64 +++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 src/fsfw/power/PowerSwitcherComponent.cpp create mode 100644 src/fsfw/power/PowerSwitcherComponent.h diff --git a/src/fsfw/power/CMakeLists.txt b/src/fsfw/power/CMakeLists.txt index 10e4a44d..e195b1c0 100644 --- a/src/fsfw/power/CMakeLists.txt +++ b/src/fsfw/power/CMakeLists.txt @@ -4,4 +4,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE PowerSensor.cpp PowerSwitcher.cpp DummyPowerSwitcher.cpp + PowerSwitcherComponent.cpp ) \ No newline at end of file diff --git a/src/fsfw/power/PowerSwitcherComponent.cpp b/src/fsfw/power/PowerSwitcherComponent.cpp new file mode 100644 index 00000000..5dda02c3 --- /dev/null +++ b/src/fsfw/power/PowerSwitcherComponent.cpp @@ -0,0 +1,108 @@ +#include "PowerSwitcherComponent.h" + +#include +#include + +PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t pwrSwitch) + : SystemObject(objectId), switcher(pwrSwitcher, pwrSwitch), modeHelper(this), + healthHelper(this, objectId) { + queue = QueueFactory::instance()->createMessageQueue(); +} + +ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) { + ReturnValue_t result; + CommandMessage command; + + for (result = queue->receiveMessage(&command); result == RETURN_OK; + result = queue->receiveMessage(&command)) { + result = healthHelper.handleHealthCommand(&command); + if (result == RETURN_OK) { + continue; + } + + result = modeHelper.handleModeCommand(&command); + if (result == RETURN_OK) { + continue; + } + } + if(switcher.active()) { + switcher.doStateMachine(); + auto currState = switcher.getState(); + if (currState == PowerSwitcher::SWITCH_IS_OFF) { + setMode(MODE_OFF, 0); + } else if(currState == PowerSwitcher::SWITCH_IS_ON) { + setMode(MODE_ON, 0); + } + } + return RETURN_OK; +} + +ReturnValue_t PowerSwitcherComponent::initialize() { + ReturnValue_t result = modeHelper.initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = healthHelper.initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return SystemObject::initialize(); +} + +MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { + return queue->getId(); +} + +void PowerSwitcherComponent::getMode(Mode_t *mode, Submode_t *submode) { + *mode = this->mode; + *submode = this->submode; +} + +ReturnValue_t PowerSwitcherComponent::setHealth(HealthState health) { + healthHelper.setHealth(health); + return RETURN_OK; +} + +ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t *msToReachTheMode) { + *msToReachTheMode = 5000; + if(mode != MODE_ON and mode != MODE_OFF) { + return TRANS_NOT_ALLOWED; + } + return RETURN_OK; +} + +void PowerSwitcherComponent::startTransition(Mode_t mode, Submode_t submode) { + if(mode == MODE_OFF) { + switcher.turnOff(true); + switcher.doStateMachine(); + if(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) { + setMode(MODE_OFF, 0); + } + } else if (mode == MODE_ON) { + switcher.turnOn(true); + switcher.doStateMachine(); + if(switcher.getState() == PowerSwitcher::SWITCH_IS_ON) { + setMode(MODE_ON, 0); + } + } +} + +void PowerSwitcherComponent::setToExternalControl() { + healthHelper.setHealth(HasHealthIF::EXTERNAL_CONTROL); +} + +void PowerSwitcherComponent::announceMode(bool recursive) { + triggerEvent(MODE_INFO, mode, submode); +} + +void PowerSwitcherComponent::setMode(Mode_t newMode, Submode_t newSubmode) { + this->mode = newMode; + this->submode = newSubmode; + modeHelper.modeChanged(mode, submode); + announceMode(false); +} + +HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { + return healthHelper.getHealth(); +} diff --git a/src/fsfw/power/PowerSwitcherComponent.h b/src/fsfw/power/PowerSwitcherComponent.h new file mode 100644 index 00000000..3a075c12 --- /dev/null +++ b/src/fsfw/power/PowerSwitcherComponent.h @@ -0,0 +1,64 @@ +#ifndef _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ +#define _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +class PowerSwitchIF; + +/** + * @brief Allows to create an power switch object with its own mode and health + * @details + * This basic component allows to create an object which is solely responsible for managing a + * switch. It also has a mode and a health by implementing the respective interface components + * which allows integrating this component into a system mode tree. + * + * Commanding this component to MODE_OFF will cause the switcher to turn the switch off while + * commanding in to MODE_ON will cause the switcher to turn the switch on. + */ +class PowerSwitcherComponent: + public SystemObject, + public HasReturnvaluesIF, + public ExecutableObjectIF, + public HasModesIF, + public HasHealthIF { +public: + PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher, + power::Switch_t pwrSwitch); + +private: + + MessageQueueIF* queue = nullptr; + PowerSwitcher switcher; + + Mode_t mode = MODE_OFF; + Submode_t submode = 0; + + ModeHelper modeHelper; + HealthHelper healthHelper; + + void setMode(Mode_t newMode, Submode_t newSubmode); + + virtual ReturnValue_t performOperation(uint8_t opCode) override; + + ReturnValue_t initialize() override; + + MessageQueueId_t getCommandQueue() const override; + void getMode(Mode_t *mode, Submode_t *submode) override; + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t *msToReachTheMode) override; + void startTransition(Mode_t mode, Submode_t submode) override; + void setToExternalControl() override; + void announceMode(bool recursive) override; + + ReturnValue_t setHealth(HealthState health) override; + HasHealthIF::HealthState getHealth() override; +}; + +#endif /* _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ */ From 738f5720432cefb5a40292491babb6cd5d829010 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Apr 2022 18:38:25 +0200 Subject: [PATCH 028/198] added unit tests, minor API change --- src/fsfw/power/DummyPowerSwitcher.cpp | 5 +- src/fsfw/power/DummyPowerSwitcher.h | 2 +- tests/src/fsfw_tests/unit/CMakeLists.txt | 3 + .../src/fsfw_tests/unit/mocks/CMakeLists.txt | 3 + .../unit/mocks/PowerSwitcherMock.cpp | 77 +++++++++++++++++++ .../fsfw_tests/unit/mocks/PowerSwitcherMock.h | 52 +++++++++++++ .../src/fsfw_tests/unit/power/CMakeLists.txt | 3 + .../unit/power/testPowerSwitcher.cpp | 66 ++++++++++++++++ .../unit/testcfg/objects/systemObjectList.h | 3 +- 9 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 tests/src/fsfw_tests/unit/mocks/CMakeLists.txt create mode 100644 tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.cpp create mode 100644 tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.h create mode 100644 tests/src/fsfw_tests/unit/power/CMakeLists.txt create mode 100644 tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp diff --git a/src/fsfw/power/DummyPowerSwitcher.cpp b/src/fsfw/power/DummyPowerSwitcher.cpp index d0a87288..799d49aa 100644 --- a/src/fsfw/power/DummyPowerSwitcher.cpp +++ b/src/fsfw/power/DummyPowerSwitcher.cpp @@ -1,8 +1,9 @@ #include "DummyPowerSwitcher.h" DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches, - size_t numberOfFuses, uint32_t switchDelayMs) - : SystemObject(objectId), + size_t numberOfFuses, bool registerGlobally, + uint32_t switchDelayMs) + : SystemObject(objectId, registerGlobally), switcherList(numberOfSwitches), fuseList(numberOfFuses), switchDelayMs(switchDelayMs) {} diff --git a/src/fsfw/power/DummyPowerSwitcher.h b/src/fsfw/power/DummyPowerSwitcher.h index 24e9d648..b2dd40d5 100644 --- a/src/fsfw/power/DummyPowerSwitcher.h +++ b/src/fsfw/power/DummyPowerSwitcher.h @@ -11,7 +11,7 @@ class DummyPowerSwitcher : public SystemObject, public PowerSwitchIF { public: DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches, size_t numberOfFuses, - uint32_t switchDelayMs = 5000); + bool registerGlobally = true, uint32_t switchDelayMs = 5000); void setInitialSwitcherList(std::vector switcherList); void setInitialFusesList(std::vector switcherList); diff --git a/tests/src/fsfw_tests/unit/CMakeLists.txt b/tests/src/fsfw_tests/unit/CMakeLists.txt index a8d31d88..b5143c3b 100644 --- a/tests/src/fsfw_tests/unit/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/CMakeLists.txt @@ -11,7 +11,10 @@ target_sources(${FSFW_TEST_TGT} PRIVATE ) add_subdirectory(testcfg) +add_subdirectory(mocks) + add_subdirectory(action) +add_subdirectory(power) add_subdirectory(container) add_subdirectory(osal) add_subdirectory(serialize) diff --git a/tests/src/fsfw_tests/unit/mocks/CMakeLists.txt b/tests/src/fsfw_tests/unit/mocks/CMakeLists.txt new file mode 100644 index 00000000..1b86547c --- /dev/null +++ b/tests/src/fsfw_tests/unit/mocks/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(${FSFW_TEST_TGT} PRIVATE + PowerSwitcherMock.cpp +) diff --git a/tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.cpp b/tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.cpp new file mode 100644 index 00000000..5c6935e4 --- /dev/null +++ b/tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.cpp @@ -0,0 +1,77 @@ +#include "PowerSwitcherMock.h" + +static uint32_t SWITCH_REQUEST_UPDATE_VALUE = 0; + +PowerSwitcherMock::PowerSwitcherMock() {} + +ReturnValue_t PowerSwitcherMock::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) { + if (switchMap.count(switchNr) == 0) { + switchMap.emplace(switchNr, SwitchInfo(switchNr, onOff)); + } else { + SwitchInfo& info = switchMap.at(switchNr); + info.currentState = onOff; + if (onOff == PowerSwitchIF::SWITCH_ON) { + info.timesCalledOn++; + } else { + info.timesCalledOff++; + } + } + return RETURN_OK; +} + +ReturnValue_t PowerSwitcherMock::sendFuseOnCommand(uint8_t fuseNr) { + if (fuseMap.count(fuseNr) == 0) { + fuseMap.emplace(fuseNr, FuseInfo(fuseNr)); + } else { + FuseInfo& info = fuseMap.at(fuseNr); + info.timesCalled++; + } + return RETURN_OK; +} + +ReturnValue_t PowerSwitcherMock::getSwitchState(power::Switch_t switchNr) const { + if (switchMap.count(switchNr) == 1) { + auto& info = switchMap.at(switchNr); + SWITCH_REQUEST_UPDATE_VALUE++; + return info.currentState; + } + return RETURN_FAILED; +} + +ReturnValue_t PowerSwitcherMock::getFuseState(uint8_t fuseNr) const { + if (fuseMap.count(fuseNr) == 1) { + return FUSE_ON; + } else { + return FUSE_OFF; + } + return RETURN_FAILED; +} + +uint32_t PowerSwitcherMock::getSwitchDelayMs(void) const { return 5000; } + +SwitchInfo::SwitchInfo() : switcher(0) {} + +SwitchInfo::SwitchInfo(power::Switch_t switcher, ReturnValue_t initState) + : switcher(switcher), currentState(initState) {} + +FuseInfo::FuseInfo(uint8_t fuse) : fuse(fuse) {} + +void PowerSwitcherMock::getSwitchInfo(power::Switch_t switcher, SwitchInfo& info) { + if (switchMap.count(switcher) == 1) { + info = switchMap.at(switcher); + } +} + +void PowerSwitcherMock::getFuseInfo(uint8_t fuse, FuseInfo& info) { + if (fuseMap.count(fuse) == 1) { + info = fuseMap.at(fuse); + } +} + +uint32_t PowerSwitcherMock::getAmountSwitchStatWasRequested() { + return SWITCH_REQUEST_UPDATE_VALUE; +} + +void PowerSwitcherMock::initSwitch(power::Switch_t switchNr) { + switchMap.emplace(switchNr, SwitchInfo(switchNr, PowerSwitchIF::SWITCH_OFF)); +} diff --git a/tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.h b/tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.h new file mode 100644 index 00000000..3a740e66 --- /dev/null +++ b/tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.h @@ -0,0 +1,52 @@ +#ifndef FSFW_TESTS_SRC_FSFW_TESTS_UNIT_MOCKS_POWERSWITCHERMOCK_H_ +#define FSFW_TESTS_SRC_FSFW_TESTS_UNIT_MOCKS_POWERSWITCHERMOCK_H_ + +#include + +#include +#include + +struct SwitchInfo { + public: + SwitchInfo(); + SwitchInfo(power::Switch_t switcher, ReturnValue_t initState); + + power::Switch_t switcher; + ReturnValue_t currentState = PowerSwitchIF::SWITCH_OFF; + uint32_t timesCalledOn = 0; + uint32_t timesCalledOff = 0; + uint32_t timesStatusRequested = 0; +}; + +struct FuseInfo { + public: + FuseInfo(uint8_t fuse); + uint8_t fuse; + uint32_t timesCalled = 0; +}; + +class PowerSwitcherMock : public PowerSwitchIF { + public: + PowerSwitcherMock(); + + ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override; + ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override; + ReturnValue_t getSwitchState(power::Switch_t switchNr) const override; + ReturnValue_t getFuseState(uint8_t fuseNr) const override; + uint32_t getSwitchDelayMs(void) const override; + + void getSwitchInfo(power::Switch_t switcher, SwitchInfo& info); + void getFuseInfo(uint8_t fuse, FuseInfo& info); + + uint32_t getAmountSwitchStatWasRequested(); + + void initSwitch(power::Switch_t switchNr); + + private: + using SwitchOnOffPair = std::pair; + using FuseOnOffPair = std::pair; + std::map switchMap; + std::map fuseMap; +}; + +#endif /* FSFW_TESTS_SRC_FSFW_TESTS_UNIT_MOCKS_POWERSWITCHERMOCK_H_ */ diff --git a/tests/src/fsfw_tests/unit/power/CMakeLists.txt b/tests/src/fsfw_tests/unit/power/CMakeLists.txt new file mode 100644 index 00000000..667e6f51 --- /dev/null +++ b/tests/src/fsfw_tests/unit/power/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(${FSFW_TEST_TGT} PRIVATE + testPowerSwitcher.cpp +) diff --git a/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp new file mode 100644 index 00000000..c368729d --- /dev/null +++ b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +#include + +#include "objects/systemObjectList.h" + +TEST_CASE("Power Switcher", "[power-switcher]") { + PowerSwitcherMock mock; + PowerSwitcher switcher(&mock, 1); + DummyPowerSwitcher dummySwitcher(objects::DUMMY_POWER_SWITCHER, 5, 5, false); + PowerSwitcher switcherUsingDummy(&dummySwitcher, 1); + SwitchInfo switchInfo; + mock.initSwitch(1); + + SECTION("Basic Tests") { + REQUIRE(switcher.getFirstSwitch() == 1); + REQUIRE(switcher.getSecondSwitch() == power::NO_SWITCH); + // Default start state + REQUIRE(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF); + switcher.turnOn(true); + REQUIRE(mock.getAmountSwitchStatWasRequested() == 1); + REQUIRE(switcher.getState() == PowerSwitcher::WAIT_ON); + REQUIRE(switcher.active()); + switcher.doStateMachine(); + REQUIRE(switcher.getState() == PowerSwitcher::SWITCH_IS_ON); + mock.getSwitchInfo(1, switchInfo); + REQUIRE(switchInfo.timesCalledOn == 1); + REQUIRE(not switcher.active()); + REQUIRE(mock.getAmountSwitchStatWasRequested() == 2); + switcher.turnOff(false); + REQUIRE(mock.getAmountSwitchStatWasRequested() == 2); + REQUIRE(switcher.getState() == PowerSwitcher::WAIT_OFF); + REQUIRE(switcher.active()); + REQUIRE(switcher.getState() == PowerSwitcher::WAIT_OFF); + switcher.doStateMachine(); + mock.getSwitchInfo(1, switchInfo); + REQUIRE(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF); + REQUIRE(switchInfo.timesCalledOn == 1); + REQUIRE(switchInfo.timesCalledOff == 1); + REQUIRE(not switcher.active()); + REQUIRE(mock.getAmountSwitchStatWasRequested() == 3); + } + + SECTION("Dummy Test") { + // Same tests, but we can't really check the dummy + REQUIRE(switcherUsingDummy.getFirstSwitch() == 1); + REQUIRE(switcherUsingDummy.getSecondSwitch() == power::NO_SWITCH); + REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::SWITCH_IS_OFF); + switcherUsingDummy.turnOn(true); + REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::WAIT_ON); + REQUIRE(switcherUsingDummy.active()); + switcherUsingDummy.doStateMachine(); + REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::SWITCH_IS_ON); + REQUIRE(not switcherUsingDummy.active()); + + switcherUsingDummy.turnOff(false); + REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::WAIT_OFF); + REQUIRE(switcherUsingDummy.active()); + REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::WAIT_OFF); + switcherUsingDummy.doStateMachine(); + REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::SWITCH_IS_OFF); + REQUIRE(not switcherUsingDummy.active()); + } +} diff --git a/tests/src/fsfw_tests/unit/testcfg/objects/systemObjectList.h b/tests/src/fsfw_tests/unit/testcfg/objects/systemObjectList.h index 3eba1484..3fcd8368 100644 --- a/tests/src/fsfw_tests/unit/testcfg/objects/systemObjectList.h +++ b/tests/src/fsfw_tests/unit/testcfg/objects/systemObjectList.h @@ -21,8 +21,9 @@ enum sourceObjects : uint32_t { HK_RECEIVER_MOCK = 22, TEST_LOCAL_POOL_OWNER_BASE = 25, - SHARED_SET_ID = 26 + SHARED_SET_ID = 26, + DUMMY_POWER_SWITCHER = 27 }; } From 2d0e4ba951da0cf245bfc8b78b5a27552b9dd0cc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Apr 2022 18:38:54 +0200 Subject: [PATCH 029/198] applied afmt --- hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp | 4 ++-- hal/src/fsfw_hal/linux/uart/UartCookie.cpp | 4 +--- src/fsfw/osal/rtems/PeriodicTask.h | 5 ++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 52b6dc07..644b488d 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -1,9 +1,9 @@ #include "MgmLIS3MDLHandler.h" -#include "fsfw/datapool/PoolReadGuard.h" - #include +#include "fsfw/datapool/PoolReadGuard.h" + MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie, uint32_t transitionDelay) : DeviceHandlerBase(objectId, deviceCommunication, comCookie), diff --git a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp index aa2dd214..3fedc9d4 100644 --- a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp @@ -24,9 +24,7 @@ void UartCookie::setParityEven() { parity = Parity::EVEN; } Parity UartCookie::getParity() const { return parity; } -void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { - bitsPerWord = bitsPerWord_; -} +void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; } BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; } diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index 24ce4af1..9f47dfc6 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -59,14 +59,13 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; -/** + /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. * @param object pointer to the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(ExecutableObjectIF* object) override; - + ReturnValue_t addComponent(ExecutableObjectIF *object) override; uint32_t getPeriodMs() const override; From b764194ed07be714ae42d5bfe0d41dbe74727dc5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 1 Apr 2022 18:43:46 +0200 Subject: [PATCH 030/198] added more unit tests --- tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp index c368729d..d8523558 100644 --- a/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp +++ b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp @@ -22,6 +22,7 @@ TEST_CASE("Power Switcher", "[power-switcher]") { switcher.turnOn(true); REQUIRE(mock.getAmountSwitchStatWasRequested() == 1); REQUIRE(switcher.getState() == PowerSwitcher::WAIT_ON); + REQUIRE(switcher.checkSwitchState() == PowerSwitcher::IN_POWER_TRANSITION); REQUIRE(switcher.active()); switcher.doStateMachine(); REQUIRE(switcher.getState() == PowerSwitcher::SWITCH_IS_ON); @@ -29,8 +30,10 @@ TEST_CASE("Power Switcher", "[power-switcher]") { REQUIRE(switchInfo.timesCalledOn == 1); REQUIRE(not switcher.active()); REQUIRE(mock.getAmountSwitchStatWasRequested() == 2); + REQUIRE(switcher.checkSwitchState() == HasReturnvaluesIF::RETURN_OK); + REQUIRE(mock.getAmountSwitchStatWasRequested() == 3); switcher.turnOff(false); - REQUIRE(mock.getAmountSwitchStatWasRequested() == 2); + REQUIRE(mock.getAmountSwitchStatWasRequested() == 3); REQUIRE(switcher.getState() == PowerSwitcher::WAIT_OFF); REQUIRE(switcher.active()); REQUIRE(switcher.getState() == PowerSwitcher::WAIT_OFF); @@ -40,7 +43,7 @@ TEST_CASE("Power Switcher", "[power-switcher]") { REQUIRE(switchInfo.timesCalledOn == 1); REQUIRE(switchInfo.timesCalledOff == 1); REQUIRE(not switcher.active()); - REQUIRE(mock.getAmountSwitchStatWasRequested() == 3); + REQUIRE(mock.getAmountSwitchStatWasRequested() == 4); } SECTION("Dummy Test") { @@ -63,4 +66,8 @@ TEST_CASE("Power Switcher", "[power-switcher]") { REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::SWITCH_IS_OFF); REQUIRE(not switcherUsingDummy.active()); } + + SECTION("More Dummy Tests") { + + } } From 17771c0497857dc8f968b8a047bb7dcbf45509e3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 13:57:18 +0200 Subject: [PATCH 031/198] progagate reply returnvalue --- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index acfa23c5..fe9ed3a4 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -801,8 +801,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId); } - hkQueue->reply(&reply); - return result; + return hkQueue->reply(&reply); } void LocalDataPoolManager::clearReceiversList() { From acc4c8d975bb05c704ad94613ea10782f707d106 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 14:33:28 +0200 Subject: [PATCH 032/198] check serialize result as well --- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index fe9ed3a4..0c255571 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -787,6 +787,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i // Serialize set packet into store. size_t size = 0; result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); + return result; + } if (expectedSize != size) { printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED, From 7761b66fe240b604a3fc4f3f6283ac5bbfe39c9f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 14:35:16 +0200 Subject: [PATCH 033/198] delete data from ipc store if reply fails --- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index 0c255571..6053bd43 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -805,7 +805,11 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i HousekeepingMessage::setHkStuctureReportReply(&reply, sid, storeId); } - return hkQueue->reply(&reply); + result = hkQueue->reply(&reply); + if(result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); + } + return result; } void LocalDataPoolManager::clearReceiversList() { From 9947a648df6929d5114d03f6d07045f309fbeea7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 16:01:26 +0200 Subject: [PATCH 034/198] fix compiler warnings --- src/fsfw/container/HybridIterator.h | 14 ++++++++++--- src/fsfw/globalfunctions/matching/MatchTree.h | 3 +++ src/fsfw/subsystem/Subsystem.cpp | 20 +++++++++++++------ src/fsfw/subsystem/Subsystem.h | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/fsfw/container/HybridIterator.h b/src/fsfw/container/HybridIterator.h index e8b24a3d..50a37988 100644 --- a/src/fsfw/container/HybridIterator.h +++ b/src/fsfw/container/HybridIterator.h @@ -10,16 +10,24 @@ class HybridIterator : public LinkedElement::Iterator, public ArrayList::Iterator *iter) - : LinkedElement::Iterator(*iter), value(iter->value), linked(true) {} + : LinkedElement::Iterator(*iter), value(iter->value), linked(true) { + if(iter != nullptr) { + value = iter->value; + } + } HybridIterator(LinkedElement *start) - : LinkedElement::Iterator(start), value(start->value), linked(true) {} + : LinkedElement::Iterator(start), linked(true) { + if(start != nullptr) { + value = start->value; + } + } HybridIterator(typename ArrayList::Iterator start, typename ArrayList::Iterator end) : ArrayList::Iterator(start), value(start.value), linked(false), end(end.value) { if (value == this->end) { - value = NULL; + value = nullptr; } } diff --git a/src/fsfw/globalfunctions/matching/MatchTree.h b/src/fsfw/globalfunctions/matching/MatchTree.h index f7775d45..47e400da 100644 --- a/src/fsfw/globalfunctions/matching/MatchTree.h +++ b/src/fsfw/globalfunctions/matching/MatchTree.h @@ -179,6 +179,9 @@ class MatchTree : public SerializeableMatcherIF, public BinaryTreematch(number); if (isMatch) { if (iter.left() == this->end()) { diff --git a/src/fsfw/subsystem/Subsystem.cpp b/src/fsfw/subsystem/Subsystem.cpp index a837bf83..767cfe39 100644 --- a/src/fsfw/subsystem/Subsystem.cpp +++ b/src/fsfw/subsystem/Subsystem.cpp @@ -30,11 +30,11 @@ ReturnValue_t Subsystem::checkSequence(HybridIterator iter, return FALLBACK_SEQUENCE_DOES_NOT_EXIST; } - if (iter.value == NULL) { + if (iter.value ==nullptr) { return NO_TARGET_TABLE; } - for (; iter.value != NULL; ++iter) { + for (; iter.value != nullptr; ++iter) { if (!existsModeTable(iter->getTableId())) { return TABLE_DOES_NOT_EXIST; } else { @@ -66,13 +66,18 @@ HybridIterator Subsystem::getCurrentTable() { void Subsystem::performChildOperation() { if (isInTransition) { if (commandsOutstanding <= 0) { // all children of the current table were commanded and replied - if (currentSequenceIterator.value == NULL) { // we're through with this sequence + if (currentSequenceIterator.value == nullptr) { // we're through with this sequence if (checkStateAgainstTable(currentTargetTable, targetSubmode) == RETURN_OK) { setMode(targetMode, targetSubmode); isInTransition = false; return; } else { - transitionFailed(TARGET_TABLE_NOT_REACHED, getSequence(targetMode)->getTableId()); + Mode_t tableId = 0; + auto seq = getSequence(targetMode); + if(seq.value != nullptr) { + tableId = seq->getTableId(); + } + transitionFailed(TARGET_TABLE_NOT_REACHED, tableId); return; } } @@ -248,10 +253,13 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage *message) { case ModeSequenceMessage::READ_TABLE: { ReturnValue_t result; Mode_t table = ModeSequenceMessage::getSequenceId(message); - EntryPointer *entry = NULL; + EntryPointer *entry = nullptr; result = modeTables.find(table, &entry); - if (result != RETURN_OK) { + if (result != RETURN_OK or entry == nullptr) { replyToCommand(result, 0); + if(entry == nullptr) { + return result; + } } SerializeIF *elements[2]; diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index 2c78c8cd..e0fafb51 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -1,7 +1,7 @@ #ifndef FSFW_SUBSYSTEM_SUBSYSTEM_H_ #define FSFW_SUBSYSTEM_SUBSYSTEM_H_ -#include +#include "fsfw/FSFW.h" #include "../container/FixedArrayList.h" #include "../container/FixedMap.h" From 72e0938f9ac7c041bf5afe2e89febfce52badd3c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 16:09:15 +0200 Subject: [PATCH 035/198] use size instead of capacity on sanity check --- src/fsfw/power/DummyPowerSwitcher.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fsfw/power/DummyPowerSwitcher.cpp b/src/fsfw/power/DummyPowerSwitcher.cpp index d0a87288..5ae3c897 100644 --- a/src/fsfw/power/DummyPowerSwitcher.cpp +++ b/src/fsfw/power/DummyPowerSwitcher.cpp @@ -16,28 +16,28 @@ void DummyPowerSwitcher::setInitialFusesList(std::vector fuseList } ReturnValue_t DummyPowerSwitcher::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) { - if (switchNr < switcherList.capacity()) { + if (switchNr < switcherList.size()) { switcherList[switchNr] = onOff; } return RETURN_FAILED; } ReturnValue_t DummyPowerSwitcher::sendFuseOnCommand(uint8_t fuseNr) { - if (fuseNr < fuseList.capacity()) { + if (fuseNr < fuseList.size()) { fuseList[fuseNr] = FUSE_ON; } return RETURN_FAILED; } ReturnValue_t DummyPowerSwitcher::getSwitchState(power::Switch_t switchNr) const { - if (switchNr < switcherList.capacity()) { + if (switchNr < switcherList.size()) { return switcherList[switchNr]; } return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t DummyPowerSwitcher::getFuseState(uint8_t fuseNr) const { - if (fuseNr < fuseList.capacity()) { + if (fuseNr < fuseList.size()) { return fuseList[fuseNr]; } return HasReturnvaluesIF::RETURN_FAILED; From 7af1c86f1c921a411111d0ce91f1c758eef0ac6d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 16:10:17 +0200 Subject: [PATCH 036/198] use default call --- src/fsfw/power/PowerSensor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fsfw/power/PowerSensor.cpp b/src/fsfw/power/PowerSensor.cpp index e73b12d0..08ff4724 100644 --- a/src/fsfw/power/PowerSensor.cpp +++ b/src/fsfw/power/PowerSensor.cpp @@ -15,8 +15,7 @@ PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, Def limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh), voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount, limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) { - commandQueue = - QueueFactory::instance()->createMessageQueue(3, MessageQueueMessage::MAX_MESSAGE_SIZE); + commandQueue = QueueFactory::instance()->createMessageQueue(); } PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); } From d1151ca707557598d5609c82497436047787dc5d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 16:13:47 +0200 Subject: [PATCH 037/198] changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3eb6942..01d60987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `oneShotAction` flag in the `TestTask` class is not static anymore - HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585 +- IPC Message Queue Handling: Allow passing an optional `MqArgs` argument into the MessageQueue + creation call. It allows passing context information and an arbitrary user argument into + the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583 ## Removed From a18bc15cbb717734952f34e9b9aaf751ebee082d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 16:16:56 +0200 Subject: [PATCH 038/198] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3eb6942..8fef44f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information inside `fsfw/version.h` PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 +- Added generic PUS TC Scheduler Service 11. It depends on the new added Emebeded Template Library + (ETL) dependency. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/594 # [v4.0.0] From 4f0669c57407af9d1cbf4bc14e28922be3a38c90 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 16:44:20 +0200 Subject: [PATCH 039/198] doc update --- CMakeLists.txt | 8 +++----- README.md | 11 +++++------ docs/getting_started.rst | 11 +++++------ 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51d40f48..d8ca812e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING "ETL library major version requirement" ) -set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.26.0 CACHE STRING +set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.2 CACHE STRING "ETL library exact version requirement" ) @@ -106,11 +106,9 @@ if(FSFW_BUILD_UNITTESTS) endif() message(STATUS "Finding and/or providing ETL library") + # Check whether the user has already installed ETL first -# I think the version provisioning feature of CMake has not been implemented for the ETL library -# yet. Therefore we can not specify any (not even the major) version here and we have to rely -# on the user having installed the correct version for now -find_package(${FSFW_ETL_LIB_NAME} QUIET) +find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide etl if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) message(STATUS diff --git a/README.md b/README.md index 51d78b25..99c842af 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,10 @@ information about the possible options. The Embedded Template Library (etl) is a dependency of the FSFW which is automatically installed and provided by the build system unless the correction version was installed. The current recommended version can be found inside the fsfw `CMakeLists.txt` file or by using -`ccmake` and looking up the `FSFW_ETL_LIB_VERSION` variable. +`ccmake` and looking up the `FSFW_ETL_LIB_MAJOR_VERSION` variable. -You can install the ETL library like this: +You can install the ETL library like this. On Linux, it might be necessary to add `sudo` before +the install call: ```cpp git clone https://github.com/ETLCPP/etl @@ -69,10 +70,8 @@ cmake .. cmake --install . ``` -Right now, the version provision feature by the ETL library has not been implemented -yet so `CMake` is unable to determine and check the major version of the ETL -library. You have to ensure that the ETL library has been installed with the -correct major version. +It is recommended to install `20.27.2` or newer for the package version handling of +ETL to work. ## Adding the library diff --git a/docs/getting_started.rst b/docs/getting_started.rst index fb316a97..01724b3a 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -25,9 +25,10 @@ Prerequisites The Embedded Template Library (etl) is a dependency of the FSFW which is automatically installed and provided by the build system unless the correction version was installed. The current recommended version can be found inside the fsfw ``CMakeLists.txt`` file or by using -``ccmake`` and looking up the ``FSFW_ETL_LIB_VERSION`` variable. +``ccmake`` and looking up the ``FSFW_ETL_LIB_MAJOR_VERSION`` variable. -You can install the ETL library like this: +You can install the ETL library like this. On Linux, it might be necessary to add ``sudo`` before +the install call: .. code-block:: console @@ -38,10 +39,8 @@ You can install the ETL library like this: cmake .. cmake --install . -Right now, the version provision feature by the ETL library has not been implemented -yet so ``CMake`` is unable to determine and check the major version of the ETL -library. You have to ensure that the ETL library has been installed with the -correct major version. +It is recommended to install ``20.27.2`` or newer for the package version handling of +ETL to work. Adding the library ------------------- From cb78fefbb3606b23c73a38ae4a90715188b47bcf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 17:14:04 +0200 Subject: [PATCH 040/198] afmt --- .../devicehandlers/MgmLIS3MDLHandler.cpp | 4 +- hal/src/fsfw_hal/linux/uart/UartCookie.cpp | 4 +- src/fsfw/container/HybridIterator.h | 7 ++- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 13 +++-- src/fsfw/globalfunctions/matching/MatchTree.h | 2 +- src/fsfw/osal/rtems/PeriodicTask.h | 5 +- src/fsfw/subsystem/Subsystem.cpp | 8 +-- src/fsfw/subsystem/Subsystem.h | 3 +- src/fsfw/version.cpp | 3 +- src/fsfw/version.h | 2 +- tests/src/fsfw_tests/unit/version.cpp | 50 +++++++++---------- 11 files changed, 48 insertions(+), 53 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 52b6dc07..644b488d 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -1,9 +1,9 @@ #include "MgmLIS3MDLHandler.h" -#include "fsfw/datapool/PoolReadGuard.h" - #include +#include "fsfw/datapool/PoolReadGuard.h" + MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie, uint32_t transitionDelay) : DeviceHandlerBase(objectId, deviceCommunication, comCookie), diff --git a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp index aa2dd214..3fedc9d4 100644 --- a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp @@ -24,9 +24,7 @@ void UartCookie::setParityEven() { parity = Parity::EVEN; } Parity UartCookie::getParity() const { return parity; } -void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { - bitsPerWord = bitsPerWord_; -} +void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; } BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; } diff --git a/src/fsfw/container/HybridIterator.h b/src/fsfw/container/HybridIterator.h index 50a37988..189f8410 100644 --- a/src/fsfw/container/HybridIterator.h +++ b/src/fsfw/container/HybridIterator.h @@ -11,14 +11,13 @@ class HybridIterator : public LinkedElement::Iterator, public ArrayList::Iterator *iter) : LinkedElement::Iterator(*iter), value(iter->value), linked(true) { - if(iter != nullptr) { + if (iter != nullptr) { value = iter->value; } } - HybridIterator(LinkedElement *start) - : LinkedElement::Iterator(start), linked(true) { - if(start != nullptr) { + HybridIterator(LinkedElement *start) : LinkedElement::Iterator(start), linked(true) { + if (start != nullptr) { value = start->value; } } diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 0e2802ac..dd9bd5d7 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -458,16 +458,15 @@ size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) { DeviceCommandId_t replyId = NO_COMMAND_ID; DeviceCommandMap::iterator command = cookieInfo.pendingCommand; if (command->second.useAlternativeReplyId) { - replyId = command->second.alternativeReplyId; - } - else { - replyId = commandId; + replyId = command->second.alternativeReplyId; + } else { + replyId = commandId; } DeviceReplyIter iter = deviceReplyMap.find(replyId); if (iter != deviceReplyMap.end()) { - if (iter->second.delayCycles != 0) { - return iter->second.replyLen; - } + if (iter->second.delayCycles != 0) { + return iter->second.replyLen; + } } return 0; } diff --git a/src/fsfw/globalfunctions/matching/MatchTree.h b/src/fsfw/globalfunctions/matching/MatchTree.h index 47e400da..68b8f270 100644 --- a/src/fsfw/globalfunctions/matching/MatchTree.h +++ b/src/fsfw/globalfunctions/matching/MatchTree.h @@ -179,7 +179,7 @@ class MatchTree : public SerializeableMatcherIF, public BinaryTreematch(number); diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index 24ce4af1..9f47dfc6 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -59,14 +59,13 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; -/** + /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. * @param object pointer to the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(ExecutableObjectIF* object) override; - + ReturnValue_t addComponent(ExecutableObjectIF *object) override; uint32_t getPeriodMs() const override; diff --git a/src/fsfw/subsystem/Subsystem.cpp b/src/fsfw/subsystem/Subsystem.cpp index 767cfe39..ab8c1b16 100644 --- a/src/fsfw/subsystem/Subsystem.cpp +++ b/src/fsfw/subsystem/Subsystem.cpp @@ -30,7 +30,7 @@ ReturnValue_t Subsystem::checkSequence(HybridIterator iter, return FALLBACK_SEQUENCE_DOES_NOT_EXIST; } - if (iter.value ==nullptr) { + if (iter.value == nullptr) { return NO_TARGET_TABLE; } @@ -74,8 +74,8 @@ void Subsystem::performChildOperation() { } else { Mode_t tableId = 0; auto seq = getSequence(targetMode); - if(seq.value != nullptr) { - tableId = seq->getTableId(); + if (seq.value != nullptr) { + tableId = seq->getTableId(); } transitionFailed(TARGET_TABLE_NOT_REACHED, tableId); return; @@ -257,7 +257,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage *message) { result = modeTables.find(table, &entry); if (result != RETURN_OK or entry == nullptr) { replyToCommand(result, 0); - if(entry == nullptr) { + if (entry == nullptr) { return result; } } diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index e0fafb51..d3e197b0 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -1,14 +1,13 @@ #ifndef FSFW_SUBSYSTEM_SUBSYSTEM_H_ #define FSFW_SUBSYSTEM_SUBSYSTEM_H_ -#include "fsfw/FSFW.h" - #include "../container/FixedArrayList.h" #include "../container/FixedMap.h" #include "../container/HybridIterator.h" #include "../container/SinglyLinkedList.h" #include "../serialize/SerialArrayListAdapter.h" #include "SubsystemBase.h" +#include "fsfw/FSFW.h" #include "modes/ModeDefinitions.h" /** diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 926e465f..e4a62002 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -1,8 +1,9 @@ #include "version.h" -#include "fsfw/FSFWVersion.h" #include +#include "fsfw/FSFWVersion.h" + #ifdef major #undef major #endif diff --git a/src/fsfw/version.h b/src/fsfw/version.h index 7cddf193..bb4d0399 100644 --- a/src/fsfw/version.h +++ b/src/fsfw/version.h @@ -29,7 +29,7 @@ class Version { } friend bool operator>(const Version& v1, const Version& v2) { - return not (v1 < v2) and not (v1 == v2); + return not(v1 < v2) and not(v1 == v2); } friend bool operator<=(const Version& v1, const Version& v2) { return ((v1 == v2) or (v1 < v2)); } diff --git a/tests/src/fsfw_tests/unit/version.cpp b/tests/src/fsfw_tests/unit/version.cpp index 92a930dc..2967dfa5 100644 --- a/tests/src/fsfw_tests/unit/version.cpp +++ b/tests/src/fsfw_tests/unit/version.cpp @@ -17,15 +17,15 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { fsfw::Version v1 = fsfw::Version(1, 1, 1); fsfw::Version v2 = fsfw::Version(1, 1, 1); REQUIRE(v1 == v2); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 > v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 > v2)); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); v1.revision -= 1; REQUIRE(v1 != v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); v1.revision += 1; @@ -33,60 +33,60 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.minor += 1; v1.major -= 1; REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.major += 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 < v2)); + REQUIRE(not(v1 != v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 < v2)); v1.major += 1; v1.minor -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.major -= 1; v1.minor += 2; v1.revision -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.minor -= 1; v1.revision += 2; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.revision -= 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); + REQUIRE(not(v1 != v2)); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "v" << fsfw::FSFW_VERSION << std::endl; #endif char verString[10] = {}; fsfw::FSFW_VERSION.getVersion(verString, sizeof(verString)); #if FSFW_DISABLE_PRINTOUT == 0 - printf("v%s\n",verString); + printf("v%s\n", verString); #endif } From a1d7a56dfa1c0cfb73a57929ee0a9ac1dcee4928 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 17:14:43 +0200 Subject: [PATCH 041/198] small fix --- src/fsfw/container/HybridIterator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/container/HybridIterator.h b/src/fsfw/container/HybridIterator.h index 189f8410..ad000ec2 100644 --- a/src/fsfw/container/HybridIterator.h +++ b/src/fsfw/container/HybridIterator.h @@ -10,7 +10,7 @@ class HybridIterator : public LinkedElement::Iterator, public ArrayList::Iterator *iter) - : LinkedElement::Iterator(*iter), value(iter->value), linked(true) { + : LinkedElement::Iterator(*iter), linked(true) { if (iter != nullptr) { value = iter->value; } From 6aa54fe1d4bd4bc3121ea91a442a9fa4c5d98f7a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 17:30:27 +0200 Subject: [PATCH 042/198] added missing empty implementation --- CHANGELOG.md | 5 +++++ hal/src/fsfw_hal/stm32h7/spi/mspInit.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3eb6942..8f3a3a1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). inside `fsfw/version.h` PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 +## Fixed + +- Small bugfix in STM32 HAL for SPI + PR: + # [v4.0.0] ## Additions diff --git a/hal/src/fsfw_hal/stm32h7/spi/mspInit.h b/hal/src/fsfw_hal/stm32h7/spi/mspInit.h index 00c68017..f0658fb9 100644 --- a/hal/src/fsfw_hal/stm32h7/spi/mspInit.h +++ b/hal/src/fsfw_hal/stm32h7/spi/mspInit.h @@ -21,7 +21,7 @@ using mspCb = void (*)(void); namespace spi { struct MspCfgBase { - MspCfgBase(); + MspCfgBase() {} MspCfgBase(stm32h7::GpioCfg sck, stm32h7::GpioCfg mosi, stm32h7::GpioCfg miso, mspCb cleanupCb = nullptr, mspCb setupCb = nullptr) : sck(sck), mosi(mosi), miso(miso), cleanupCb(cleanupCb), setupCb(setupCb) {} From 7c2e50b665f515d6234f3d2f070609f8f37efde2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Apr 2022 17:32:01 +0200 Subject: [PATCH 043/198] added related PR in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f3a3a1b..85f6ef28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Fixed - Small bugfix in STM32 HAL for SPI - PR: + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/599 # [v4.0.0] From 613dbe9592c30d9acf4cdb95d81d9f216f07374b Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 21 Apr 2022 09:33:06 +0200 Subject: [PATCH 044/198] default argument --- src/fsfw/tmtcpacket/SpacePacket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/tmtcpacket/SpacePacket.h b/src/fsfw/tmtcpacket/SpacePacket.h index 10140db1..4fadd236 100644 --- a/src/fsfw/tmtcpacket/SpacePacket.h +++ b/src/fsfw/tmtcpacket/SpacePacket.h @@ -25,7 +25,7 @@ class SpacePacket : public SpacePacketBase { * @param apid Sets the packet's APID field. The default value describes an idle packet. * @param sequenceCount ets the packet's Source Sequence Count field. */ - SpacePacket(uint16_t packetDataLength, bool isTelecommand = false, + SpacePacket(uint16_t packetDataLength = PACKET_MAX_SIZE, bool isTelecommand = false, uint16_t apid = APID_IDLE_PACKET, uint16_t sequenceCount = 0); /** * The class's default destructor. From 085213c60f0f86dd7e28769767a0d235ed333336 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 21 Apr 2022 10:30:46 +0200 Subject: [PATCH 045/198] add nullptr check --- hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 52b6dc07..278f6f4b 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -375,13 +375,16 @@ float MgmLIS3MDLHandler::getSensitivityFactor(MGMLIS3MDL::Sensitivies sens) { ReturnValue_t MgmLIS3MDLHandler::enableTemperatureSensor(const uint8_t *commandData, size_t commandDataLen) { + if(commandData == nullptr) { + return INVALID_COMMAND_PARAMETER; + } triggerEvent(CHANGE_OF_SETUP_PARAMETER); uint32_t size = 2; commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1); if (commandDataLen > 1) { return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS; } - switch (*commandData) { + switch (commandData[0]) { case (MGMLIS3MDL::ON): { commandBuffer[1] = registers[0] | (1 << 7); break; From 9f7b9be800402215e97759eb35d4c40a484d1f68 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 21 Apr 2022 14:24:20 +0200 Subject: [PATCH 046/198] space packet default length 0 --- src/fsfw/tmtcpacket/SpacePacket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/tmtcpacket/SpacePacket.h b/src/fsfw/tmtcpacket/SpacePacket.h index 4fadd236..dc45576e 100644 --- a/src/fsfw/tmtcpacket/SpacePacket.h +++ b/src/fsfw/tmtcpacket/SpacePacket.h @@ -25,7 +25,7 @@ class SpacePacket : public SpacePacketBase { * @param apid Sets the packet's APID field. The default value describes an idle packet. * @param sequenceCount ets the packet's Source Sequence Count field. */ - SpacePacket(uint16_t packetDataLength = PACKET_MAX_SIZE, bool isTelecommand = false, + SpacePacket(uint16_t packetDataLength = 0, bool isTelecommand = false, uint16_t apid = APID_IDLE_PACKET, uint16_t sequenceCount = 0); /** * The class's default destructor. From 8c6c8ad3c0c8ff652f8c20893219d826f80698d9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 11:58:44 +0200 Subject: [PATCH 047/198] exntend version class to allow add info --- src/fsfw/version.cpp | 24 ++++++++++++++++++------ src/fsfw/version.h | 16 ++++++++-------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 926e465f..a7f1d6a1 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -11,12 +11,24 @@ #undef minor #endif -const fsfw::Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, - FSFW_VERSION_REVISION}; +const Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, FSFW_VERSION_REVISION}; -fsfw::Version::Version(uint32_t major, uint32_t minor, uint32_t revision) - : major(major), minor(minor), revision(revision) {} +Version::Version(uint32_t major, uint32_t minor, uint32_t revision, const char* addInfo) + : major(major), minor(minor), revision(revision), addInfo(addInfo) {} -void fsfw::Version::getVersion(char* str, size_t maxLen) const { - snprintf(str, maxLen, "%d.%d.%d", major, minor, revision); +void Version::getVersion(char* str, size_t maxLen) const { + size_t len = snprintf(str, maxLen, "%d.%d.%d", major, minor, revision); + if (addInfo != nullptr) { + snprintf(str + len, maxLen - len, "-%s", addInfo); + } } + +#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) { + os << "-" << v.addInfo; + } + return os; +} +#endif diff --git a/src/fsfw/version.h b/src/fsfw/version.h index 7cddf193..d8497703 100644 --- a/src/fsfw/version.h +++ b/src/fsfw/version.h @@ -8,15 +8,16 @@ #endif #include -namespace fsfw { - class Version { public: - Version(uint32_t major, uint32_t minor, uint32_t revision); + Version(uint32_t major, uint32_t minor, uint32_t revision, const char* addInfo = nullptr); uint32_t major = 0; uint32_t minor = 0; uint32_t revision = 0; + // Additional information, e.g. a git SHA hash + const char* addInfo = nullptr; + friend bool operator==(const Version& v1, const Version& v2) { return (v1.major == v2.major and v1.minor == v2.minor and v1.revision == v2.revision); } @@ -43,10 +44,7 @@ class Version { * @param v * @return */ - friend std::ostream& operator<<(std::ostream& os, const Version& v) { - os << v.major << "." << v.minor << "." << v.revision; - return os; - } + friend std::ostream& operator<<(std::ostream& os, const Version& v); #endif /** @@ -57,7 +55,9 @@ class Version { void getVersion(char* str, size_t maxLen) const; }; -extern const fsfw::Version FSFW_VERSION; +namespace fsfw { + +extern const Version FSFW_VERSION; } // namespace fsfw From 07155e25464afe73ae3ae79b88913d4f0961f9c5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:04:18 +0200 Subject: [PATCH 048/198] extend version handling with git describe --- CMakeLists.txt | 22 +- cmake/GetGitRevisionDescription.cmake | 284 +++++++++++++++++++++++ cmake/GetGitRevisionDescription.cmake.in | 43 ++++ cmake/helpers.cmake | 28 +++ src/fsfw/FSFWVersion.h.in | 7 +- src/fsfw/version.cpp | 2 +- src/fsfw/version.h | 8 +- 7 files changed, 382 insertions(+), 12 deletions(-) create mode 100644 cmake/GetGitRevisionDescription.cmake create mode 100644 cmake/GetGitRevisionDescription.cmake.in create mode 100644 cmake/helpers.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ef11493..4f9ed91d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,5 @@ cmake_minimum_required(VERSION 3.13) -set(FSFW_VERSION 4) -set(FSFW_SUBVERSION 0) -set(FSFW_REVISION 0) - # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) @@ -45,6 +41,24 @@ set(FSFW_DUMMY_TGT fsfw-dummy) project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) +# Version handling +include("GetGitRevisionDescription") +determine_version_with_git("--exclude" "docker_*") +set(GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") +list(GET GIT_INFO 1 FSFW_VERSION) +list(GET GIT_INFO 2 FSFW_SUBVERSION) +list(GET GIT_INFO 3 FSFW_REVISION) +list(GET GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) +if(NOT FSFW_VERSION) + set(FSFW_VERSION -1) +endif() +if(NOT FSFW_SUBVERSION) + set(FSFW_SUBVERSION -1) +endif() +if(NOT FSFW_REVISION) + set(FSFW_REVISION -1) +endif() + if(FSFW_BUILD_UNITTESTS) message(STATUS "Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake new file mode 100644 index 00000000..69ef78b2 --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake @@ -0,0 +1,284 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_describe_working_tree( [ ...]) +# +# Returns the results of git describe on the working tree (--dirty option), +# and adjusting the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# git_local_changes() +# +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. +# Uses the return code of "git diff-index --quiet HEAD --". +# Does not regard untracked files. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2020 Ryan Pavlik +# http://academic.cleardefinition.com +# +# Copyright 2009-2013, Iowa State University. +# Copyright 2013-2020, Ryan Pavlik +# Copyright 2013-2020, Contributors +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +# Function _git_find_closest_git_dir finds the next closest .git directory +# that is part of any directory in the path defined by _start_dir. +# The result is returned in the parent scope variable whose name is passed +# as variable _git_dir_var. If no .git directory can be found, the +# function returns an empty string via _git_dir_var. +# +# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and +# neither foo nor bar contain a file/directory .git. This wil return +# C:/bla/.git +# +function(_git_find_closest_git_dir _start_dir _git_dir_var) + set(cur_dir "${_start_dir}") + set(git_dir "${_start_dir}/.git") + while(NOT EXISTS "${git_dir}") + # .git dir not found, search parent directories + set(git_previous_parent "${cur_dir}") + get_filename_component(cur_dir "${cur_dir}" DIRECTORY) + if(cur_dir STREQUAL git_previous_parent) + # We have reached the root directory, we are not in git + set(${_git_dir_var} + "" + PARENT_SCOPE) + return() + endif() + set(git_dir "${cur_dir}/.git") + endwhile() + set(${_git_dir_var} + "${git_dir}" + PARENT_SCOPE) +endfunction() + +function(get_git_head_revision _refspecvar _hashvar) + _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) + + if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR") + set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE) + else() + set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE) + endif() + if(NOT "${GIT_DIR}" STREQUAL "") + file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}" + "${GIT_DIR}") + if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR) + # We've gone above the CMake root dir. + set(GIT_DIR "") + endif() + endif() + if("${GIT_DIR}" STREQUAL "") + set(${_refspecvar} + "GITDIR-NOTFOUND" + PARENT_SCOPE) + set(${_hashvar} + "GITDIR-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + # Check if the current source dir is a git submodule or a worktree. + # In both cases .git is a file instead of a directory. + # + if(NOT IS_DIRECTORY ${GIT_DIR}) + # The following git command will return a non empty string that + # points to the super project working tree if the current + # source dir is inside a git submodule. + # Otherwise the command will return an empty string. + # + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse + --show-superproject-working-tree + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT "${out}" STREQUAL "") + # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE + ${submodule}) + string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} + ABSOLUTE) + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") + else() + # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree + file(READ ${GIT_DIR} worktree_ref) + # The .git directory contains a path to the worktree information directory + # inside the parent git repo of the worktree. + # + string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir + ${worktree_ref}) + string(STRIP ${git_worktree_dir} git_worktree_dir) + _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) + set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") + endif() + else() + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${HEAD_SOURCE_FILE}") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} + "${HEAD_REF}" + PARENT_SCOPE) + set(${_hashvar} + "${HEAD_HASH}" + PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_describe_working_tree _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_local_changes _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD -- + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(res EQUAL 0) + set(${_var} + "CLEAN" + PARENT_SCOPE) + else() + set(${_var} + "DIRTY" + PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in new file mode 100644 index 00000000..66eee637 --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -0,0 +1,43 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright 2009-2012, Iowa State University +# Copyright 2011-2015, Contributors +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# SPDX-License-Identifier: BSL-1.0 + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake new file mode 100644 index 00000000..14fc4978 --- /dev/null +++ b/cmake/helpers.cmake @@ -0,0 +1,28 @@ +# Determines the git version with git describe and returns it by setting +# the GIT_INFO list in the parent scope. The list has the following entries +# 1. Full version string +# 2. Major version +# 3. Minor version +# 4. Revision +# 5. git SHA hash and commits since tag +function(determine_version_with_git) + include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake) + git_describe(VERSION ${ARGN}) + string(FIND ${VERSION} "." VALID_VERSION) + if(VALID_VERSION EQUAL -1) + message(WARNING "Version string ${VERSION} retrieved with git describe is invalid") + return() + endif() + # Parse the version information into pieces. + string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" _VERSION_MAJOR "${VERSION}") + string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" _VERSION_MINOR "${VERSION}") + string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" _VERSION_PATCH "${VERSION}") + string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+-(.*)" "\\1" VERSION_SHA1 "${VERSION}") + set(GIT_INFO ${VERSION}) + list(APPEND GIT_INFO ${_VERSION_MAJOR}) + list(APPEND GIT_INFO ${_VERSION_MINOR}) + list(APPEND GIT_INFO ${_VERSION_PATCH}) + list(APPEND GIT_INFO ${VERSION_SHA1}) + set(GIT_INFO ${GIT_INFO} PARENT_SCOPE) + message(STATUS "Set git version info into GIT_INFO from the git tag ${VERSION}") +endfunction() diff --git a/src/fsfw/FSFWVersion.h.in b/src/fsfw/FSFWVersion.h.in index 19a56214..79d1f130 100644 --- a/src/fsfw/FSFWVersion.h.in +++ b/src/fsfw/FSFWVersion.h.in @@ -2,8 +2,9 @@ #define FSFW_VERSION_H_ // Versioning is kept in project CMakeLists.txt file -#define FSFW_VERSION_MAJOR @FSFW_VERSION@ -#define FSFW_VERSION_MINOR @FSFW_SUBVERSION@ -#define FSFW_VERSION_REVISION @FSFW_REVISION@ +static constexpr int FSFW_VERSION_MAJOR = @FSFW_VERSION@; +static constexpr int FSFW_VERSION_MINOR = @FSFW_SUBVERSION@; +static constexpr int FSFW_VERSION_REVISION = @FSFW_REVISION@; +static const char FSFW_VERSION_CST_GIT_SHA1[] = "@FSFW_VERSION_CST_GIT_SHA1@"; #endif /* FSFW_VERSION_H_ */ diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index a7f1d6a1..4717b188 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -13,7 +13,7 @@ const Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, FSFW_VERSION_REVISION}; -Version::Version(uint32_t major, uint32_t minor, uint32_t revision, const char* addInfo) +Version::Version(int major, int minor, int revision, const char* addInfo) : major(major), minor(minor), revision(revision), addInfo(addInfo) {} void Version::getVersion(char* str, size_t maxLen) const { diff --git a/src/fsfw/version.h b/src/fsfw/version.h index d8497703..d97306ec 100644 --- a/src/fsfw/version.h +++ b/src/fsfw/version.h @@ -10,10 +10,10 @@ class Version { public: - Version(uint32_t major, uint32_t minor, uint32_t revision, const char* addInfo = nullptr); - uint32_t major = 0; - uint32_t minor = 0; - uint32_t revision = 0; + Version(int major, int minor, int revision, const char* addInfo = nullptr); + int major = -1; + int minor = -1; + int revision = -1; // Additional information, e.g. a git SHA hash const char* addInfo = nullptr; From 7e1aed6ad9bdd9a2b02c1e17a135472dcc9fa11d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:04:30 +0200 Subject: [PATCH 049/198] apply afmt --- .../devicehandlers/MgmLIS3MDLHandler.cpp | 4 +- hal/src/fsfw_hal/linux/uart/UartCookie.cpp | 4 +- .../datapoollocal/LocalDataPoolManager.cpp | 10 ++-- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 13 +++-- src/fsfw/osal/rtems/PeriodicTask.h | 5 +- src/fsfw/version.cpp | 3 +- src/fsfw/version.h | 2 +- tests/src/fsfw_tests/unit/version.cpp | 50 +++++++++---------- 8 files changed, 44 insertions(+), 47 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 52b6dc07..644b488d 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -1,9 +1,9 @@ #include "MgmLIS3MDLHandler.h" -#include "fsfw/datapool/PoolReadGuard.h" - #include +#include "fsfw/datapool/PoolReadGuard.h" + MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie, uint32_t transitionDelay) : DeviceHandlerBase(objectId, deviceCommunication, comCookie), diff --git a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp index aa2dd214..3fedc9d4 100644 --- a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp @@ -24,9 +24,7 @@ void UartCookie::setParityEven() { parity = Parity::EVEN; } Parity UartCookie::getParity() const { return parity; } -void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { - bitsPerWord = bitsPerWord_; -} +void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; } BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; } diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index 6053bd43..781d8f71 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -787,9 +787,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i // Serialize set packet into store. size_t size = 0; result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK) { - ipcStore->deleteData(storeId); - return result; + if (result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); + return result; } if (expectedSize != size) { printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket", @@ -806,8 +806,8 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i } result = hkQueue->reply(&reply); - if(result != HasReturnvaluesIF::RETURN_OK) { - ipcStore->deleteData(storeId); + if (result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); } return result; } diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 0e2802ac..dd9bd5d7 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -458,16 +458,15 @@ size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) { DeviceCommandId_t replyId = NO_COMMAND_ID; DeviceCommandMap::iterator command = cookieInfo.pendingCommand; if (command->second.useAlternativeReplyId) { - replyId = command->second.alternativeReplyId; - } - else { - replyId = commandId; + replyId = command->second.alternativeReplyId; + } else { + replyId = commandId; } DeviceReplyIter iter = deviceReplyMap.find(replyId); if (iter != deviceReplyMap.end()) { - if (iter->second.delayCycles != 0) { - return iter->second.replyLen; - } + if (iter->second.delayCycles != 0) { + return iter->second.replyLen; + } } return 0; } diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index 24ce4af1..9f47dfc6 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -59,14 +59,13 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; -/** + /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. * @param object pointer to the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(ExecutableObjectIF* object) override; - + ReturnValue_t addComponent(ExecutableObjectIF *object) override; uint32_t getPeriodMs() const override; diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 4717b188..7355fc1d 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -1,8 +1,9 @@ #include "version.h" -#include "fsfw/FSFWVersion.h" #include +#include "fsfw/FSFWVersion.h" + #ifdef major #undef major #endif diff --git a/src/fsfw/version.h b/src/fsfw/version.h index d97306ec..f7d56d91 100644 --- a/src/fsfw/version.h +++ b/src/fsfw/version.h @@ -30,7 +30,7 @@ class Version { } friend bool operator>(const Version& v1, const Version& v2) { - return not (v1 < v2) and not (v1 == v2); + return not(v1 < v2) and not(v1 == v2); } friend bool operator<=(const Version& v1, const Version& v2) { return ((v1 == v2) or (v1 < v2)); } diff --git a/tests/src/fsfw_tests/unit/version.cpp b/tests/src/fsfw_tests/unit/version.cpp index 92a930dc..2967dfa5 100644 --- a/tests/src/fsfw_tests/unit/version.cpp +++ b/tests/src/fsfw_tests/unit/version.cpp @@ -17,15 +17,15 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { fsfw::Version v1 = fsfw::Version(1, 1, 1); fsfw::Version v2 = fsfw::Version(1, 1, 1); REQUIRE(v1 == v2); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 > v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 > v2)); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); v1.revision -= 1; REQUIRE(v1 != v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); v1.revision += 1; @@ -33,60 +33,60 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.minor += 1; v1.major -= 1; REQUIRE(v1 != v2); REQUIRE(v1 < v2); REQUIRE(v1 <= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 >= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 >= v2)); v1.major += 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); - REQUIRE(not (v1 > v2)); - REQUIRE(not (v1 < v2)); + REQUIRE(not(v1 != v2)); + REQUIRE(not(v1 > v2)); + REQUIRE(not(v1 < v2)); v1.major += 1; v1.minor -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.major -= 1; v1.minor += 2; v1.revision -= 1; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.minor -= 1; v1.revision += 2; REQUIRE(v1 != v2); REQUIRE(v1 > v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 == v2)); - REQUIRE(not (v1 < v2)); - REQUIRE(not (v1 <= v2)); + REQUIRE(not(v1 == v2)); + REQUIRE(not(v1 < v2)); + REQUIRE(not(v1 <= v2)); v1.revision -= 1; REQUIRE(v1 == v2); REQUIRE(v1 <= v2); REQUIRE(v1 >= v2); - REQUIRE(not (v1 != v2)); + REQUIRE(not(v1 != v2)); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "v" << fsfw::FSFW_VERSION << std::endl; #endif char verString[10] = {}; fsfw::FSFW_VERSION.getVersion(verString, sizeof(verString)); #if FSFW_DISABLE_PRINTOUT == 0 - printf("v%s\n",verString); + printf("v%s\n", verString); #endif } From b951cb736a41c8b8db6532da3168529ad88cc017 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:08:26 +0200 Subject: [PATCH 050/198] add fsfw specific cmake message prefix --- CMakeLists.txt | 24 +++++++++++++----------- cmake/helpers.cmake | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f9ed91d..21495f37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.13) # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +set(MSG_PREFIX "fsfw |") + option(FSFW_GENERATE_SECTIONS "Generate function and data sections. Required to remove unused code" ON ) @@ -60,12 +62,12 @@ if(NOT FSFW_REVISION) endif() if(FSFW_BUILD_UNITTESTS) - message(STATUS "Building the FSFW unittests in addition to the static library") + message(STATUS "${MSG_PREFIX} Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first find_package(Catch2 3 QUIET) # Not installed, so use FetchContent to download and provide Catch2 if(NOT Catch2_FOUND) - message(STATUS "Catch2 installation not found. Downloading Catch2 library with FetchContent") + message(STATUS "${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent") include(FetchContent) FetchContent_Declare( @@ -87,8 +89,8 @@ if(FSFW_BUILD_UNITTESTS) add_executable(${FSFW_TEST_TGT}) if(FSFW_TESTS_GEN_COV) - message(STATUS "Generating coverage data for the library") - message(STATUS "Targets linking against ${LIB_FSFW_NAME} " + message(STATUS "${MSG_PREFIX} Generating coverage data for the library") + message(STATUS "${MSG_PREFIX} Targets linking against ${LIB_FSFW_NAME} " "will be compiled with coverage data as well" ) include(FetchContent) @@ -119,17 +121,17 @@ if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) elseif(${CMAKE_CXX_STANDARD} LESS 11) - message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++11 support") + message(FATAL_ERROR "${MSG_PREFIX} Compiling the FSFW requires a minimum of C++11 support") endif() # Backwards comptability if(OS_FSFW AND NOT FSFW_OSAL) - message(WARNING "Please pass the FSFW OSAL as FSFW_OSAL instead of OS_FSFW") + message(WARNING "${MSG_PREFIX} Please pass the FSFW OSAL as FSFW_OSAL instead of OS_FSFW") set(FSFW_OSAL OS_FSFW) endif() if(NOT FSFW_OSAL) - message(STATUS "No OS for FSFW via FSFW_OSAL set. Assuming host OS") + message(STATUS "${MSG_PREFIX} No OS for FSFW via FSFW_OSAL set. Assuming host OS") # Assume host OS and autodetermine from OS_FSFW if(UNIX) set(FSFW_OSAL "linux" @@ -163,7 +165,7 @@ elseif(FSFW_OSAL STREQUAL rtems) set(FSFW_OSAL_RTEMS ON) else() message(WARNING - "Invalid operating system for FSFW specified! Setting to host.." + "${MSG_PREFIX} Invalid operating system for FSFW specified! Setting to host.." ) set(FSFW_OS_NAME "Host") set(OS_FSFW "host") @@ -172,7 +174,7 @@ endif() configure_file(src/fsfw/FSFW.h.in fsfw/FSFW.h) configure_file(src/fsfw/FSFWVersion.h.in fsfw/FSFWVersion.h) -message(STATUS "Compiling FSFW for the ${FSFW_OS_NAME} operating system.") +message(STATUS "${MSG_PREFIX} Compiling FSFW for the ${FSFW_OS_NAME} operating system") add_subdirectory(src) add_subdirectory(tests) @@ -256,8 +258,8 @@ endif() if(NOT FSFW_CONFIG_PATH) set(DEF_CONF_PATH misc/defaultcfg/fsfwconfig) if(NOT FSFW_BUILD_DOCS) - message(WARNING "Flight Software Framework configuration path not set!") - message(WARNING "Setting default configuration from ${DEF_CONF_PATH} ..") + message(WARNING "${MSG_PREFIX} Flight Software Framework configuration path not set") + message(WARNING "${MSG_PREFIX} Setting default configuration from ${DEF_CONF_PATH} ..") endif() add_subdirectory(${DEF_CONF_PATH}) set(FSFW_CONFIG_PATH ${DEF_CONF_PATH}) diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake index 14fc4978..530926a6 100644 --- a/cmake/helpers.cmake +++ b/cmake/helpers.cmake @@ -24,5 +24,5 @@ function(determine_version_with_git) list(APPEND GIT_INFO ${_VERSION_PATCH}) list(APPEND GIT_INFO ${VERSION_SHA1}) set(GIT_INFO ${GIT_INFO} PARENT_SCOPE) - message(STATUS "Set git version info into GIT_INFO from the git tag ${VERSION}") + message(STATUS "${MSG_PREFIX} Set git version info into GIT_INFO from the git tag ${VERSION}") endfunction() From effecd46627feeb5590333014523670a6a12772e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:33:34 +0200 Subject: [PATCH 051/198] include cmake-modules manually instead - Instead of using FetchContent - Separate folder for easier update and for distintion - LICENSE file included --- CMakeLists.txt | 13 +- cmake/GetGitRevisionDescription.cmake | 284 ------- cmake/cmake-modules/CodeCoverage.cmake | 719 ++++++++++++++++++ .../GetGitRevisionDescription.cmake | 141 ++++ .../GetGitRevisionDescription.cmake.in | 21 +- cmake/cmake-modules/LICENSE_1_0.txt | 23 + cmake/cmake-modules/README.md | 5 + cmake/helpers.cmake | 2 +- 8 files changed, 900 insertions(+), 308 deletions(-) delete mode 100644 cmake/GetGitRevisionDescription.cmake create mode 100644 cmake/cmake-modules/CodeCoverage.cmake create mode 100644 cmake/cmake-modules/GetGitRevisionDescription.cmake rename cmake/{ => cmake-modules}/GetGitRevisionDescription.cmake.in (59%) create mode 100644 cmake/cmake-modules/LICENSE_1_0.txt create mode 100644 cmake/cmake-modules/README.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 21495f37..282eadcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.13) # Add the cmake folder so the FindSphinx module is found -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) - +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-modules") set(MSG_PREFIX "fsfw |") option(FSFW_GENERATE_SECTIONS @@ -44,7 +44,7 @@ project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) # Version handling -include("GetGitRevisionDescription") +include(helpers) determine_version_with_git("--exclude" "docker_*") set(GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") list(GET GIT_INFO 1 FSFW_VERSION) @@ -93,14 +93,7 @@ if(FSFW_BUILD_UNITTESTS) message(STATUS "${MSG_PREFIX} Targets linking against ${LIB_FSFW_NAME} " "will be compiled with coverage data as well" ) - include(FetchContent) - FetchContent_Declare( - cmake-modules - GIT_REPOSITORY https://github.com/bilke/cmake-modules.git - ) - FetchContent_MakeAvailable(cmake-modules) set(CMAKE_BUILD_TYPE "Debug") - list(APPEND CMAKE_MODULE_PATH ${cmake-modules_SOURCE_DIR}) include(CodeCoverage) endif() endif() diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake deleted file mode 100644 index 69ef78b2..00000000 --- a/cmake/GetGitRevisionDescription.cmake +++ /dev/null @@ -1,284 +0,0 @@ -# - Returns a version string from Git -# -# These functions force a re-configure on each git commit so that you can -# trust the values of the variables in your build system. -# -# get_git_head_revision( [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR]) -# -# Returns the refspec and sha hash of the current head revision -# -# git_describe( [ ...]) -# -# Returns the results of git describe on the source tree, and adjusting -# the output so that it tests false if an error occurs. -# -# git_describe_working_tree( [ ...]) -# -# Returns the results of git describe on the working tree (--dirty option), -# and adjusting the output so that it tests false if an error occurs. -# -# git_get_exact_tag( [ ...]) -# -# Returns the results of git describe --exact-match on the source tree, -# and adjusting the output so that it tests false if there was no exact -# matching tag. -# -# git_local_changes() -# -# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. -# Uses the return code of "git diff-index --quiet HEAD --". -# Does not regard untracked files. -# -# Requires CMake 2.6 or newer (uses the 'function' command) -# -# Original Author: -# 2009-2020 Ryan Pavlik -# http://academic.cleardefinition.com -# -# Copyright 2009-2013, Iowa State University. -# Copyright 2013-2020, Ryan Pavlik -# Copyright 2013-2020, Contributors -# SPDX-License-Identifier: BSL-1.0 -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -if(__get_git_revision_description) - return() -endif() -set(__get_git_revision_description YES) - -# We must run the following at "include" time, not at function call time, -# to find the path to this module rather than the path to a calling list file -get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) - -# Function _git_find_closest_git_dir finds the next closest .git directory -# that is part of any directory in the path defined by _start_dir. -# The result is returned in the parent scope variable whose name is passed -# as variable _git_dir_var. If no .git directory can be found, the -# function returns an empty string via _git_dir_var. -# -# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and -# neither foo nor bar contain a file/directory .git. This wil return -# C:/bla/.git -# -function(_git_find_closest_git_dir _start_dir _git_dir_var) - set(cur_dir "${_start_dir}") - set(git_dir "${_start_dir}/.git") - while(NOT EXISTS "${git_dir}") - # .git dir not found, search parent directories - set(git_previous_parent "${cur_dir}") - get_filename_component(cur_dir "${cur_dir}" DIRECTORY) - if(cur_dir STREQUAL git_previous_parent) - # We have reached the root directory, we are not in git - set(${_git_dir_var} - "" - PARENT_SCOPE) - return() - endif() - set(git_dir "${cur_dir}/.git") - endwhile() - set(${_git_dir_var} - "${git_dir}" - PARENT_SCOPE) -endfunction() - -function(get_git_head_revision _refspecvar _hashvar) - _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) - - if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR") - set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE) - else() - set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE) - endif() - if(NOT "${GIT_DIR}" STREQUAL "") - file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}" - "${GIT_DIR}") - if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR) - # We've gone above the CMake root dir. - set(GIT_DIR "") - endif() - endif() - if("${GIT_DIR}" STREQUAL "") - set(${_refspecvar} - "GITDIR-NOTFOUND" - PARENT_SCOPE) - set(${_hashvar} - "GITDIR-NOTFOUND" - PARENT_SCOPE) - return() - endif() - - # Check if the current source dir is a git submodule or a worktree. - # In both cases .git is a file instead of a directory. - # - if(NOT IS_DIRECTORY ${GIT_DIR}) - # The following git command will return a non empty string that - # points to the super project working tree if the current - # source dir is inside a git submodule. - # Otherwise the command will return an empty string. - # - execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse - --show-superproject-working-tree - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT "${out}" STREQUAL "") - # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule - file(READ ${GIT_DIR} submodule) - string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE - ${submodule}) - string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) - get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) - get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} - ABSOLUTE) - set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") - else() - # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree - file(READ ${GIT_DIR} worktree_ref) - # The .git directory contains a path to the worktree information directory - # inside the parent git repo of the worktree. - # - string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir - ${worktree_ref}) - string(STRIP ${git_worktree_dir} git_worktree_dir) - _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) - set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") - endif() - else() - set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") - endif() - set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") - if(NOT EXISTS "${GIT_DATA}") - file(MAKE_DIRECTORY "${GIT_DATA}") - endif() - - if(NOT EXISTS "${HEAD_SOURCE_FILE}") - return() - endif() - set(HEAD_FILE "${GIT_DATA}/HEAD") - configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) - - configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" - "${GIT_DATA}/grabRef.cmake" @ONLY) - include("${GIT_DATA}/grabRef.cmake") - - set(${_refspecvar} - "${HEAD_REF}" - PARENT_SCOPE) - set(${_hashvar} - "${HEAD_HASH}" - PARENT_SCOPE) -endfunction() - -function(git_describe _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - get_git_head_revision(refspec hash) - if(NOT GIT_FOUND) - set(${_var} - "GIT-NOTFOUND" - PARENT_SCOPE) - return() - endif() - if(NOT hash) - set(${_var} - "HEAD-HASH-NOTFOUND" - PARENT_SCOPE) - return() - endif() - - # TODO sanitize - #if((${ARGN}" MATCHES "&&") OR - # (ARGN MATCHES "||") OR - # (ARGN MATCHES "\\;")) - # message("Please report the following error to the project!") - # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") - #endif() - - #message(STATUS "Arguments to execute_process: ${ARGN}") - - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") - endif() - - set(${_var} - "${out}" - PARENT_SCOPE) -endfunction() - -function(git_describe_working_tree _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - if(NOT GIT_FOUND) - set(${_var} - "GIT-NOTFOUND" - PARENT_SCOPE) - return() - endif() - - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") - endif() - - set(${_var} - "${out}" - PARENT_SCOPE) -endfunction() - -function(git_get_exact_tag _var) - git_describe(out --exact-match ${ARGN}) - set(${_var} - "${out}" - PARENT_SCOPE) -endfunction() - -function(git_local_changes _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - get_git_head_revision(refspec hash) - if(NOT GIT_FOUND) - set(${_var} - "GIT-NOTFOUND" - PARENT_SCOPE) - return() - endif() - if(NOT hash) - set(${_var} - "HEAD-HASH-NOTFOUND" - PARENT_SCOPE) - return() - endif() - - execute_process( - COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD -- - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE out - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(res EQUAL 0) - set(${_var} - "CLEAN" - PARENT_SCOPE) - else() - set(${_var} - "DIRTY" - PARENT_SCOPE) - endif() -endfunction() diff --git a/cmake/cmake-modules/CodeCoverage.cmake b/cmake/cmake-modules/CodeCoverage.cmake new file mode 100644 index 00000000..aef3d943 --- /dev/null +++ b/cmake/cmake-modules/CodeCoverage.cmake @@ -0,0 +1,719 @@ +# Copyright (c) 2012 - 2017, Lars Bilke +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# CHANGES: +# +# 2012-01-31, Lars Bilke +# - Enable Code Coverage +# +# 2013-09-17, Joakim Söderberg +# - Added support for Clang. +# - Some additional usage instructions. +# +# 2016-02-03, Lars Bilke +# - Refactored functions to use named parameters +# +# 2017-06-02, Lars Bilke +# - Merged with modified version from github.com/ufz/ogs +# +# 2019-05-06, Anatolii Kurotych +# - Remove unnecessary --coverage flag +# +# 2019-12-13, FeRD (Frank Dana) +# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor +# of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments. +# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY +# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list +# - Set lcov basedir with -b argument +# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be +# overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().) +# - Delete output dir, .info file on 'make clean' +# - Remove Python detection, since version mismatches will break gcovr +# - Minor cleanup (lowercase function names, update examples...) +# +# 2019-12-19, FeRD (Frank Dana) +# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets +# +# 2020-01-19, Bob Apthorpe +# - Added gfortran support +# +# 2020-02-17, FeRD (Frank Dana) +# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters +# in EXCLUDEs, and remove manual escaping from gcovr targets +# +# 2021-01-19, Robin Mueller +# - Add CODE_COVERAGE_VERBOSE option which will allow to print out commands which are run +# - Added the option for users to set the GCOVR_ADDITIONAL_ARGS variable to supply additional +# flags to the gcovr command +# +# 2020-05-04, Mihchael Davis +# - Add -fprofile-abs-path to make gcno files contain absolute paths +# - Fix BASE_DIRECTORY not working when defined +# - Change BYPRODUCT from folder to index.html to stop ninja from complaining about double defines +# +# 2021-05-10, Martin Stump +# - Check if the generator is multi-config before warning about non-Debug builds +# +# 2022-02-22, Marko Wehle +# - Change gcovr output from -o for --xml and --html output respectively. +# This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt". +# +# USAGE: +# +# 1. Copy this file into your cmake modules path. +# +# 2. Add the following line to your CMakeLists.txt (best inside an if-condition +# using a CMake option() to enable it just optionally): +# include(CodeCoverage) +# +# 3. Append necessary compiler flags for all supported source files: +# append_coverage_compiler_flags() +# Or for specific target: +# append_coverage_compiler_flags_to_target(YOUR_TARGET_NAME) +# +# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og +# +# 4. If you need to exclude additional directories from the report, specify them +# using full paths in the COVERAGE_EXCLUDES variable before calling +# setup_target_for_coverage_*(). +# Example: +# set(COVERAGE_EXCLUDES +# '${PROJECT_SOURCE_DIR}/src/dir1/*' +# '/path/to/my/src/dir2/*') +# Or, use the EXCLUDE argument to setup_target_for_coverage_*(). +# Example: +# setup_target_for_coverage_lcov( +# NAME coverage +# EXECUTABLE testrunner +# EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*") +# +# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set +# relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR) +# Example: +# set(COVERAGE_EXCLUDES "dir1/*") +# setup_target_for_coverage_gcovr_html( +# NAME coverage +# EXECUTABLE testrunner +# BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src" +# EXCLUDE "dir2/*") +# +# 5. Use the functions described below to create a custom make target which +# runs your test executable and produces a code coverage report. +# +# 6. Build a Debug build: +# cmake -DCMAKE_BUILD_TYPE=Debug .. +# make +# make my_coverage_target +# + +include(CMakeParseArguments) + +option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE) + +# Check prereqs +find_program( GCOV_PATH gcov ) +find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl) +find_program( FASTCOV_PATH NAMES fastcov fastcov.py ) +find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat ) +find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) +find_program( CPPFILT_PATH NAMES c++filt ) + +if(NOT GCOV_PATH) + message(FATAL_ERROR "gcov not found! Aborting...") +endif() # NOT GCOV_PATH + +get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) +list(GET LANGUAGES 0 LANG) + +if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") + if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3) + message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") + endif() +elseif(NOT CMAKE_COMPILER_IS_GNUCXX) + if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "[Ff]lang") + # Do nothing; exit conditional without error if true + elseif("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU") + # Do nothing; exit conditional without error if true + else() + message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...") + endif() +endif() + +set(COVERAGE_COMPILER_FLAGS "-g -fprofile-arcs -ftest-coverage" + CACHE INTERNAL "") +if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-fprofile-abs-path HAVE_fprofile_abs_path) + if(HAVE_fprofile_abs_path) + set(COVERAGE_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path") + endif() +endif() + +set(CMAKE_Fortran_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the Fortran compiler during coverage builds." + FORCE ) +set(CMAKE_CXX_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C++ compiler during coverage builds." + FORCE ) +set(CMAKE_C_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C compiler during coverage builds." + FORCE ) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used for linking binaries during coverage builds." + FORCE ) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used by the shared libraries linker during coverage builds." + FORCE ) +mark_as_advanced( + CMAKE_Fortran_FLAGS_COVERAGE + CMAKE_CXX_FLAGS_COVERAGE + CMAKE_C_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) + +get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)) + message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") +endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + link_libraries(gcov) +endif() + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# setup_target_for_coverage_lcov( +# NAME testrunner_coverage # New target name +# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES testrunner # Dependencies to build first +# BASE_DIRECTORY "../" # Base directory for report +# # (defaults to PROJECT_SOURCE_DIR) +# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative +# # to BASE_DIRECTORY, with CMake 3.4+) +# NO_DEMANGLE # Don't demangle C++ symbols +# # even if c++filt is found +# ) +function(setup_target_for_coverage_lcov) + + set(options NO_DEMANGLE) + set(oneValueArgs BASE_DIRECTORY NAME) + set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT LCOV_PATH) + message(FATAL_ERROR "lcov not found! Aborting...") + endif() # NOT LCOV_PATH + + if(NOT GENHTML_PATH) + message(FATAL_ERROR "genhtml not found! Aborting...") + endif() # NOT GENHTML_PATH + + # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR + if(DEFINED Coverage_BASE_DIRECTORY) + get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) + else() + set(BASEDIR ${PROJECT_SOURCE_DIR}) + endif() + + # Collect excludes (CMake 3.4+: Also compute absolute paths) + set(LCOV_EXCLUDES "") + foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_LCOV_EXCLUDES}) + if(CMAKE_VERSION VERSION_GREATER 3.4) + get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) + endif() + list(APPEND LCOV_EXCLUDES "${EXCLUDE}") + endforeach() + list(REMOVE_DUPLICATES LCOV_EXCLUDES) + + # Conditional arguments + if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE}) + set(GENHTML_EXTRA_ARGS "--demangle-cpp") + endif() + + # Setting up commands which will be run to generate coverage data. + # Cleanup lcov + set(LCOV_CLEAN_CMD + ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory . + -b ${BASEDIR} --zerocounters + ) + # Create baseline to make sure untouched files show up in the report + set(LCOV_BASELINE_CMD + ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -b + ${BASEDIR} -o ${Coverage_NAME}.base + ) + # Run tests + set(LCOV_EXEC_TESTS_CMD + ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS} + ) + # Capturing lcov counters and generating report + set(LCOV_CAPTURE_CMD + ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . -b + ${BASEDIR} --capture --output-file ${Coverage_NAME}.capture + ) + # add baseline counters + set(LCOV_BASELINE_COUNT_CMD + ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base + -a ${Coverage_NAME}.capture --output-file ${Coverage_NAME}.total + ) + # filter collected data to final coverage report + set(LCOV_FILTER_CMD + ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove + ${Coverage_NAME}.total ${LCOV_EXCLUDES} --output-file ${Coverage_NAME}.info + ) + # Generate HTML output + set(LCOV_GEN_HTML_CMD + ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o + ${Coverage_NAME} ${Coverage_NAME}.info + ) + + + if(CODE_COVERAGE_VERBOSE) + message(STATUS "Executed command report") + message(STATUS "Command to clean up lcov: ") + string(REPLACE ";" " " LCOV_CLEAN_CMD_SPACED "${LCOV_CLEAN_CMD}") + message(STATUS "${LCOV_CLEAN_CMD_SPACED}") + + message(STATUS "Command to create baseline: ") + string(REPLACE ";" " " LCOV_BASELINE_CMD_SPACED "${LCOV_BASELINE_CMD}") + message(STATUS "${LCOV_BASELINE_CMD_SPACED}") + + message(STATUS "Command to run the tests: ") + string(REPLACE ";" " " LCOV_EXEC_TESTS_CMD_SPACED "${LCOV_EXEC_TESTS_CMD}") + message(STATUS "${LCOV_EXEC_TESTS_CMD_SPACED}") + + message(STATUS "Command to capture counters and generate report: ") + string(REPLACE ";" " " LCOV_CAPTURE_CMD_SPACED "${LCOV_CAPTURE_CMD}") + message(STATUS "${LCOV_CAPTURE_CMD_SPACED}") + + message(STATUS "Command to add baseline counters: ") + string(REPLACE ";" " " LCOV_BASELINE_COUNT_CMD_SPACED "${LCOV_BASELINE_COUNT_CMD}") + message(STATUS "${LCOV_BASELINE_COUNT_CMD_SPACED}") + + message(STATUS "Command to filter collected data: ") + string(REPLACE ";" " " LCOV_FILTER_CMD_SPACED "${LCOV_FILTER_CMD}") + message(STATUS "${LCOV_FILTER_CMD_SPACED}") + + message(STATUS "Command to generate lcov HTML output: ") + string(REPLACE ";" " " LCOV_GEN_HTML_CMD_SPACED "${LCOV_GEN_HTML_CMD}") + message(STATUS "${LCOV_GEN_HTML_CMD_SPACED}") + endif() + + # Setup target + add_custom_target(${Coverage_NAME} + COMMAND ${LCOV_CLEAN_CMD} + COMMAND ${LCOV_BASELINE_CMD} + COMMAND ${LCOV_EXEC_TESTS_CMD} + COMMAND ${LCOV_CAPTURE_CMD} + COMMAND ${LCOV_BASELINE_COUNT_CMD} + COMMAND ${LCOV_FILTER_CMD} + COMMAND ${LCOV_GEN_HTML_CMD} + + # Set output files as GENERATED (will be removed on 'make clean') + BYPRODUCTS + ${Coverage_NAME}.base + ${Coverage_NAME}.capture + ${Coverage_NAME}.total + ${Coverage_NAME}.info + ${Coverage_NAME}/index.html + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + VERBATIM # Protect arguments to commands + COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + ) + + # Show where to find the lcov info report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." + ) + +endfunction() # setup_target_for_coverage_lcov + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# setup_target_for_coverage_gcovr_xml( +# NAME ctest_coverage # New target name +# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES executable_target # Dependencies to build first +# BASE_DIRECTORY "../" # Base directory for report +# # (defaults to PROJECT_SOURCE_DIR) +# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative +# # to BASE_DIRECTORY, with CMake 3.4+) +# ) +# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the +# GCVOR command. +function(setup_target_for_coverage_gcovr_xml) + + set(options NONE) + set(oneValueArgs BASE_DIRECTORY NAME) + set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT GCOVR_PATH) + message(FATAL_ERROR "gcovr not found! Aborting...") + endif() # NOT GCOVR_PATH + + # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR + if(DEFINED Coverage_BASE_DIRECTORY) + get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) + else() + set(BASEDIR ${PROJECT_SOURCE_DIR}) + endif() + + # Collect excludes (CMake 3.4+: Also compute absolute paths) + set(GCOVR_EXCLUDES "") + foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES}) + if(CMAKE_VERSION VERSION_GREATER 3.4) + get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) + endif() + list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") + endforeach() + list(REMOVE_DUPLICATES GCOVR_EXCLUDES) + + # Combine excludes to several -e arguments + set(GCOVR_EXCLUDE_ARGS "") + foreach(EXCLUDE ${GCOVR_EXCLUDES}) + list(APPEND GCOVR_EXCLUDE_ARGS "-e") + list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}") + endforeach() + + # Set up commands which will be run to generate coverage data + # Run tests + set(GCOVR_XML_EXEC_TESTS_CMD + ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS} + ) + # Running gcovr + set(GCOVR_XML_CMD + ${GCOVR_PATH} --xml ${Coverage_NAME}.xml -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS} + ${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR} + ) + + if(CODE_COVERAGE_VERBOSE) + message(STATUS "Executed command report") + + message(STATUS "Command to run tests: ") + string(REPLACE ";" " " GCOVR_XML_EXEC_TESTS_CMD_SPACED "${GCOVR_XML_EXEC_TESTS_CMD}") + message(STATUS "${GCOVR_XML_EXEC_TESTS_CMD_SPACED}") + + message(STATUS "Command to generate gcovr XML coverage data: ") + string(REPLACE ";" " " GCOVR_XML_CMD_SPACED "${GCOVR_XML_CMD}") + message(STATUS "${GCOVR_XML_CMD_SPACED}") + endif() + + add_custom_target(${Coverage_NAME} + COMMAND ${GCOVR_XML_EXEC_TESTS_CMD} + COMMAND ${GCOVR_XML_CMD} + + BYPRODUCTS ${Coverage_NAME}.xml + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + VERBATIM # Protect arguments to commands + COMMENT "Running gcovr to produce Cobertura code coverage report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml." + ) +endfunction() # setup_target_for_coverage_gcovr_xml + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# setup_target_for_coverage_gcovr_html( +# NAME ctest_coverage # New target name +# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES executable_target # Dependencies to build first +# BASE_DIRECTORY "../" # Base directory for report +# # (defaults to PROJECT_SOURCE_DIR) +# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative +# # to BASE_DIRECTORY, with CMake 3.4+) +# ) +# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the +# GCVOR command. +function(setup_target_for_coverage_gcovr_html) + + set(options NONE) + set(oneValueArgs BASE_DIRECTORY NAME) + set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT GCOVR_PATH) + message(FATAL_ERROR "gcovr not found! Aborting...") + endif() # NOT GCOVR_PATH + + # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR + if(DEFINED Coverage_BASE_DIRECTORY) + get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) + else() + set(BASEDIR ${PROJECT_SOURCE_DIR}) + endif() + + # Collect excludes (CMake 3.4+: Also compute absolute paths) + set(GCOVR_EXCLUDES "") + foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES}) + if(CMAKE_VERSION VERSION_GREATER 3.4) + get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) + endif() + list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") + endforeach() + list(REMOVE_DUPLICATES GCOVR_EXCLUDES) + + # Combine excludes to several -e arguments + set(GCOVR_EXCLUDE_ARGS "") + foreach(EXCLUDE ${GCOVR_EXCLUDES}) + list(APPEND GCOVR_EXCLUDE_ARGS "-e") + list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}") + endforeach() + + # Set up commands which will be run to generate coverage data + # Run tests + set(GCOVR_HTML_EXEC_TESTS_CMD + ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS} + ) + # Create folder + set(GCOVR_HTML_FOLDER_CMD + ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME} + ) + # Running gcovr + set(GCOVR_HTML_CMD + ${GCOVR_PATH} --html ${Coverage_NAME}/index.html --html-details -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS} + ${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR} + ) + + if(CODE_COVERAGE_VERBOSE) + message(STATUS "Executed command report") + + message(STATUS "Command to run tests: ") + string(REPLACE ";" " " GCOVR_HTML_EXEC_TESTS_CMD_SPACED "${GCOVR_HTML_EXEC_TESTS_CMD}") + message(STATUS "${GCOVR_HTML_EXEC_TESTS_CMD_SPACED}") + + message(STATUS "Command to create a folder: ") + string(REPLACE ";" " " GCOVR_HTML_FOLDER_CMD_SPACED "${GCOVR_HTML_FOLDER_CMD}") + message(STATUS "${GCOVR_HTML_FOLDER_CMD_SPACED}") + + message(STATUS "Command to generate gcovr HTML coverage data: ") + string(REPLACE ";" " " GCOVR_HTML_CMD_SPACED "${GCOVR_HTML_CMD}") + message(STATUS "${GCOVR_HTML_CMD_SPACED}") + endif() + + add_custom_target(${Coverage_NAME} + COMMAND ${GCOVR_HTML_EXEC_TESTS_CMD} + COMMAND ${GCOVR_HTML_FOLDER_CMD} + COMMAND ${GCOVR_HTML_CMD} + + BYPRODUCTS ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html # report directory + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + VERBATIM # Protect arguments to commands + COMMENT "Running gcovr to produce HTML code coverage report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." + ) + +endfunction() # setup_target_for_coverage_gcovr_html + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# setup_target_for_coverage_fastcov( +# NAME testrunner_coverage # New target name +# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES testrunner # Dependencies to build first +# BASE_DIRECTORY "../" # Base directory for report +# # (defaults to PROJECT_SOURCE_DIR) +# EXCLUDE "src/dir1/" "src/dir2/" # Patterns to exclude. +# NO_DEMANGLE # Don't demangle C++ symbols +# # even if c++filt is found +# SKIP_HTML # Don't create html report +# POST_CMD perl -i -pe s!${PROJECT_SOURCE_DIR}/!!g ctest_coverage.json # E.g. for stripping source dir from file paths +# ) +function(setup_target_for_coverage_fastcov) + + set(options NO_DEMANGLE SKIP_HTML) + set(oneValueArgs BASE_DIRECTORY NAME) + set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES FASTCOV_ARGS GENHTML_ARGS POST_CMD) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT FASTCOV_PATH) + message(FATAL_ERROR "fastcov not found! Aborting...") + endif() + + if(NOT Coverage_SKIP_HTML AND NOT GENHTML_PATH) + message(FATAL_ERROR "genhtml not found! Aborting...") + endif() + + # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR + if(Coverage_BASE_DIRECTORY) + get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) + else() + set(BASEDIR ${PROJECT_SOURCE_DIR}) + endif() + + # Collect excludes (Patterns, not paths, for fastcov) + set(FASTCOV_EXCLUDES "") + foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_FASTCOV_EXCLUDES}) + list(APPEND FASTCOV_EXCLUDES "${EXCLUDE}") + endforeach() + list(REMOVE_DUPLICATES FASTCOV_EXCLUDES) + + # Conditional arguments + if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE}) + set(GENHTML_EXTRA_ARGS "--demangle-cpp") + endif() + + # Set up commands which will be run to generate coverage data + set(FASTCOV_EXEC_TESTS_CMD ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}) + + set(FASTCOV_CAPTURE_CMD ${FASTCOV_PATH} ${Coverage_FASTCOV_ARGS} --gcov ${GCOV_PATH} + --search-directory ${BASEDIR} + --process-gcno + --output ${Coverage_NAME}.json + --exclude ${FASTCOV_EXCLUDES} + --exclude ${FASTCOV_EXCLUDES} + ) + + set(FASTCOV_CONVERT_CMD ${FASTCOV_PATH} + -C ${Coverage_NAME}.json --lcov --output ${Coverage_NAME}.info + ) + + if(Coverage_SKIP_HTML) + set(FASTCOV_HTML_CMD ";") + else() + set(FASTCOV_HTML_CMD ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} + -o ${Coverage_NAME} ${Coverage_NAME}.info + ) + endif() + + set(FASTCOV_POST_CMD ";") + if(Coverage_POST_CMD) + set(FASTCOV_POST_CMD ${Coverage_POST_CMD}) + endif() + + if(CODE_COVERAGE_VERBOSE) + message(STATUS "Code coverage commands for target ${Coverage_NAME} (fastcov):") + + message(" Running tests:") + string(REPLACE ";" " " FASTCOV_EXEC_TESTS_CMD_SPACED "${FASTCOV_EXEC_TESTS_CMD}") + message(" ${FASTCOV_EXEC_TESTS_CMD_SPACED}") + + message(" Capturing fastcov counters and generating report:") + string(REPLACE ";" " " FASTCOV_CAPTURE_CMD_SPACED "${FASTCOV_CAPTURE_CMD}") + message(" ${FASTCOV_CAPTURE_CMD_SPACED}") + + message(" Converting fastcov .json to lcov .info:") + string(REPLACE ";" " " FASTCOV_CONVERT_CMD_SPACED "${FASTCOV_CONVERT_CMD}") + message(" ${FASTCOV_CONVERT_CMD_SPACED}") + + if(NOT Coverage_SKIP_HTML) + message(" Generating HTML report: ") + string(REPLACE ";" " " FASTCOV_HTML_CMD_SPACED "${FASTCOV_HTML_CMD}") + message(" ${FASTCOV_HTML_CMD_SPACED}") + endif() + if(Coverage_POST_CMD) + message(" Running post command: ") + string(REPLACE ";" " " FASTCOV_POST_CMD_SPACED "${FASTCOV_POST_CMD}") + message(" ${FASTCOV_POST_CMD_SPACED}") + endif() + endif() + + # Setup target + add_custom_target(${Coverage_NAME} + + # Cleanup fastcov + COMMAND ${FASTCOV_PATH} ${Coverage_FASTCOV_ARGS} --gcov ${GCOV_PATH} + --search-directory ${BASEDIR} + --zerocounters + + COMMAND ${FASTCOV_EXEC_TESTS_CMD} + COMMAND ${FASTCOV_CAPTURE_CMD} + COMMAND ${FASTCOV_CONVERT_CMD} + COMMAND ${FASTCOV_HTML_CMD} + COMMAND ${FASTCOV_POST_CMD} + + # Set output files as GENERATED (will be removed on 'make clean') + BYPRODUCTS + ${Coverage_NAME}.info + ${Coverage_NAME}.json + ${Coverage_NAME}/index.html # report directory + + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + VERBATIM # Protect arguments to commands + COMMENT "Resetting code coverage counters to zero. Processing code coverage counters and generating report." + ) + + set(INFO_MSG "fastcov code coverage info report saved in ${Coverage_NAME}.info and ${Coverage_NAME}.json.") + if(NOT Coverage_SKIP_HTML) + string(APPEND INFO_MSG " Open ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html in your browser to view the coverage report.") + endif() + # Show where to find the fastcov info report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo ${INFO_MSG} + ) + +endfunction() # setup_target_for_coverage_fastcov + +function(append_coverage_compiler_flags) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}") +endfunction() # append_coverage_compiler_flags + +# Setup coverage for specific library +function(append_coverage_compiler_flags_to_target name) + target_compile_options(${name} + PRIVATE ${COVERAGE_COMPILER_FLAGS}) +endfunction() diff --git a/cmake/cmake-modules/GetGitRevisionDescription.cmake b/cmake/cmake-modules/GetGitRevisionDescription.cmake new file mode 100644 index 00000000..1175e673 --- /dev/null +++ b/cmake/cmake-modules/GetGitRevisionDescription.cmake @@ -0,0 +1,141 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + + if (IS_ABSOLUTE ${GIT_DIR_RELATIVE}) + set(GIT_DIR ${GIT_DIR_RELATIVE}) + else() + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + ${GIT_EXECUTABLE} + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_tag _var) + git_describe(out --tags ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/cmake-modules/GetGitRevisionDescription.cmake.in similarity index 59% rename from cmake/GetGitRevisionDescription.cmake.in rename to cmake/cmake-modules/GetGitRevisionDescription.cmake.in index 66eee637..ae19652b 100644 --- a/cmake/GetGitRevisionDescription.cmake.in +++ b/cmake/cmake-modules/GetGitRevisionDescription.cmake.in @@ -1,4 +1,4 @@ -# +# # Internal file for GetGitRevisionDescription.cmake # # Requires CMake 2.6 or newer (uses the 'function' command) @@ -8,12 +8,10 @@ # http://academic.cleardefinition.com # Iowa State University HCI Graduate Program/VRAC # -# Copyright 2009-2012, Iowa State University -# Copyright 2011-2015, Contributors +# Copyright Iowa State University 2009-2010. # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -# SPDX-License-Identifier: BSL-1.0 set(HEAD_HASH) @@ -24,13 +22,10 @@ if(HEAD_CONTENTS MATCHES "ref") # named branch string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") if(EXISTS "@GIT_DIR@/${HEAD_REF}") - configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - else() - configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) - file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) - if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") - set(HEAD_HASH "${CMAKE_MATCH_1}") - endif() + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") + configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + set(HEAD_HASH "${HEAD_REF}") endif() else() # detached HEAD @@ -38,6 +33,6 @@ else() endif() if(NOT HEAD_HASH) - file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) - string(STRIP "${HEAD_HASH}" HEAD_HASH) +file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) +string(STRIP "${HEAD_HASH}" HEAD_HASH) endif() diff --git a/cmake/cmake-modules/LICENSE_1_0.txt b/cmake/cmake-modules/LICENSE_1_0.txt new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/cmake/cmake-modules/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/cmake/cmake-modules/README.md b/cmake/cmake-modules/README.md new file mode 100644 index 00000000..4692eddb --- /dev/null +++ b/cmake/cmake-modules/README.md @@ -0,0 +1,5 @@ +The files in these folder were manually copy and pasted from the +[cmake-modules repository](https://github.com/bilke/cmake-modules). It was decided to do +this because only a small subset of its provided functions are needed. + +The license file in included here as well. diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake index 530926a6..3f22ebde 100644 --- a/cmake/helpers.cmake +++ b/cmake/helpers.cmake @@ -6,7 +6,7 @@ # 4. Revision # 5. git SHA hash and commits since tag function(determine_version_with_git) - include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake) + include(GetGitRevisionDescription) git_describe(VERSION ${ARGN}) string(FIND ${VERSION} "." VALID_VERSION) if(VALID_VERSION EQUAL -1) From 513ae9dc105755307b12c66111708a386f9aac52 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:38:32 +0200 Subject: [PATCH 052/198] prefixed git info variable --- CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 282eadcc..e54a4b80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,12 +45,12 @@ add_library(${LIB_FSFW_NAME}) # Version handling include(helpers) -determine_version_with_git("--exclude" "docker_*") -set(GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") -list(GET GIT_INFO 1 FSFW_VERSION) -list(GET GIT_INFO 2 FSFW_SUBVERSION) -list(GET GIT_INFO 3 FSFW_REVISION) -list(GET GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) +determine_version_with_git() +set(FSFW_GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") +list(GET FSFW_GIT_INFO 1 FSFW_VERSION) +list(GET FSFW_GIT_INFO 2 FSFW_SUBVERSION) +list(GET FSFW_GIT_INFO 3 FSFW_REVISION) +list(GET FSFW_GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) if(NOT FSFW_VERSION) set(FSFW_VERSION -1) endif() From 9c7eba4431cef294e96ec6544013ce082c596ba6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:47:28 +0200 Subject: [PATCH 053/198] git version handler more robust now --- CMakeLists.txt | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e54a4b80..9066cec2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.13) +set(FSFW_VERSION_IF_GIT_FAILS 4) +set(FSFW_SUBVERSION_IF_GIT_FAILS 0) +set(FSFW_REVISION_IF_GIT_FAILS 0) + # Add the cmake folder so the FindSphinx module is found list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-modules") @@ -44,21 +48,27 @@ project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) # Version handling -include(helpers) -determine_version_with_git() -set(FSFW_GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") -list(GET FSFW_GIT_INFO 1 FSFW_VERSION) -list(GET FSFW_GIT_INFO 2 FSFW_SUBVERSION) -list(GET FSFW_GIT_INFO 3 FSFW_REVISION) -list(GET FSFW_GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) -if(NOT FSFW_VERSION) - set(FSFW_VERSION -1) -endif() -if(NOT FSFW_SUBVERSION) - set(FSFW_SUBVERSION -1) -endif() -if(NOT FSFW_REVISION) - set(FSFW_REVISION -1) +if(EXISTS .git) + include(helpers) + determine_version_with_git("--exclude" "docker_*") + set(FSFW_GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") + list(GET FSFW_GIT_INFO 1 FSFW_VERSION) + list(GET FSFW_GIT_INFO 2 FSFW_SUBVERSION) + list(GET FSFW_GIT_INFO 3 FSFW_REVISION) + list(GET FSFW_GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) + if(NOT FSFW_VERSION) + set(FSFW_VERSION ${FSFW_VERSION_IF_GIT_FAILS}) + endif() + if(NOT FSFW_SUBVERSION) + set(FSFW_SUBVERSION ${FSFW_SUBVERSION_IF_GIT_FAILS}) + endif() + if(NOT FSFW_REVISION) + set(FSFW_REVISION ${FSFW_REVISION_IF_GIT_FAILS}) + endif() +else() + set(FSFW_VERSION ${FSFW_VERSION_IF_GIT_FAILS}) + set(FSFW_SUBVERSION ${FSFW_SUBVERSION_IF_GIT_FAILS}) + set(FSFW_REVISION ${FSFW_REVISION_IF_GIT_FAILS}) endif() if(FSFW_BUILD_UNITTESTS) From a569990ca2683c537acb88b4866962e57f9a054c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:50:50 +0200 Subject: [PATCH 054/198] fix tests --- tests/src/fsfw_tests/unit/version.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/src/fsfw_tests/unit/version.cpp b/tests/src/fsfw_tests/unit/version.cpp index 2967dfa5..f9170a4d 100644 --- a/tests/src/fsfw_tests/unit/version.cpp +++ b/tests/src/fsfw_tests/unit/version.cpp @@ -10,12 +10,12 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { // Check that major version is non-zero REQUIRE(fsfw::FSFW_VERSION.major > 0); uint32_t fsfwMajor = fsfw::FSFW_VERSION.major; - REQUIRE(fsfw::Version(255, 0, 0) > fsfw::FSFW_VERSION); - REQUIRE(fsfw::Version(255, 0, 0) >= fsfw::FSFW_VERSION); - REQUIRE(fsfw::Version(0, 0, 0) < fsfw::FSFW_VERSION); - REQUIRE(fsfw::Version(0, 0, 0) <= fsfw::FSFW_VERSION); - fsfw::Version v1 = fsfw::Version(1, 1, 1); - fsfw::Version v2 = fsfw::Version(1, 1, 1); + REQUIRE(Version(255, 0, 0) > fsfw::FSFW_VERSION); + REQUIRE(Version(255, 0, 0) >= fsfw::FSFW_VERSION); + REQUIRE(Version(0, 0, 0) < fsfw::FSFW_VERSION); + REQUIRE(Version(0, 0, 0) <= fsfw::FSFW_VERSION); + Version v1 = fsfw::Version(1, 1, 1); + Version v2 = fsfw::Version(1, 1, 1); REQUIRE(v1 == v2); REQUIRE(not(v1 < v2)); REQUIRE(not(v1 > v2)); From 4079edc80e57bd29394b28b7d0119367960b3fff Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:52:55 +0200 Subject: [PATCH 055/198] update changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85f6ef28..975375f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `oneShotAction` flag in the `TestTask` class is not static anymore - HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585 +- Major update for version handling, using `git describe` to fetch version information with git. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/601 + - Place `Version` class outside of `fsfw` namespace. It is generic + - Add helper functions provided by [`cmake-modules`](https://github.com/bilke/cmake-modules) manually now. Those should not change too often and only a small subset is needed + - Separate folder for easier update and for distintion + - LICENSE file included + - use `int` for version numbers to allow unset or uninitialized version + - Initialize Version object with numbers set to -1 + - Instead of hardcoding the git hash, it is now retrieved from git + - `Version` now allows specifying additional version information like the git SHA1 hash and the versions since the last tag + - Additional information is set to the last part of the git describe output for `FSFW_VERSION` now. + - Version still need to be hand-updated if the FSFW is not included as a submodule for now. ## Removed From 539e01deee7df2c0f3cf220b77eb29b80ec92cb8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:53:12 +0200 Subject: [PATCH 056/198] minor form change --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 975375f2..8badeea4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,13 +27,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Major update for version handling, using `git describe` to fetch version information with git. PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/601 - Place `Version` class outside of `fsfw` namespace. It is generic - - Add helper functions provided by [`cmake-modules`](https://github.com/bilke/cmake-modules) manually now. Those should not change too often and only a small subset is needed + - Add helper functions provided by [`cmake-modules`](https://github.com/bilke/cmake-modules) + manually now. Those should not change too often and only a small subset is needed - Separate folder for easier update and for distintion - LICENSE file included - use `int` for version numbers to allow unset or uninitialized version - Initialize Version object with numbers set to -1 - Instead of hardcoding the git hash, it is now retrieved from git - - `Version` now allows specifying additional version information like the git SHA1 hash and the versions since the last tag + - `Version` now allows specifying additional version information like the git SHA1 hash and the + versions since the last tag - Additional information is set to the last part of the git describe output for `FSFW_VERSION` now. - Version still need to be hand-updated if the FSFW is not included as a submodule for now. From 750369b0a6ddae3d301054dd6c91a79db27e5acc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 14:55:17 +0200 Subject: [PATCH 057/198] small addition and possible fix --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9066cec2..5d401046 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,8 @@ project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) # Version handling -if(EXISTS .git) +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) + message(STATUS "${MSG_PREFIX} Determining version information with git") include(helpers) determine_version_with_git("--exclude" "docker_*") set(FSFW_GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") From cccdced74dec589b8566c641a599f978844864c1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 15:00:04 +0200 Subject: [PATCH 058/198] unique helper file name --- CMakeLists.txt | 2 +- cmake/{helpers.cmake => FsfwHelpers.cmake} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename cmake/{helpers.cmake => FsfwHelpers.cmake} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d401046..3dc3a16a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ add_library(${LIB_FSFW_NAME}) # Version handling if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) message(STATUS "${MSG_PREFIX} Determining version information with git") - include(helpers) + include(FsfwHelpers) determine_version_with_git("--exclude" "docker_*") set(FSFW_GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") list(GET FSFW_GIT_INFO 1 FSFW_VERSION) diff --git a/cmake/helpers.cmake b/cmake/FsfwHelpers.cmake similarity index 100% rename from cmake/helpers.cmake rename to cmake/FsfwHelpers.cmake From 617d41c7d5e709e07e59decb93a0b469d1c9337d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 15:08:16 +0200 Subject: [PATCH 059/198] maybe this fixed CI/CD issues --- CMakeLists.txt | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dc3a16a..ead7f531 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,26 +47,33 @@ set(FSFW_DUMMY_TGT fsfw-dummy) project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) +set(FSFW_GIT_VER_HANDLING_OK FALSE) # Version handling if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) message(STATUS "${MSG_PREFIX} Determining version information with git") include(FsfwHelpers) determine_version_with_git("--exclude" "docker_*") - set(FSFW_GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") - list(GET FSFW_GIT_INFO 1 FSFW_VERSION) - list(GET FSFW_GIT_INFO 2 FSFW_SUBVERSION) - list(GET FSFW_GIT_INFO 3 FSFW_REVISION) - list(GET FSFW_GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) - if(NOT FSFW_VERSION) - set(FSFW_VERSION ${FSFW_VERSION_IF_GIT_FAILS}) - endif() - if(NOT FSFW_SUBVERSION) - set(FSFW_SUBVERSION ${FSFW_SUBVERSION_IF_GIT_FAILS}) - endif() - if(NOT FSFW_REVISION) - set(FSFW_REVISION ${FSFW_REVISION_IF_GIT_FAILS}) - endif() -else() + if(GIT_INFO) + set(FSFW_GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") + list(GET FSFW_GIT_INFO 1 FSFW_VERSION) + list(GET FSFW_GIT_INFO 2 FSFW_SUBVERSION) + list(GET FSFW_GIT_INFO 3 FSFW_REVISION) + list(GET FSFW_GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) + if(NOT FSFW_VERSION) + set(FSFW_VERSION ${FSFW_VERSION_IF_GIT_FAILS}) + endif() + if(NOT FSFW_SUBVERSION) + set(FSFW_SUBVERSION ${FSFW_SUBVERSION_IF_GIT_FAILS}) + endif() + if(NOT FSFW_REVISION) + set(FSFW_REVISION ${FSFW_REVISION_IF_GIT_FAILS}) + endif() + set(FSFW_GIT_VER_HANDLING_OK TRUE) + else() + set(FSFW_GIT_VER_HANDLING_OK FALSE) + endif() +endif() +if(NOT FSFW_GIT_VER_HANDLING_OK) set(FSFW_VERSION ${FSFW_VERSION_IF_GIT_FAILS}) set(FSFW_SUBVERSION ${FSFW_SUBVERSION_IF_GIT_FAILS}) set(FSFW_REVISION ${FSFW_REVISION_IF_GIT_FAILS}) From 85e849ca002d594bb5d68b037f139e9a6630d32d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 15:10:08 +0200 Subject: [PATCH 060/198] small remaining fix --- tests/src/fsfw_tests/unit/version.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/fsfw_tests/unit/version.cpp b/tests/src/fsfw_tests/unit/version.cpp index f9170a4d..a95c1ea9 100644 --- a/tests/src/fsfw_tests/unit/version.cpp +++ b/tests/src/fsfw_tests/unit/version.cpp @@ -14,8 +14,8 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { REQUIRE(Version(255, 0, 0) >= fsfw::FSFW_VERSION); REQUIRE(Version(0, 0, 0) < fsfw::FSFW_VERSION); REQUIRE(Version(0, 0, 0) <= fsfw::FSFW_VERSION); - Version v1 = fsfw::Version(1, 1, 1); - Version v2 = fsfw::Version(1, 1, 1); + Version v1 = Version(1, 1, 1); + Version v2 = Version(1, 1, 1); REQUIRE(v1 == v2); REQUIRE(not(v1 < v2)); REQUIRE(not(v1 > v2)); From 68231db9a1dd6d1de153b2ecb03e911f05a1a4ec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 15:37:14 +0200 Subject: [PATCH 061/198] changelog typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8badeea4..3907c5b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Place `Version` class outside of `fsfw` namespace. It is generic - Add helper functions provided by [`cmake-modules`](https://github.com/bilke/cmake-modules) manually now. Those should not change too often and only a small subset is needed - - Separate folder for easier update and for distintion + - Separate folder for easier update and for distinction - LICENSE file included - use `int` for version numbers to allow unset or uninitialized version - Initialize Version object with numbers set to -1 From 18f99583321c2e0726e7e65573cb985b8999f197 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Apr 2022 15:39:44 +0200 Subject: [PATCH 062/198] add git CST and sha info to version ctor --- src/fsfw/FSFWVersion.h.in | 3 ++- src/fsfw/version.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fsfw/FSFWVersion.h.in b/src/fsfw/FSFWVersion.h.in index 79d1f130..3b93bee5 100644 --- a/src/fsfw/FSFWVersion.h.in +++ b/src/fsfw/FSFWVersion.h.in @@ -1,10 +1,11 @@ #ifndef FSFW_VERSION_H_ #define FSFW_VERSION_H_ -// Versioning is kept in project CMakeLists.txt file +// Versioning is managed in project CMakeLists.txt file static constexpr int FSFW_VERSION_MAJOR = @FSFW_VERSION@; static constexpr int FSFW_VERSION_MINOR = @FSFW_SUBVERSION@; static constexpr int FSFW_VERSION_REVISION = @FSFW_REVISION@; +// Also contains CST (Commits since tag) information static const char FSFW_VERSION_CST_GIT_SHA1[] = "@FSFW_VERSION_CST_GIT_SHA1@"; #endif /* FSFW_VERSION_H_ */ diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 7355fc1d..0b2ee60c 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -12,7 +12,8 @@ #undef minor #endif -const Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, FSFW_VERSION_REVISION}; +const Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, FSFW_VERSION_REVISION, + FSFW_VERSION_CST_GIT_SHA1}; Version::Version(int major, int minor, int revision, const char* addInfo) : major(major), minor(minor), revision(revision), addInfo(addInfo) {} From dd90980520709e554e8b743c9e214c1a84460a3f Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 25 Apr 2022 14:19:03 +0200 Subject: [PATCH 063/198] push test --- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index 3b9a21f7..287699bf 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -55,7 +55,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { if (regularGpio == nullptr) { return GPIO_INVALID_INSTANCE; } - configureGpioByChip(gpioConfig.first, *regularGpio); + result = configureGpioByChip(gpioConfig.first, *regularGpio); break; } case (gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): { @@ -83,6 +83,9 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { gpioCallback->initValue, gpioCallback->callbackArgs); } } + if (result != OK) { + return result; + } } return RETURN_OK; } From 70d3197212f6edb5bc95e61fb38a71dff0577467 Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 25 Apr 2022 14:32:05 +0200 Subject: [PATCH 064/198] gpio init bug fix Return values from configureGpios were not checked --- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 11 ++++++----- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index 287699bf..f46ad386 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -44,6 +44,7 @@ ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { } ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { + ReturnValue_t result = RETURN_OK; for (auto& gpioConfig : mapToAdd) { auto& gpioType = gpioConfig.second->gpioType; switch (gpioType) { @@ -63,7 +64,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { if (regularGpio == nullptr) { return GPIO_INVALID_INSTANCE; } - configureGpioByLabel(gpioConfig.first, *regularGpio); + result = configureGpioByLabel(gpioConfig.first, *regularGpio); break; } case (gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): { @@ -71,7 +72,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { if (regularGpio == nullptr) { return GPIO_INVALID_INSTANCE; } - configureGpioByLineName(gpioConfig.first, *regularGpio); + result = configureGpioByLineName(gpioConfig.first, *regularGpio); break; } case (gpio::GpioTypes::CALLBACK): { @@ -83,11 +84,11 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { gpioCallback->initValue, gpioCallback->callbackArgs); } } - if (result != OK) { - return result; + if (result != RETURN_OK) { + return GPIO_INIT_FAILED; } } - return RETURN_OK; + return result; } ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId, diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h index 7d49e6e2..fcc9c775 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h @@ -29,6 +29,8 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject { HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4); static constexpr ReturnValue_t GPIO_DUPLICATE_DETECTED = HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 5); + static constexpr ReturnValue_t GPIO_INIT_FAILED = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 6); LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); From 29015b340b66ffd84dfae9755219fcc96be9af15 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 25 Apr 2022 15:10:50 +0200 Subject: [PATCH 065/198] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2091ed75..87927357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). creation call. It allows passing context information and an arbitrary user argument into the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583 +- Clock: + - `timeval` to `TimeOfDay_t` + - Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/) + - Moved the statics used by Clock in ClockCommon.cpp to this file + - Better check for leap seconds + - Added Unittests for Clock (only getter) ## Removed From 572d602b728e63507053014ca8184840761aecc1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 25 Apr 2022 15:42:44 +0200 Subject: [PATCH 066/198] improve changelog, add entry --- CHANGELOG.md | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5181a862..06424aaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,28 +12,43 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Changes + +- New CMake option `FSFW_HAL_LINUX_ADD_LIBGPIOD` to specifically exclude `gpiod` code. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572 +- HAL Devicehandlers: Periodic printout is run-time configurable now +- `oneShotAction` flag in the `TestTask` class is not static anymore +- IPC Message Queue Handling: Allow passing an optional `MqArgs` argument into the MessageQueue + creation call. It allows passing context information and an arbitrary user argument into + the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583 + +### HAL + - HAL Linux SPI: Set the Clock Default State when setting new SPI speed and mode PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/573 - GPIO HAL: `Direction`, `GpioOperation` and `Levels` are enum classes now, which prevents name clashes with Windows defines. PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572 -- New CMake option `FSFW_HAL_LINUX_ADD_LIBGPIOD` to specifically exclude `gpiod` code. - PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572 -- HAL Devicehandlers: Periodic printout is run-time configurable now -- `oneShotAction` flag in the `TestTask` class is not static anymore - HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585 -- IPC Message Queue Handling: Allow passing an optional `MqArgs` argument into the MessageQueue - creation call. It allows passing context information and an arbitrary user argument into - the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs - PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583 -- Clock: - - `timeval` to `TimeOfDay_t` - - Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/) - - Moved the statics used by Clock in ClockCommon.cpp to this file - - Better check for leap seconds - - Added Unittests for Clock (only getter) + +### Time + +- `timeval` to `TimeOfDay_t` +- Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/) +- Moved the statics used by Clock in ClockCommon.cpp to this file +- Better check for leap seconds +- Added Unittests for Clock (only getter) + +### Power + +- `PowerSwitchIF`: Remove `const` specifier from `sendSwitchCommand` and `sendFuseOnCommand` and + also specify a `ReturnValue_t` return type + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590 +- Extend `PowerSwitcher` module to optionally check current state when calling `turnOn` or + `turnOff`. Tis can be helpful to avoid commanding switches which do not need commanding + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590 ## Removed @@ -49,6 +64,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 - Added ETL dependency and improved library dependency management PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592 +- Add a `DummyPowerSwitcher` module which can be useful for test setups when no PCDU is available + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590 +- New typedef for switcher type + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590 ## Fixed From b94685e045f5fc6203f8f2a65cb03b757bf01c58 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 25 Apr 2022 15:44:46 +0200 Subject: [PATCH 067/198] added missing PR cross-ref --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06424aaf..5ffb84cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Time +PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/584 and +https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593 + - `timeval` to `TimeOfDay_t` - Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/) - Moved the statics used by Clock in ClockCommon.cpp to this file From 900ef5b9124063b5eec88de19d851006b2e1e601 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 26 Apr 2022 09:07:03 +0200 Subject: [PATCH 068/198] option to use coutdwon object to time out replies --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 73 +++++++++++++++---- src/fsfw/devicehandlers/DeviceHandlerBase.h | 27 ++++++- src/fsfw/timemanager/Countdown.cpp | 9 ++- src/fsfw/timemanager/Countdown.h | 3 +- 4 files changed, 93 insertions(+), 19 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index b0a5d1f0..52178683 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -243,17 +243,28 @@ ReturnValue_t DeviceHandlerBase::initialize() { } void DeviceHandlerBase::decrementDeviceReplyMap() { + bool timedOut = false; for (std::pair& replyPair : deviceReplyMap) { - if (replyPair.second.delayCycles != 0) { + if (replyPair.second.countdown != nullptr && replyPair.second.active) { + if (replyPair.second.countdown->hasTimedOut()) { + timedOut = true; + } + } + if (replyPair.second.delayCycles != 0 && replyPair.second.countdown == nullptr) { replyPair.second.delayCycles--; if (replyPair.second.delayCycles == 0) { if (replyPair.second.periodic) { replyPair.second.delayCycles = replyPair.second.maxDelayCycles; } - replyToReply(replyPair.first, replyPair.second, TIMEOUT); - missedReply(replyPair.first); + timedOut = true; } } + if (timedOut) { + replyToReply(replyPair.first, replyPair.second, TIMEOUT); + missedReply(replyPair.first); + timedOut = false; + replyPair.second.active = false; + } } } @@ -416,20 +427,22 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, Submode_t s ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet, - size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) { + size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId, + Countdown* countdown) { // No need to check, as we may try to insert multiple times. insertInCommandMap(deviceCommand, hasDifferentReplyId, replyId); if (hasDifferentReplyId) { - return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic); + return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic, countdown); } else { - return insertInReplyMap(deviceCommand, maxDelayCycles, replyDataSet, replyLen, periodic); + return insertInReplyMap(deviceCommand, maxDelayCycles, replyDataSet, replyLen, periodic, + countdown); } } ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet, size_t replyLen, - bool periodic) { + bool periodic, Countdown* countdown) { DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; info.periodic = periodic; @@ -437,6 +450,10 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, info.replyLen = replyLen; info.dataSet = dataSet; info.command = deviceCommandMap.end(); + info.countdown = countdown; + if (info.periodic) { + info.active = true; + } auto resultPair = deviceReplyMap.emplace(replyId, info); if (resultPair.second) { return RETURN_OK; @@ -472,7 +489,8 @@ size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) { } DeviceReplyIter iter = deviceReplyMap.find(replyId); if (iter != deviceReplyMap.end()) { - if (iter->second.delayCycles != 0) { + if ((iter->second.delayCycles != 0 && iter->second.countdown == nullptr) || + (iter->second.active && iter->second.countdown != nullptr)) { return iter->second.replyLen; } } @@ -816,17 +834,18 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId DeviceReplyInfo* info = &(iter->second); - if (info->delayCycles != 0) { + if ((info->delayCycles != 0 && info->countdown == nullptr) || + (info->active && info->countdown != nullptr)) { result = interpretDeviceReply(foundId, receivedData); if (result == IGNORE_REPLY_DATA) { return; } - if (info->periodic) { - info->delayCycles = info->maxDelayCycles; - } else { - info->delayCycles = 0; + if (info->active && info->countdown != nullptr) { + disableTimeoutControlledReply(info); + } else if (info->delayCycles != 0) { + disableDelayCyclesControlledReply(info); } if (result != RETURN_OK) { @@ -845,6 +864,24 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId } } +void DeviceHandlerBase::disableTimeoutControlledReply(DeviceReplyInfo* info) { + if (info->periodic) { + info->countdown->resetTimer(); + } else { + info->active = false; + info->countdown->timeOut(); + } +} + +void DeviceHandlerBase::disableDelayCyclesControlledReply(DeviceReplyInfo* info) { + if (info->periodic) { + info->delayCycles = info->maxDelayCycles; + } else { + info->delayCycles = 0; + info->active = false; + } +} + ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, uint8_t** data, size_t* len) { size_t lenTmp; @@ -970,6 +1007,10 @@ ReturnValue_t DeviceHandlerBase::enableReplyInReplyMap(DeviceCommandMap::iterato info->delayCycles = info->maxDelayCycles; info->command = command; command->second.expectedReplies = expectedReplies; + if (info->countdown != nullptr) { + info->countdown->resetTimer(); + } + info->active = true; return RETURN_OK; } else { return NO_REPLY_EXPECTED; @@ -1204,7 +1245,8 @@ void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) { bool DeviceHandlerBase::isAwaitingReply() { std::map::iterator iter; for (iter = deviceReplyMap.begin(); iter != deviceReplyMap.end(); ++iter) { - if (iter->second.delayCycles != 0) { + if ((iter->second.delayCycles != 0 && iter->second.countdown == nullptr) || + (iter->second.active && iter->second.countdown != nullptr)) { return true; } } @@ -1360,6 +1402,9 @@ uint8_t DeviceHandlerBase::getReplyDelayCycles(DeviceCommandId_t deviceCommand) if (iter == deviceReplyMap.end()) { return 0; } + else if (iter->second.countdown != nullptr) { + return 0; + } return iter->second.delayCycles; } diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index d8c3363e..4e457c33 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -451,6 +451,9 @@ class DeviceHandlerBase : public DeviceHandlerIF, * by the device repeatedly without request) or not. Default is aperiodic (0). * Please note that periodic replies are disabled by default. You can enable them with * #updatePeriodicReply + * @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible + * to provide a pointer to a Countdown object which will signal the timeout + * when expired * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ @@ -458,7 +461,8 @@ class DeviceHandlerBase : public DeviceHandlerIF, LocalPoolDataSetBase *replyDataSet = nullptr, size_t replyLen = 0, bool periodic = false, bool hasDifferentReplyId = false, - DeviceCommandId_t replyId = 0); + DeviceCommandId_t replyId = 0, + Countdown *countdown = nullptr); /** * @brief This is a helper method to insert replies in the reply map. * @param deviceCommand Identifier of the reply to add. @@ -468,12 +472,15 @@ class DeviceHandlerBase : public DeviceHandlerIF, * by the device repeatedly without request) or not. Default is aperiodic (0). * Please note that periodic replies are disabled by default. You can enable them with * #updatePeriodicReply + * @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible + * to provide a pointer to a Countdown object which will signal the timeout + * when expired * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase *dataSet = nullptr, size_t replyLen = 0, - bool periodic = false); + bool periodic = false, Countdown *countdown = nullptr); /** * @brief A simple command to add a command to the commandList. @@ -792,6 +799,11 @@ class DeviceHandlerBase : public DeviceHandlerIF, LocalPoolDataSetBase *dataSet = nullptr; //! The command that expects this reply. DeviceCommandMap::iterator command; + //! Instead of using delayCycles to specify the maximum time to wait for the device reply, it + //! is also possible specify a countdown + Countdown* countdown = nullptr; + //! will be set to true when reply is enabled + bool active = false; }; using DeviceReplyMap = std::map; @@ -1253,6 +1265,17 @@ class DeviceHandlerBase : public DeviceHandlerIF, */ void doGetRead(void); + /** + * @brief Handles disabling of replies which use a timeout to detect missed replies. + */ + void disableTimeoutControlledReply(DeviceReplyInfo* info); + + /** + * @brief Handles disabling of replies which use a number of maximum delay cycles to detect + * missed replies. + */ + void disableDelayCyclesControlledReply(DeviceReplyInfo* info); + /** * Retrive data from the #IPCStore. * diff --git a/src/fsfw/timemanager/Countdown.cpp b/src/fsfw/timemanager/Countdown.cpp index a8ba78cb..327995f8 100644 --- a/src/fsfw/timemanager/Countdown.cpp +++ b/src/fsfw/timemanager/Countdown.cpp @@ -1,7 +1,12 @@ #include "fsfw/timemanager/Countdown.h" -Countdown::Countdown(uint32_t initialTimeout) : timeout(initialTimeout) { - setTimeout(initialTimeout); +Countdown::Countdown(uint32_t initialTimeout, bool startImmediately) : timeout(initialTimeout) { + if (startImmediately) { + setTimeout(initialTimeout); + } + else { + timeout = initialTimeout; + } } Countdown::~Countdown() {} diff --git a/src/fsfw/timemanager/Countdown.h b/src/fsfw/timemanager/Countdown.h index 44be2b1a..26534789 100644 --- a/src/fsfw/timemanager/Countdown.h +++ b/src/fsfw/timemanager/Countdown.h @@ -26,8 +26,9 @@ class Countdown { * Otherwise a call to hasTimedOut might return True. * * @param initialTimeout Countdown duration in milliseconds + * @param startImmediately Set to false if countdown should not be started immediately */ - Countdown(uint32_t initialTimeout = 0); + Countdown(uint32_t initialTimeout = 0, bool startImmediately = true); ~Countdown(); /** * Call to set a new countdown duration. From 1739edd9b07933ddbdfcbfd19cf98146815ebe3f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 26 Apr 2022 10:32:37 +0200 Subject: [PATCH 069/198] warning fix for modern compilers --- src/fsfw/globalfunctions/DleParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/globalfunctions/DleParser.cpp b/src/fsfw/globalfunctions/DleParser.cpp index b68dbde1..71da7e6a 100644 --- a/src/fsfw/globalfunctions/DleParser.cpp +++ b/src/fsfw/globalfunctions/DleParser.cpp @@ -187,7 +187,7 @@ void DleParser::defaultErrorHandler(ErrorTypes err, ErrorInfo ctx) { case (ErrorTypes::ENCODED_BUF_TOO_SMALL): case (ErrorTypes::DECODING_BUF_TOO_SMALL): { char opt[64]; - snprintf(opt, sizeof(opt), ": Too small for packet with length %d", ctx.len); + snprintf(opt, sizeof(opt), ": Too small for packet with length %zu", ctx.len); if (err == ErrorTypes::ENCODED_BUF_TOO_SMALL) { errorPrinter("Encoded buf too small", opt); } else { From 3d047f9629c3a6fe25514f92dd008bd34d0784dd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 26 Apr 2022 11:15:24 +0200 Subject: [PATCH 070/198] trying to export ETL lib --- CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cc1671c..003b9723 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ set(MSG_PREFIX "fsfw |") set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING "ETL library major version requirement" ) -set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.2 CACHE STRING +set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 CACHE STRING "ETL library exact version requirement" ) @@ -132,7 +132,7 @@ if(FSFW_BUILD_UNITTESTS) endif() endif() -message(STATUS "Finding and/or providing ETL library") +message(STATUS "Finding and/or providing ETL library with version ${FSFW_ETL_LIB_MAJOR_VERSION}") # Check whether the user has already installed ETL first find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) @@ -153,6 +153,11 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) FetchContent_MakeAvailable(etl) endif() +export(EXPORT etl + FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/etl.cmake" + NAMESPACE fsfw:: +) + set(FSFW_CORE_INC_PATH "inc") set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux rtems freertos) From 6a8da303fbfb9dd9c0178b0b68d1d08ab1880d49 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 26 Apr 2022 14:06:30 +0200 Subject: [PATCH 071/198] exporting etl target --- CMakeLists.txt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 003b9723..e5b945f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,10 +153,18 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) FetchContent_MakeAvailable(etl) endif() -export(EXPORT etl - FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/etl.cmake" - NAMESPACE fsfw:: +# Export the ETL library and make it available in the fsfw namespace. This allows user code +# to use the same ETL dependency the framework is using +# You can do this by using the two following directives +# include(fsfw-etl) +# target_link_libraries(${TARGET_NAME} PRIVATE fsfw::etl) +export( + TARGETS ${FSFW_ETL_LIB_NAME} + FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/fsfw-etl.cmake" + NAMESPACE fsfw:: ) +# Append the export directory to the module path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/cmake") set(FSFW_CORE_INC_PATH "inc") From c5a7b98a7dc7c53b5dffbbcf2869c05be29a1208 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 26 Apr 2022 16:24:14 +0200 Subject: [PATCH 072/198] name correction --- CMakeLists.txt | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e5b945f4..25d9bb93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,14 +132,14 @@ if(FSFW_BUILD_UNITTESTS) endif() endif() -message(STATUS "Finding and/or providing ETL library with version ${FSFW_ETL_LIB_MAJOR_VERSION}") +message(STATUS "Finding and/or providing etl library with version ${FSFW_ETL_LIB_MAJOR_VERSION}") # Check whether the user has already installed ETL first find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide etl if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) message(STATUS - "No ETL installation was found with find_package. Installing and providing " + "No etl installation was found with find_package. Installing and providing " "etl with FindPackage" ) include(FetchContent) @@ -153,19 +153,6 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) FetchContent_MakeAvailable(etl) endif() -# Export the ETL library and make it available in the fsfw namespace. This allows user code -# to use the same ETL dependency the framework is using -# You can do this by using the two following directives -# include(fsfw-etl) -# target_link_libraries(${TARGET_NAME} PRIVATE fsfw::etl) -export( - TARGETS ${FSFW_ETL_LIB_NAME} - FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/fsfw-etl.cmake" - NAMESPACE fsfw:: -) -# Append the export directory to the module path -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/cmake") - set(FSFW_CORE_INC_PATH "inc") set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux rtems freertos) From ec2e274f22e3e254469abc9819bc906f03fe590a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 26 Apr 2022 16:31:45 +0200 Subject: [PATCH 073/198] find_package call for Catch2 quiet --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25d9bb93..2354f504 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,7 +98,7 @@ endif() if(FSFW_BUILD_UNITTESTS) message(STATUS "${MSG_PREFIX} Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first - find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION}) + find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide Catch2 if(NOT Catch2_FOUND) message(STATUS "${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent") From c1be1fe2320eed167e808eecf3e582c87b688cde Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 26 Apr 2022 20:06:26 +0200 Subject: [PATCH 074/198] update CMakeLists.txt etl handling --- CMakeLists.txt | 34 +++++++++---------- .../devicehandlers/MgmLIS3MDLHandler.cpp | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2354f504..337a56f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.13) +project(${LIB_FSFW_NAME}) set(FSFW_VERSION_IF_GIT_FAILS 4) set(FSFW_SUBVERSION_IF_GIT_FAILS 0) @@ -60,7 +61,6 @@ set(LIB_FSFW_NAME fsfw) set(FSFW_TEST_TGT fsfw-tests) set(FSFW_DUMMY_TGT fsfw-dummy) -project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) set(FSFW_GIT_VER_HANDLING_OK FALSE) @@ -98,7 +98,7 @@ endif() if(FSFW_BUILD_UNITTESTS) message(STATUS "${MSG_PREFIX} Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first - find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} QUIET) + find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} CONFIG QUIET) # Not installed, so use FetchContent to download and provide Catch2 if(NOT Catch2_FOUND) message(STATUS "${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent") @@ -135,23 +135,23 @@ endif() message(STATUS "Finding and/or providing etl library with version ${FSFW_ETL_LIB_MAJOR_VERSION}") # Check whether the user has already installed ETL first -find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) +# find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} CONFIG QUIET) # Not installed, so use FetchContent to download and provide etl -if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) - message(STATUS - "No etl installation was found with find_package. Installing and providing " - "etl with FindPackage" - ) - include(FetchContent) +# if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) +message(STATUS + "No etl installation was found with find_package. Installing and providing " + "etl with FetchContent" +) +include(FetchContent) - FetchContent_Declare( - ${FSFW_ETL_LIB_NAME} - GIT_REPOSITORY https://github.com/ETLCPP/etl - GIT_TAG ${FSFW_ETL_LIB_VERSION} - ) +FetchContent_Declare( + ${FSFW_ETL_LIB_NAME} + GIT_REPOSITORY https://github.com/ETLCPP/etl + GIT_TAG ${FSFW_ETL_LIB_VERSION} +) - FetchContent_MakeAvailable(etl) -endif() +FetchContent_MakeAvailable(${FSFW_ETL_LIB_NAME}) +# endif() set(FSFW_CORE_INC_PATH "inc") @@ -414,7 +414,7 @@ target_compile_options(${LIB_FSFW_NAME} PRIVATE ) target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${FSFW_ETL_LIB_NAME} + etl ${FSFW_ADDITIONAL_LINK_LIBS} ) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index a887934d..a13ae791 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -375,7 +375,7 @@ float MgmLIS3MDLHandler::getSensitivityFactor(MGMLIS3MDL::Sensitivies sens) { ReturnValue_t MgmLIS3MDLHandler::enableTemperatureSensor(const uint8_t *commandData, size_t commandDataLen) { - if(commandData == nullptr) { + if (commandData == nullptr) { return INVALID_COMMAND_PARAMETER; } triggerEvent(CHANGE_OF_SETUP_PARAMETER); From 5b7ca8c13c4a4a75a32af9b5beadbb310e43516c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 08:39:21 +0200 Subject: [PATCH 075/198] update CHANGELOG.md, apply afmt --- CHANGELOG.md | 3 ++ .../devicehandlers/MgmLIS3MDLHandler.cpp | 4 +-- hal/src/fsfw_hal/linux/uart/UartCookie.cpp | 4 +-- .../datapoollocal/LocalDataPoolManager.cpp | 10 +++---- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 13 ++++----- src/fsfw/ipc/MessageQueueBase.cpp | 28 ++++++------------- src/fsfw/ipc/MessageQueueBase.h | 19 ++++++------- src/fsfw/ipc/MessageQueueIF.h | 4 ++- src/fsfw/osal/freertos/MessageQueue.h | 1 + src/fsfw/osal/host/MessageQueue.h | 8 +++--- src/fsfw/osal/linux/MessageQueue.h | 3 +- src/fsfw/osal/rtems/MessageQueue.h | 5 ++-- src/fsfw/osal/rtems/PeriodicTask.h | 5 ++-- .../unit/mocks/MessageQueueMockBase.h | 4 +-- 14 files changed, 51 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5181a862..3d28c5c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Small bugfix in STM32 HAL for SPI PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/599 +- HAL GPIO: Improved error checking in `LinuxLibgpioIF::configureGpios(...)`. If a GPIO + configuration fails, the function will exit prematurely with a dedicated error code + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/602 # [v4.0.0] diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 52b6dc07..644b488d 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -1,9 +1,9 @@ #include "MgmLIS3MDLHandler.h" -#include "fsfw/datapool/PoolReadGuard.h" - #include +#include "fsfw/datapool/PoolReadGuard.h" + MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie, uint32_t transitionDelay) : DeviceHandlerBase(objectId, deviceCommunication, comCookie), diff --git a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp index aa2dd214..3fedc9d4 100644 --- a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp @@ -24,9 +24,7 @@ void UartCookie::setParityEven() { parity = Parity::EVEN; } Parity UartCookie::getParity() const { return parity; } -void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { - bitsPerWord = bitsPerWord_; -} +void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; } BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; } diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index 6053bd43..781d8f71 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -787,9 +787,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i // Serialize set packet into store. size_t size = 0; result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK) { - ipcStore->deleteData(storeId); - return result; + if (result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); + return result; } if (expectedSize != size) { printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket", @@ -806,8 +806,8 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i } result = hkQueue->reply(&reply); - if(result != HasReturnvaluesIF::RETURN_OK) { - ipcStore->deleteData(storeId); + if (result != HasReturnvaluesIF::RETURN_OK) { + ipcStore->deleteData(storeId); } return result; } diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 0e2802ac..dd9bd5d7 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -458,16 +458,15 @@ size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) { DeviceCommandId_t replyId = NO_COMMAND_ID; DeviceCommandMap::iterator command = cookieInfo.pendingCommand; if (command->second.useAlternativeReplyId) { - replyId = command->second.alternativeReplyId; - } - else { - replyId = commandId; + replyId = command->second.alternativeReplyId; + } else { + replyId = commandId; } DeviceReplyIter iter = deviceReplyMap.find(replyId); if (iter != deviceReplyMap.end()) { - if (iter->second.delayCycles != 0) { - return iter->second.replyLen; - } + if (iter->second.delayCycles != 0) { + return iter->second.replyLen; + } } return 0; } diff --git a/src/fsfw/ipc/MessageQueueBase.cpp b/src/fsfw/ipc/MessageQueueBase.cpp index 1b0934ff..c43670ed 100644 --- a/src/fsfw/ipc/MessageQueueBase.cpp +++ b/src/fsfw/ipc/MessageQueueBase.cpp @@ -1,9 +1,9 @@ #include "MessageQueueBase.h" -MessageQueueBase::MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, - MqArgs* args): id(id) { +MessageQueueBase::MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* args) + : id(id) { this->defaultDest = defaultDest; - if(args != nullptr) { + if (args != nullptr) { this->args = *args; } } @@ -23,35 +23,25 @@ ReturnValue_t MessageQueueBase::reply(MessageQueueMessageIF* message) { } ReturnValue_t MessageQueueBase::receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) { + MessageQueueId_t* receivedFrom) { ReturnValue_t status = this->receiveMessage(message); *receivedFrom = this->last; return status; } -MessageQueueId_t MessageQueueBase::getLastPartner() const { - return last; -} +MessageQueueId_t MessageQueueBase::getLastPartner() const { return last; } -MessageQueueId_t MessageQueueBase::getId() const { - return id; -} +MessageQueueId_t MessageQueueBase::getId() const { return id; } -MqArgs& MessageQueueBase::getMqArgs() { - return args; -} +MqArgs& MessageQueueBase::getMqArgs() { return args; } void MessageQueueBase::setDefaultDestination(MessageQueueId_t defaultDestination) { this->defaultDest = defaultDestination; } -MessageQueueId_t MessageQueueBase::getDefaultDestination() const { - return defaultDest; -} +MessageQueueId_t MessageQueueBase::getDefaultDestination() const { return defaultDest; } -bool MessageQueueBase::isDefaultDestinationSet() const { - return (defaultDest != NO_QUEUE); -} +bool MessageQueueBase::isDefaultDestinationSet() const { return (defaultDest != NO_QUEUE); } ReturnValue_t MessageQueueBase::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, bool ignoreFault) { diff --git a/src/fsfw/ipc/MessageQueueBase.h b/src/fsfw/ipc/MessageQueueBase.h index 8313f69a..942b6121 100644 --- a/src/fsfw/ipc/MessageQueueBase.h +++ b/src/fsfw/ipc/MessageQueueBase.h @@ -1,11 +1,11 @@ #ifndef FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ #define FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ -#include #include +#include -class MessageQueueBase: public MessageQueueIF { -public: +class MessageQueueBase : public MessageQueueIF { + public: MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* mqArgs); virtual ~MessageQueueBase(); @@ -17,25 +17,24 @@ public: virtual MessageQueueId_t getDefaultDestination() const override; virtual bool isDefaultDestinationSet() const override; virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - bool ignoreFault) override; + bool ignoreFault) override; virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override; virtual ReturnValue_t reply(MessageQueueMessageIF* message) override; virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t* receivedFrom) override; - virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, bool ignoreFault = false) override; + MessageQueueId_t* receivedFrom) override; + virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom, + bool ignoreFault = false) override; // OSAL specific, forward the abstract function virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) = 0; virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault = false) = 0; -protected: + + protected: MessageQueueId_t id = MessageQueueIF::NO_QUEUE; MessageQueueId_t last = MessageQueueIF::NO_QUEUE; MessageQueueId_t defaultDest = MessageQueueIF::NO_QUEUE; MqArgs args = {}; }; - - #endif /* FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ */ diff --git a/src/fsfw/ipc/MessageQueueIF.h b/src/fsfw/ipc/MessageQueueIF.h index d7b6889b..9532b2d6 100644 --- a/src/fsfw/ipc/MessageQueueIF.h +++ b/src/fsfw/ipc/MessageQueueIF.h @@ -2,6 +2,7 @@ #define FSFW_IPC_MESSAGEQUEUEIF_H_ #include + #include #include "../returnvalues/HasReturnvaluesIF.h" @@ -45,7 +46,8 @@ class MessageQueueIF { virtual ReturnValue_t reply(MessageQueueMessageIF* message) = 0; /** - * @brief This function reads available messages from the message queue and returns the sender. + * @brief This function reads available messages from the message queue and returns the + * sender. * @details * It works identically to the other receiveMessage call, but in addition * returns the sender's queue id. diff --git a/src/fsfw/osal/freertos/MessageQueue.h b/src/fsfw/osal/freertos/MessageQueue.h index 00dfea68..ee3479aa 100644 --- a/src/fsfw/osal/freertos/MessageQueue.h +++ b/src/fsfw/osal/freertos/MessageQueue.h @@ -2,6 +2,7 @@ #define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_ #include + #include "FreeRTOS.h" #include "TaskManagement.h" #include "fsfw/internalerror/InternalErrorReporterIF.h" diff --git a/src/fsfw/osal/host/MessageQueue.h b/src/fsfw/osal/host/MessageQueue.h index bb4f26a1..4020c6dc 100644 --- a/src/fsfw/osal/host/MessageQueue.h +++ b/src/fsfw/osal/host/MessageQueue.h @@ -1,17 +1,17 @@ #ifndef FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ #define FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ -#include "fsfw/ipc/MessageQueueBase.h" +#include +#include + #include "fsfw/internalerror/InternalErrorReporterIF.h" +#include "fsfw/ipc/MessageQueueBase.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw/ipc/MutexIF.h" #include "fsfw/ipc/definitions.h" #include "fsfw/timemanager/Clock.h" -#include -#include - /** * @brief This class manages sending and receiving of * message queue messages. diff --git a/src/fsfw/osal/linux/MessageQueue.h b/src/fsfw/osal/linux/MessageQueue.h index 8614d101..108ec797 100644 --- a/src/fsfw/osal/linux/MessageQueue.h +++ b/src/fsfw/osal/linux/MessageQueue.h @@ -61,8 +61,7 @@ class MessageQueue : public MessageQueueBase { ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; ReturnValue_t flush(uint32_t* count) override; ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - MessageQueueId_t sentFrom, - bool ignoreFault = false) override; + MessageQueueId_t sentFrom, bool ignoreFault = false) override; protected: /** diff --git a/src/fsfw/osal/rtems/MessageQueue.h b/src/fsfw/osal/rtems/MessageQueue.h index 4648fdfa..bb31a508 100644 --- a/src/fsfw/osal/rtems/MessageQueue.h +++ b/src/fsfw/osal/rtems/MessageQueue.h @@ -2,6 +2,7 @@ #define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_ #include + #include "RtemsBasic.h" #include "fsfw/internalerror/InternalErrorReporterIF.h" #include "fsfw/ipc/MessageQueueIF.h" @@ -52,8 +53,8 @@ class MessageQueue : public MessageQueueBase { // Implement non-generic MessageQueueIF functions not handled by MessageQueueBase ReturnValue_t flush(uint32_t* count) override; ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault = false) override; + MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault = false) override; private: /** diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index 24ce4af1..9f47dfc6 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -59,14 +59,13 @@ class PeriodicTask : public RTEMSTaskBase, public PeriodicTaskIF { */ ReturnValue_t addComponent(object_id_t object) override; -/** + /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. * @param object pointer to the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(ExecutableObjectIF* object) override; - + ReturnValue_t addComponent(ExecutableObjectIF *object) override; uint32_t getPeriodMs() const override; diff --git a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h index c3d08a86..4236593e 100644 --- a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h +++ b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h @@ -4,8 +4,8 @@ #include #include -#include "fsfw/ipc/MessageQueueBase.h" #include "fsfw/ipc/CommandMessage.h" +#include "fsfw/ipc/MessageQueueBase.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw_tests/unit/CatchDefinitions.h" @@ -13,7 +13,7 @@ class MessageQueueMockBase : public MessageQueueBase { public: MessageQueueMockBase() - : MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {} + : MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {} uint8_t messageSentCounter = 0; bool messageSent = false; From c80f06fbcb81f303ded1a08d23032429f61067c3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 09:08:17 +0200 Subject: [PATCH 076/198] hotfix for ETL lib dep --- CMakeLists.txt | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8ca812e..fd3cee36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,23 +108,23 @@ endif() message(STATUS "Finding and/or providing ETL library") # Check whether the user has already installed ETL first -find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) +# find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide etl -if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) - message(STATUS - "No ETL installation was found with find_package. Installing and providing " - "etl with FindPackage" - ) - include(FetchContent) +# if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) +message(STATUS + "No ETL installation was found with find_package. Installing and providing " + "etl with FindPackage" +) +include(FetchContent) - FetchContent_Declare( - ${FSFW_ETL_LIB_NAME} - GIT_REPOSITORY https://github.com/ETLCPP/etl - GIT_TAG ${FSFW_ETL_LIB_VERSION} - ) +FetchContent_Declare( + ${FSFW_ETL_LIB_NAME} + GIT_REPOSITORY https://github.com/ETLCPP/etl + GIT_TAG ${FSFW_ETL_LIB_VERSION} +) - FetchContent_MakeAvailable(etl) -endif() +FetchContent_MakeAvailable(etl) +# endif() set(FSFW_CORE_INC_PATH "inc") From 64f0166b64ef7c10f415e32d167518eeb4c89e8f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 09:16:52 +0200 Subject: [PATCH 077/198] hotfix for new ETL dependency --- CMakeLists.txt | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd3cee36..a74e58f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.2 CACHE STRING "ETL library exact version requirement" ) +set(FSFW_ETL_LINK_TARGET etl::etl) set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE STRING "Catch2 library major version requirement" @@ -108,23 +109,24 @@ endif() message(STATUS "Finding and/or providing ETL library") # Check whether the user has already installed ETL first -# find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) +find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide etl -# if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) -message(STATUS - "No ETL installation was found with find_package. Installing and providing " - "etl with FindPackage" -) -include(FetchContent) +if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) + message(STATUS + "No ETL installation was found with find_package. Installing and providing " + "etl with FindPackage" + ) + include(FetchContent) -FetchContent_Declare( - ${FSFW_ETL_LIB_NAME} - GIT_REPOSITORY https://github.com/ETLCPP/etl - GIT_TAG ${FSFW_ETL_LIB_VERSION} -) + FetchContent_Declare( + ${FSFW_ETL_LIB_NAME} + GIT_REPOSITORY https://github.com/ETLCPP/etl + GIT_TAG ${FSFW_ETL_LIB_VERSION} + ) -FetchContent_MakeAvailable(etl) -# endif() + FetchContent_MakeAvailable(etl) + add_library(${FSFW_ETL_LINK_TARGET} ALIAS etl) +endif() set(FSFW_CORE_INC_PATH "inc") @@ -387,7 +389,7 @@ target_compile_options(${LIB_FSFW_NAME} PRIVATE ) target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${FSFW_ETL_LIB_NAME} + ${FSFW_ETL_LINK_TARGET} ${FSFW_ADDITIONAL_LINK_LIBS} ) From 17e609c3a599090a3aea5518c2f5d33412e90fcf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 09:37:11 +0200 Subject: [PATCH 078/198] some more var replacements --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a74e58f4..9d9c1891 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,8 +124,8 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) GIT_TAG ${FSFW_ETL_LIB_VERSION} ) - FetchContent_MakeAvailable(etl) - add_library(${FSFW_ETL_LINK_TARGET} ALIAS etl) + FetchContent_MakeAvailable(${FSFW_ETL_LIB_NAME}) + add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME}) endif() set(FSFW_CORE_INC_PATH "inc") From b00d83cb1a20c2fd61343ba19f93173e789d69e4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 09:41:16 +0200 Subject: [PATCH 079/198] bump ETL revision --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d9c1891..705d5cc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING "ETL library major version requirement" ) -set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.2 CACHE STRING +set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 CACHE STRING "ETL library exact version requirement" ) set(FSFW_ETL_LINK_TARGET etl::etl) From 8c34051d8bf2bb39a0cad0863e7c96e4e742b040 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 09:45:20 +0200 Subject: [PATCH 080/198] bump Catch2 revision --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d9c1891..225ee784 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ set(FSFW_ETL_LINK_TARGET etl::etl) set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE STRING "Catch2 library major version requirement" ) -set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview4 CACHE STRING +set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE STRING "Catch2 library exact version requirement" ) From 50b1b48678c526f85f0509ddcebb4ed8fe47b70e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 13:36:26 +0200 Subject: [PATCH 081/198] link Catch2 issue --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7435a867..4c45e090 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,8 @@ if(FSFW_BUILD_UNITTESTS) ) FetchContent_MakeAvailable(Catch2) - #fixes regression -preview4, to be confirmed in later releases + # fixes regression -preview4, to be confirmed in later releases + # Related GitHub issue: https://github.com/catchorg/Catch2/issues/2417 set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "") endif() From b5d890eedd51bdb225bc8344e08ff88b4c6b0dae Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 13:43:49 +0200 Subject: [PATCH 082/198] install Catch2 for docker_d2 and update Jenkinsfile --- automation/Dockerfile | 5 +++++ automation/Jenkinsfile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/automation/Dockerfile b/automation/Dockerfile index 9df67fc8..5eda79e9 100644 --- a/automation/Dockerfile +++ b/automation/Dockerfile @@ -6,3 +6,8 @@ RUN apt-get --yes upgrade #tzdata is a dependency, won't install otherwise ARG DEBIAN_FRONTEND=noninteractive RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping + +RUN git clone https://github.com/catchorg/Catch2.git && \ + cd Catch2 && \ + cmake -Bbuild -H. -DBUILD_TESTING=OFF && \ + cmake --build build/ --target install diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index d1459e52..6abf5636 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -3,7 +3,7 @@ pipeline { BUILDDIR = 'build-tests' } agent { - docker { image 'fsfw-ci:d1'} + docker { image 'fsfw-ci:d2'} } stages { stage('Clean') { From 70f0a72f1b60706c3db372abcd9fbdd354d5176d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 13:54:15 +0200 Subject: [PATCH 083/198] added explicit checkout of v3.0.0-preview5 --- automation/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/automation/Dockerfile b/automation/Dockerfile index 5eda79e9..0eb98fbb 100644 --- a/automation/Dockerfile +++ b/automation/Dockerfile @@ -9,5 +9,6 @@ RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping RUN git clone https://github.com/catchorg/Catch2.git && \ cd Catch2 && \ + git checkout v3.0.0-preview5 && \ cmake -Bbuild -H. -DBUILD_TESTING=OFF && \ cmake --build build/ --target install From 6aa72892edf060798ce7665521e15f825cb94ab5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 21:53:57 +0200 Subject: [PATCH 084/198] clean usage of FetchContent_MakeAvailable --- CMakeLists.txt | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 705d5cc6..a7fa1712 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,9 +77,7 @@ if(FSFW_BUILD_UNITTESTS) GIT_TAG ${FSFW_CATCH2_LIB_VERSION} ) - FetchContent_MakeAvailable(Catch2) - #fixes regression -preview4, to be confirmed in later releases - set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "") + list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2) endif() set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg) @@ -124,8 +122,21 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) GIT_TAG ${FSFW_ETL_LIB_VERSION} ) - FetchContent_MakeAvailable(${FSFW_ETL_LIB_NAME}) - add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME}) + list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_ETL_LIB_NAME}) +endif() + +# The documentation for FetchContent recommends declaring all the dependencies +# before making them available. We make all declared dependency available here +# after their declaration +if(FSFW_FETCH_CONTENT_TARGETS) + FetchContent_MakeAvailable(${FSFW_FETCH_CONTENT_TARGETS}) + if(TARGET ${FSFW_ETL_LIB_NAME}) + add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME}) + endif() + if(TARGET Catch2) + # Fixes regression -preview4, to be confirmed in later releases + set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "") + endif() endif() set(FSFW_CORE_INC_PATH "inc") From 29b0a352fcc6ddde8c19fca695d5c067ef2d4e30 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 28 Apr 2022 14:26:00 +0200 Subject: [PATCH 085/198] added new functions to add sequences and tables --- src/fsfw/subsystem/Subsystem.cpp | 9 +++++++++ src/fsfw/subsystem/Subsystem.h | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/fsfw/subsystem/Subsystem.cpp b/src/fsfw/subsystem/Subsystem.cpp index a837bf83..8930d0a1 100644 --- a/src/fsfw/subsystem/Subsystem.cpp +++ b/src/fsfw/subsystem/Subsystem.cpp @@ -299,6 +299,11 @@ void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) { } } +ReturnValue_t Subsystem::addSequence(SequenceEntry sequence) { + return addSequence(sequence.table, sequence.mode, sequence.fallbackMode, sequence.inStore, + sequence.preInit); +} + ReturnValue_t Subsystem::addSequence(ArrayList *sequence, Mode_t id, Mode_t fallbackSequence, bool inStore, bool preInit) { ReturnValue_t result; @@ -342,6 +347,10 @@ ReturnValue_t Subsystem::addSequence(ArrayList *sequence, Mode_t return result; } +ReturnValue_t Subsystem::addTable(TableEntry table) { + return addTable(table.table, table.mode, table.inStore, table.preInit); +} + ReturnValue_t Subsystem::addTable(ArrayList *table, Mode_t id, bool inStore, bool preInit) { ReturnValue_t result; diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index 2c78c8cd..5b2777e8 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -11,6 +11,28 @@ #include "SubsystemBase.h" #include "modes/ModeDefinitions.h" +struct TableSequenceBase { + public: + TableSequenceBase(Mode_t mode, ArrayList *table) : mode(mode), table(table){}; + Mode_t mode; + ArrayList *table; + bool inStore = false; + bool preInit = true; +}; + +struct TableEntry : public TableSequenceBase { + public: + TableEntry(Mode_t mode, ArrayList *table) : TableSequenceBase(mode, table){}; +}; + +struct SequenceEntry : public TableSequenceBase { + public: + SequenceEntry(Mode_t mode, ArrayList *table, Mode_t fallbackMode) + : TableSequenceBase(mode, table), fallbackMode(fallbackMode) {} + + Mode_t fallbackMode; +}; + /** * @brief TODO: documentation missing * @details @@ -45,9 +67,11 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { uint32_t maxNumberOfTables); virtual ~Subsystem(); + ReturnValue_t addSequence(SequenceEntry sequence); ReturnValue_t addSequence(ArrayList *sequence, Mode_t id, Mode_t fallbackSequence, bool inStore = true, bool preInit = true); + ReturnValue_t addTable(TableEntry table); ReturnValue_t addTable(ArrayList *table, Mode_t id, bool inStore = true, bool preInit = true); From e98857fab4eb8b91c7b1862e35cada5d540f4976 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 28 Apr 2022 14:37:21 +0200 Subject: [PATCH 086/198] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d28c5c6..a45ebab2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 - Added ETL dependency and improved library dependency management PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592 +- `Subsystem`: New API to add table and sequence entries ## Fixed From 3225a8e350efbc3ff2e8d9dd9757de52be90d4fd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 28 Apr 2022 16:48:14 +0200 Subject: [PATCH 087/198] added option to change initial submode --- src/fsfw/subsystem/Subsystem.cpp | 6 +++++- src/fsfw/subsystem/Subsystem.h | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/fsfw/subsystem/Subsystem.cpp b/src/fsfw/subsystem/Subsystem.cpp index 1e860efc..27e6ae8e 100644 --- a/src/fsfw/subsystem/Subsystem.cpp +++ b/src/fsfw/subsystem/Subsystem.cpp @@ -467,6 +467,7 @@ ReturnValue_t Subsystem::initialize() { } mode = initialMode; + submode = initSubmode; return RETURN_OK; } @@ -604,7 +605,10 @@ ReturnValue_t Subsystem::checkObjectConnections() { return RETURN_OK; } -void Subsystem::setInitialMode(Mode_t mode) { initialMode = mode; } +void Subsystem::setInitialMode(Mode_t mode, Submode_t submode) { + this->initialMode = mode; + this->initSubmode = submode; +} void Subsystem::cantKeepMode() { ReturnValue_t result; diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index a3ee5744..1055def3 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -78,7 +78,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { ReturnValue_t addTable(ArrayList *table, Mode_t id, bool inStore = true, bool preInit = true); - void setInitialMode(Mode_t mode); + void setInitialMode(Mode_t mode, Submode_t submode = SUBMODE_NONE); virtual ReturnValue_t initialize() override; @@ -117,6 +117,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { Submode_t targetSubmode; Mode_t initialMode = 0; + Submode_t initSubmode = SUBMODE_NONE; HybridIterator currentSequenceIterator; From bf2e0f2d73149a16bf3e6e60dc6912698f3995b5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 28 Apr 2022 16:48:14 +0200 Subject: [PATCH 088/198] added option to change initial submode --- src/fsfw/subsystem/Subsystem.cpp | 6 +++++- src/fsfw/subsystem/Subsystem.h | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/fsfw/subsystem/Subsystem.cpp b/src/fsfw/subsystem/Subsystem.cpp index 8930d0a1..4e9d52f3 100644 --- a/src/fsfw/subsystem/Subsystem.cpp +++ b/src/fsfw/subsystem/Subsystem.cpp @@ -459,6 +459,7 @@ ReturnValue_t Subsystem::initialize() { } mode = initialMode; + submode = initSubmode; return RETURN_OK; } @@ -596,7 +597,10 @@ ReturnValue_t Subsystem::checkObjectConnections() { return RETURN_OK; } -void Subsystem::setInitialMode(Mode_t mode) { initialMode = mode; } +void Subsystem::setInitialMode(Mode_t mode, Submode_t submode) { + this->initialMode = mode; + this->initSubmode = submode; +} void Subsystem::cantKeepMode() { ReturnValue_t result; diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index 5b2777e8..84d5f6a7 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -75,7 +75,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { ReturnValue_t addTable(ArrayList *table, Mode_t id, bool inStore = true, bool preInit = true); - void setInitialMode(Mode_t mode); + void setInitialMode(Mode_t mode, Submode_t submode = SUBMODE_NONE); virtual ReturnValue_t initialize() override; @@ -114,6 +114,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { Submode_t targetSubmode; Mode_t initialMode = 0; + Submode_t initSubmode = SUBMODE_NONE; HybridIterator currentSequenceIterator; From 43aad11859d5ca772d4323b24626d7a94646f3fd Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 29 Apr 2022 07:43:52 +0200 Subject: [PATCH 089/198] space packet bugfix --- src/fsfw/tmtcpacket/SpacePacket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/tmtcpacket/SpacePacket.cpp b/src/fsfw/tmtcpacket/SpacePacket.cpp index c8ebbd97..16d968fb 100644 --- a/src/fsfw/tmtcpacket/SpacePacket.cpp +++ b/src/fsfw/tmtcpacket/SpacePacket.cpp @@ -19,8 +19,8 @@ SpacePacket::SpacePacket(uint16_t packetDataLength, bool isTelecommand, uint16_t SpacePacket::~SpacePacket(void) {} bool SpacePacket::addWholeData(const uint8_t* p_Data, uint32_t packet_size) { - if (packet_size <= sizeof(this->data)) { - memcpy(&this->localData.byteStream, p_Data, packet_size); + if (packet_size <= sizeof(this->localData)) { + memcpy(this->localData.byteStream, p_Data, packet_size); return true; } else { return false; From 9731dc1e619e6e52207174e67daf0468a675a5ec Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 29 Apr 2022 07:47:23 +0200 Subject: [PATCH 090/198] space packet bug fix --- src/fsfw/tmtcpacket/SpacePacket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/tmtcpacket/SpacePacket.cpp b/src/fsfw/tmtcpacket/SpacePacket.cpp index c8ebbd97..16d968fb 100644 --- a/src/fsfw/tmtcpacket/SpacePacket.cpp +++ b/src/fsfw/tmtcpacket/SpacePacket.cpp @@ -19,8 +19,8 @@ SpacePacket::SpacePacket(uint16_t packetDataLength, bool isTelecommand, uint16_t SpacePacket::~SpacePacket(void) {} bool SpacePacket::addWholeData(const uint8_t* p_Data, uint32_t packet_size) { - if (packet_size <= sizeof(this->data)) { - memcpy(&this->localData.byteStream, p_Data, packet_size); + if (packet_size <= sizeof(this->localData)) { + memcpy(this->localData.byteStream, p_Data, packet_size); return true; } else { return false; From afcbc8be0a24f6ede4a8c665cc222e938d769e6e Mon Sep 17 00:00:00 2001 From: Robin Date: Sat, 30 Apr 2022 18:40:22 +0200 Subject: [PATCH 091/198] changes for MacOS --- CMakeLists.txt | 1 + hal/src/fsfw_hal/linux/CMakeLists.txt | 9 +++++++-- hal/src/fsfw_hal/linux/spi/SpiCookie.cpp | 2 +- src/fsfw/datapool/PoolDataSetBase.h | 2 +- src/fsfw/globalfunctions/matching/MatchTree.h | 2 +- src/fsfw/globalfunctions/matching/RangeMatcher.h | 2 +- src/fsfw/objectmanager/SystemObject.h | 4 ++-- src/fsfw/subsystem/Subsystem.h | 2 +- src/fsfw/subsystem/SubsystemBase.h | 2 +- src/fsfw/tmtcservices/CommandingServiceBase.h | 2 +- 10 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8ca812e..8619f17b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,6 +332,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") -Warray-bounds=2 # Some array bounds violations will be found -Wshift-overflow=2 # Search for bit left shift overflows (, public BinaryTree>(root.element), maxDepth(maxDepth) {} MatchTree() : BinaryTree>(), maxDepth(-1) {} virtual ~MatchTree() {} - virtual bool match(T number) { return matchesTree(number); } + virtual bool match(T number) override { return matchesTree(number); } bool matchesTree(T number) { iterator iter = this->begin(); if (iter == this->end()) { diff --git a/src/fsfw/globalfunctions/matching/RangeMatcher.h b/src/fsfw/globalfunctions/matching/RangeMatcher.h index 4e1f3922..c5962ab3 100644 --- a/src/fsfw/globalfunctions/matching/RangeMatcher.h +++ b/src/fsfw/globalfunctions/matching/RangeMatcher.h @@ -15,7 +15,7 @@ class RangeMatcher : public SerializeableMatcherIF { RangeMatcher(T lowerBound, T upperBound, bool inverted = false) : inverted(inverted), lowerBound(lowerBound), upperBound(upperBound) {} - bool match(T input) { + bool match(T input) override { if (inverted) { return !doMatch(input); } else { diff --git a/src/fsfw/objectmanager/SystemObject.h b/src/fsfw/objectmanager/SystemObject.h index 6d5b8303..eeb68b8f 100644 --- a/src/fsfw/objectmanager/SystemObject.h +++ b/src/fsfw/objectmanager/SystemObject.h @@ -48,9 +48,9 @@ class SystemObject : public SystemObjectIF { virtual ~SystemObject(); object_id_t getObjectId() const override; virtual ReturnValue_t initialize() override; - virtual ReturnValue_t checkObjectConnections(); + virtual ReturnValue_t checkObjectConnections() override; - virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const; + virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override; }; #endif /* FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ */ diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index 2c78c8cd..0aa99148 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -138,7 +138,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - virtual void startTransition(Mode_t mode, Submode_t submode); + virtual void startTransition(Mode_t mode, Submode_t submode) override; void sendSerializablesAsCommandMessage(Command_t command, SerializeIF **elements, uint8_t count); diff --git a/src/fsfw/subsystem/SubsystemBase.h b/src/fsfw/subsystem/SubsystemBase.h index 8cfd5be0..d51be540 100644 --- a/src/fsfw/subsystem/SubsystemBase.h +++ b/src/fsfw/subsystem/SubsystemBase.h @@ -123,7 +123,7 @@ class SubsystemBase : public SystemObject, virtual void performChildOperation() = 0; virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode) = 0; + uint32_t *msToReachTheMode) override = 0; virtual void startTransition(Mode_t mode, Submode_t submode) = 0; diff --git a/src/fsfw/tmtcservices/CommandingServiceBase.h b/src/fsfw/tmtcservices/CommandingServiceBase.h index 0ae19505..ecc936b7 100644 --- a/src/fsfw/tmtcservices/CommandingServiceBase.h +++ b/src/fsfw/tmtcservices/CommandingServiceBase.h @@ -104,7 +104,7 @@ class CommandingServiceBase : public SystemObject, * * @return requestQueue messageQueueId_t */ - virtual MessageQueueId_t getRequestQueue(); + virtual MessageQueueId_t getRequestQueue() override; /** * Returns the commandQueue MessageQueueId_t From 7d61e67d20feb67b26564bda59efaff291a99950 Mon Sep 17 00:00:00 2001 From: Robin Date: Sat, 30 Apr 2022 19:02:41 +0200 Subject: [PATCH 092/198] more macos changes --- hal/src/fsfw_hal/linux/uart/UartComIF.cpp | 2 ++ src/fsfw/cfdp/pdu/HeaderSerializer.h | 2 +- src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp | 11 ++++++----- src/fsfw/datapoollocal/LocalPoolObjectBase.h | 4 ++-- src/fsfw/monitoring/MonitoringMessageContent.h | 3 +-- src/fsfw/pus/Service3Housekeeping.h | 2 +- src/fsfw/subsystem/Subsystem.h | 4 ++-- src/fsfw/subsystem/SubsystemBase.h | 4 ++-- src/fsfw/tmtcservices/CommandingServiceBase.h | 2 +- 9 files changed, 18 insertions(+), 16 deletions(-) diff --git a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp index 5aa72138..72c79df6 100644 --- a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp @@ -265,6 +265,7 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki cfsetispeed(options, B230400); cfsetospeed(options, B230400); break; +#ifndef __APPLE__ case UartBaudRate::RATE_460800: cfsetispeed(options, B460800); cfsetospeed(options, B460800); @@ -313,6 +314,7 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki cfsetispeed(options, B4000000); cfsetospeed(options, B4000000); break; +#endif // ! __APPLE__ default: #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl; diff --git a/src/fsfw/cfdp/pdu/HeaderSerializer.h b/src/fsfw/cfdp/pdu/HeaderSerializer.h index 8f2fc3fd..1de97d63 100644 --- a/src/fsfw/cfdp/pdu/HeaderSerializer.h +++ b/src/fsfw/cfdp/pdu/HeaderSerializer.h @@ -44,7 +44,7 @@ class HeaderSerializer : public SerializeIF, public PduHeaderIF { cfdp::WidthInBytes getLenEntityIds() const override; cfdp::WidthInBytes getLenSeqNum() const override; cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override; - bool hasSegmentMetadataFlag() const; + bool hasSegmentMetadataFlag() const override; void setSegmentationControl(cfdp::SegmentationControl); void getSourceId(cfdp::EntityId& sourceId) const override; diff --git a/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp b/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp index 4a076212..09f35057 100644 --- a/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp +++ b/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp @@ -94,13 +94,14 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer( ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; const uint8_t validityMaskSize = std::ceil(static_cast(fillCount) / 8.0); uint8_t *validityPtr = nullptr; -#ifdef _MSC_VER - /* Use a std::vector here because MSVC will (rightly) not create a fixed size array - with a non constant size specifier */ - std::vector validityMask(validityMaskSize); +#if defined(_MSC_VER) || defined(__APPLE__) + // Use a std::vector here because MSVC will (rightly) not create a fixed size array + // with a non constant size specifier. The Apple compiler (LLVM) will not accept + // the initialization of a variable sized array + std::vector validityMask(validityMaskSize) = {}; validityPtr = validityMask.data(); #else - uint8_t validityMask[validityMaskSize] = {0}; + uint8_t validityMask[validityMaskSize] = {}; validityPtr = validityMask; #endif uint8_t validBufferIndex = 0; diff --git a/src/fsfw/datapoollocal/LocalPoolObjectBase.h b/src/fsfw/datapoollocal/LocalPoolObjectBase.h index 56e190df..b2ffa4c1 100644 --- a/src/fsfw/datapoollocal/LocalPoolObjectBase.h +++ b/src/fsfw/datapoollocal/LocalPoolObjectBase.h @@ -23,8 +23,8 @@ class LocalPoolObjectBase : public PoolVariableIF, public HasReturnvaluesIF, pub LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr, pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE); - void setReadWriteMode(pool_rwm_t newReadWriteMode); - pool_rwm_t getReadWriteMode() const; + void setReadWriteMode(pool_rwm_t newReadWriteMode) override; + pool_rwm_t getReadWriteMode() const override; bool isValid() const override; void setValid(bool valid) override; diff --git a/src/fsfw/monitoring/MonitoringMessageContent.h b/src/fsfw/monitoring/MonitoringMessageContent.h index 0ac455eb..fb3ace3d 100644 --- a/src/fsfw/monitoring/MonitoringMessageContent.h +++ b/src/fsfw/monitoring/MonitoringMessageContent.h @@ -34,7 +34,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter { SerializeElement limitValue; SerializeElement oldState; SerializeElement newState; - uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; + uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE] = {}; SerializeElement> timestampSerializer; TimeStamperIF* timeStamper; MonitoringReportContent() @@ -46,7 +46,6 @@ class MonitoringReportContent : public SerialLinkedListAdapter { limitValue(0), oldState(0), newState(0), - rawTimestamp({0}), timestampSerializer(rawTimestamp, sizeof(rawTimestamp)), timeStamper(NULL) { setAllNext(); diff --git a/src/fsfw/pus/Service3Housekeeping.h b/src/fsfw/pus/Service3Housekeeping.h index c1928891..70f15762 100644 --- a/src/fsfw/pus/Service3Housekeeping.h +++ b/src/fsfw/pus/Service3Housekeeping.h @@ -43,7 +43,7 @@ class Service3Housekeeping : public CommandingServiceBase, public AcceptsHkPacke CommandMessage* optionalNextCommand, object_id_t objectId, bool* isStep) override; - virtual MessageQueueId_t getHkQueue() const; + virtual MessageQueueId_t getHkQueue() const override; private: enum class Subservice { diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index 0aa99148..06181ca7 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -127,7 +127,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { ReturnValue_t deleteTable(Mode_t id); - virtual void performChildOperation(); + virtual void performChildOperation() override; virtual ReturnValue_t handleCommandMessage(CommandMessage *message); @@ -136,7 +136,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { bool isTableUsed(Mode_t tableId); virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode); + uint32_t *msToReachTheMode) override; virtual void startTransition(Mode_t mode, Submode_t submode) override; diff --git a/src/fsfw/subsystem/SubsystemBase.h b/src/fsfw/subsystem/SubsystemBase.h index d51be540..a908e13a 100644 --- a/src/fsfw/subsystem/SubsystemBase.h +++ b/src/fsfw/subsystem/SubsystemBase.h @@ -127,9 +127,9 @@ class SubsystemBase : public SystemObject, virtual void startTransition(Mode_t mode, Submode_t submode) = 0; - virtual void getMode(Mode_t *mode, Submode_t *submode); + virtual void getMode(Mode_t *mode, Submode_t *submode) override; - virtual void setToExternalControl(); + virtual void setToExternalControl() override; virtual void announceMode(bool recursive); diff --git a/src/fsfw/tmtcservices/CommandingServiceBase.h b/src/fsfw/tmtcservices/CommandingServiceBase.h index ecc936b7..867fc287 100644 --- a/src/fsfw/tmtcservices/CommandingServiceBase.h +++ b/src/fsfw/tmtcservices/CommandingServiceBase.h @@ -95,7 +95,7 @@ class CommandingServiceBase : public SystemObject, */ virtual ReturnValue_t performOperation(uint8_t opCode) override; - virtual uint16_t getIdentifier(); + virtual uint16_t getIdentifier() override; /** * Returns the requestQueue MessageQueueId_t From 28015c47356524472822052243ca827f2f2ef02b Mon Sep 17 00:00:00 2001 From: Robin Date: Sun, 1 May 2022 17:48:49 +0200 Subject: [PATCH 093/198] it compiles and runs --- src/fsfw/container/FixedArrayList.h | 2 +- src/fsfw/controller/ControllerBase.h | 8 ++-- .../datapoollocal/LocalPoolDataSetBase.cpp | 4 +- src/fsfw/devicehandlers/DeviceHandlerBase.h | 8 ++-- src/fsfw/osal/common/UdpTcPollingTask.cpp | 19 ++++---- src/fsfw/osal/common/UdpTcPollingTask.h | 12 ++--- src/fsfw/osal/common/UdpTmTcBridge.cpp | 16 +++---- src/fsfw/osal/common/UdpTmTcBridge.h | 8 ++-- src/fsfw/osal/host/CMakeLists.txt | 43 +++++++++-------- src/fsfw/osal/linux/CMakeLists.txt | 48 +++++++++---------- src/fsfw/power/Fuse.h | 2 +- src/fsfw/subsystem/Subsystem.h | 2 +- src/fsfw/subsystem/SubsystemBase.h | 4 +- 13 files changed, 89 insertions(+), 87 deletions(-) diff --git a/src/fsfw/container/FixedArrayList.h b/src/fsfw/container/FixedArrayList.h index c09a421e..26a73921 100644 --- a/src/fsfw/container/FixedArrayList.h +++ b/src/fsfw/container/FixedArrayList.h @@ -9,7 +9,7 @@ */ template class FixedArrayList : public ArrayList { -#if !defined(_MSC_VER) +#if !defined(_MSC_VER) && !defined(__clang__) static_assert(MAX_SIZE <= (std::pow(2, sizeof(count_t) * 8) - 1), "count_t is not large enough to hold MAX_SIZE"); #endif diff --git a/src/fsfw/controller/ControllerBase.h b/src/fsfw/controller/ControllerBase.h index 7032f817..227b859b 100644 --- a/src/fsfw/controller/ControllerBase.h +++ b/src/fsfw/controller/ControllerBase.h @@ -55,7 +55,7 @@ class ControllerBase : public HasModesIF, virtual void performControlOperation() = 0; virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode) = 0; + uint32_t *msToReachTheMode) override = 0; const object_id_t parentId; @@ -80,9 +80,9 @@ class ControllerBase : public HasModesIF, /** Mode helpers */ virtual void modeChanged(Mode_t mode, Submode_t submode); - virtual void startTransition(Mode_t mode, Submode_t submode); - virtual void getMode(Mode_t *mode, Submode_t *submode); - virtual void setToExternalControl(); + virtual void startTransition(Mode_t mode, Submode_t submode) override; + virtual void getMode(Mode_t *mode, Submode_t *submode) override; + virtual void setToExternalControl() override; virtual void announceMode(bool recursive); /** HK helpers */ virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); diff --git a/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp b/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp index 09f35057..62fdb184 100644 --- a/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp +++ b/src/fsfw/datapoollocal/LocalPoolDataSetBase.cpp @@ -94,11 +94,11 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer( ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; const uint8_t validityMaskSize = std::ceil(static_cast(fillCount) / 8.0); uint8_t *validityPtr = nullptr; -#if defined(_MSC_VER) || defined(__APPLE__) +#if defined(_MSC_VER) || defined(__clang__) // Use a std::vector here because MSVC will (rightly) not create a fixed size array // with a non constant size specifier. The Apple compiler (LLVM) will not accept // the initialization of a variable sized array - std::vector validityMask(validityMaskSize) = {}; + std::vector validityMask(validityMaskSize, 0); validityPtr = validityMask.data(); #else uint8_t validityMask[validityMaskSize] = {}; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 5e974831..5808b8e6 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -163,7 +163,7 @@ class DeviceHandlerBase : public DeviceHandlerIF, * @param counter Specifies which Action to perform * @return RETURN_OK for successful execution */ - virtual ReturnValue_t performOperation(uint8_t counter); + virtual ReturnValue_t performOperation(uint8_t counter) override; /** * @brief Initializes the device handler @@ -173,7 +173,7 @@ class DeviceHandlerBase : public DeviceHandlerIF, * Calls fillCommandAndReplyMap(). * @return */ - virtual ReturnValue_t initialize(); + virtual ReturnValue_t initialize() override; /** * @brief Intialization steps performed after all tasks have been created. @@ -1058,11 +1058,11 @@ class DeviceHandlerBase : public DeviceHandlerIF, * @param parameter1 Optional parameter 1 * @param parameter2 Optional parameter 2 */ - void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0); + void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) override; /** * Same as triggerEvent, but for forwarding if object is used as proxy. */ - virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const; + virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override; /** * Checks if current mode is transitional mode. diff --git a/src/fsfw/osal/common/UdpTcPollingTask.cpp b/src/fsfw/osal/common/UdpTcPollingTask.cpp index ab982a3c..38fb1921 100644 --- a/src/fsfw/osal/common/UdpTcPollingTask.cpp +++ b/src/fsfw/osal/common/UdpTcPollingTask.cpp @@ -16,11 +16,13 @@ //! Debugging preprocessor define. #define FSFW_UDP_RECV_WIRETAPPING_ENABLED 0 +const timeval UdpTcPollingTask::DEFAULT_TIMEOUT = {0, 500000}; + UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBridge, size_t maxRecvSize, double timeoutSeconds) : SystemObject(objectId), tmtcBridgeId(tmtcUdpBridge) { - if (frameSize > 0) { - this->frameSize = frameSize; + if (maxRecvSize > 0) { + this->frameSize = maxRecvSize; } else { this->frameSize = DEFAULT_MAX_RECV_SIZE; } @@ -31,22 +33,20 @@ UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBrid receptionBuffer.resize(this->frameSize); if (timeoutSeconds == -1) { - receptionTimeout = DEFAULT_TIMEOUT; + receptionTimeout = UdpTcPollingTask::DEFAULT_TIMEOUT; } else { receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); } } -UdpTcPollingTask::~UdpTcPollingTask() {} - -ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { +[[noreturn]] ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { /* Sender Address is cached here. */ - struct sockaddr senderAddress; + struct sockaddr senderAddress {}; socklen_t senderAddressSize = sizeof(senderAddress); /* Poll for new UDP datagrams in permanent loop. */ while (true) { - int bytesReceived = + ssize_t bytesReceived = recvfrom(this->serverSocket, reinterpret_cast(receptionBuffer.data()), frameSize, receptionFlags, &senderAddress, &senderAddressSize); if (bytesReceived == SOCKET_ERROR) { @@ -70,7 +70,6 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { } tmtcBridge->checkAndSetClientAddress(senderAddress); } - return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) { @@ -155,7 +154,7 @@ void UdpTcPollingTask::setTimeout(double timeoutSeconds) { #endif } #elif defined(PLATFORM_UNIX) - timeval tval; + timeval tval {}; tval = timevalOperations::toTimeval(timeoutSeconds); int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(receptionTimeout)); if (result == -1) { diff --git a/src/fsfw/osal/common/UdpTcPollingTask.h b/src/fsfw/osal/common/UdpTcPollingTask.h index afcd32a1..894716d7 100644 --- a/src/fsfw/osal/common/UdpTcPollingTask.h +++ b/src/fsfw/osal/common/UdpTcPollingTask.h @@ -21,11 +21,11 @@ class UdpTcPollingTask : public TcpIpBase, public SystemObject, public Executabl public: static constexpr size_t DEFAULT_MAX_RECV_SIZE = 1500; //! 0.5 default milliseconds timeout for now. - static constexpr timeval DEFAULT_TIMEOUT = {0, 500}; + static const timeval DEFAULT_TIMEOUT; UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBridge, size_t maxRecvSize = 0, double timeoutSeconds = -1); - virtual ~UdpTcPollingTask(); + ~UdpTcPollingTask() override = default; /** * Turn on optional timeout for UDP polling. In the default mode, @@ -34,9 +34,9 @@ class UdpTcPollingTask : public TcpIpBase, public SystemObject, public Executabl */ void setTimeout(double timeoutSeconds); - virtual ReturnValue_t performOperation(uint8_t opCode) override; - virtual ReturnValue_t initialize() override; - virtual ReturnValue_t initializeAfterTaskCreation() override; + [[noreturn]] ReturnValue_t performOperation(uint8_t opCode) override; + ReturnValue_t initialize() override; + ReturnValue_t initializeAfterTaskCreation() override; protected: StorageManagerIF* tcStore = nullptr; @@ -51,7 +51,7 @@ class UdpTcPollingTask : public TcpIpBase, public SystemObject, public Executabl std::vector receptionBuffer; size_t frameSize = 0; - timeval receptionTimeout; + timeval receptionTimeout{}; ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); }; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index 0efe1c74..6089f266 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -20,13 +20,13 @@ const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, - std::string udpServerPort, object_id_t tmStoreId, + const std::string& udpServerPort_, object_id_t tmStoreId, object_id_t tcStoreId) : TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { - if (udpServerPort == "") { - this->udpServerPort = DEFAULT_SERVER_PORT; + if (udpServerPort_.empty()) { + udpServerPort = DEFAULT_SERVER_PORT; } else { - this->udpServerPort = udpServerPort; + udpServerPort = udpServerPort_; } mutex = MutexFactory::instance()->createMutex(); @@ -117,7 +117,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { tcpip::printAddress(&clientAddress); #endif - int bytesSent = sendto(serverSocket, reinterpret_cast(data), dataLen, flags, + ssize_t bytesSent = sendto(serverSocket, reinterpret_cast(data), dataLen, flags, &clientAddress, clientAddressLen); if (bytesSent == SOCKET_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -150,7 +150,7 @@ void UdpTmTcBridge::checkAndSetClientAddress(sockaddr &newAddress) { clientAddressLen = sizeof(clientAddress); } -void UdpTmTcBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs) { - this->timeoutType = timeoutType; - this->mutexTimeoutMs = timeoutMs; +void UdpTmTcBridge::setMutexProperties(MutexIF::TimeoutType timeoutType_, dur_millis_t timeoutMs) { + timeoutType = timeoutType_; + mutexTimeoutMs = timeoutMs; } diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index 78843ccd..b0a67430 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -29,10 +29,10 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase { /* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_SERVER_PORT; - UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort = "", + UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, const std::string& udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, object_id_t tcStoreId = objects::TC_STORE); - virtual ~UdpTmTcBridge(); + ~UdpTmTcBridge() override; /** * Set properties of internal mutex. @@ -46,12 +46,12 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase { std::string getUdpPort() const; protected: - virtual ReturnValue_t sendTm(const uint8_t* data, size_t dataLen) override; + ReturnValue_t sendTm(const uint8_t* data, size_t dataLen) override; private: std::string udpServerPort; - struct sockaddr clientAddress; + struct sockaddr clientAddress = {}; socklen_t clientAddressLen = 0; //! Access to the client address is mutex protected as it is set by another task. diff --git a/src/fsfw/osal/host/CMakeLists.txt b/src/fsfw/osal/host/CMakeLists.txt index 2d29ce5d..8b11a531 100644 --- a/src/fsfw/osal/host/CMakeLists.txt +++ b/src/fsfw/osal/host/CMakeLists.txt @@ -1,24 +1,27 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - Clock.cpp - FixedTimeslotTask.cpp - MessageQueue.cpp - Mutex.cpp - MutexFactory.cpp - PeriodicTask.cpp - QueueFactory.cpp - QueueMapManager.cpp - SemaphoreFactory.cpp - TaskFactory.cpp - taskHelpers.cpp +target_sources(${LIB_FSFW_NAME} PRIVATE + Clock.cpp + FixedTimeslotTask.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicTask.cpp + QueueFactory.cpp + QueueMapManager.cpp + SemaphoreFactory.cpp + TaskFactory.cpp + taskHelpers.cpp ) if(UNIX) - find_package(Threads REQUIRED) - - target_link_libraries(${LIB_FSFW_NAME} - PRIVATE - rt - ${CMAKE_THREAD_LIBS_INIT} - ) + find_package(Threads REQUIRED) + + target_link_libraries(${LIB_FSFW_NAME} PRIVATE + ${CMAKE_THREAD_LIBS_INIT} + ) + if(NOT APPLE) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE + rt + ) + endif() + endif() \ No newline at end of file diff --git a/src/fsfw/osal/linux/CMakeLists.txt b/src/fsfw/osal/linux/CMakeLists.txt index 679b2931..2e88d6d0 100644 --- a/src/fsfw/osal/linux/CMakeLists.txt +++ b/src/fsfw/osal/linux/CMakeLists.txt @@ -1,29 +1,29 @@ target_sources(${LIB_FSFW_NAME} PRIVATE - Clock.cpp - BinarySemaphore.cpp - CountingSemaphore.cpp - FixedTimeslotTask.cpp - InternalErrorCodes.cpp - MessageQueue.cpp - Mutex.cpp - MutexFactory.cpp - PeriodicPosixTask.cpp - PosixThread.cpp - QueueFactory.cpp - SemaphoreFactory.cpp - TaskFactory.cpp - tcpipHelpers.cpp - unixUtility.cpp -) + Clock.cpp + BinarySemaphore.cpp + CountingSemaphore.cpp + FixedTimeslotTask.cpp + InternalErrorCodes.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicPosixTask.cpp + PosixThread.cpp + QueueFactory.cpp + SemaphoreFactory.cpp + TaskFactory.cpp + tcpipHelpers.cpp + unixUtility.cpp + ) find_package(Threads REQUIRED) -target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${CMAKE_THREAD_LIBS_INIT} +target_link_libraries(${LIB_FSFW_NAME} PUBLIC + ${CMAKE_THREAD_LIBS_INIT} + ) + +if(NOT APPLE) + target_link_libraries(${LIB_FSFW_NAME} PUBLIC rt -) - -target_link_libraries(${LIB_FSFW_NAME} INTERFACE - ${CMAKE_THREAD_LIBS_INIT} -) - + ) +endif() diff --git a/src/fsfw/power/Fuse.h b/src/fsfw/power/Fuse.h index e6f9c149..787fa38d 100644 --- a/src/fsfw/power/Fuse.h +++ b/src/fsfw/power/Fuse.h @@ -54,7 +54,7 @@ class Fuse : public SystemObject, ReturnValue_t check(); uint8_t getFuseId() const; - ReturnValue_t initialize(); + ReturnValue_t initialize() override; DeviceList devices; ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const override; diff --git a/src/fsfw/subsystem/Subsystem.h b/src/fsfw/subsystem/Subsystem.h index 06181ca7..f4f09d1c 100644 --- a/src/fsfw/subsystem/Subsystem.h +++ b/src/fsfw/subsystem/Subsystem.h @@ -129,7 +129,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF { virtual void performChildOperation() override; - virtual ReturnValue_t handleCommandMessage(CommandMessage *message); + virtual ReturnValue_t handleCommandMessage(CommandMessage *message) override; bool isFallbackSequence(Mode_t SequenceId); diff --git a/src/fsfw/subsystem/SubsystemBase.h b/src/fsfw/subsystem/SubsystemBase.h index a908e13a..52f9891e 100644 --- a/src/fsfw/subsystem/SubsystemBase.h +++ b/src/fsfw/subsystem/SubsystemBase.h @@ -125,13 +125,13 @@ class SubsystemBase : public SystemObject, virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) override = 0; - virtual void startTransition(Mode_t mode, Submode_t submode) = 0; + virtual void startTransition(Mode_t mode, Submode_t submode) override = 0; virtual void getMode(Mode_t *mode, Submode_t *submode) override; virtual void setToExternalControl() override; - virtual void announceMode(bool recursive); + virtual void announceMode(bool recursive) override; virtual void modeChanged(); }; From 77450eb4b7b2629f0b88fdab66ae99bfc546daa4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 2 May 2022 09:09:41 +0200 Subject: [PATCH 094/198] removed flag which does not exist --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8619f17b..d8ca812e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,7 +332,6 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") -Warray-bounds=2 # Some array bounds violations will be found -Wshift-overflow=2 # Search for bit left shift overflows ( Date: Mon, 2 May 2022 15:12:38 +0200 Subject: [PATCH 095/198] preproc guards --- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index f46ad386..c4054bf1 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -20,7 +20,9 @@ LinuxLibgpioIF::~LinuxLibgpioIF() { ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { ReturnValue_t result; if (gpioCookie == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "LinuxLibgpioIF::addGpios: Invalid cookie" << std::endl; +#endif return RETURN_FAILED; } @@ -96,8 +98,10 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId, std::string& label = gpioByLabel.label; struct gpiod_chip* chip = gpiod_chip_open_by_label(label.c_str()); if (chip == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LinuxLibgpioIF::configureGpioByLabel: Failed to open gpio from gpio " << "group with label " << label << ". Gpio ID: " << gpioId << std::endl; +#endif return RETURN_FAILED; } std::string failOutput = "label: " + label; @@ -108,8 +112,10 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId, GpiodRegularB std::string& chipname = gpioByChip.chipname; struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname.c_str()); if (chip == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LinuxLibgpioIF::configureGpioByChip: Failed to open chip " << chipname << ". Gpio ID: " << gpioId << std::endl; +#endif return RETURN_FAILED; } std::string failOutput = "chipname: " + chipname; @@ -133,8 +139,10 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByLineName(gpioId_t gpioId, struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname); if (chip == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LinuxLibgpioIF::configureGpioByLineName: Failed to open chip " << chipname << ". Date: Mon, 2 May 2022 16:14:23 +0200 Subject: [PATCH 096/198] Proposed fix for gcc and clang --- src/fsfw/container/FixedArrayList.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fsfw/container/FixedArrayList.h b/src/fsfw/container/FixedArrayList.h index 26a73921..1981abe1 100644 --- a/src/fsfw/container/FixedArrayList.h +++ b/src/fsfw/container/FixedArrayList.h @@ -2,6 +2,7 @@ #define FIXEDARRAYLIST_H_ #include +#include #include "ArrayList.h" /** @@ -9,8 +10,8 @@ */ template class FixedArrayList : public ArrayList { -#if !defined(_MSC_VER) && !defined(__clang__) - static_assert(MAX_SIZE <= (std::pow(2, sizeof(count_t) * 8) - 1), +#if !defined(_MSC_VER) + static_assert(MAX_SIZE <= std::numeric_limits::max(), "count_t is not large enough to hold MAX_SIZE"); #endif private: From 3332f68ce79adc42c2ba6d72a84e18b982eb1d3c Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 2 May 2022 17:22:13 +0200 Subject: [PATCH 097/198] Tested only std::numeric_limits in MSVC --- src/fsfw/container/FixedArrayList.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fsfw/container/FixedArrayList.h b/src/fsfw/container/FixedArrayList.h index 1981abe1..11882537 100644 --- a/src/fsfw/container/FixedArrayList.h +++ b/src/fsfw/container/FixedArrayList.h @@ -10,10 +10,8 @@ */ template class FixedArrayList : public ArrayList { -#if !defined(_MSC_VER) static_assert(MAX_SIZE <= std::numeric_limits::max(), "count_t is not large enough to hold MAX_SIZE"); -#endif private: T data[MAX_SIZE]; From 2220120d5487a06036ec6009f2be923d0b4a6331 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 3 May 2022 16:43:15 +0200 Subject: [PATCH 098/198] improved i2c error printout --- hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp | 22 +++++++++++---------- hal/src/fsfw_hal/linux/uart/UartComIF.cpp | 2 +- src/fsfw/devicehandlers/DeviceHandlerBase.h | 3 ++- src/fsfw/objectmanager/SystemObject.h | 3 ++- src/fsfw/osal/common/UdpTcPollingTask.cpp | 2 +- src/fsfw/osal/common/UdpTmTcBridge.cpp | 4 ++-- src/fsfw/osal/common/UdpTmTcBridge.h | 4 ++-- 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp b/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp index 4f53dc1f..1740b022 100644 --- a/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp +++ b/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp @@ -170,18 +170,20 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe int readLen = read(fd, replyBuffer, requestLen); if (readLen != static_cast(requestLen)) { -#if FSFW_VERBOSE_LEVEL >= 1 and FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C " - << "device failed with error code " << errno << ". Description" - << " of error: " << strerror(errno) << std::endl; - sif::error << "I2cComIF::requestReceiveMessage: Read only " << readLen << " from " << requestLen - << " bytes" << std::endl; +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if (readLen < 0) { + sif::warning << "I2cComIF::requestReceiveMessage: Reading from I2C " + << "device failed with error code " << errno << " | " << strerror(errno) + << std::endl; + } else { + sif::warning << "I2cComIF::requestReceiveMessage: Read only " << readLen << " from " + << requestLen << " bytes" << std::endl; + } +#else +#endif #endif i2cDeviceMapIter->second.replyLen = 0; -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen - << " bytes" << std::endl; -#endif return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp index 72c79df6..f77bdeae 100644 --- a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp @@ -314,7 +314,7 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki cfsetispeed(options, B4000000); cfsetospeed(options, B4000000); break; -#endif // ! __APPLE__ +#endif // ! __APPLE__ default: #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 4a08e60f..e833e129 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -1072,7 +1072,8 @@ class DeviceHandlerBase : public DeviceHandlerIF, /** * Same as triggerEvent, but for forwarding if object is used as proxy. */ - virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override; + virtual void forwardEvent(Event event, uint32_t parameter1 = 0, + uint32_t parameter2 = 0) const override; /** * Checks if current mode is transitional mode. diff --git a/src/fsfw/objectmanager/SystemObject.h b/src/fsfw/objectmanager/SystemObject.h index eeb68b8f..c541ac5e 100644 --- a/src/fsfw/objectmanager/SystemObject.h +++ b/src/fsfw/objectmanager/SystemObject.h @@ -50,7 +50,8 @@ class SystemObject : public SystemObjectIF { virtual ReturnValue_t initialize() override; virtual ReturnValue_t checkObjectConnections() override; - virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override; + virtual void forwardEvent(Event event, uint32_t parameter1 = 0, + uint32_t parameter2 = 0) const override; }; #endif /* FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ */ diff --git a/src/fsfw/osal/common/UdpTcPollingTask.cpp b/src/fsfw/osal/common/UdpTcPollingTask.cpp index 38fb1921..bcc8e9e3 100644 --- a/src/fsfw/osal/common/UdpTcPollingTask.cpp +++ b/src/fsfw/osal/common/UdpTcPollingTask.cpp @@ -154,7 +154,7 @@ void UdpTcPollingTask::setTimeout(double timeoutSeconds) { #endif } #elif defined(PLATFORM_UNIX) - timeval tval {}; + timeval tval{}; tval = timevalOperations::toTimeval(timeoutSeconds); int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(receptionTimeout)); if (result == -1) { diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index 6089f266..e3cad58f 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -20,7 +20,7 @@ const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, - const std::string& udpServerPort_, object_id_t tmStoreId, + const std::string &udpServerPort_, object_id_t tmStoreId, object_id_t tcStoreId) : TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if (udpServerPort_.empty()) { @@ -118,7 +118,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { #endif ssize_t bytesSent = sendto(serverSocket, reinterpret_cast(data), dataLen, flags, - &clientAddress, clientAddressLen); + &clientAddress, clientAddressLen); if (bytesSent == SOCKET_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TmTcUdpBridge::sendTm: Send operation failed." << std::endl; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index b0a67430..92829c46 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -29,8 +29,8 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase { /* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_SERVER_PORT; - UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, const std::string& udpServerPort = "", - object_id_t tmStoreId = objects::TM_STORE, + UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, + const std::string& udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, object_id_t tcStoreId = objects::TC_STORE); ~UdpTmTcBridge() override; From a9041b84a3adc360106c1b4530d4df9d5dc9c080 Mon Sep 17 00:00:00 2001 From: Cleanroom Laptop L15 Date: Wed, 4 May 2022 10:27:20 +0200 Subject: [PATCH 099/198] update read gpio API --- hal/src/fsfw_hal/common/gpio/GpioIF.h | 2 +- hal/src/fsfw_hal/common/gpio/gpioDefinitions.h | 2 +- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 4 ++-- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hal/src/fsfw_hal/common/gpio/GpioIF.h b/hal/src/fsfw_hal/common/gpio/GpioIF.h index 5cca1481..2c284094 100644 --- a/hal/src/fsfw_hal/common/gpio/GpioIF.h +++ b/hal/src/fsfw_hal/common/gpio/GpioIF.h @@ -48,7 +48,7 @@ class GpioIF : public HasReturnvaluesIF { * @param gpioId A unique number which specifies the GPIO to read. * @param gpioState State of GPIO will be written to this pointer. */ - virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0; + virtual ReturnValue_t readGpio(gpioId_t gpioId, gpio::Levels& gpioState) = 0; }; #endif /* COMMON_GPIO_GPIOIF_H_ */ diff --git a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h index eb90629e..a15ffbc0 100644 --- a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h +++ b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h @@ -9,7 +9,7 @@ using gpioId_t = uint16_t; namespace gpio { -enum class Levels : int { LOW = 0, HIGH = 1, NONE = 99 }; +enum class Levels : int { LOW = 0, HIGH = 1, FAILED = -1, NONE = 99 }; enum class Direction : int { IN = 0, OUT = 1 }; diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index f46ad386..e9da5b03 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -280,7 +280,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegularBase& regul return RETURN_OK; } -ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { +ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState) { gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -299,7 +299,7 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { if (regularGpio == nullptr) { return GPIO_TYPE_FAILURE; } - *gpioState = gpiod_line_get_value(regularGpio->lineHandle); + gpioState = static_cast(gpiod_line_get_value(regularGpio->lineHandle)); } else { auto gpioCallback = dynamic_cast(gpioMapIter->second); if (gpioCallback->callback == nullptr) { diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h index fcc9c775..4ac2e7d9 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h @@ -38,7 +38,7 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject { ReturnValue_t addGpios(GpioCookie* gpioCookie) override; ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override; - ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; + ReturnValue_t readGpio(gpioId_t gpioId, gpio::Levels& gpioState) override; private: static const size_t MAX_CHIPNAME_LENGTH = 11; From 3556eca8e875aaa4aab1c96e60f0b1eaefc7e982 Mon Sep 17 00:00:00 2001 From: Cleanroom Laptop L15 Date: Wed, 4 May 2022 10:33:55 +0200 Subject: [PATCH 100/198] error check on line getter --- hal/src/fsfw_hal/common/gpio/GpioIF.h | 2 +- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/common/gpio/GpioIF.h b/hal/src/fsfw_hal/common/gpio/GpioIF.h index 2c284094..f8ef9d9c 100644 --- a/hal/src/fsfw_hal/common/gpio/GpioIF.h +++ b/hal/src/fsfw_hal/common/gpio/GpioIF.h @@ -46,7 +46,7 @@ class GpioIF : public HasReturnvaluesIF { * an ouput or input gpio. * * @param gpioId A unique number which specifies the GPIO to read. - * @param gpioState State of GPIO will be written to this pointer. + * @param gpioState State of GPIO will be written to this reference */ virtual ReturnValue_t readGpio(gpioId_t gpioId, gpio::Levels& gpioState) = 0; }; diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index e9da5b03..03bc1830 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -300,6 +300,10 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState) return GPIO_TYPE_FAILURE; } gpioState = static_cast(gpiod_line_get_value(regularGpio->lineHandle)); + if (gpioState == gpio::Levels::FAILED) { + // TODO: Print error + return RETURN_FAILED; + } } else { auto gpioCallback = dynamic_cast(gpioMapIter->second); if (gpioCallback->callback == nullptr) { From 8ee26f81f9449e28566a8d34fbb3454cfd1da01c Mon Sep 17 00:00:00 2001 From: Cleanroom Laptop L15 Date: Wed, 4 May 2022 10:36:32 +0200 Subject: [PATCH 101/198] dedicated returnvalue for line get failure --- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 3 +-- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index 03bc1830..136dfe11 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -301,8 +301,7 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState) } gpioState = static_cast(gpiod_line_get_value(regularGpio->lineHandle)); if (gpioState == gpio::Levels::FAILED) { - // TODO: Print error - return RETURN_FAILED; + return GPIO_GET_VALUE_FAILED; } } else { auto gpioCallback = dynamic_cast(gpioMapIter->second); diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h index 4ac2e7d9..a50e480d 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h @@ -31,7 +31,9 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject { HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 5); static constexpr ReturnValue_t GPIO_INIT_FAILED = HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 6); - + // Will be returned if getting the line value failed. Error type will be set to errno in this case + static constexpr ReturnValue_t GPIO_GET_VALUE_FAILED = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 7); LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); From f59b05c86cd54390d2a259eda770ee7935587112 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 May 2022 02:00:41 +0200 Subject: [PATCH 102/198] use warning instead of error --- src/fsfw/osal/freertos/FixedTimeslotTask.cpp | 2 +- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 2 +- src/fsfw/osal/rtems/FixedTimeslotTask.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp index e0e3779e..0f3bfe18 100644 --- a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp @@ -46,7 +46,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { FixedTimeslotTask::deadlineMissedCount++; if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." + sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." << std::endl; #endif } diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp index 1f4d6e23..d64c020d 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp @@ -87,7 +87,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { FixedTimeslotTask::deadlineMissedCount++; if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." + sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." << std::endl; #endif } diff --git a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp index 3347739a..12434e1b 100644 --- a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp @@ -50,7 +50,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { FixedTimeslotTask::deadlineMissedCount++; if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." + sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." << std::endl; #endif } From 71f704c980ec8847bdd0bb1bf354c8de30d3524b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 May 2022 12:29:46 +0200 Subject: [PATCH 103/198] remove the dot --- src/fsfw/osal/freertos/FixedTimeslotTask.cpp | 2 +- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 2 +- src/fsfw/osal/rtems/FixedTimeslotTask.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp index 0f3bfe18..e8823f8a 100644 --- a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp @@ -46,7 +46,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { FixedTimeslotTask::deadlineMissedCount++; if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." + sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines" << std::endl; #endif } diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp index d64c020d..37b958de 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp @@ -87,7 +87,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { FixedTimeslotTask::deadlineMissedCount++; if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." + sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines" << std::endl; #endif } diff --git a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp index 12434e1b..745b8d70 100644 --- a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp @@ -50,7 +50,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { FixedTimeslotTask::deadlineMissedCount++; if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines." + sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines" << std::endl; #endif } From d72b212fa629029924d9862e3e862d0388911f8e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 6 May 2022 10:36:01 +0200 Subject: [PATCH 104/198] cmakelists.txt hotfix --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f10ab8e..5c898369 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.13) +set(LIB_FSFW_NAME fsfw) project(${LIB_FSFW_NAME}) set(FSFW_VERSION_IF_GIT_FAILS 4) @@ -58,7 +59,7 @@ option(FSFW_ADD_TMSTORAGE "Compile with tm storage components" OFF) # Contrib sources option(FSFW_ADD_SGP4_PROPAGATOR "Add SGP4 propagator code" OFF) -set(LIB_FSFW_NAME fsfw) + set(FSFW_TEST_TGT fsfw-tests) set(FSFW_DUMMY_TGT fsfw-dummy) From cb0c80d8dc7510435c15431d5e39c9a9e484948d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 02:22:16 +0200 Subject: [PATCH 105/198] add option and cmake module for lto support --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfe3da84..d34511e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,13 @@ set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE set(FSFW_ETL_LIB_NAME etl) +include(CheckIPOSupported) +check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR) +if(NOT IPO_SUPPORTED) + message(STATUS "FSFW | IPO/LTO not supported: ${IPO_ERROR}") +endif() + +option(FSFW_ENABLE_IPO "Enable interprocedural optimization or link-time optimization if available" ON) option(FSFW_GENERATE_SECTIONS "Generate function and data sections. Required to remove unused code" ON ) From a943e4eebb1aeb3cc2a01e8df7e1069341ac085b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 02:23:20 +0200 Subject: [PATCH 106/198] enable LTO where applicable --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d34511e8..1700236f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,10 @@ set(FSFW_DUMMY_TGT fsfw-dummy) project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) +if(IPO_SUPPORTED AND FSFW_ENABLE_IPO) + set_property(TARGET ${LIB_FSFW_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) +endif() + if(FSFW_BUILD_UNITTESTS) message(STATUS "Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first From a4bd5a2aaaff36e7ad1d207a48533eb42e51439d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 10:31:03 +0200 Subject: [PATCH 107/198] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d28c5c6..4d713f26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Additions +- LTO support: Allow using LTO/IPO by setting `FSFW_ENABLE_LTO=1`. CMake is able to detect whether + the user compiler supports IPO/LPO. LTO is on by default now. Most modern compilers support it + and can make good use of it and is usually makes the code faster and/or larger. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 - Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1 - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information inside `fsfw/version.h` From 637512ad77023a13c15214b5b513535eee4f7f40 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 10:34:14 +0200 Subject: [PATCH 108/198] changelog update --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d713f26..dc9577f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,8 +44,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Additions - LTO support: Allow using LTO/IPO by setting `FSFW_ENABLE_LTO=1`. CMake is able to detect whether - the user compiler supports IPO/LPO. LTO is on by default now. Most modern compilers support it - and can make good use of it and is usually makes the code faster and/or larger. + the user compiler supports IPO/LPO. LTO is on by default now. Most modern compilers support it, + can make good use of it and it usually makes the code faster and/or smaller. PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 - Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1 - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information From 4e4820af05d989aa89b1b153cded1267ca56d5ca Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 10:47:23 +0200 Subject: [PATCH 109/198] bugfix for prepareHealthSetReply function --- src/fsfw/pus/CService201HealthCommanding.cpp | 15 +++++++++------ src/fsfw/pus/CService201HealthCommanding.h | 10 ++++------ src/fsfw/tmtcservices/CommandingServiceBase.h | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/fsfw/pus/CService201HealthCommanding.cpp b/src/fsfw/pus/CService201HealthCommanding.cpp index 4d9806f9..c62791c6 100644 --- a/src/fsfw/pus/CService201HealthCommanding.cpp +++ b/src/fsfw/pus/CService201HealthCommanding.cpp @@ -13,7 +13,7 @@ CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, u : CommandingServiceBase(objectId, apid, serviceId, numParallelCommands, commandTimeoutSeconds) { } -CService201HealthCommanding::~CService201HealthCommanding() {} +CService201HealthCommanding::~CService201HealthCommanding() = default; ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) { switch (subservice) { @@ -43,8 +43,8 @@ ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(uint8_t subs } ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue( - MessageQueueId_t *messageQueueToSet, object_id_t *objectId) { - HasHealthIF *destination = ObjectManager::instance()->get(*objectId); + MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) { + auto *destination = ObjectManager::instance()->get(*objectId); if (destination == nullptr) { return CommandingServiceBase::INVALID_OBJECT; } @@ -77,6 +77,10 @@ ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *messag HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE_ALL); break; } + default: { + // Should never happen, subservice was already checked + result = RETURN_FAILED; + } } return result; } @@ -96,9 +100,8 @@ ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *rep // Not used for now, health state already reported by event ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(const CommandMessage *reply) { - prepareHealthSetReply(reply); - uint8_t health = static_cast(HealthMessage::getHealth(reply)); - uint8_t oldHealth = static_cast(HealthMessage::getOldHealth(reply)); + auto health = static_cast(HealthMessage::getHealth(reply)); + auto oldHealth = static_cast(HealthMessage::getOldHealth(reply)); HealthSetReply healthSetReply(health, oldHealth); return sendTmPacket(Subservice::REPLY_HEALTH_SET, &healthSetReply); } diff --git a/src/fsfw/pus/CService201HealthCommanding.h b/src/fsfw/pus/CService201HealthCommanding.h index 5e52ab39..e4ad749f 100644 --- a/src/fsfw/pus/CService201HealthCommanding.h +++ b/src/fsfw/pus/CService201HealthCommanding.h @@ -1,7 +1,7 @@ #ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_ #define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_ -#include "../tmtcservices/CommandingServiceBase.h" +#include "fsfw/tmtcservices/CommandingServiceBase.h" /** * @brief Custom PUS service to set health of all objects @@ -21,7 +21,7 @@ class CService201HealthCommanding : public CommandingServiceBase { public: CService201HealthCommanding(object_id_t objectId, uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands = 4, uint16_t commandTimeoutSeconds = 60); - virtual ~CService201HealthCommanding(); + ~CService201HealthCommanding() override; protected: /* CSB abstract function implementations */ @@ -38,10 +38,8 @@ class CService201HealthCommanding : public CommandingServiceBase { bool *isStep) override; private: - ReturnValue_t checkAndAcquireTargetID(object_id_t *objectIdToSet, const uint8_t *tcData, - size_t tcDataLen); - ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet, - object_id_t *objectId); + static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet, + const object_id_t *objectId); ReturnValue_t prepareHealthSetReply(const CommandMessage *reply); diff --git a/src/fsfw/tmtcservices/CommandingServiceBase.h b/src/fsfw/tmtcservices/CommandingServiceBase.h index 867fc287..4dcad024 100644 --- a/src/fsfw/tmtcservices/CommandingServiceBase.h +++ b/src/fsfw/tmtcservices/CommandingServiceBase.h @@ -166,7 +166,7 @@ class CommandingServiceBase : public SystemObject, * @param objectId Target object ID * @return * - @c RETURN_OK to generate a verification start message - * - @c EXECUTION_COMPELTE Fire-and-forget command. Generate a completion + * - @c EXECUTION_COMPLETE Fire-and-forget command. Generate a completion * verification message. * - @c Anything else rejects the packets and generates a start failure * verification. From e5e163bdbf720cf12d03314a9d11cb0ee010bbf3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 10:47:56 +0200 Subject: [PATCH 110/198] mark unused function --- src/fsfw/pus/CService201HealthCommanding.cpp | 2 +- src/fsfw/pus/CService201HealthCommanding.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/pus/CService201HealthCommanding.cpp b/src/fsfw/pus/CService201HealthCommanding.cpp index c62791c6..91ea4e7a 100644 --- a/src/fsfw/pus/CService201HealthCommanding.cpp +++ b/src/fsfw/pus/CService201HealthCommanding.cpp @@ -99,7 +99,7 @@ ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *rep } // Not used for now, health state already reported by event -ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(const CommandMessage *reply) { +[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(const CommandMessage *reply) { auto health = static_cast(HealthMessage::getHealth(reply)); auto oldHealth = static_cast(HealthMessage::getOldHealth(reply)); HealthSetReply healthSetReply(health, oldHealth); diff --git a/src/fsfw/pus/CService201HealthCommanding.h b/src/fsfw/pus/CService201HealthCommanding.h index e4ad749f..29f21695 100644 --- a/src/fsfw/pus/CService201HealthCommanding.h +++ b/src/fsfw/pus/CService201HealthCommanding.h @@ -41,7 +41,7 @@ class CService201HealthCommanding : public CommandingServiceBase { static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet, const object_id_t *objectId); - ReturnValue_t prepareHealthSetReply(const CommandMessage *reply); + [[maybe_unused]] ReturnValue_t prepareHealthSetReply(const CommandMessage *reply); enum Subservice { //! [EXPORT] : [TC] Set health of target object From 79f17843d82e7b90c4be31c136635ee6eb917a24 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 10:50:29 +0200 Subject: [PATCH 111/198] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d28c5c6..4a7c6083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Fixed +- Fix infinite recursion in `prepareHealthSetReply` of PUS Health Service 201. + Is not currently used right now but might be used in the future + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/617 - Small bugfix in STM32 HAL for SPI PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/599 - HAL GPIO: Improved error checking in `LinuxLibgpioIF::configureGpios(...)`. If a GPIO From 16e55a98cee33f205634b9feb1322558dfbb88db Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 10:57:23 +0200 Subject: [PATCH 112/198] important bugfix for TCP server --- src/fsfw/osal/common/TcpTmTcServer.cpp | 22 +++++++++++++--------- src/fsfw/osal/common/TcpTmTcServer.h | 11 ++++++----- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index 2e6910c5..91cb9574 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -19,6 +19,8 @@ #include #elif defined(PLATFORM_UNIX) #include + +#include #endif const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; @@ -29,7 +31,7 @@ TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, : SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), receptionMode(receptionMode), - tcpConfig(customTcpServerPort), + tcpConfig(std::move(customTcpServerPort)), receptionBuffer(receptionBufferSize), ringBuffer(ringBufferSize, true) {} @@ -103,7 +105,7 @@ ReturnValue_t TcpTmTcServer::initialize() { TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); } -ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { +[[noreturn]] ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { using namespace tcpip; // If a connection is accepted, the corresponding socket will be assigned to the new socket socket_t connSocket = 0; @@ -138,7 +140,6 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { closeSocket(connSocket); connSocket = 0; } - return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t TcpTmTcServer::initializeAfterTaskCreation() { @@ -159,7 +160,7 @@ void TcpTmTcServer::handleServerOperation(socket_t& connSocket) { #endif while (true) { - int retval = recv(connSocket, reinterpret_cast(receptionBuffer.data()), + ssize_t retval = recv(connSocket, reinterpret_cast(receptionBuffer.data()), receptionBuffer.capacity(), tcpConfig.tcpFlags); if (retval == 0) { size_t availableReadData = ringBuffer.getAvailableReadData(); @@ -252,17 +253,17 @@ ReturnValue_t TcpTmTcServer::handleTcReception(uint8_t* spacePacket, size_t pack return result; } -std::string TcpTmTcServer::getTcpPort() const { return tcpConfig.tcpPort; } +const std::string& TcpTmTcServer::getTcpPort() const { return tcpConfig.tcpPort; } -void TcpTmTcServer::setSpacePacketParsingOptions(std::vector validPacketIds) { - this->validPacketIds = validPacketIds; +void TcpTmTcServer::setSpacePacketParsingOptions(std::vector validPacketIds_) { + this->validPacketIds = std::move(validPacketIds_); } TcpTmTcServer::TcpConfig& TcpTmTcServer::getTcpConfigStruct() { return tcpConfig; } ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent) { // Access to the FIFO is mutex protected because it is filled by the bridge - MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs); + MutexGuard mg(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs); store_address_t storeId; while ((not tmtcBridge->tmFifo->empty()) and (tmtcBridge->packetSentCounter < tmtcBridge->sentPacketsPerCycle)) { @@ -283,7 +284,7 @@ ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent) #endif arrayprinter::print(storeAccessor.data(), storeAccessor.size()); } - int retval = send(connSocket, reinterpret_cast(storeAccessor.data()), + ssize_t retval = send(connSocket, reinterpret_cast(storeAccessor.data()), storeAccessor.size(), tcpConfig.tcpTmFlags); if (retval == static_cast(storeAccessor.size())) { // Packet sent, clear FIFO entry @@ -339,6 +340,9 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) { size_t foundSize = 0; size_t readLen = 0; while (readLen < readAmount) { + if(spacePacketParser == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } result = spacePacketParser->parseSpacePackets(bufPtrPtr, readAmount, startIdx, foundSize, readLen); switch (result) { diff --git a/src/fsfw/osal/common/TcpTmTcServer.h b/src/fsfw/osal/common/TcpTmTcServer.h index d062a0ce..faf6e0a1 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.h +++ b/src/fsfw/osal/common/TcpTmTcServer.h @@ -17,6 +17,7 @@ #endif #include +#include #include class TcpTmTcBridge; @@ -44,7 +45,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb struct TcpConfig { public: - TcpConfig(std::string tcpPort) : tcpPort(tcpPort) {} + explicit TcpConfig(std::string tcpPort) : tcpPort(std::move(tcpPort)) {} /** * Passed to the recv call @@ -84,7 +85,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb size_t ringBufferSize = RING_BUFFER_SIZE, std::string customTcpServerPort = DEFAULT_SERVER_PORT, ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS); - virtual ~TcpTmTcServer(); + ~TcpTmTcServer() override; void enableWiretapping(bool enable); @@ -97,10 +98,10 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb void setSpacePacketParsingOptions(std::vector validPacketIds); ReturnValue_t initialize() override; - ReturnValue_t performOperation(uint8_t opCode) override; + [[noreturn]] ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t initializeAfterTaskCreation() override; - std::string getTcpPort() const; + [[nodiscard]] const std::string& getTcpPort() const; protected: StorageManagerIF* tcStore = nullptr; @@ -115,7 +116,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb ReceptionModes receptionMode; TcpConfig tcpConfig; - struct sockaddr tcpAddress; + struct sockaddr tcpAddress = {}; socket_t listenerTcpSocket = 0; MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; From 6bfdace5128a1b77119260d86e6278b7e57ea190 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 11:00:31 +0200 Subject: [PATCH 113/198] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d28c5c6..c03bf648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Fixed +- TCP TMTC Server: `MutexGuard` was not created properly in + `TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent)` call. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/618 - Small bugfix in STM32 HAL for SPI PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/599 - HAL GPIO: Improved error checking in `LinuxLibgpioIF::configureGpios(...)`. If a GPIO From 80a5ed3c5b3bb110d679f8fe9858fc43883c46af Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 11:06:45 +0200 Subject: [PATCH 114/198] added back fsfw namespace --- hal/src/fsfw_hal/linux/uart/UartComIF.cpp | 2 +- src/fsfw/devicehandlers/DeviceHandlerBase.h | 3 ++- src/fsfw/objectmanager/SystemObject.h | 3 ++- src/fsfw/osal/common/UdpTcPollingTask.cpp | 2 +- src/fsfw/osal/common/UdpTmTcBridge.cpp | 4 ++-- src/fsfw/osal/common/UdpTmTcBridge.h | 4 ++-- src/fsfw/version.cpp | 12 ++++++++---- src/fsfw/version.h | 4 ++-- 8 files changed, 20 insertions(+), 14 deletions(-) diff --git a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp index 72c79df6..f77bdeae 100644 --- a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp @@ -314,7 +314,7 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki cfsetispeed(options, B4000000); cfsetospeed(options, B4000000); break; -#endif // ! __APPLE__ +#endif // ! __APPLE__ default: #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 5808b8e6..84dcb8dc 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -1062,7 +1062,8 @@ class DeviceHandlerBase : public DeviceHandlerIF, /** * Same as triggerEvent, but for forwarding if object is used as proxy. */ - virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override; + virtual void forwardEvent(Event event, uint32_t parameter1 = 0, + uint32_t parameter2 = 0) const override; /** * Checks if current mode is transitional mode. diff --git a/src/fsfw/objectmanager/SystemObject.h b/src/fsfw/objectmanager/SystemObject.h index eeb68b8f..c541ac5e 100644 --- a/src/fsfw/objectmanager/SystemObject.h +++ b/src/fsfw/objectmanager/SystemObject.h @@ -50,7 +50,8 @@ class SystemObject : public SystemObjectIF { virtual ReturnValue_t initialize() override; virtual ReturnValue_t checkObjectConnections() override; - virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override; + virtual void forwardEvent(Event event, uint32_t parameter1 = 0, + uint32_t parameter2 = 0) const override; }; #endif /* FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ */ diff --git a/src/fsfw/osal/common/UdpTcPollingTask.cpp b/src/fsfw/osal/common/UdpTcPollingTask.cpp index 38fb1921..bcc8e9e3 100644 --- a/src/fsfw/osal/common/UdpTcPollingTask.cpp +++ b/src/fsfw/osal/common/UdpTcPollingTask.cpp @@ -154,7 +154,7 @@ void UdpTcPollingTask::setTimeout(double timeoutSeconds) { #endif } #elif defined(PLATFORM_UNIX) - timeval tval {}; + timeval tval{}; tval = timevalOperations::toTimeval(timeoutSeconds); int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(receptionTimeout)); if (result == -1) { diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index 6089f266..e3cad58f 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -20,7 +20,7 @@ const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, - const std::string& udpServerPort_, object_id_t tmStoreId, + const std::string &udpServerPort_, object_id_t tmStoreId, object_id_t tcStoreId) : TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if (udpServerPort_.empty()) { @@ -118,7 +118,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { #endif ssize_t bytesSent = sendto(serverSocket, reinterpret_cast(data), dataLen, flags, - &clientAddress, clientAddressLen); + &clientAddress, clientAddressLen); if (bytesSent == SOCKET_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TmTcUdpBridge::sendTm: Send operation failed." << std::endl; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index b0a67430..92829c46 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -29,8 +29,8 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase { /* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_SERVER_PORT; - UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, const std::string& udpServerPort = "", - object_id_t tmStoreId = objects::TM_STORE, + UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, + const std::string& udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, object_id_t tcStoreId = objects::TC_STORE); ~UdpTmTcBridge() override; diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 0b2ee60c..050a275d 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -12,19 +12,21 @@ #undef minor #endif -const Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, FSFW_VERSION_REVISION, - FSFW_VERSION_CST_GIT_SHA1}; +const fsfw::Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, + FSFW_VERSION_REVISION, FSFW_VERSION_CST_GIT_SHA1}; -Version::Version(int major, int minor, int revision, const char* addInfo) +fsfw::Version::Version(int major, int minor, int revision, const char* addInfo) : major(major), minor(minor), revision(revision), addInfo(addInfo) {} -void Version::getVersion(char* str, size_t maxLen) const { +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) { snprintf(str + len, maxLen - len, "-%s", addInfo); } } +namespace fsfw { + #if FSFW_CPP_OSTREAM_ENABLED == 1 std::ostream& operator<<(std::ostream& os, const Version& v) { os << v.major << "." << v.minor << "." << v.revision; @@ -34,3 +36,5 @@ std::ostream& operator<<(std::ostream& os, const Version& v) { return os; } #endif + +} // namespace fsfw diff --git a/src/fsfw/version.h b/src/fsfw/version.h index f7d56d91..a538c39a 100644 --- a/src/fsfw/version.h +++ b/src/fsfw/version.h @@ -8,6 +8,8 @@ #endif #include +namespace fsfw { + class Version { public: Version(int major, int minor, int revision, const char* addInfo = nullptr); @@ -55,8 +57,6 @@ class Version { void getVersion(char* str, size_t maxLen) const; }; -namespace fsfw { - extern const Version FSFW_VERSION; } // namespace fsfw From 398d04dc5092ae6ed63955ea09ea0eb2cfe003b5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 11:15:18 +0200 Subject: [PATCH 115/198] fixed tests --- CHANGELOG.md | 1 - tests/src/fsfw_tests/unit/version.cpp | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c912ac..add17372 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585 - Major update for version handling, using `git describe` to fetch version information with git. PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/601 - - Place `Version` class outside of `fsfw` namespace. It is generic - Add helper functions provided by [`cmake-modules`](https://github.com/bilke/cmake-modules) manually now. Those should not change too often and only a small subset is needed - Separate folder for easier update and for distinction diff --git a/tests/src/fsfw_tests/unit/version.cpp b/tests/src/fsfw_tests/unit/version.cpp index a95c1ea9..662b1290 100644 --- a/tests/src/fsfw_tests/unit/version.cpp +++ b/tests/src/fsfw_tests/unit/version.cpp @@ -10,12 +10,12 @@ TEST_CASE("Version API Tests", "[TestVersionAPI]") { // Check that major version is non-zero REQUIRE(fsfw::FSFW_VERSION.major > 0); uint32_t fsfwMajor = fsfw::FSFW_VERSION.major; - REQUIRE(Version(255, 0, 0) > fsfw::FSFW_VERSION); - REQUIRE(Version(255, 0, 0) >= fsfw::FSFW_VERSION); - REQUIRE(Version(0, 0, 0) < fsfw::FSFW_VERSION); - REQUIRE(Version(0, 0, 0) <= fsfw::FSFW_VERSION); - Version v1 = Version(1, 1, 1); - Version v2 = Version(1, 1, 1); + REQUIRE(fsfw::Version(255, 0, 0) > fsfw::FSFW_VERSION); + REQUIRE(fsfw::Version(255, 0, 0) >= fsfw::FSFW_VERSION); + REQUIRE(fsfw::Version(0, 0, 0) < fsfw::FSFW_VERSION); + REQUIRE(fsfw::Version(0, 0, 0) <= fsfw::FSFW_VERSION); + auto v1 = fsfw::Version(1, 1, 1); + auto v2 = fsfw::Version(1, 1, 1); REQUIRE(v1 == v2); REQUIRE(not(v1 < v2)); REQUIRE(not(v1 > v2)); From 6308427d03f1c6f116b587861dd927c2c80f5e12 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 11:18:56 +0200 Subject: [PATCH 116/198] run auto-formatter over cmakelists.txt --- CMakeLists.txt | 504 ++++++++++++++++++++++++------------------------- 1 file changed, 252 insertions(+), 252 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfe3da84..f8ccf115 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,33 +8,33 @@ set(FSFW_REVISION 0) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING - "ETL library major version requirement" -) + "ETL library major version requirement" + ) set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 CACHE STRING - "ETL library exact version requirement" -) + "ETL library exact version requirement" + ) set(FSFW_ETL_LINK_TARGET etl::etl) set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE STRING - "Catch2 library major version requirement" -) + "Catch2 library major version requirement" + ) set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE STRING - "Catch2 library exact version requirement" -) + "Catch2 library exact version requirement" + ) set(FSFW_ETL_LIB_NAME etl) option(FSFW_GENERATE_SECTIONS - "Generate function and data sections. Required to remove unused code" ON -) + "Generate function and data sections. Required to remove unused code" ON + ) if(FSFW_GENERATE_SECTIONS) - option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON) + option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON) endif() option(FSFW_BUILD_UNITTESTS "Build unittest binary in addition to static library" OFF) option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF) if(FSFW_BUILD_UNITTESTS) - option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON) + option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON) endif() option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON) @@ -63,45 +63,45 @@ project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) if(FSFW_BUILD_UNITTESTS) - message(STATUS "Building the FSFW unittests in addition to the static library") - # Check whether the user has already installed Catch2 first - find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION}) - # Not installed, so use FetchContent to download and provide Catch2 - if(NOT Catch2_FOUND) - message(STATUS "Catch2 installation not found. Downloading Catch2 library with FetchContent") - include(FetchContent) + message(STATUS "Building the FSFW unittests in addition to the static library") + # Check whether the user has already installed Catch2 first + find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION}) + # Not installed, so use FetchContent to download and provide Catch2 + if(NOT Catch2_FOUND) + message(STATUS "Catch2 installation not found. Downloading Catch2 library with FetchContent") + include(FetchContent) - FetchContent_Declare( - Catch2 - GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG ${FSFW_CATCH2_LIB_VERSION} - ) + FetchContent_Declare( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG ${FSFW_CATCH2_LIB_VERSION} + ) - list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2) - endif() + list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2) + endif() - set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg) - configure_file(tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in FSFWConfig.h) - configure_file(tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in tests/TestsConfig.h) + set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg) + configure_file(tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in FSFWConfig.h) + configure_file(tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in tests/TestsConfig.h) - project(${FSFW_TEST_TGT} CXX C) - add_executable(${FSFW_TEST_TGT}) + project(${FSFW_TEST_TGT} CXX C) + add_executable(${FSFW_TEST_TGT}) - if(FSFW_TESTS_GEN_COV) - message(STATUS "Generating coverage data for the library") - message(STATUS "Targets linking against ${LIB_FSFW_NAME} " - "will be compiled with coverage data as well" - ) - include(FetchContent) - FetchContent_Declare( - cmake-modules - GIT_REPOSITORY https://github.com/bilke/cmake-modules.git - ) - FetchContent_MakeAvailable(cmake-modules) - set(CMAKE_BUILD_TYPE "Debug") - list(APPEND CMAKE_MODULE_PATH ${cmake-modules_SOURCE_DIR}) - include(CodeCoverage) - endif() + if(FSFW_TESTS_GEN_COV) + message(STATUS "Generating coverage data for the library") + message(STATUS "Targets linking against ${LIB_FSFW_NAME} " + "will be compiled with coverage data as well" + ) + include(FetchContent) + FetchContent_Declare( + cmake-modules + GIT_REPOSITORY https://github.com/bilke/cmake-modules.git + ) + FetchContent_MakeAvailable(cmake-modules) + set(CMAKE_BUILD_TYPE "Debug") + list(APPEND CMAKE_MODULE_PATH ${cmake-modules_SOURCE_DIR}) + include(CodeCoverage) + endif() endif() message(STATUS "Finding and/or providing ETL library") @@ -110,34 +110,34 @@ message(STATUS "Finding and/or providing ETL library") find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide etl if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) - message(STATUS - "No ETL installation was found with find_package. Installing and providing " - "etl with FindPackage" + message(STATUS + "No ETL installation was found with find_package. Installing and providing " + "etl with FindPackage" ) - include(FetchContent) + include(FetchContent) - FetchContent_Declare( - ${FSFW_ETL_LIB_NAME} - GIT_REPOSITORY https://github.com/ETLCPP/etl - GIT_TAG ${FSFW_ETL_LIB_VERSION} - ) + FetchContent_Declare( + ${FSFW_ETL_LIB_NAME} + GIT_REPOSITORY https://github.com/ETLCPP/etl + GIT_TAG ${FSFW_ETL_LIB_VERSION} + ) - list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_ETL_LIB_NAME}) + list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_ETL_LIB_NAME}) endif() # The documentation for FetchContent recommends declaring all the dependencies # before making them available. We make all declared dependency available here # after their declaration if(FSFW_FETCH_CONTENT_TARGETS) - FetchContent_MakeAvailable(${FSFW_FETCH_CONTENT_TARGETS}) - if(TARGET ${FSFW_ETL_LIB_NAME}) - add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME}) - endif() - if(TARGET Catch2) - # Fixes regression -preview4, to be confirmed in later releases - # Related GitHub issue: https://github.com/catchorg/Catch2/issues/2417 - set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "") - endif() + FetchContent_MakeAvailable(${FSFW_FETCH_CONTENT_TARGETS}) + if(TARGET ${FSFW_ETL_LIB_NAME}) + add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME}) + endif() + if(TARGET Catch2) + # Fixes regression -preview4, to be confirmed in later releases + # Related GitHub issue: https://github.com/catchorg/Catch2/issues/2417 + set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "") + endif() endif() set(FSFW_CORE_INC_PATH "inc") @@ -146,64 +146,64 @@ set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux rtems freertos) # For configure files target_include_directories(${LIB_FSFW_NAME} PRIVATE - ${CMAKE_CURRENT_BINARY_DIR} -) + ${CMAKE_CURRENT_BINARY_DIR} + ) target_include_directories(${LIB_FSFW_NAME} INTERFACE - ${CMAKE_CURRENT_BINARY_DIR} -) + ${CMAKE_CURRENT_BINARY_DIR} + ) if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_STANDARD_REQUIRED True) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED True) elseif(${CMAKE_CXX_STANDARD} LESS 11) - message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++11 support") + message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++11 support") endif() # Backwards comptability if(OS_FSFW AND NOT FSFW_OSAL) - message(WARNING "Please pass the FSFW OSAL as FSFW_OSAL instead of OS_FSFW") - set(FSFW_OSAL OS_FSFW) + message(WARNING "Please pass the FSFW OSAL as FSFW_OSAL instead of OS_FSFW") + set(FSFW_OSAL OS_FSFW) endif() if(NOT FSFW_OSAL) - message(STATUS "No OS for FSFW via FSFW_OSAL set. Assuming host OS") - # Assume host OS and autodetermine from OS_FSFW - if(UNIX) - set(FSFW_OSAL "linux" - CACHE STRING - "OS abstraction layer used in the FSFW" - ) - elseif(WIN32) - set(FSFW_OSAL "host" - CACHE STRING "OS abstraction layer used in the FSFW" - ) - endif() + message(STATUS "No OS for FSFW via FSFW_OSAL set. Assuming host OS") + # Assume host OS and autodetermine from OS_FSFW + if(UNIX) + set(FSFW_OSAL "linux" + CACHE STRING + "OS abstraction layer used in the FSFW" + ) + elseif(WIN32) + set(FSFW_OSAL "host" + CACHE STRING "OS abstraction layer used in the FSFW" + ) + endif() endif() set(FSFW_OSAL_DEFINITION FSFW_OSAL_HOST) if(FSFW_OSAL MATCHES host) - set(FSFW_OS_NAME "Host") - set(FSFW_OSAL_HOST ON) + set(FSFW_OS_NAME "Host") + set(FSFW_OSAL_HOST ON) elseif(FSFW_OSAL MATCHES linux) - set(FSFW_OS_NAME "Linux") - set(FSFW_OSAL_LINUX ON) + set(FSFW_OS_NAME "Linux") + set(FSFW_OSAL_LINUX ON) elseif(FSFW_OSAL MATCHES freertos) - set(FSFW_OS_NAME "FreeRTOS") - set(FSFW_OSAL_FREERTOS ON) - target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${LIB_OS_NAME} + set(FSFW_OS_NAME "FreeRTOS") + set(FSFW_OSAL_FREERTOS ON) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE + ${LIB_OS_NAME} ) elseif(FSFW_OSAL STREQUAL rtems) - set(FSFW_OS_NAME "RTEMS") - set(FSFW_OSAL_RTEMS ON) + set(FSFW_OS_NAME "RTEMS") + set(FSFW_OSAL_RTEMS ON) else() - message(WARNING - "Invalid operating system for FSFW specified! Setting to host.." + message(WARNING + "Invalid operating system for FSFW specified! Setting to host.." ) - set(FSFW_OS_NAME "Host") - set(OS_FSFW "host") + set(FSFW_OS_NAME "Host") + set(OS_FSFW "host") endif() configure_file(src/fsfw/FSFW.h.in fsfw/FSFW.h) @@ -214,206 +214,206 @@ message(STATUS "Compiling FSFW for the ${FSFW_OS_NAME} operating system.") add_subdirectory(src) add_subdirectory(tests) if(FSFW_ADD_HAL) - add_subdirectory(hal) + add_subdirectory(hal) endif() add_subdirectory(contrib) if(FSFW_BUILD_DOCS) - add_subdirectory(docs) + add_subdirectory(docs) endif() if(FSFW_BUILD_UNITTESTS) - if(FSFW_TESTS_GEN_COV) - if(CMAKE_COMPILER_IS_GNUCXX) - include(CodeCoverage) + if(FSFW_TESTS_GEN_COV) + if(CMAKE_COMPILER_IS_GNUCXX) + include(CodeCoverage) - # Remove quotes. - separate_arguments(COVERAGE_COMPILER_FLAGS - NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}" - ) + # Remove quotes. + separate_arguments(COVERAGE_COMPILER_FLAGS + NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}" + ) - # Add compile options manually, we don't want coverage for Catch2 - target_compile_options(${FSFW_TEST_TGT} PRIVATE - "${COVERAGE_COMPILER_FLAGS}" - ) - target_compile_options(${LIB_FSFW_NAME} PRIVATE - "${COVERAGE_COMPILER_FLAGS}" - ) + # Add compile options manually, we don't want coverage for Catch2 + target_compile_options(${FSFW_TEST_TGT} PRIVATE + "${COVERAGE_COMPILER_FLAGS}" + ) + target_compile_options(${LIB_FSFW_NAME} PRIVATE + "${COVERAGE_COMPILER_FLAGS}" + ) - # Exclude directories here - if(WIN32) - set(GCOVR_ADDITIONAL_ARGS - "--exclude-throw-branches" - "--exclude-unreachable-branches" - ) - set(COVERAGE_EXCLUDES - "/c/msys64/mingw64/*" "*/fsfw_hal/*" - ) - elseif(UNIX) - set(COVERAGE_EXCLUDES - "/usr/include/*" "/usr/bin/*" "Catch2/*" - "/usr/local/include/*" "*/fsfw_tests/*" - "*/catch2-src/*" "*/fsfw_hal/*" - ) - endif() + # Exclude directories here + if(WIN32) + set(GCOVR_ADDITIONAL_ARGS + "--exclude-throw-branches" + "--exclude-unreachable-branches" + ) + set(COVERAGE_EXCLUDES + "/c/msys64/mingw64/*" "*/fsfw_hal/*" + ) + elseif(UNIX) + set(COVERAGE_EXCLUDES + "/usr/include/*" "/usr/bin/*" "Catch2/*" + "/usr/local/include/*" "*/fsfw_tests/*" + "*/catch2-src/*" "*/fsfw_hal/*" + ) + endif() - target_link_options(${FSFW_TEST_TGT} PRIVATE - -fprofile-arcs - -ftest-coverage - ) - target_link_options(${LIB_FSFW_NAME} PRIVATE - -fprofile-arcs - -ftest-coverage - ) - # Need to specify this as an interface, otherwise there will the compile issues - target_link_options(${LIB_FSFW_NAME} INTERFACE - -fprofile-arcs - -ftest-coverage - ) + target_link_options(${FSFW_TEST_TGT} PRIVATE + -fprofile-arcs + -ftest-coverage + ) + target_link_options(${LIB_FSFW_NAME} PRIVATE + -fprofile-arcs + -ftest-coverage + ) + # Need to specify this as an interface, otherwise there will the compile issues + target_link_options(${LIB_FSFW_NAME} INTERFACE + -fprofile-arcs + -ftest-coverage + ) - if(WIN32) - setup_target_for_coverage_gcovr_html( - NAME ${FSFW_TEST_TGT}_coverage - EXECUTABLE ${FSFW_TEST_TGT} - DEPENDENCIES ${FSFW_TEST_TGT} - ) - else() - setup_target_for_coverage_lcov( - NAME ${FSFW_TEST_TGT}_coverage - EXECUTABLE ${FSFW_TEST_TGT} - DEPENDENCIES ${FSFW_TEST_TGT} - ) - endif() - endif() + if(WIN32) + setup_target_for_coverage_gcovr_html( + NAME ${FSFW_TEST_TGT}_coverage + EXECUTABLE ${FSFW_TEST_TGT} + DEPENDENCIES ${FSFW_TEST_TGT} + ) + else() + setup_target_for_coverage_lcov( + NAME ${FSFW_TEST_TGT}_coverage + EXECUTABLE ${FSFW_TEST_TGT} + DEPENDENCIES ${FSFW_TEST_TGT} + ) + endif() endif() - target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2 ${LIB_FSFW_NAME}) + endif() + target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2 ${LIB_FSFW_NAME}) endif() # The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. # If this is not given, we include the default configuration and emit a warning. if(NOT FSFW_CONFIG_PATH) - set(DEF_CONF_PATH misc/defaultcfg/fsfwconfig) - if(NOT FSFW_BUILD_DOCS) - message(WARNING "Flight Software Framework configuration path not set!") - message(WARNING "Setting default configuration from ${DEF_CONF_PATH} ..") - endif() - add_subdirectory(${DEF_CONF_PATH}) - set(FSFW_CONFIG_PATH ${DEF_CONF_PATH}) + set(DEF_CONF_PATH misc/defaultcfg/fsfwconfig) + if(NOT FSFW_BUILD_DOCS) + message(WARNING "Flight Software Framework configuration path not set!") + message(WARNING "Setting default configuration from ${DEF_CONF_PATH} ..") + endif() + add_subdirectory(${DEF_CONF_PATH}) + set(FSFW_CONFIG_PATH ${DEF_CONF_PATH}) endif() # FSFW might be part of a possibly complicated folder structure, so we # extract the absolute path of the fsfwconfig folder. if(IS_ABSOLUTE ${FSFW_CONFIG_PATH}) - set(FSFW_CONFIG_PATH_ABSOLUTE ${FSFW_CONFIG_PATH}) + set(FSFW_CONFIG_PATH_ABSOLUTE ${FSFW_CONFIG_PATH}) else() - get_filename_component(FSFW_CONFIG_PATH_ABSOLUTE - ${FSFW_CONFIG_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR} - ) + get_filename_component(FSFW_CONFIG_PATH_ABSOLUTE + ${FSFW_CONFIG_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR} + ) endif() foreach(INCLUDE_PATH ${FSFW_ADDITIONAL_INC_PATHS}) - if(IS_ABSOLUTE ${INCLUDE_PATH}) - set(CURR_ABS_INC_PATH "${INCLUDE_PATH}") - else() - get_filename_component(CURR_ABS_INC_PATH - ${INCLUDE_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}) - endif() + if(IS_ABSOLUTE ${INCLUDE_PATH}) + set(CURR_ABS_INC_PATH "${INCLUDE_PATH}") + else() + get_filename_component(CURR_ABS_INC_PATH + ${INCLUDE_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}) + endif() - if(CMAKE_VERBOSE) - message(STATUS "FSFW include path: ${CURR_ABS_INC_PATH}") - endif() + if(CMAKE_VERBOSE) + message(STATUS "FSFW include path: ${CURR_ABS_INC_PATH}") + endif() - list(APPEND FSFW_ADD_INC_PATHS_ABS ${CURR_ABS_INC_PATH}) + list(APPEND FSFW_ADD_INC_PATHS_ABS ${CURR_ABS_INC_PATH}) endforeach() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if(NOT DEFINED FSFW_WARNING_FLAGS) - set(FSFW_WARNING_FLAGS - -Wall - -Wextra - -Wimplicit-fallthrough=1 - -Wno-unused-parameter - -Wno-psabi - -Wduplicated-cond # check for duplicate conditions - -Wduplicated-branches # check for duplicate branches - -Wlogical-op # Search for bitwise operations instead of logical - -Wnull-dereference # Search for NULL dereference - -Wundef # Warn if undefind marcos are used - -Wformat=2 # Format string problem detection - -Wformat-overflow=2 # Formatting issues in printf - -Wformat-truncation=2 # Formatting issues in printf - -Wformat-security # Search for dangerous printf operations - -Wstrict-overflow=3 # Warn if integer overflows might happen - -Warray-bounds=2 # Some array bounds violations will be found - -Wshift-overflow=2 # Search for bit left shift overflows ( Date: Mon, 9 May 2022 14:53:52 +0200 Subject: [PATCH 117/198] Move some directives up top --- CMakeLists.txt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfe3da84..3c85114b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,15 @@ cmake_minimum_required(VERSION 3.13) +set(LIB_FSFW_NAME fsfw) +project(${LIB_FSFW_NAME}) + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED True) +elseif(${CMAKE_CXX_STANDARD} LESS 11) + message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++11 support") +endif() + set(FSFW_VERSION 4) set(FSFW_SUBVERSION 0) set(FSFW_REVISION 0) @@ -55,11 +65,10 @@ option(FSFW_ADD_TMSTORAGE "Compile with tm storage components" OFF) # Contrib sources option(FSFW_ADD_SGP4_PROPAGATOR "Add SGP4 propagator code" OFF) -set(LIB_FSFW_NAME fsfw) + set(FSFW_TEST_TGT fsfw-tests) set(FSFW_DUMMY_TGT fsfw-dummy) -project(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME}) if(FSFW_BUILD_UNITTESTS) @@ -152,12 +161,6 @@ target_include_directories(${LIB_FSFW_NAME} INTERFACE ${CMAKE_CURRENT_BINARY_DIR} ) -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_STANDARD_REQUIRED True) -elseif(${CMAKE_CXX_STANDARD} LESS 11) - message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++11 support") -endif() # Backwards comptability if(OS_FSFW AND NOT FSFW_OSAL) From b0d71597f038122ecbb6bb85f3fdd0a77bf842dc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 14:58:39 +0200 Subject: [PATCH 118/198] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d28c5c6..ae574c15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Fixed +- Move some CMake directives further up top so they are not ignored + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/621 - Small bugfix in STM32 HAL for SPI PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/599 - HAL GPIO: Improved error checking in `LinuxLibgpioIF::configureGpios(...)`. If a GPIO From 73ff9b97db023f91e4962d9f74e89f667cce1435 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 15:07:46 +0200 Subject: [PATCH 119/198] bump CMAKE_CXX_STANDARD to C++17 --- CHANGELOG.md | 2 ++ CMakeLists.txt | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae574c15..6e913de8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Changes +- Bump C++ required version to C++17. Every project which uses the FSFW and every modern + compiler supports it - HAL Linux SPI: Set the Clock Default State when setting new SPI speed and mode PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/573 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c85114b..1df1008b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,10 +4,10 @@ set(LIB_FSFW_NAME fsfw) project(${LIB_FSFW_NAME}) if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) -elseif(${CMAKE_CXX_STANDARD} LESS 11) - message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++11 support") +elseif(${CMAKE_CXX_STANDARD} LESS 17) + message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++17 support") endif() set(FSFW_VERSION 4) From 10cc954d276353eb6d981d2408b3c927835b82d6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 15:09:07 +0200 Subject: [PATCH 120/198] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e913de8..a500f27d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Bump C++ required version to C++17. Every project which uses the FSFW and every modern compiler supports it + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/622 - HAL Linux SPI: Set the Clock Default State when setting new SPI speed and mode PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/573 From 736f8d0238ec82e4d92b63ff2a14af59128aef57 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 15:50:49 +0200 Subject: [PATCH 121/198] order fix --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index efb52b9d..aa872f6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.13) set(MSG_PREFIX "fsfw |") +# Add the cmake folder so the FindSphinx module is found +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-modules") + ########################## # Version file handling # ########################## @@ -52,9 +56,6 @@ elseif(${CMAKE_CXX_STANDARD} LESS 17) message(FATAL_ERROR "${MSG_PREFIX} Compiling the FSFW requires a minimum of C++17 support") endif() -# Add the cmake folder so the FindSphinx module is found -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-modules") set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING "ETL library major version requirement" From 5989c88c88613ce14f3323b982ad7d6e6e1ea044 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 15:54:29 +0200 Subject: [PATCH 122/198] indentation --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef96f1df..909255be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,10 +4,10 @@ set(LIB_FSFW_NAME fsfw) project(${LIB_FSFW_NAME}) if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED True) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED True) elseif(${CMAKE_CXX_STANDARD} LESS 17) - message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++17 support") + message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++17 support") endif() set(FSFW_VERSION 4) From fd112ed5973bb522a351ed42e1e89995c484d3ad Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 16:07:05 +0200 Subject: [PATCH 123/198] enable lto for test target --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93f8c24f..2f4ffe75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,9 @@ if(FSFW_BUILD_UNITTESTS) project(${FSFW_TEST_TGT} CXX C) add_executable(${FSFW_TEST_TGT}) + if(IPO_SUPPORTED AND FSFW_ENABLE_IPO) + set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + endif() if(FSFW_TESTS_GEN_COV) message(STATUS "Generating coverage data for the library") From 0fe1b70baedfe250d5d39be3e5545bab3806a9f0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 May 2022 11:19:29 +0200 Subject: [PATCH 124/198] keep LTO option off by default --- CHANGELOG.md | 10 ++++++++++ CMakeLists.txt | 17 +++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0452e58b..f3523a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - LTO support: Allow using LTO/IPO by setting `FSFW_ENABLE_LTO=1`. CMake is able to detect whether the user compiler supports IPO/LPO. LTO is on by default now. Most modern compilers support it, can make good use of it and it usually makes the code faster and/or smaller. + After some more research: + Enabling LTO will actually cause the compiler to only produce thin LTO by adding + `-flto -fno-fat-lto-objects` to the compiler options. I am not sure this is an ideal choice + because if an application linking against the FSFW does not use LTO, there can be compile + issues (e.g. observed when compiling the FSFW tests without LTO). This is a known issue as + can be seen in the multiple CMake issues for it: + - https://gitlab.kitware.com/cmake/cmake/-/issues/22913, + - https://gitlab.kitware.com/cmake/cmake/-/issues/16808, + - https://gitlab.kitware.com/cmake/cmake/-/issues/21696 + Easiest solution for now: Keep this option OFF by default. PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 - Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1 - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f686d1d..61145e1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,11 +17,12 @@ set(FSFW_REVISION 0) # Add the cmake folder so the FindSphinx module is found set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +set(FSFW_ETL_LIB_NAME etl) set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING - "ETL library major version requirement" + "ETL library major version requirement" ) set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 CACHE STRING - "ETL library exact version requirement" + "ETL library exact version requirement" ) set(FSFW_ETL_LINK_TARGET etl::etl) @@ -32,26 +33,26 @@ set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE "Catch2 library exact version requirement" ) -set(FSFW_ETL_LIB_NAME etl) - include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR) if(NOT IPO_SUPPORTED) message(STATUS "FSFW | IPO/LTO not supported: ${IPO_ERROR}") endif() -option(FSFW_ENABLE_IPO "Enable interprocedural optimization or link-time optimization if available" ON) +# Keep this off by default for now. See PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 +# for information which keeping this on by default is problematic +option(FSFW_ENABLE_IPO "Enable interprocedural optimization or link-time optimization if available" OFF) option(FSFW_GENERATE_SECTIONS - "Generate function and data sections. Required to remove unused code" ON + "Generate function and data sections. Required to remove unused code" ON ) if(FSFW_GENERATE_SECTIONS) - option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON) + option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON) endif() option(FSFW_BUILD_UNITTESTS "Build unittest binary in addition to static library" OFF) option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF) if(FSFW_BUILD_UNITTESTS) - option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON) + option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON) endif() option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON) From dd986fefd31de76ec62f91a050b031ca1e7d93b4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 May 2022 11:51:25 +0200 Subject: [PATCH 125/198] experimenting with PRE_BUILD command --- CMakeLists.txt | 9 ++++++++- FSFWVersion.h.in | 0 src/fsfw/FSFWVersion.h.in | 2 +- src/fsfw/version.cpp | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 FSFWVersion.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index aa872f6e..7dc7f2a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) list(GET FSFW_GIT_INFO 1 FSFW_VERSION) list(GET FSFW_GIT_INFO 2 FSFW_SUBVERSION) list(GET FSFW_GIT_INFO 3 FSFW_REVISION) - list(GET FSFW_GIT_INFO 4 FSFW_VERSION_CST_GIT_SHA1) + list(GET FSFW_GIT_INFO 4 FSFW_VCS_INFO) if(NOT FSFW_VERSION) set(FSFW_VERSION ${FSFW_VERSION_IF_GIT_FAILS}) endif() @@ -448,6 +448,13 @@ string(CONCAT POST_BUILD_COMMENT "######################################################################\n" ) +add_custom_command( + TARGET ${LIB_FSFW_NAME} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/FSFWVersion.h.in + COMMENT "${MSG_PREFIX} Updating FSFWVersion.h" +) + add_custom_command( TARGET ${LIB_FSFW_NAME} POST_BUILD diff --git a/FSFWVersion.h.in b/FSFWVersion.h.in new file mode 100644 index 00000000..e69de29b diff --git a/src/fsfw/FSFWVersion.h.in b/src/fsfw/FSFWVersion.h.in index 3b93bee5..caff1efb 100644 --- a/src/fsfw/FSFWVersion.h.in +++ b/src/fsfw/FSFWVersion.h.in @@ -6,6 +6,6 @@ static constexpr int FSFW_VERSION_MAJOR = @FSFW_VERSION@; static constexpr int FSFW_VERSION_MINOR = @FSFW_SUBVERSION@; static constexpr int FSFW_VERSION_REVISION = @FSFW_REVISION@; // Also contains CST (Commits since tag) information -static const char FSFW_VERSION_CST_GIT_SHA1[] = "@FSFW_VERSION_CST_GIT_SHA1@"; +static const char FSFW_VCS_INFO[] = "@FSFW_VCS_INFO@"; #endif /* FSFW_VERSION_H_ */ diff --git a/src/fsfw/version.cpp b/src/fsfw/version.cpp index 050a275d..050187a9 100644 --- a/src/fsfw/version.cpp +++ b/src/fsfw/version.cpp @@ -13,7 +13,7 @@ #endif const fsfw::Version fsfw::FSFW_VERSION = {FSFW_VERSION_MAJOR, FSFW_VERSION_MINOR, - FSFW_VERSION_REVISION, FSFW_VERSION_CST_GIT_SHA1}; + FSFW_VERSION_REVISION, FSFW_VCS_INFO}; fsfw::Version::Version(int major, int minor, int revision, const char* addInfo) : major(major), minor(minor), revision(revision), addInfo(addInfo) {} From efb3d982f3e6a3e34b66708f473ee08ee5ad4cb3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 May 2022 11:52:40 +0200 Subject: [PATCH 126/198] added missing prefix --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dc7f2a2..92f40be6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,7 +147,7 @@ if(FSFW_BUILD_UNITTESTS) endif() endif() -message(STATUS "Finding and/or providing ETL library") +message(STATUS "${MSG_PREFIX} Finding and/or providing ETL library") # Check whether the user has already installed ETL first find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) From 25775614de4bf6e7d11e70f8b15965247b9a51ee Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 May 2022 11:56:51 +0200 Subject: [PATCH 127/198] only check IPO support if enabled --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61145e1e..e1ab522a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,15 +33,18 @@ set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE "Catch2 library exact version requirement" ) +# Keep this off by default for now. See PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 +# for information which keeping this on by default is problematic +option(FSFW_ENABLE_IPO "Enable interprocedural optimization or link-time optimization if available" OFF) + +if(FSFW_ENABLE_IPO) include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR) if(NOT IPO_SUPPORTED) message(STATUS "FSFW | IPO/LTO not supported: ${IPO_ERROR}") endif() +endif() -# Keep this off by default for now. See PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 -# for information which keeping this on by default is problematic -option(FSFW_ENABLE_IPO "Enable interprocedural optimization or link-time optimization if available" OFF) option(FSFW_GENERATE_SECTIONS "Generate function and data sections. Required to remove unused code" ON ) From 377c3325d255a6dd9af239ee85c3be416e930826 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 May 2022 12:16:38 +0200 Subject: [PATCH 128/198] update cmake-modules file --- CMakeLists.txt | 18 +- .../GetGitRevisionDescription.cmake | 141 --------- cmake/cmake-modules/README.md | 6 +- .../{ => bilke}/CodeCoverage.cmake | 0 .../cmake-modules/{ => bilke}/LICENSE_1_0.txt | 0 .../rpavlik/GetGitRevisionDescription.cmake | 284 ++++++++++++++++++ .../GetGitRevisionDescription.cmake.in | 21 +- .../rpavlik/LICENSES/BSD-3-Clause.txt | 26 ++ .../rpavlik/LICENSES/BSL-1.0.txt | 23 ++ cmake/cmake-modules/rpavlik/LICENSE_1_0.txt | 23 ++ 10 files changed, 383 insertions(+), 159 deletions(-) delete mode 100644 cmake/cmake-modules/GetGitRevisionDescription.cmake rename cmake/cmake-modules/{ => bilke}/CodeCoverage.cmake (100%) rename cmake/cmake-modules/{ => bilke}/LICENSE_1_0.txt (100%) create mode 100644 cmake/cmake-modules/rpavlik/GetGitRevisionDescription.cmake rename cmake/cmake-modules/{ => rpavlik}/GetGitRevisionDescription.cmake.in (59%) create mode 100644 cmake/cmake-modules/rpavlik/LICENSES/BSD-3-Clause.txt create mode 100644 cmake/cmake-modules/rpavlik/LICENSES/BSL-1.0.txt create mode 100644 cmake/cmake-modules/rpavlik/LICENSE_1_0.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 92f40be6..06bb5430 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,8 @@ set(MSG_PREFIX "fsfw |") # Add the cmake folder so the FindSphinx module is found list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-modules") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-modules/bilke") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake-modules/rpavlik") ########################## # Version file handling # @@ -56,6 +57,7 @@ elseif(${CMAKE_CXX_STANDARD} LESS 17) message(FATAL_ERROR "${MSG_PREFIX} Compiling the FSFW requires a minimum of C++17 support") endif() +set(FSFW_SOURCES_DIR "${CMAKE_SOURCE_DIR}/src/fsfw") set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING "ETL library major version requirement" @@ -448,15 +450,15 @@ string(CONCAT POST_BUILD_COMMENT "######################################################################\n" ) -add_custom_command( - TARGET ${LIB_FSFW_NAME} - PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/FSFWVersion.h.in - COMMENT "${MSG_PREFIX} Updating FSFWVersion.h" -) - add_custom_command( TARGET ${LIB_FSFW_NAME} POST_BUILD COMMENT ${POST_BUILD_COMMENT} ) + +add_custom_command( + TARGET ${LIB_FSFW_NAME} + PRE_BUILD + COMMAND touch ${FSFW_SOURCES_DIR}/FSFWVersion.h.in + COMMENT "${MSG_PREFIX} Updating FSFWVersion.h" +) diff --git a/cmake/cmake-modules/GetGitRevisionDescription.cmake b/cmake/cmake-modules/GetGitRevisionDescription.cmake deleted file mode 100644 index 1175e673..00000000 --- a/cmake/cmake-modules/GetGitRevisionDescription.cmake +++ /dev/null @@ -1,141 +0,0 @@ -# - Returns a version string from Git -# -# These functions force a re-configure on each git commit so that you can -# trust the values of the variables in your build system. -# -# get_git_head_revision( [ ...]) -# -# Returns the refspec and sha hash of the current head revision -# -# git_describe( [ ...]) -# -# Returns the results of git describe on the source tree, and adjusting -# the output so that it tests false if an error occurs. -# -# git_get_exact_tag( [ ...]) -# -# Returns the results of git describe --exact-match on the source tree, -# and adjusting the output so that it tests false if there was no exact -# matching tag. -# -# Requires CMake 2.6 or newer (uses the 'function' command) -# -# Original Author: -# 2009-2010 Ryan Pavlik -# http://academic.cleardefinition.com -# Iowa State University HCI Graduate Program/VRAC -# -# Copyright Iowa State University 2009-2010. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -if(__get_git_revision_description) - return() -endif() -set(__get_git_revision_description YES) - -# We must run the following at "include" time, not at function call time, -# to find the path to this module rather than the path to a calling list file -get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) - -function(get_git_head_revision _refspecvar _hashvar) - set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - set(GIT_DIR "${GIT_PARENT_DIR}/.git") - while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories - set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") - get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) - if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) - # We have reached the root directory, we are not in git - set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) - set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) - return() - endif() - set(GIT_DIR "${GIT_PARENT_DIR}/.git") - endwhile() - # check if this is a submodule - if(NOT IS_DIRECTORY ${GIT_DIR}) - file(READ ${GIT_DIR} submodule) - string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) - get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) - - if (IS_ABSOLUTE ${GIT_DIR_RELATIVE}) - set(GIT_DIR ${GIT_DIR_RELATIVE}) - else() - get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) - endif() - - endif() - set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") - if(NOT EXISTS "${GIT_DATA}") - file(MAKE_DIRECTORY "${GIT_DATA}") - endif() - - if(NOT EXISTS "${GIT_DIR}/HEAD") - return() - endif() - set(HEAD_FILE "${GIT_DATA}/HEAD") - configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) - - configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" - "${GIT_DATA}/grabRef.cmake" - @ONLY) - include("${GIT_DATA}/grabRef.cmake") - - set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) - set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) -endfunction() - -function(git_describe _var) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - get_git_head_revision(refspec hash) - if(NOT GIT_FOUND) - set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) - return() - endif() - if(NOT hash) - set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) - return() - endif() - - # TODO sanitize - #if((${ARGN}" MATCHES "&&") OR - # (ARGN MATCHES "||") OR - # (ARGN MATCHES "\\;")) - # message("Please report the following error to the project!") - # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") - #endif() - - #message(STATUS "Arguments to execute_process: ${ARGN}") - - execute_process(COMMAND - ${GIT_EXECUTABLE} - describe - ${hash} - ${ARGN} - WORKING_DIRECTORY - "${CMAKE_SOURCE_DIR}" - RESULT_VARIABLE - res - OUTPUT_VARIABLE - out - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") - endif() - - set(${_var} "${out}" PARENT_SCOPE) -endfunction() - -function(git_get_exact_tag _var) - git_describe(out --exact-match ${ARGN}) - set(${_var} "${out}" PARENT_SCOPE) -endfunction() - -function(git_get_tag _var) - git_describe(out --tags ${ARGN}) - set(${_var} "${out}" PARENT_SCOPE) -endfunction() diff --git a/cmake/cmake-modules/README.md b/cmake/cmake-modules/README.md index 4692eddb..b6355c3f 100644 --- a/cmake/cmake-modules/README.md +++ b/cmake/cmake-modules/README.md @@ -1,5 +1,7 @@ -The files in these folder were manually copy and pasted from the +The files in the `bilke` folder were manually copy and pasted from the [cmake-modules repository](https://github.com/bilke/cmake-modules). It was decided to do this because only a small subset of its provided functions are needed. -The license file in included here as well. +The files in the `rpavlik` folder were manually copy and pasted from the +[cmake-modules repository](https://github.com/rpavlik/cmake-modules). It was decided to do +this because only a small subset of its provided functions are needed. diff --git a/cmake/cmake-modules/CodeCoverage.cmake b/cmake/cmake-modules/bilke/CodeCoverage.cmake similarity index 100% rename from cmake/cmake-modules/CodeCoverage.cmake rename to cmake/cmake-modules/bilke/CodeCoverage.cmake diff --git a/cmake/cmake-modules/LICENSE_1_0.txt b/cmake/cmake-modules/bilke/LICENSE_1_0.txt similarity index 100% rename from cmake/cmake-modules/LICENSE_1_0.txt rename to cmake/cmake-modules/bilke/LICENSE_1_0.txt diff --git a/cmake/cmake-modules/rpavlik/GetGitRevisionDescription.cmake b/cmake/cmake-modules/rpavlik/GetGitRevisionDescription.cmake new file mode 100644 index 00000000..69ef78b2 --- /dev/null +++ b/cmake/cmake-modules/rpavlik/GetGitRevisionDescription.cmake @@ -0,0 +1,284 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_describe_working_tree( [ ...]) +# +# Returns the results of git describe on the working tree (--dirty option), +# and adjusting the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# git_local_changes() +# +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. +# Uses the return code of "git diff-index --quiet HEAD --". +# Does not regard untracked files. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2020 Ryan Pavlik +# http://academic.cleardefinition.com +# +# Copyright 2009-2013, Iowa State University. +# Copyright 2013-2020, Ryan Pavlik +# Copyright 2013-2020, Contributors +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +# Function _git_find_closest_git_dir finds the next closest .git directory +# that is part of any directory in the path defined by _start_dir. +# The result is returned in the parent scope variable whose name is passed +# as variable _git_dir_var. If no .git directory can be found, the +# function returns an empty string via _git_dir_var. +# +# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and +# neither foo nor bar contain a file/directory .git. This wil return +# C:/bla/.git +# +function(_git_find_closest_git_dir _start_dir _git_dir_var) + set(cur_dir "${_start_dir}") + set(git_dir "${_start_dir}/.git") + while(NOT EXISTS "${git_dir}") + # .git dir not found, search parent directories + set(git_previous_parent "${cur_dir}") + get_filename_component(cur_dir "${cur_dir}" DIRECTORY) + if(cur_dir STREQUAL git_previous_parent) + # We have reached the root directory, we are not in git + set(${_git_dir_var} + "" + PARENT_SCOPE) + return() + endif() + set(git_dir "${cur_dir}/.git") + endwhile() + set(${_git_dir_var} + "${git_dir}" + PARENT_SCOPE) +endfunction() + +function(get_git_head_revision _refspecvar _hashvar) + _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) + + if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR") + set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE) + else() + set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE) + endif() + if(NOT "${GIT_DIR}" STREQUAL "") + file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}" + "${GIT_DIR}") + if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR) + # We've gone above the CMake root dir. + set(GIT_DIR "") + endif() + endif() + if("${GIT_DIR}" STREQUAL "") + set(${_refspecvar} + "GITDIR-NOTFOUND" + PARENT_SCOPE) + set(${_hashvar} + "GITDIR-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + # Check if the current source dir is a git submodule or a worktree. + # In both cases .git is a file instead of a directory. + # + if(NOT IS_DIRECTORY ${GIT_DIR}) + # The following git command will return a non empty string that + # points to the super project working tree if the current + # source dir is inside a git submodule. + # Otherwise the command will return an empty string. + # + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse + --show-superproject-working-tree + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT "${out}" STREQUAL "") + # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE + ${submodule}) + string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} + ABSOLUTE) + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") + else() + # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree + file(READ ${GIT_DIR} worktree_ref) + # The .git directory contains a path to the worktree information directory + # inside the parent git repo of the worktree. + # + string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir + ${worktree_ref}) + string(STRIP ${git_worktree_dir} git_worktree_dir) + _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) + set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") + endif() + else() + set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${HEAD_SOURCE_FILE}") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} + "${HEAD_REF}" + PARENT_SCOPE) + set(${_hashvar} + "${HEAD_HASH}" + PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_describe_working_tree _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} + "${out}" + PARENT_SCOPE) +endfunction() + +function(git_local_changes _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} + "GIT-NOTFOUND" + PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} + "HEAD-HASH-NOTFOUND" + PARENT_SCOPE) + return() + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD -- + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE res + OUTPUT_VARIABLE out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(res EQUAL 0) + set(${_var} + "CLEAN" + PARENT_SCOPE) + else() + set(${_var} + "DIRTY" + PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/cmake-modules/GetGitRevisionDescription.cmake.in b/cmake/cmake-modules/rpavlik/GetGitRevisionDescription.cmake.in similarity index 59% rename from cmake/cmake-modules/GetGitRevisionDescription.cmake.in rename to cmake/cmake-modules/rpavlik/GetGitRevisionDescription.cmake.in index ae19652b..66eee637 100644 --- a/cmake/cmake-modules/GetGitRevisionDescription.cmake.in +++ b/cmake/cmake-modules/rpavlik/GetGitRevisionDescription.cmake.in @@ -1,4 +1,4 @@ -# +# # Internal file for GetGitRevisionDescription.cmake # # Requires CMake 2.6 or newer (uses the 'function' command) @@ -8,10 +8,12 @@ # http://academic.cleardefinition.com # Iowa State University HCI Graduate Program/VRAC # -# Copyright Iowa State University 2009-2010. +# Copyright 2009-2012, Iowa State University +# Copyright 2011-2015, Contributors # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +# SPDX-License-Identifier: BSL-1.0 set(HEAD_HASH) @@ -22,10 +24,13 @@ if(HEAD_CONTENTS MATCHES "ref") # named branch string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") if(EXISTS "@GIT_DIR@/${HEAD_REF}") - configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") - configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - set(HEAD_HASH "${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() endif() else() # detached HEAD @@ -33,6 +38,6 @@ else() endif() if(NOT HEAD_HASH) -file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) -string(STRIP "${HEAD_HASH}" HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) endif() diff --git a/cmake/cmake-modules/rpavlik/LICENSES/BSD-3-Clause.txt b/cmake/cmake-modules/rpavlik/LICENSES/BSD-3-Clause.txt new file mode 100644 index 00000000..0741db78 --- /dev/null +++ b/cmake/cmake-modules/rpavlik/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,26 @@ +Copyright (c) . All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cmake/cmake-modules/rpavlik/LICENSES/BSL-1.0.txt b/cmake/cmake-modules/rpavlik/LICENSES/BSL-1.0.txt new file mode 100644 index 00000000..cff35365 --- /dev/null +++ b/cmake/cmake-modules/rpavlik/LICENSES/BSL-1.0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, execute, +and transmit the Software, and to prepare derivative works of the Software, +and to permit third-parties to whom the Software is furnished to do so, all +subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, must +be included in all copies of the Software, in whole or in part, and all derivative +works of the Software, unless such copies or derivative works are solely in +the form of machine-executable object code generated by a source language +processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES +OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/cmake/cmake-modules/rpavlik/LICENSE_1_0.txt b/cmake/cmake-modules/rpavlik/LICENSE_1_0.txt new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/cmake/cmake-modules/rpavlik/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. From e05c72b062836eb5f9cd4cdc1d35b0a2846653e0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 May 2022 13:08:14 +0200 Subject: [PATCH 129/198] minor formatting fix --- CMakeLists.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1ab522a..3cca727e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,13 +36,12 @@ set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE # Keep this off by default for now. See PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 # for information which keeping this on by default is problematic option(FSFW_ENABLE_IPO "Enable interprocedural optimization or link-time optimization if available" OFF) - if(FSFW_ENABLE_IPO) -include(CheckIPOSupported) -check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR) -if(NOT IPO_SUPPORTED) - message(STATUS "FSFW | IPO/LTO not supported: ${IPO_ERROR}") -endif() + include(CheckIPOSupported) + check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR) + if(NOT IPO_SUPPORTED) + message(STATUS "FSFW | IPO/LTO not supported: ${IPO_ERROR}") + endif() endif() option(FSFW_GENERATE_SECTIONS From 29c3a4376058bb392edd9ef25623723f000058a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 May 2022 10:54:13 +0200 Subject: [PATCH 130/198] getter functions for speed and mode --- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 14 ++++++++++++++ hal/src/fsfw_hal/linux/spi/SpiComIF.h | 1 + 2 files changed, 15 insertions(+) diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index dcf92b5d..db694613 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -410,3 +410,17 @@ void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed"); } } + +void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes &mode, uint32_t &speed) const { + uint8_t tmpMode = 0; + int retval = ioctl(spiFd, SPI_IOC_RD_MODE, &tmpMode); + if (retval != 0) { + utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Reading SPI mode failed"); + } + mode = static_cast(tmpMode); + + retval = ioctl(spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); + if (retval != 0) { + utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Getting SPI speed failed"); + } +} diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index 357afa2f..ded47e04 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -59,6 +59,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { GpioIF* getGpioInterface(); void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); + void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const; void performSpiWiretapping(SpiCookie* spiCookie); ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); From 0e880de0d08d05b14125a5af785930aeff636d1b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 May 2022 10:54:39 +0200 Subject: [PATCH 131/198] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84fb2ca1..856580cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Additions +- Linux HAL: Getter functions for SPI speed and mode. - Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1 - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information inside `fsfw/version.h` From e06c457743991b2a0c2d84de9e169508ac428aa8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 May 2022 11:11:39 +0200 Subject: [PATCH 132/198] Cache SPI device name in ComIF - Architecturally, this makes a lot more sense because each ComIF should be responsible for one SPI bus --- hal/src/fsfw_hal/linux/UnixFileGuard.cpp | 2 +- hal/src/fsfw_hal/linux/UnixFileGuard.h | 2 +- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 17 +++++------ hal/src/fsfw_hal/linux/spi/SpiComIF.h | 6 ++-- hal/src/fsfw_hal/linux/spi/SpiCookie.cpp | 29 +++++++++---------- hal/src/fsfw_hal/linux/spi/SpiCookie.h | 17 +++++------ src/fsfw/container/FixedArrayList.h | 1 + src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 3 +- src/fsfw/devicehandlers/DeviceHandlerBase.h | 6 ++-- src/fsfw/osal/common/TcpTmTcServer.cpp | 6 ++-- src/fsfw/osal/freertos/FixedTimeslotTask.cpp | 2 +- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 2 +- src/fsfw/osal/rtems/FixedTimeslotTask.cpp | 2 +- src/fsfw/pus/CService201HealthCommanding.cpp | 3 +- src/fsfw/pus/CService201HealthCommanding.h | 2 +- src/fsfw/timemanager/Countdown.cpp | 3 +- 16 files changed, 49 insertions(+), 54 deletions(-) diff --git a/hal/src/fsfw_hal/linux/UnixFileGuard.cpp b/hal/src/fsfw_hal/linux/UnixFileGuard.cpp index 41293815..3e916ba2 100644 --- a/hal/src/fsfw_hal/linux/UnixFileGuard.cpp +++ b/hal/src/fsfw_hal/linux/UnixFileGuard.cpp @@ -6,7 +6,7 @@ #include "fsfw/FSFW.h" #include "fsfw/serviceinterface.h" -UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags, +UnixFileGuard::UnixFileGuard(const std::string& device, int* fileDescriptor, int flags, std::string diagnosticPrefix) : fileDescriptor(fileDescriptor) { if (fileDescriptor == nullptr) { diff --git a/hal/src/fsfw_hal/linux/UnixFileGuard.h b/hal/src/fsfw_hal/linux/UnixFileGuard.h index d94234b6..04f379d6 100644 --- a/hal/src/fsfw_hal/linux/UnixFileGuard.h +++ b/hal/src/fsfw_hal/linux/UnixFileGuard.h @@ -15,7 +15,7 @@ class UnixFileGuard { static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; - UnixFileGuard(std::string device, int* fileDescriptor, int flags, + UnixFileGuard(const std::string& device, int* fileDescriptor, int flags, std::string diagnosticPrefix = ""); virtual ~UnixFileGuard(); diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index db694613..da95bfcb 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -15,8 +15,8 @@ #include "fsfw_hal/linux/spi/SpiCookie.h" #include "fsfw_hal/linux/utility.h" -SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF) - : SystemObject(objectId), gpioComIF(gpioComIF) { +SpiComIF::SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF) + : SystemObject(objectId), gpioComIF(gpioComIF), dev(std::move(devname)) { if (gpioComIF == nullptr) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -85,8 +85,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) { spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms); int fileDescriptor = 0; - UnixFileGuard fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR, - "SpiComIF::initializeInterface"); + UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface"); if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return fileHelper.getOpenResult(); } @@ -182,8 +181,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const int retval = 0; /* Prepare transfer */ int fileDescriptor = 0; - std::string device = spiCookie->getSpiDevice(); - UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage"); + UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage"); if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return OPENING_FILE_FAILED; } @@ -278,9 +276,8 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - std::string device = spiCookie->getSpiDevice(); int fileDescriptor = 0; - UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage"); + UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage"); if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return OPENING_FILE_FAILED; } @@ -411,7 +408,7 @@ void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) } } -void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes &mode, uint32_t &speed) const { +void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const { uint8_t tmpMode = 0; int retval = ioctl(spiFd, SPI_IOC_RD_MODE, &tmpMode); if (retval != 0) { @@ -424,3 +421,5 @@ void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes &mode, uint32_t &spee utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Getting SPI speed failed"); } } + +const std::string& SpiComIF::getSpiDev() const { return dev; } diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index ded47e04..881af8c4 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -32,7 +32,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = HasReturnvaluesIF::makeReturnCode(spiRetvalId, 2); - SpiComIF(object_id_t objectId, GpioIF* gpioComIF); + SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF); ReturnValue_t initializeInterface(CookieIF* cookie) override; ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override; @@ -60,6 +60,8 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { GpioIF* getGpioInterface(); void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const; + + const std::string& getSpiDev() const; void performSpiWiretapping(SpiCookie* spiCookie); ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); @@ -71,7 +73,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { }; GpioIF* gpioComIF = nullptr; - + std::string dev = ""; MutexIF* spiMutex = nullptr; MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; uint32_t timeoutMs = 20; diff --git a/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp b/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp index c94fcdf1..85f96f28 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp @@ -1,26 +1,25 @@ #include "SpiCookie.h" -SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, - const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed) - : SpiCookie(spi::SpiComIfModes::REGULAR, spiAddress, chipSelect, spiDev, maxSize, spiMode, - spiSpeed, nullptr, nullptr) {} - -SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize, +SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed) - : SpiCookie(spiAddress, gpio::NO_GPIO, spiDev, maxSize, spiMode, spiSpeed) {} + : SpiCookie(spi::SpiComIfModes::REGULAR, spiAddress, chipSelect, maxSize, spiMode, spiSpeed, + nullptr, nullptr) {} -SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, - const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed, +SpiCookie::SpiCookie(address_t spiAddress, const size_t maxSize, spi::SpiModes spiMode, + uint32_t spiSpeed) + : SpiCookie(spiAddress, gpio::NO_GPIO, maxSize, spiMode, spiSpeed) {} + +SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, + spi::SpiModes spiMode, uint32_t spiSpeed, spi::send_callback_function_t callback, void* args) - : SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, chipSelect, spiDev, maxSize, spiMode, - spiSpeed, callback, args) {} + : SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, chipSelect, maxSize, spiMode, spiSpeed, + callback, args) {} SpiCookie::SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect, - std::string spiDev, const size_t maxSize, spi::SpiModes spiMode, - uint32_t spiSpeed, spi::send_callback_function_t callback, void* args) + const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed, + spi::send_callback_function_t callback, void* args) : spiAddress(spiAddress), chipSelectPin(chipSelect), - spiDevice(spiDev), comIfMode(comIfMode), maxSize(maxSize), spiMode(spiMode), @@ -50,8 +49,6 @@ size_t SpiCookie::getMaxBufferSize() const { return maxSize; } address_t SpiCookie::getSpiAddress() const { return spiAddress; } -std::string SpiCookie::getSpiDevice() const { return spiDevice; } - void SpiCookie::setThreeWireSpi(bool enable) { uncommonParameters.threeWireSpi = enable; } void SpiCookie::setLsbFirst(bool enable) { uncommonParameters.lsbFirst = enable; } diff --git a/hal/src/fsfw_hal/linux/spi/SpiCookie.h b/hal/src/fsfw_hal/linux/spi/SpiCookie.h index 5f4bf2d5..d6d4078f 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiCookie.h +++ b/hal/src/fsfw_hal/linux/spi/SpiCookie.h @@ -29,23 +29,22 @@ class SpiCookie : public CookieIF { * @param spiDev * @param maxSize */ - SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize, - spi::SpiModes spiMode, uint32_t spiSpeed); + SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode, + uint32_t spiSpeed); /** * Like constructor above, but without a dedicated GPIO CS. Can be used for hardware * slave select or if CS logic is performed with decoders. */ - SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxReplySize, - spi::SpiModes spiMode, uint32_t spiSpeed); + SpiCookie(address_t spiAddress, const size_t maxReplySize, spi::SpiModes spiMode, + uint32_t spiSpeed); /** * Use the callback mode of the SPI communication interface. The user can pass the callback * function here or by using the setter function #setCallbackMode */ - SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize, - spi::SpiModes spiMode, uint32_t spiSpeed, spi::send_callback_function_t callback, - void* args); + SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode, + uint32_t spiSpeed, spi::send_callback_function_t callback, void* args); /** * Get the callback function @@ -55,7 +54,6 @@ class SpiCookie : public CookieIF { void getCallback(spi::send_callback_function_t* callback, void** args); address_t getSpiAddress() const; - std::string getSpiDevice() const; gpioId_t getChipSelectPin() const; size_t getMaxBufferSize() const; @@ -154,12 +152,11 @@ class SpiCookie : public CookieIF { * @param args */ SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect, - std::string spiDev, const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed, + const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed, spi::send_callback_function_t callback, void* args); address_t spiAddress; gpioId_t chipSelectPin; - std::string spiDevice; spi::SpiComIfModes comIfMode; diff --git a/src/fsfw/container/FixedArrayList.h b/src/fsfw/container/FixedArrayList.h index 11882537..fc8be393 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"); + private: T data[MAX_SIZE]; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 52178683..69baf54f 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -1401,8 +1401,7 @@ uint8_t DeviceHandlerBase::getReplyDelayCycles(DeviceCommandId_t deviceCommand) DeviceReplyMap::iterator iter = deviceReplyMap.find(deviceCommand); if (iter == deviceReplyMap.end()) { return 0; - } - else if (iter->second.countdown != nullptr) { + } else if (iter->second.countdown != nullptr) { return 0; } return iter->second.delayCycles; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index c67aed27..0a273675 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -801,7 +801,7 @@ class DeviceHandlerBase : public DeviceHandlerIF, DeviceCommandMap::iterator command; //! Instead of using delayCycles to specify the maximum time to wait for the device reply, it //! is also possible specify a countdown - Countdown* countdown = nullptr; + Countdown *countdown = nullptr; //! will be set to true when reply is enabled bool active = false; }; @@ -1269,13 +1269,13 @@ class DeviceHandlerBase : public DeviceHandlerIF, /** * @brief Handles disabling of replies which use a timeout to detect missed replies. */ - void disableTimeoutControlledReply(DeviceReplyInfo* info); + void disableTimeoutControlledReply(DeviceReplyInfo *info); /** * @brief Handles disabling of replies which use a number of maximum delay cycles to detect * missed replies. */ - void disableDelayCyclesControlledReply(DeviceReplyInfo* info); + void disableDelayCyclesControlledReply(DeviceReplyInfo *info); /** * Retrive data from the #IPCStore. diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index 91cb9574..b9089245 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -161,7 +161,7 @@ void TcpTmTcServer::handleServerOperation(socket_t& connSocket) { while (true) { ssize_t retval = recv(connSocket, reinterpret_cast(receptionBuffer.data()), - receptionBuffer.capacity(), tcpConfig.tcpFlags); + receptionBuffer.capacity(), tcpConfig.tcpFlags); if (retval == 0) { size_t availableReadData = ringBuffer.getAvailableReadData(); if (availableReadData > lastRingBufferSize) { @@ -285,7 +285,7 @@ ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent) arrayprinter::print(storeAccessor.data(), storeAccessor.size()); } ssize_t retval = send(connSocket, reinterpret_cast(storeAccessor.data()), - storeAccessor.size(), tcpConfig.tcpTmFlags); + storeAccessor.size(), tcpConfig.tcpTmFlags); if (retval == static_cast(storeAccessor.size())) { // Packet sent, clear FIFO entry tmtcBridge->tmFifo->pop(); @@ -340,7 +340,7 @@ ReturnValue_t TcpTmTcServer::handleTcRingBufferData(size_t availableReadData) { size_t foundSize = 0; size_t readLen = 0; while (readLen < readAmount) { - if(spacePacketParser == nullptr) { + if (spacePacketParser == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } result = diff --git a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp index e8823f8a..87d262f3 100644 --- a/src/fsfw/osal/freertos/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/freertos/FixedTimeslotTask.cpp @@ -47,7 +47,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines" - << std::endl; + << std::endl; #endif } } diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp index 37b958de..a6337fb0 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp @@ -88,7 +88,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines" - << std::endl; + << std::endl; #endif } } diff --git a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp index 745b8d70..d83a4d4a 100644 --- a/src/fsfw/osal/rtems/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/rtems/FixedTimeslotTask.cpp @@ -51,7 +51,7 @@ void FixedTimeslotTask::missedDeadlineCounter() { if (FixedTimeslotTask::deadlineMissedCount % 10 == 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "PST missed " << FixedTimeslotTask::deadlineMissedCount << " deadlines" - << std::endl; + << std::endl; #endif } } diff --git a/src/fsfw/pus/CService201HealthCommanding.cpp b/src/fsfw/pus/CService201HealthCommanding.cpp index f6c49cd3..644e0d7c 100644 --- a/src/fsfw/pus/CService201HealthCommanding.cpp +++ b/src/fsfw/pus/CService201HealthCommanding.cpp @@ -97,7 +97,8 @@ ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *rep } // Not used for now, health state already reported by event -[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(const CommandMessage *reply) { +[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply( + const CommandMessage *reply) { auto health = static_cast(HealthMessage::getHealth(reply)); auto oldHealth = static_cast(HealthMessage::getOldHealth(reply)); HealthSetReply healthSetReply(health, oldHealth); diff --git a/src/fsfw/pus/CService201HealthCommanding.h b/src/fsfw/pus/CService201HealthCommanding.h index 7ffa06d2..71b7caa0 100644 --- a/src/fsfw/pus/CService201HealthCommanding.h +++ b/src/fsfw/pus/CService201HealthCommanding.h @@ -39,7 +39,7 @@ class CService201HealthCommanding : public CommandingServiceBase { private: static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet, - const object_id_t *objectId); + const object_id_t *objectId); [[maybe_unused]] ReturnValue_t prepareHealthSetReply(const CommandMessage *reply); diff --git a/src/fsfw/timemanager/Countdown.cpp b/src/fsfw/timemanager/Countdown.cpp index 327995f8..334883ae 100644 --- a/src/fsfw/timemanager/Countdown.cpp +++ b/src/fsfw/timemanager/Countdown.cpp @@ -3,8 +3,7 @@ Countdown::Countdown(uint32_t initialTimeout, bool startImmediately) : timeout(initialTimeout) { if (startImmediately) { setTimeout(initialTimeout); - } - else { + } else { timeout = initialTimeout; } } From 56e4fca06f9644d857493ddfd27d8788b48a47a9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 May 2022 11:24:06 +0200 Subject: [PATCH 133/198] Some improvements - Rename mutex to csMutex to better represent its purpose - Move the empty transfer to update the line polarity to separate function --- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 35 ++++++++++++++----------- hal/src/fsfw_hal/linux/spi/SpiComIF.h | 17 +++++++++++- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index da95bfcb..12d95f0d 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -27,7 +27,7 @@ SpiComIF::SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF) #endif /* FSFW_VERBOSE_LEVEL >= 1 */ } - spiMutex = MutexFactory::instance()->createMutex(); + csMutex = MutexFactory::instance()->createMutex(); } ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) { @@ -197,7 +197,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const /* Pull SPI CS low. For now, no support for active high given */ if (gpioId != gpio::NO_GPIO) { - result = spiMutex->lockMutex(timeoutType, timeoutMs); + result = csMutex->lockMutex(timeoutType, timeoutMs); if (result != RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -208,6 +208,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const #endif return result; } + updateLinePolarity(fileDescriptor); ReturnValue_t result = gpioComIF->pullLow(gpioId); if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 @@ -219,6 +220,8 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const #endif return result; } + } else { + updateLinePolarity(fileDescriptor); } /* Execute transfer */ @@ -248,7 +251,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const if (gpioId != gpio::NO_GPIO) { gpioComIF->pullHigh(gpioId); - result = spiMutex->unlockMutex(); + result = csMutex->unlockMutex(); if (result != RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "SpiComIF::sendMessage: Failed to unlock mutex" << std::endl; @@ -291,7 +294,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) { gpioId_t gpioId = spiCookie->getChipSelectPin(); if (gpioId != gpio::NO_GPIO) { - result = spiMutex->lockMutex(timeoutType, timeoutMs); + result = csMutex->lockMutex(timeoutType, timeoutMs); if (result != RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "SpiComIF::getSendSuccess: Failed to lock mutex" << std::endl; @@ -314,7 +317,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) { if (gpioId != gpio::NO_GPIO) { gpioComIF->pullHigh(gpioId); - result = spiMutex->unlockMutex(); + result = csMutex->unlockMutex(); if (result != RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "SpiComIF::getSendSuccess: Failed to unlock mutex" << std::endl; @@ -350,7 +353,7 @@ MutexIF* SpiComIF::getMutex(MutexIF::TimeoutType* timeoutType, uint32_t* timeout if (timeoutMs != nullptr) { *timeoutMs = this->timeoutMs; } - return spiMutex; + return csMutex; } void SpiComIF::performSpiWiretapping(SpiCookie* spiCookie) { @@ -398,14 +401,6 @@ void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) if (retval != 0) { utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed"); } - // This updates the SPI clock default polarity. Only setting the mode does not update - // the line state, which can be an issue on mode switches because the clock line will - // switch the state after the chip select is pulled low - clockUpdateTransfer.len = 0; - retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer); - if (retval != 0) { - utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed"); - } } void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const { @@ -422,4 +417,14 @@ void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& spee } } -const std::string& SpiComIF::getSpiDev() const { return dev; } +const std::string& SpiComIF::getSpiDev() const { + return dev; +} + +void SpiComIF::updateLinePolarity(int spiFd) { + clockUpdateTransfer.len = 0; + int retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer); + if (retval != 0) { + utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed"); + } +} diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index 881af8c4..aca94765 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -59,6 +59,17 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { GpioIF* getGpioInterface(); void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); + + /** + * This updates the SPI clock default polarity. Only setting the mode does not update + * the line state, which can be an issue on mode switches because the clock line will + * switch the state after the chip select is pulled low. + * + * It is recommended to call this function after #setSpiSpeedAndMode if the SPI bus + * has multiple SPI devices with different speed and SPI modes attached. + * @param spiFd + */ + void updateLinePolarity(int spiFd); void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const; const std::string& getSpiDev() const; @@ -74,7 +85,11 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { GpioIF* gpioComIF = nullptr; std::string dev = ""; - MutexIF* spiMutex = nullptr; + /** + * Protects the chip select operations. Lock when GPIO is pulled low, unlock after it was + * pulled high + */ + MutexIF* csMutex = nullptr; MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; uint32_t timeoutMs = 20; spi_ioc_transfer clockUpdateTransfer = {}; From ab2d7ca98fbfbb862e129ea57b65b712e3dec589 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 May 2022 11:29:28 +0200 Subject: [PATCH 134/198] update changelog and docs --- CHANGELOG.md | 13 +++++++++++-- hal/src/fsfw_hal/linux/spi/SpiComIF.h | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34f40ed3..2019fdcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,8 +60,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Additions -- Linux HAL: Getter functions for SPI speed and mode. -- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1 - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information inside `fsfw/version.h` PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 @@ -69,6 +67,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/). PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592 - `Subsystem`: New API to add table and sequence entries +## HAL + +- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a + lot more sense because each ComIF should be responsible for one SPI bus. +- SPI: Move the empty transfer to update the line polarity to separate function. This means + it is not automatically called when calling the setter function for SPI speed and mode. + The user should call this function after locking the CS mutex if multiple SPI devices with + differing speeds and modes are attached to one bus. +- SPI: Getter functions for SPI speed and mode. +- I2C: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1. + ## Fixed - TCP TMTC Server: `MutexGuard` was not created properly in diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index aca94765..3d15009d 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -65,8 +65,8 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { * the line state, which can be an issue on mode switches because the clock line will * switch the state after the chip select is pulled low. * - * It is recommended to call this function after #setSpiSpeedAndMode if the SPI bus - * has multiple SPI devices with different speed and SPI modes attached. + * It is recommended to call this function after #setSpiSpeedAndMode and after locking the + * CS mutex if the SPI bus has multiple SPI devices with different speed and SPI modes attached. * @param spiFd */ void updateLinePolarity(int spiFd); From bc994595dae47fbe57d5a4fa70ad23f90e9410f9 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 11 May 2022 14:31:49 +0200 Subject: [PATCH 135/198] sequence count init value --- src/fsfw/tmtcservices/SourceSequenceCounter.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fsfw/tmtcservices/SourceSequenceCounter.h b/src/fsfw/tmtcservices/SourceSequenceCounter.h index 6f2778a4..d7ab5d4a 100644 --- a/src/fsfw/tmtcservices/SourceSequenceCounter.h +++ b/src/fsfw/tmtcservices/SourceSequenceCounter.h @@ -8,7 +8,7 @@ class SourceSequenceCounter { uint16_t sequenceCount; public: - SourceSequenceCounter() : sequenceCount(0) {} + SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {} void increment() { sequenceCount = (sequenceCount + 1) % (SpacePacketBase::LIMIT_SEQUENCE_COUNT); } @@ -31,6 +31,7 @@ class SourceSequenceCounter { sequenceCount = newCount; return *this; } + operator uint16_t() { return this->get(); } }; From 0a97077a0e0f5e1c4859d9c867a74f277405c00c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 May 2022 15:42:52 +0200 Subject: [PATCH 136/198] hotfix --- src/fsfw/tmtcservices/SourceSequenceCounter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/tmtcservices/SourceSequenceCounter.h b/src/fsfw/tmtcservices/SourceSequenceCounter.h index 6f2778a4..00f4021e 100644 --- a/src/fsfw/tmtcservices/SourceSequenceCounter.h +++ b/src/fsfw/tmtcservices/SourceSequenceCounter.h @@ -5,7 +5,7 @@ class SourceSequenceCounter { private: - uint16_t sequenceCount; + uint16_t sequenceCount = 0; public: SourceSequenceCounter() : sequenceCount(0) {} From d1ff32bf968cbf769ca8daa37265af70e050d9c0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 May 2022 16:12:24 +0200 Subject: [PATCH 137/198] reset read vec values, add getter function --- hal/src/fsfw_hal/linux/CommandExecutor.cpp | 6 ++++++ hal/src/fsfw_hal/linux/CommandExecutor.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/hal/src/fsfw_hal/linux/CommandExecutor.cpp b/hal/src/fsfw_hal/linux/CommandExecutor.cpp index 49c44ebf..54464be2 100644 --- a/hal/src/fsfw_hal/linux/CommandExecutor.cpp +++ b/hal/src/fsfw_hal/linux/CommandExecutor.cpp @@ -32,6 +32,8 @@ ReturnValue_t CommandExecutor::execute() { } else if (state == States::PENDING) { return COMMAND_PENDING; } + // Reset data in read vector + std::memset(readVec.data(), 0, readVec.size()); currentCmdFile = popen(currentCmd.c_str(), "r"); if (currentCmdFile == nullptr) { lastError = errno; @@ -205,3 +207,7 @@ ReturnValue_t CommandExecutor::executeBlocking() { } return HasReturnvaluesIF::RETURN_OK; } + +const std::vector& CommandExecutor::getReadVector() const { + return readVec; +} diff --git a/hal/src/fsfw_hal/linux/CommandExecutor.h b/hal/src/fsfw_hal/linux/CommandExecutor.h index 90662c0f..5d403848 100644 --- a/hal/src/fsfw_hal/linux/CommandExecutor.h +++ b/hal/src/fsfw_hal/linux/CommandExecutor.h @@ -109,6 +109,8 @@ class CommandExecutor { */ void reset(); + const std::vector& getReadVector() const; + private: std::string currentCmd; bool blocking = true; From d11f898f70cb394c0be2450779dac4f5ad995e35 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 12 May 2022 15:02:06 +0200 Subject: [PATCH 138/198] update dummy power switcher docs --- src/fsfw/power/DummyPowerSwitcher.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/fsfw/power/DummyPowerSwitcher.h b/src/fsfw/power/DummyPowerSwitcher.h index b2dd40d5..6ccd8dd7 100644 --- a/src/fsfw/power/DummyPowerSwitcher.h +++ b/src/fsfw/power/DummyPowerSwitcher.h @@ -8,6 +8,13 @@ #include "definitions.h" #include "fsfw/objectmanager/SystemObject.h" +/** + * @brief This component can be used to simulate a power switcher like a + * Power Control Distribution Unit (PCDU) + * @details + * The dummy switcher will simply cache the commanded fuse and switch states and return them + * in the according switch getter functions. In that sense, it simulates an ideal PCDU. + */ class DummyPowerSwitcher : public SystemObject, public PowerSwitchIF { public: DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches, size_t numberOfFuses, From c4c340fde17a6f3cf68eab30b3de4b73b1f55497 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 12 May 2022 16:53:34 +0200 Subject: [PATCH 139/198] lot of refactoring --- src/fsfw/pus/Service11TelecommandScheduling.h | 22 ++- .../pus/Service11TelecommandScheduling.tpp | 179 ++++++++---------- src/fsfw/returnvalues/FwClassIds.h | 1 + 3 files changed, 99 insertions(+), 103 deletions(-) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.h b/src/fsfw/pus/Service11TelecommandScheduling.h index 97a343a7..f8b17c63 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.h +++ b/src/fsfw/pus/Service11TelecommandScheduling.h @@ -6,6 +6,7 @@ #include #include "fsfw/FSFW.h" +#include "fsfw/returnvalues/FwClassIds.h" /** * @brief: PUS-Service 11 - Telecommand scheduling. @@ -34,8 +35,12 @@ template class Service11TelecommandScheduling final : public PusServiceBase { public: + static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_11; + + static constexpr ReturnValue_t INVALID_TYPE_TIME_WINDOW = + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1); // The types of PUS-11 subservices - enum Subservice { + enum Subservice : uint8_t { ENABLE_SCHEDULING = 1, DISABLE_SCHEDULING = 2, RESET_SCHEDULING = 3, @@ -103,31 +108,31 @@ class Service11TelecommandScheduling final : public PusServiceBase { * @brief Logic to be performed on an incoming TC[11,4]. * @return RETURN_OK if successful */ - ReturnValue_t doInsertActivity(void); + ReturnValue_t doInsertActivity(const uint8_t* data, size_t size); /** * @brief Logic to be performed on an incoming TC[11,5]. * @return RETURN_OK if successful */ - ReturnValue_t doDeleteActivity(void); + ReturnValue_t doDeleteActivity(const uint8_t* data, size_t size); /** * @brief Logic to be performed on an incoming TC[11,6]. * @return RETURN_OK if successful */ - ReturnValue_t doFilterDeleteActivity(void); + ReturnValue_t doFilterDeleteActivity(const uint8_t* data, size_t size); /** * @brief Logic to be performed on an incoming TC[11,7]. * @return RETURN_OK if successful */ - ReturnValue_t doTimeshiftActivity(void); + ReturnValue_t doTimeshiftActivity(const uint8_t* data, size_t size); /** * @brief Logic to be performed on an incoming TC[11,8]. * @return RETURN_OK if successful */ - ReturnValue_t doFilterTimeshiftActivity(void); + ReturnValue_t doFilterTimeshiftActivity(const uint8_t* data, size_t size); /** * @brief Deserializes a generic type from a payload buffer by using the FSFW @@ -158,7 +163,7 @@ class Service11TelecommandScheduling final : public PusServiceBase { * @param [out] requestId Request ID * @return RETURN_OK if successful */ - ReturnValue_t getRequestIdFromData(const uint8_t* data, size_t& dataSize, uint64_t& requestId); + ReturnValue_t getRequestIdFromData(const uint8_t*& data, size_t& dataSize, uint64_t& requestId); /** * @brief Builds the Request ID from its three elements. @@ -177,9 +182,10 @@ class Service11TelecommandScheduling final : public PusServiceBase { * @param [out] itEnd End of filter range * @return RETURN_OK if successful */ - ReturnValue_t getMapFilterFromData(const uint8_t* data, size_t dataSize, TcMapIter& itBegin, + ReturnValue_t getMapFilterFromData(const uint8_t*& data, size_t& size, TcMapIter& itBegin, TcMapIter& itEnd); + ReturnValue_t handleInvalidData(const char* ctx); /** * @brief Prints content of multimap. Use for simple debugging only. */ diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index bfd9e96f..cc830f12 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -6,6 +6,8 @@ #include +static constexpr auto DEF_END = SerializeIF::Endianness::BIG; + template inline Service11TelecommandScheduling::Service11TelecommandScheduling( object_id_t objectId, uint16_t apid, uint8_t serviceId, AcceptsTelecommandsIF *tcRecipient, @@ -28,17 +30,23 @@ inline ReturnValue_t Service11TelecommandScheduling::handleRequest( sif::printInfo("PUS11::handleRequest: Handling request %d\n", subservice); #endif } + // Get de-serialized Timestamp + const uint8_t *data = currentPacket.getApplicationData(); + size_t size = currentPacket.getApplicationDataSize(); + if (data == nullptr) { + return handleInvalidData("handleRequest"); + } switch (subservice) { case Subservice::INSERT_ACTIVITY: - return doInsertActivity(); + return doInsertActivity(data, size); case Subservice::DELETE_ACTIVITY: - return doDeleteActivity(); + return doDeleteActivity(data, size); case Subservice::FILTER_DELETE_ACTIVITY: - return doFilterDeleteActivity(); + return doFilterDeleteActivity(data, size); case Subservice::TIMESHIFT_ACTIVITY: - return doTimeshiftActivity(); + return doTimeshiftActivity(data, size); case Subservice::FILTER_TIMESHIFT_ACTIVITY: - return doFilterTimeshiftActivity(); + return doFilterTimeshiftActivity(data, size); default: break; } @@ -105,17 +113,15 @@ inline ReturnValue_t Service11TelecommandScheduling::initialize() { } template -inline ReturnValue_t Service11TelecommandScheduling::doInsertActivity(void) { - // Get de-serialized Timestamp - const uint8_t *data = currentPacket.getApplicationData(); - size_t dataSize = currentPacket.getApplicationDataSize(); - +inline ReturnValue_t Service11TelecommandScheduling::doInsertActivity( + const uint8_t *data, size_t size) { uint32_t timestamp = 0; - if (deserializeViaFsfwInterface(timestamp, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + const uint8_t *initData = data; + size_t initSz = size; + ReturnValue_t result = SerializeAdapter::deSerialize(×tamp, &data, &size, DEF_END); + if (result != RETURN_OK) { + return result; } - data += sizeof(uint32_t); // move ptr past timestamp (for later) - dataSize -= sizeof(uint32_t); // and reduce size accordingly // Insert possible if sched. time is above margin // (See requirement for Time margin) @@ -135,8 +141,8 @@ inline ReturnValue_t Service11TelecommandScheduling::doInsertActivi } // store currentPacket and receive the store address - store_address_t addr; - if (tcStore->addData(&addr, data, dataSize) != RETURN_OK || + store_address_t addr{}; + if (tcStore->addData(&addr, initData, initSz) != RETURN_OK || addr.raw == storeId::INVALID_STORE_ADDRESS) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "Service11TelecommandScheduling::doInsertActivity: Adding data to TC Store failed" @@ -172,14 +178,13 @@ inline ReturnValue_t Service11TelecommandScheduling::doInsertActivi } template -inline ReturnValue_t Service11TelecommandScheduling::doDeleteActivity(void) { - const uint8_t *data = currentPacket.getApplicationData(); - size_t dataSize = currentPacket.getApplicationDataSize(); - +inline ReturnValue_t Service11TelecommandScheduling::doDeleteActivity( + const uint8_t *data, size_t size) { // Get request ID uint64_t requestId; - if (getRequestIdFromData(data, dataSize, requestId) != RETURN_OK) { - return RETURN_FAILED; + ReturnValue_t result = getRequestIdFromData(data, size, requestId); + if (result != RETURN_OK) { + return result; } // DEBUG @@ -240,16 +245,15 @@ inline ReturnValue_t Service11TelecommandScheduling::doDeleteActivi } template -inline ReturnValue_t Service11TelecommandScheduling::doFilterDeleteActivity(void) { - const uint8_t *data = currentPacket.getApplicationData(); - size_t dataSize = currentPacket.getApplicationDataSize(); - +inline ReturnValue_t Service11TelecommandScheduling::doFilterDeleteActivity( + const uint8_t *data, size_t size) { TcMapIter itBegin; TcMapIter itEnd; + ReturnValue_t result = getMapFilterFromData(data, size, itBegin, itEnd); // get the filter window as map range via dedicated method - if (getMapFilterFromData(data, dataSize, itBegin, itEnd) != RETURN_OK) { - return RETURN_FAILED; + if (result != RETURN_OK) { + return result; } int deletedTCs = 0; @@ -290,26 +294,22 @@ inline ReturnValue_t Service11TelecommandScheduling::doFilterDelete } template -inline ReturnValue_t Service11TelecommandScheduling::doTimeshiftActivity(void) { - const uint8_t *data = currentPacket.getApplicationData(); - size_t dataSize = currentPacket.getApplicationDataSize(); - +inline ReturnValue_t Service11TelecommandScheduling::doTimeshiftActivity( + const uint8_t *data, size_t size) { // Get relative time uint32_t relativeTime = 0; - if (deserializeViaFsfwInterface(relativeTime, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + ReturnValue_t result = SerializeAdapter::deSerialize(&relativeTime, &data, &size, DEF_END); + if (result != RETURN_OK) { + return result; } if (relativeTime == 0) { return RETURN_FAILED; } // TODO further check sanity of the relative time? - data += sizeof(uint32_t); - dataSize -= sizeof(uint32_t); - // Get request ID uint64_t requestId; - if (getRequestIdFromData(data, dataSize, requestId) != RETURN_OK) { + if (getRequestIdFromData(data, size, requestId) != RETURN_OK) { return RETURN_FAILED; } @@ -371,26 +371,24 @@ inline ReturnValue_t Service11TelecommandScheduling::doTimeshiftAct } template -inline ReturnValue_t Service11TelecommandScheduling::doFilterTimeshiftActivity(void) { - const uint8_t *data = currentPacket.getApplicationData(); - uint32_t dataSize = currentPacket.getApplicationDataSize(); - +inline ReturnValue_t Service11TelecommandScheduling::doFilterTimeshiftActivity( + const uint8_t *data, size_t size) { // Get relative time uint32_t relativeTime = 0; - if (deserializeViaFsfwInterface(relativeTime, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + ReturnValue_t result = SerializeAdapter::deSerialize(&relativeTime, &data, &size, DEF_END); + if (result != RETURN_OK) { + return result; } if (relativeTime == 0) { return RETURN_FAILED; } - data += sizeof(uint32_t); - dataSize -= sizeof(uint32_t); // Do time window TcMapIter itBegin; TcMapIter itEnd; - if (getMapFilterFromData(data, dataSize, itBegin, itEnd) != RETURN_OK) { - return RETURN_FAILED; + result = getMapFilterFromData(data, size, itBegin, itEnd); + if (result != RETURN_OK) { + return result; } int shiftedItemsCount = 0; @@ -438,27 +436,23 @@ inline uint64_t Service11TelecommandScheduling::getRequestIdFromDat template inline ReturnValue_t Service11TelecommandScheduling::getRequestIdFromData( - const uint8_t *data, size_t &dataSize, uint64_t &requestId) { + const uint8_t *&data, size_t &dataSize, uint64_t &requestId) { uint32_t srcId = 0; uint16_t apid = 0; uint16_t ssc = 0; - if (deserializeViaFsfwInterface(srcId, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + ReturnValue_t result = SerializeAdapter::deSerialize(&srcId, &data, &dataSize, DEF_END); + if (result != RETURN_OK) { + return result; } - - data += sizeof(uint32_t); - dataSize -= sizeof(uint32_t); - if (deserializeViaFsfwInterface(apid, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + result = SerializeAdapter::deSerialize(&apid, &data, &dataSize, DEF_END); + if (result != RETURN_OK) { + return result; } - - data += sizeof(uint32_t); - dataSize -= sizeof(uint32_t); - if (deserializeViaFsfwInterface(ssc, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + result = SerializeAdapter::deSerialize(&ssc, &data, &dataSize, DEF_END); + if (result != RETURN_OK) { + return result; } - requestId = buildRequestId(srcId, apid, ssc); return RETURN_OK; @@ -477,16 +471,17 @@ inline uint64_t Service11TelecommandScheduling::buildRequestId(uint template inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFromData( - const uint8_t *data, size_t dataSize, TcMapIter &itBegin, TcMapIter &itEnd) { + const uint8_t *&data, size_t &dataSize, TcMapIter &itBegin, TcMapIter &itEnd) { // get filter type first - uint32_t typeRaw; - if (deserializeViaFsfwInterface(typeRaw, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + uint32_t typeRaw = 0; + ReturnValue_t result = SerializeAdapter::deSerialize(&typeRaw, &data, &dataSize, DEF_END); + if (result != RETURN_OK) { + return result; } - // can be modified as the uint8_t pointer is passed by value (copy of ptr is modified) - data += sizeof(uint32_t); - dataSize -= sizeof(uint32_t); + if (typeRaw > 3) { + return INVALID_TYPE_TIME_WINDOW; + } TypeOfTimeWindow type = static_cast(typeRaw); // we now have the type of delete activity - so now we set the range to delete, @@ -501,9 +496,10 @@ inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFr } case TypeOfTimeWindow::FROM_TIMETAG: { - uint32_t fromTimestamp; - if (deserializeViaFsfwInterface(fromTimestamp, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + uint32_t fromTimestamp = 0; + result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize, DEF_END); + if (result != RETURN_OK) { + return result; } itBegin = telecommandMap.begin(); @@ -517,8 +513,9 @@ inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFr case TypeOfTimeWindow::TO_TIMETAG: { uint32_t toTimestamp; - if (deserializeViaFsfwInterface(toTimestamp, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize, DEF_END); + if (result != RETURN_OK) { + return result; } itBegin = telecommandMap.begin(); itEnd = telecommandMap.begin(); @@ -532,14 +529,15 @@ inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFr uint32_t fromTimestamp; uint32_t toTimestamp; - if (deserializeViaFsfwInterface(fromTimestamp, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + return result; } - data += sizeof(uint32_t); - dataSize -= sizeof(uint32_t); - - if (deserializeViaFsfwInterface(toTimestamp, data, dataSize) != RETURN_OK) { - return RETURN_FAILED; + result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + return result; } itBegin = telecommandMap.begin(); itEnd = telecommandMap.begin(); @@ -568,25 +566,16 @@ inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFr } template -template -inline ReturnValue_t Service11TelecommandScheduling::deserializeViaFsfwInterface( - T &output, const uint8_t *buf, size_t bufsize) { - if (buf == nullptr) { +inline ReturnValue_t Service11TelecommandScheduling::handleInvalidData( + const char *ctx) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "Service11TelecommandScheduling::deserializeViaFsfwInterface: " - "Invalid buffer" - << std::endl; + sif::warning << "Service11TelecommandScheduling:: " << ctx << ": Invalid buffer" << std::endl; #else - sif::printWarning( - "Service11TelecommandScheduling::deserializeViaFsfwInterface: " - "Invalid buffer\n"); + sif::printWarning("Service11TelecommandScheduling::%s: Invalid buffer\n", ctx); #endif #endif - return RETURN_FAILED; - } - - return SerializeAdapter::deSerialize(&output, &buf, &bufsize, SerializeIF::Endianness::BIG); + return RETURN_FAILED; } template diff --git a/src/fsfw/returnvalues/FwClassIds.h b/src/fsfw/returnvalues/FwClassIds.h index d07cedc9..f5f57276 100644 --- a/src/fsfw/returnvalues/FwClassIds.h +++ b/src/fsfw/returnvalues/FwClassIds.h @@ -72,6 +72,7 @@ enum : uint8_t { DLE_ENCODER, // DLEE PUS_SERVICE_3, // PUS3 PUS_SERVICE_9, // PUS9 + PUS_SERVICE_11, // PUS11 FILE_SYSTEM, // FILS LINUX_OSAL, // UXOS HAL_SPI, // HSPI From b8cfb36426f1778a787e88b7681aa74dadb3d209 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 12 May 2022 17:05:58 +0200 Subject: [PATCH 140/198] added additional explicit returnvalues --- src/fsfw/pus/Service11TelecommandScheduling.h | 5 +++++ src/fsfw/pus/Service11TelecommandScheduling.tpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.h b/src/fsfw/pus/Service11TelecommandScheduling.h index f8b17c63..5e446b07 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.h +++ b/src/fsfw/pus/Service11TelecommandScheduling.h @@ -39,6 +39,11 @@ class Service11TelecommandScheduling final : public PusServiceBase { static constexpr ReturnValue_t INVALID_TYPE_TIME_WINDOW = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1); + static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2); + static constexpr ReturnValue_t INVALID_RELATIVE_TIME = + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3); + // The types of PUS-11 subservices enum Subservice : uint8_t { ENABLE_SCHEDULING = 1, diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index cc830f12..31957652 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -345,7 +345,7 @@ inline ReturnValue_t Service11TelecommandScheduling::doTimeshiftAct "Service11TelecommandScheduling::doTimeshiftActivity: Either 0 or more than 1 TCs found. " "No explicit timeshifting possible\n"); #endif - return RETURN_FAILED; + return TIMESHIFTING_NOT_POSSIBLE; } // temporarily hold the item @@ -380,7 +380,7 @@ inline ReturnValue_t Service11TelecommandScheduling::doFilterTimesh return result; } if (relativeTime == 0) { - return RETURN_FAILED; + return INVALID_RELATIVE_TIME; } // Do time window From 3046822e88f06e7d44d449f7c5a757d0ba6f49e3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 12 May 2022 17:27:39 +0200 Subject: [PATCH 141/198] run cmake-format --- CMakeLists.txt | 312 ++++++++++++++++++++++--------------------------- 1 file changed, 141 insertions(+), 171 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c172439..db606b83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,24 +18,28 @@ set(FSFW_REVISION 0) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(FSFW_ETL_LIB_NAME etl) -set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING - "ETL library major version requirement" - ) -set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 CACHE STRING - "ETL library exact version requirement" - ) +set(FSFW_ETL_LIB_MAJOR_VERSION + 20 + CACHE STRING "ETL library major version requirement") +set(FSFW_ETL_LIB_VERSION + ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 + CACHE STRING "ETL library exact version requirement") set(FSFW_ETL_LINK_TARGET etl::etl) -set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE STRING - "Catch2 library major version requirement" - ) -set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE STRING - "Catch2 library exact version requirement" - ) +set(FSFW_CATCH2_LIB_MAJOR_VERSION + 3 + CACHE STRING "Catch2 library major version requirement") +set(FSFW_CATCH2_LIB_VERSION + v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 + CACHE STRING "Catch2 library exact version requirement") -# Keep this off by default for now. See PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 -# for information which keeping this on by default is problematic -option(FSFW_ENABLE_IPO "Enable interprocedural optimization or link-time optimization if available" OFF) +# Keep this off by default for now. See PR: +# https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 for information which +# keeping this on by default is problematic +option( + FSFW_ENABLE_IPO + "Enable interprocedural optimization or link-time optimization if available" + OFF) if(FSFW_ENABLE_IPO) include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR) @@ -45,13 +49,13 @@ if(FSFW_ENABLE_IPO) endif() option(FSFW_GENERATE_SECTIONS - "Generate function and data sections. Required to remove unused code" ON - ) + "Generate function and data sections. Required to remove unused code" ON) if(FSFW_GENERATE_SECTIONS) option(FSFW_REMOVE_UNUSED_CODE "Remove unused code" ON) endif() -option(FSFW_BUILD_UNITTESTS "Build unittest binary in addition to static library" OFF) +option(FSFW_BUILD_UNITTESTS + "Build unittest binary in addition to static library" OFF) option(FSFW_BUILD_DOCS "Build documentation with Sphinx and Doxygen" OFF) if(FSFW_BUILD_UNITTESTS) option(FSFW_TESTS_GEN_COV "Generate coverage data for unittests" ON) @@ -75,54 +79,56 @@ option(FSFW_ADD_TMSTORAGE "Compile with tm storage components" OFF) # Contrib sources option(FSFW_ADD_SGP4_PROPAGATOR "Add SGP4 propagator code" OFF) - set(FSFW_TEST_TGT fsfw-tests) set(FSFW_DUMMY_TGT fsfw-dummy) add_library(${LIB_FSFW_NAME}) if(IPO_SUPPORTED AND FSFW_ENABLE_IPO) - set_property(TARGET ${LIB_FSFW_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + set_property(TARGET ${LIB_FSFW_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION + TRUE) endif() if(FSFW_BUILD_UNITTESTS) - message(STATUS "Building the FSFW unittests in addition to the static library") + message( + STATUS "Building the FSFW unittests in addition to the static library") # Check whether the user has already installed Catch2 first find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION}) # Not installed, so use FetchContent to download and provide Catch2 if(NOT Catch2_FOUND) - message(STATUS "Catch2 installation not found. Downloading Catch2 library with FetchContent") + message( + STATUS + "Catch2 installation not found. Downloading Catch2 library with FetchContent" + ) include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG ${FSFW_CATCH2_LIB_VERSION} - ) + GIT_TAG ${FSFW_CATCH2_LIB_VERSION}) list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2) endif() set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg) configure_file(tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in FSFWConfig.h) - configure_file(tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in tests/TestsConfig.h) + configure_file(tests/src/fsfw_tests/unit/testcfg/TestsConfig.h.in + tests/TestsConfig.h) project(${FSFW_TEST_TGT} CXX C) add_executable(${FSFW_TEST_TGT}) if(IPO_SUPPORTED AND FSFW_ENABLE_IPO) - set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + set_property(TARGET ${FSFW_TEST_TGT} PROPERTY INTERPROCEDURAL_OPTIMIZATION + TRUE) endif() if(FSFW_TESTS_GEN_COV) message(STATUS "Generating coverage data for the library") message(STATUS "Targets linking against ${LIB_FSFW_NAME} " - "will be compiled with coverage data as well" - ) + "will be compiled with coverage data as well") include(FetchContent) FetchContent_Declare( - cmake-modules - GIT_REPOSITORY https://github.com/bilke/cmake-modules.git - ) + cmake-modules GIT_REPOSITORY https://github.com/bilke/cmake-modules.git) FetchContent_MakeAvailable(cmake-modules) set(CMAKE_BUILD_TYPE "Debug") list(APPEND CMAKE_MODULE_PATH ${cmake-modules_SOURCE_DIR}) @@ -136,17 +142,16 @@ message(STATUS "Finding and/or providing ETL library") find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET) # Not installed, so use FetchContent to download and provide etl if(NOT ${FSFW_ETL_LIB_NAME}_FOUND) - message(STATUS - "No ETL installation was found with find_package. Installing and providing " - "etl with FindPackage" - ) + message( + STATUS + "No ETL installation was found with find_package. Installing and providing " + "etl with FindPackage") include(FetchContent) FetchContent_Declare( ${FSFW_ETL_LIB_NAME} GIT_REPOSITORY https://github.com/ETLCPP/etl - GIT_TAG ${FSFW_ETL_LIB_VERSION} - ) + GIT_TAG ${FSFW_ETL_LIB_VERSION}) list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_ETL_LIB_NAME}) endif() @@ -160,8 +165,8 @@ if(FSFW_FETCH_CONTENT_TARGETS) add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME}) endif() if(TARGET Catch2) - # Fixes regression -preview4, to be confirmed in later releases - # Related GitHub issue: https://github.com/catchorg/Catch2/issues/2417 + # Fixes regression -preview4, to be confirmed in later releases Related + # GitHub issue: https://github.com/catchorg/Catch2/issues/2417 set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "") endif() endif() @@ -171,12 +176,9 @@ set(FSFW_CORE_INC_PATH "inc") set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux rtems freertos) # For configure files -target_include_directories(${LIB_FSFW_NAME} PRIVATE - ${CMAKE_CURRENT_BINARY_DIR} - ) -target_include_directories(${LIB_FSFW_NAME} INTERFACE - ${CMAKE_CURRENT_BINARY_DIR} - ) +target_include_directories(${LIB_FSFW_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_include_directories(${LIB_FSFW_NAME} + INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) # Backwards comptability if(OS_FSFW AND NOT FSFW_OSAL) @@ -188,14 +190,13 @@ if(NOT FSFW_OSAL) message(STATUS "No OS for FSFW via FSFW_OSAL set. Assuming host OS") # Assume host OS and autodetermine from OS_FSFW if(UNIX) - set(FSFW_OSAL "linux" - CACHE STRING - "OS abstraction layer used in the FSFW" - ) + set(FSFW_OSAL + "linux" + CACHE STRING "OS abstraction layer used in the FSFW") elseif(WIN32) - set(FSFW_OSAL "host" - CACHE STRING "OS abstraction layer used in the FSFW" - ) + set(FSFW_OSAL + "host" + CACHE STRING "OS abstraction layer used in the FSFW") endif() endif() @@ -211,16 +212,13 @@ elseif(FSFW_OSAL MATCHES linux) elseif(FSFW_OSAL MATCHES freertos) set(FSFW_OS_NAME "FreeRTOS") set(FSFW_OSAL_FREERTOS ON) - target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${LIB_OS_NAME} - ) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${LIB_OS_NAME}) elseif(FSFW_OSAL STREQUAL rtems) set(FSFW_OS_NAME "RTEMS") set(FSFW_OSAL_RTEMS ON) else() - message(WARNING - "Invalid operating system for FSFW specified! Setting to host.." - ) + message( + WARNING "Invalid operating system for FSFW specified! Setting to host..") set(FSFW_OS_NAME "Host") set(OS_FSFW "host") endif() @@ -246,69 +244,57 @@ if(FSFW_BUILD_UNITTESTS) include(CodeCoverage) # Remove quotes. - separate_arguments(COVERAGE_COMPILER_FLAGS - NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}" - ) + separate_arguments(COVERAGE_COMPILER_FLAGS NATIVE_COMMAND + "${COVERAGE_COMPILER_FLAGS}") # Add compile options manually, we don't want coverage for Catch2 - target_compile_options(${FSFW_TEST_TGT} PRIVATE - "${COVERAGE_COMPILER_FLAGS}" - ) - target_compile_options(${LIB_FSFW_NAME} PRIVATE - "${COVERAGE_COMPILER_FLAGS}" - ) + target_compile_options(${FSFW_TEST_TGT} + PRIVATE "${COVERAGE_COMPILER_FLAGS}") + target_compile_options(${LIB_FSFW_NAME} + PRIVATE "${COVERAGE_COMPILER_FLAGS}") # Exclude directories here if(WIN32) - set(GCOVR_ADDITIONAL_ARGS - "--exclude-throw-branches" - "--exclude-unreachable-branches" - ) - set(COVERAGE_EXCLUDES - "/c/msys64/mingw64/*" "*/fsfw_hal/*" - ) + set(GCOVR_ADDITIONAL_ARGS "--exclude-throw-branches" + "--exclude-unreachable-branches") + set(COVERAGE_EXCLUDES "/c/msys64/mingw64/*" "*/fsfw_hal/*") elseif(UNIX) set(COVERAGE_EXCLUDES - "/usr/include/*" "/usr/bin/*" "Catch2/*" - "/usr/local/include/*" "*/fsfw_tests/*" - "*/catch2-src/*" "*/fsfw_hal/*" - ) + "/usr/include/*" + "/usr/bin/*" + "Catch2/*" + "/usr/local/include/*" + "*/fsfw_tests/*" + "*/catch2-src/*" + "*/fsfw_hal/*") endif() - target_link_options(${FSFW_TEST_TGT} PRIVATE - -fprofile-arcs - -ftest-coverage - ) - target_link_options(${LIB_FSFW_NAME} PRIVATE - -fprofile-arcs - -ftest-coverage - ) - # Need to specify this as an interface, otherwise there will the compile issues - target_link_options(${LIB_FSFW_NAME} INTERFACE - -fprofile-arcs - -ftest-coverage - ) + target_link_options(${FSFW_TEST_TGT} PRIVATE -fprofile-arcs + -ftest-coverage) + target_link_options(${LIB_FSFW_NAME} PRIVATE -fprofile-arcs + -ftest-coverage) + # Need to specify this as an interface, otherwise there will the compile + # issues + target_link_options(${LIB_FSFW_NAME} INTERFACE -fprofile-arcs + -ftest-coverage) if(WIN32) setup_target_for_coverage_gcovr_html( - NAME ${FSFW_TEST_TGT}_coverage - EXECUTABLE ${FSFW_TEST_TGT} - DEPENDENCIES ${FSFW_TEST_TGT} - ) + NAME ${FSFW_TEST_TGT}_coverage EXECUTABLE ${FSFW_TEST_TGT} + DEPENDENCIES ${FSFW_TEST_TGT}) else() setup_target_for_coverage_lcov( - NAME ${FSFW_TEST_TGT}_coverage - EXECUTABLE ${FSFW_TEST_TGT} - DEPENDENCIES ${FSFW_TEST_TGT} - ) + NAME ${FSFW_TEST_TGT}_coverage EXECUTABLE ${FSFW_TEST_TGT} + DEPENDENCIES ${FSFW_TEST_TGT}) endif() endif() endif() - target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2 ${LIB_FSFW_NAME}) + target_link_libraries(${FSFW_TEST_TGT} PRIVATE Catch2::Catch2 + ${LIB_FSFW_NAME}) endif() -# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. -# If this is not given, we include the default configuration and emit a warning. +# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. If +# this is not given, we include the default configuration and emit a warning. if(NOT FSFW_CONFIG_PATH) set(DEF_CONF_PATH misc/defaultcfg/fsfwconfig) if(NOT FSFW_BUILD_DOCS) @@ -319,22 +305,21 @@ if(NOT FSFW_CONFIG_PATH) set(FSFW_CONFIG_PATH ${DEF_CONF_PATH}) endif() -# FSFW might be part of a possibly complicated folder structure, so we -# extract the absolute path of the fsfwconfig folder. +# FSFW might be part of a possibly complicated folder structure, so we extract +# the absolute path of the fsfwconfig folder. if(IS_ABSOLUTE ${FSFW_CONFIG_PATH}) set(FSFW_CONFIG_PATH_ABSOLUTE ${FSFW_CONFIG_PATH}) else() - get_filename_component(FSFW_CONFIG_PATH_ABSOLUTE - ${FSFW_CONFIG_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR} - ) + get_filename_component(FSFW_CONFIG_PATH_ABSOLUTE ${FSFW_CONFIG_PATH} REALPATH + BASE_DIR ${CMAKE_SOURCE_DIR}) endif() foreach(INCLUDE_PATH ${FSFW_ADDITIONAL_INC_PATHS}) if(IS_ABSOLUTE ${INCLUDE_PATH}) set(CURR_ABS_INC_PATH "${INCLUDE_PATH}") else() - get_filename_component(CURR_ABS_INC_PATH - ${INCLUDE_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}) + get_filename_component(CURR_ABS_INC_PATH ${INCLUDE_PATH} REALPATH BASE_DIR + ${CMAKE_SOURCE_DIR}) endif() if(CMAKE_VERBOSE) @@ -347,43 +332,39 @@ endforeach() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(NOT DEFINED FSFW_WARNING_FLAGS) set(FSFW_WARNING_FLAGS - -Wall - -Wextra - -Wimplicit-fallthrough=1 - -Wno-unused-parameter - -Wno-psabi - -Wduplicated-cond # check for duplicate conditions - -Wduplicated-branches # check for duplicate branches - -Wlogical-op # Search for bitwise operations instead of logical - -Wnull-dereference # Search for NULL dereference - -Wundef # Warn if undefind marcos are used - -Wformat=2 # Format string problem detection - -Wformat-overflow=2 # Formatting issues in printf - -Wformat-truncation=2 # Formatting issues in printf - -Wformat-security # Search for dangerous printf operations - -Wstrict-overflow=3 # Warn if integer overflows might happen - -Warray-bounds=2 # Some array bounds violations will be found - -Wshift-overflow=2 # Search for bit left shift overflows ( Date: Thu, 12 May 2022 20:06:10 +0200 Subject: [PATCH 142/198] HasHealthIF additions --- src/fsfw/health/HasHealthIF.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/fsfw/health/HasHealthIF.h b/src/fsfw/health/HasHealthIF.h index 41abeef3..197f08aa 100644 --- a/src/fsfw/health/HasHealthIF.h +++ b/src/fsfw/health/HasHealthIF.h @@ -16,10 +16,15 @@ class HasHealthIF { }; static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF; - static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1); - static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2); + static constexpr ReturnValue_t OBJECT_NOT_HEALTHY = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1); + static constexpr ReturnValue_t INVALID_HEALTH_STATE = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2); + static constexpr ReturnValue_t IS_EXTERNALLY_CONTROLLED = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1; + //! P1: New Health, P2: Old Health static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO); static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO); static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW); From fc2b709148d273368e59969ee073670cb282ac29 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 12 May 2022 20:48:50 +0200 Subject: [PATCH 143/198] resolve merge conflict --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 773b29c1..2cd9e333 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,7 +85,6 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593 ## Additions -<<<<<<< HEAD - LTO support: Allow using LTO/IPO by setting `FSFW_ENABLE_LTO=1`. CMake is able to detect whether the user compiler supports IPO/LPO. LTO is on by default now. Most modern compilers support it, can make good use of it and it usually makes the code faster and/or smaller. @@ -100,9 +99,6 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593 - https://gitlab.kitware.com/cmake/cmake/-/issues/21696 Easiest solution for now: Keep this option OFF by default. PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616 -- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1 -======= ->>>>>>> origin/develop - Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information inside `fsfw/version.h` PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559 From c215508a12e0fa4e343f9e589592775c0d28517d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 00:25:52 +0200 Subject: [PATCH 144/198] another missing preproc guard --- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index c4054bf1..15061d14 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -216,7 +216,9 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) { gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LinuxLibgpioIF::pullHigh: Unknown GPIO ID " << gpioId << std::endl; +#endif return UNKNOWN_GPIO_ID; } From 038e47a46e38738b555f8d5117fa287d59aedcac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 00:30:01 +0200 Subject: [PATCH 145/198] better returncode handling --- src/fsfw/pus/Service11TelecommandScheduling.tpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index 31957652..c72e6631 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -303,14 +303,15 @@ inline ReturnValue_t Service11TelecommandScheduling::doTimeshiftAct return result; } if (relativeTime == 0) { - return RETURN_FAILED; + return INVALID_RELATIVE_TIME; } // TODO further check sanity of the relative time? // Get request ID uint64_t requestId; - if (getRequestIdFromData(data, size, requestId) != RETURN_OK) { - return RETURN_FAILED; + result = getRequestIdFromData(data, size, requestId); + if (result != RETURN_OK) { + return result; } if (debugMode) { From 994c7299b979e62cdcc7eff985423a093e1603d2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:34:44 +0200 Subject: [PATCH 146/198] add cmake-format command to shell script --- scripts/apply-clang-format.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index 27202324..d3aa1d1a 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -3,6 +3,12 @@ if [[ ! -f README.md ]]; then cd .. fi +cmake_fmt="python3 -m cmake-format" +if command -v ${cmake_fmt} &> /dev/null + cmake_fmt_cmd=${cmake_fmt} -i CMakeLists.txt + eval ${cmake_fmt_cmd} +then + find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i From 9e3d5b6a0cb7ead82ba0991ef238520214258302 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:35:18 +0200 Subject: [PATCH 147/198] small fix --- scripts/apply-clang-format.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index d3aa1d1a..b4a44c43 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -5,7 +5,7 @@ fi cmake_fmt="python3 -m cmake-format" if command -v ${cmake_fmt} &> /dev/null - cmake_fmt_cmd=${cmake_fmt} -i CMakeLists.txt + cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" eval ${cmake_fmt_cmd} then From ad0b6f1ed1132a9d41c3e10b407fef9220f395f3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:35:59 +0200 Subject: [PATCH 148/198] another small fix --- scripts/apply-clang-format.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index b4a44c43..6ea055f9 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -4,10 +4,10 @@ if [[ ! -f README.md ]]; then fi cmake_fmt="python3 -m cmake-format" -if command -v ${cmake_fmt} &> /dev/null +if command -v ${cmake_fmt} &> /dev/null; then cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" eval ${cmake_fmt_cmd} -then +fi find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i From deee4c43c0c6e7dff860bb8ead16480560e26f7b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:37:58 +0200 Subject: [PATCH 149/198] finally this works --- scripts/apply-clang-format.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index 6ea055f9..97783e95 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -3,7 +3,7 @@ if [[ ! -f README.md ]]; then cd .. fi -cmake_fmt="python3 -m cmake-format" +cmake_fmt="cmake-format" if command -v ${cmake_fmt} &> /dev/null; then cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" eval ${cmake_fmt_cmd} From cfa6843c8f3fc57617482fd5f359bfab7941c9a3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:46:04 +0200 Subject: [PATCH 150/198] check whether clang-format is installed --- scripts/apply-clang-format.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index 97783e95..fe05ddd2 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -7,8 +7,15 @@ cmake_fmt="cmake-format" if command -v ${cmake_fmt} &> /dev/null; then cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" eval ${cmake_fmt_cmd} +else + echo "No cmake-format tool found, not formatting CMake files" fi -find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i -find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i +cpp_format="clang-format" +if command -v ${clang-format} &> /dev/null; then + find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i + find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i + find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i +else + echo "No clang-format tool found, not formatting C++/C files" +fi \ No newline at end of file From d4a6f987bc6bd0bbe5e711d8a5201ffec4ddfebe Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:46:59 +0200 Subject: [PATCH 151/198] small fix --- scripts/apply-clang-format.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index fe05ddd2..a456c744 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -12,7 +12,7 @@ else fi cpp_format="clang-format" -if command -v ${clang-format} &> /dev/null; then +if command -v ${cpp_format} &> /dev/null; then find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i From 99fe6487c8d5a5fe3934afbcda2b8268365ea6aa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:48:18 +0200 Subject: [PATCH 152/198] another small improvement --- scripts/apply-clang-format.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index a456c744..cbb8b654 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -8,7 +8,7 @@ if command -v ${cmake_fmt} &> /dev/null; then cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" eval ${cmake_fmt_cmd} else - echo "No cmake-format tool found, not formatting CMake files" + echo "No ${cmake_fmt} tool found, not formatting CMake files" fi cpp_format="clang-format" @@ -17,5 +17,5 @@ if command -v ${cpp_format} &> /dev/null; then find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i else - echo "No clang-format tool found, not formatting C++/C files" + echo "No ${cpp_format} tool found, not formatting C++/C files" fi \ No newline at end of file From 01ebf0f4d3dd9969742a27748540d312f81d9088 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:49:01 +0200 Subject: [PATCH 153/198] tab size --- scripts/apply-clang-format.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index cbb8b654..460b41e9 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -1,21 +1,21 @@ #!/bin/bash if [[ ! -f README.md ]]; then - cd .. + cd .. fi cmake_fmt="cmake-format" if command -v ${cmake_fmt} &> /dev/null; then - cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" - eval ${cmake_fmt_cmd} + cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" + eval ${cmake_fmt_cmd} else - echo "No ${cmake_fmt} tool found, not formatting CMake files" + echo "No ${cmake_fmt} tool found, not formatting CMake files" fi cpp_format="clang-format" if command -v ${cpp_format} &> /dev/null; then - find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i - find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i - find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i + find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i + find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i + find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i else - echo "No ${cpp_format} tool found, not formatting C++/C files" + echo "No ${cpp_format} tool found, not formatting C++/C files" fi \ No newline at end of file From 4092de911cd683313e5bcafcb5b934d93bdad7b1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:55:19 +0200 Subject: [PATCH 154/198] use variable for repeated section --- scripts/apply-clang-format.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh index 460b41e9..7b67ee9d 100755 --- a/scripts/apply-clang-format.sh +++ b/scripts/apply-clang-format.sh @@ -12,10 +12,11 @@ else fi cpp_format="clang-format" +file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" if command -v ${cpp_format} &> /dev/null; then - find ./src -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i - find ./hal -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i - find ./tests -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i + find ./src ${file_selectors} | xargs clang-format --style=file -i + find ./hal ${file_selectors} | xargs clang-format --style=file -i + find ./tests ${file_selectors} | xargs clang-format --style=file -i else echo "No ${cpp_format} tool found, not formatting C++/C files" -fi \ No newline at end of file +fi From c86e99e6dc066252e70d1b86d9709bd8db52adf8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:56:20 +0200 Subject: [PATCH 155/198] rename auto-formatter --- scripts/auto-formatting.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 scripts/auto-formatting.sh diff --git a/scripts/auto-formatting.sh b/scripts/auto-formatting.sh new file mode 100755 index 00000000..7b67ee9d --- /dev/null +++ b/scripts/auto-formatting.sh @@ -0,0 +1,22 @@ +#!/bin/bash +if [[ ! -f README.md ]]; then + cd .. +fi + +cmake_fmt="cmake-format" +if command -v ${cmake_fmt} &> /dev/null; then + cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" + eval ${cmake_fmt_cmd} +else + echo "No ${cmake_fmt} tool found, not formatting CMake files" +fi + +cpp_format="clang-format" +file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" +if command -v ${cpp_format} &> /dev/null; then + find ./src ${file_selectors} | xargs clang-format --style=file -i + find ./hal ${file_selectors} | xargs clang-format --style=file -i + find ./tests ${file_selectors} | xargs clang-format --style=file -i +else + echo "No ${cpp_format} tool found, not formatting C++/C files" +fi From 23fb06578bcfa6455f88a91bfbd2e32970b2236d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:56:37 +0200 Subject: [PATCH 156/198] this is better --- scripts/auto-formatter.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 scripts/auto-formatter.sh diff --git a/scripts/auto-formatter.sh b/scripts/auto-formatter.sh new file mode 100755 index 00000000..7b67ee9d --- /dev/null +++ b/scripts/auto-formatter.sh @@ -0,0 +1,22 @@ +#!/bin/bash +if [[ ! -f README.md ]]; then + cd .. +fi + +cmake_fmt="cmake-format" +if command -v ${cmake_fmt} &> /dev/null; then + cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" + eval ${cmake_fmt_cmd} +else + echo "No ${cmake_fmt} tool found, not formatting CMake files" +fi + +cpp_format="clang-format" +file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" +if command -v ${cpp_format} &> /dev/null; then + find ./src ${file_selectors} | xargs clang-format --style=file -i + find ./hal ${file_selectors} | xargs clang-format --style=file -i + find ./tests ${file_selectors} | xargs clang-format --style=file -i +else + echo "No ${cpp_format} tool found, not formatting C++/C files" +fi From 811287aac895e2bc36db9f50916a5e65705f31b1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 11:57:22 +0200 Subject: [PATCH 157/198] delete old scripts --- scripts/apply-clang-format.sh | 22 ---------------------- scripts/auto-formatting.sh | 22 ---------------------- 2 files changed, 44 deletions(-) delete mode 100755 scripts/apply-clang-format.sh delete mode 100755 scripts/auto-formatting.sh diff --git a/scripts/apply-clang-format.sh b/scripts/apply-clang-format.sh deleted file mode 100755 index 7b67ee9d..00000000 --- a/scripts/apply-clang-format.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -if [[ ! -f README.md ]]; then - cd .. -fi - -cmake_fmt="cmake-format" -if command -v ${cmake_fmt} &> /dev/null; then - cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" - eval ${cmake_fmt_cmd} -else - echo "No ${cmake_fmt} tool found, not formatting CMake files" -fi - -cpp_format="clang-format" -file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" -if command -v ${cpp_format} &> /dev/null; then - find ./src ${file_selectors} | xargs clang-format --style=file -i - find ./hal ${file_selectors} | xargs clang-format --style=file -i - find ./tests ${file_selectors} | xargs clang-format --style=file -i -else - echo "No ${cpp_format} tool found, not formatting C++/C files" -fi diff --git a/scripts/auto-formatting.sh b/scripts/auto-formatting.sh deleted file mode 100755 index 7b67ee9d..00000000 --- a/scripts/auto-formatting.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -if [[ ! -f README.md ]]; then - cd .. -fi - -cmake_fmt="cmake-format" -if command -v ${cmake_fmt} &> /dev/null; then - cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" - eval ${cmake_fmt_cmd} -else - echo "No ${cmake_fmt} tool found, not formatting CMake files" -fi - -cpp_format="clang-format" -file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" -if command -v ${cpp_format} &> /dev/null; then - find ./src ${file_selectors} | xargs clang-format --style=file -i - find ./hal ${file_selectors} | xargs clang-format --style=file -i - find ./tests ${file_selectors} | xargs clang-format --style=file -i -else - echo "No ${cpp_format} tool found, not formatting C++/C files" -fi From 4841d5d92d721383e92b521b584c7d0e62c9873d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 13 May 2022 17:24:55 +0200 Subject: [PATCH 158/198] doc update --- src/fsfw/devicehandlers/DeviceHandlerBase.h | 23 ++++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 0a273675..34171067 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -467,14 +467,14 @@ class DeviceHandlerBase : public DeviceHandlerIF, * @brief This is a helper method to insert replies in the reply map. * @param deviceCommand Identifier of the reply to add. * @param maxDelayCycles The maximum number of delay cycles the reply waits - * until it times out. + * until it times out. * @param periodic Indicates if the command is periodic (i.e. it is sent - * by the device repeatedly without request) or not. Default is aperiodic (0). - * Please note that periodic replies are disabled by default. You can enable them with - * #updatePeriodicReply + * by the device repeatedly without request) or not. Default is aperiodic (0). + * Please note that periodic replies are disabled by default. You can enable them with + * #updatePeriodicReply * @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible - * to provide a pointer to a Countdown object which will signal the timeout - * when expired + * to provide a pointer to a Countdown object which will signal the timeout + * when expired * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ @@ -783,11 +783,18 @@ class DeviceHandlerBase : public DeviceHandlerIF, * This is used to keep track of pending replies. */ struct DeviceReplyInfo { + //! For Command-Reply combinations: //! The maximum number of cycles the handler should wait for a reply //! to this command. + //! + //! Reply Only: + //! For periodic replies, this variable will be the number of delay cycles between the replies. + //! For the non-periodic variant, this variable is not used as there is no meaningful + //! definition for delay uint16_t maxDelayCycles; - //! The currently remaining cycles the handler should wait for a reply, - //! 0 means there is no reply expected + //! This variable will be set to #maxDelayCycles if a reply is expected. + //! For non-periodic replies without a command, this variable is unused. + //! A runtime value of 0 means there is no reply is currently expected. uint16_t delayCycles; size_t replyLen = 0; //!< Expected size of the reply. //! if this is !=0, the delayCycles will not be reset to 0 but to From 7df1922633061419f0a66c03e34ad16d4db7457d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 14 May 2022 09:38:59 +0200 Subject: [PATCH 159/198] refactor task IF --- hal/src/fsfw_hal/linux/CommandExecutor.cpp | 2 + hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 27 ++++++++++-- hal/src/fsfw_hal/linux/spi/SpiComIF.h | 30 +++++++++++--- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 4 +- src/fsfw/osal/linux/FixedTimeslotTask.h | 13 +++--- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 41 +++++++++++++++---- src/fsfw/osal/linux/PeriodicPosixTask.h | 14 +++++-- src/fsfw/tasks/FixedSlotSequence.cpp | 2 + src/fsfw/tasks/FixedSlotSequence.h | 2 + src/fsfw/tasks/FixedTimeslotTaskIF.h | 2 +- src/fsfw/tasks/PeriodicTaskIF.h | 6 ++- .../unit/power/testPowerSwitcher.cpp | 4 +- 12 files changed, 114 insertions(+), 33 deletions(-) diff --git a/hal/src/fsfw_hal/linux/CommandExecutor.cpp b/hal/src/fsfw_hal/linux/CommandExecutor.cpp index 49c44ebf..dcdd10ee 100644 --- a/hal/src/fsfw_hal/linux/CommandExecutor.cpp +++ b/hal/src/fsfw_hal/linux/CommandExecutor.cpp @@ -205,3 +205,5 @@ ReturnValue_t CommandExecutor::executeBlocking() { } return HasReturnvaluesIF::RETURN_OK; } + +const std::vector& CommandExecutor::getReadVector() const { return readVec; } diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index dcf92b5d..3c257f1f 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -401,12 +401,33 @@ void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) if (retval != 0) { utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed"); } - // This updates the SPI clock default polarity. Only setting the mode does not update - // the line state, which can be an issue on mode switches because the clock line will - // switch the state after the chip select is pulled low +} + +void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const { + uint8_t tmpMode = 0; + int retval = ioctl(spiFd, SPI_IOC_RD_MODE, &tmpMode); + if (retval != 0) { + utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Reading SPI mode failed"); + } + mode = static_cast(tmpMode); + + retval = ioctl(spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); + if (retval != 0) { + utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Getting SPI speed failed"); + } +} + +const std::string& SpiComIF::getSpiDev() const { return dev; } + +void SpiComIF::updateLinePolarity(int spiFd) { clockUpdateTransfer.len = 0; retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer); if (retval != 0) { utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed"); } } + +void SpiComIF::setMutexParams(MutexIF::TimeoutType timeoutType_, uint32_t timeoutMs_) { + timeoutType = timeoutType_; + timeoutMs = timeoutMs_; +} diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index 357afa2f..1400dcfc 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -22,15 +22,17 @@ class SpiCookie; */ class SpiComIF : public DeviceCommunicationIF, public SystemObject { public: - static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI; + static constexpr dur_millis_t DEFAULT_MUTEX_TIMEOUT = 20; + + static constexpr uint8_t CLASS_ID = CLASS_ID::HAL_SPI; static constexpr ReturnValue_t OPENING_FILE_FAILED = - HasReturnvaluesIF::makeReturnCode(spiRetvalId, 0); + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0); /* Full duplex (ioctl) transfer failure */ static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED = - HasReturnvaluesIF::makeReturnCode(spiRetvalId, 1); + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1); /* Half duplex (read/write) transfer failure */ static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = - HasReturnvaluesIF::makeReturnCode(spiRetvalId, 2); + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2); SpiComIF(object_id_t objectId, GpioIF* gpioComIF); @@ -45,6 +47,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { * the chip select must be driven from outside of the com if. */ MutexIF* getMutex(MutexIF::TimeoutType* timeoutType = nullptr, uint32_t* timeoutMs = nullptr); + void setMutexParams(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs); /** * Perform a regular send operation using Linux iotcl. This is public so it can be used @@ -59,6 +62,23 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { GpioIF* getGpioInterface(); void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); +<<<<<<< Updated upstream +======= + void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const; + + /** + * This updates the SPI clock default polarity. Only setting the mode does not update + * the line state, which can be an issue on mode switches because the clock line will + * switch the state after the chip select is pulled low. + * + * It is recommended to call this function after #setSpiSpeedAndMode and after locking the + * CS mutex if the SPI bus has multiple SPI devices with different speed and SPI modes attached. + * @param spiFd + */ + void updateLinePolarity(int spiFd); + + const std::string& getSpiDev() const; +>>>>>>> Stashed changes void performSpiWiretapping(SpiCookie* spiCookie); ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); @@ -73,7 +93,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { MutexIF* spiMutex = nullptr; MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; - uint32_t timeoutMs = 20; + uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT; spi_ioc_transfer clockUpdateTransfer = {}; using SpiDeviceMap = std::unordered_map; diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp index 1f4d6e23..d1fccdf9 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp @@ -14,6 +14,8 @@ FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t st FixedTimeslotTask::~FixedTimeslotTask() {} +bool FixedTimeslotTask::isEmpty() const { return pst.isEmpty(); } + void* FixedTimeslotTask::taskEntryPoint(void* arg) { // The argument is re-interpreted as PollingTask. FixedTimeslotTask* originalTask(reinterpret_cast(arg)); @@ -50,7 +52,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotT return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkSequence() const { return pst.checkSequence(); } +ReturnValue_t FixedTimeslotTask::checkSequence() { return pst.checkSequence(); } void FixedTimeslotTask::taskFunctionality() { // Like FreeRTOS pthreads are running as soon as they are created diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.h b/src/fsfw/osal/linux/FixedTimeslotTask.h index 76b92db3..a5dc9032 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.h +++ b/src/fsfw/osal/linux/FixedTimeslotTask.h @@ -24,15 +24,18 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread { FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); virtual ~FixedTimeslotTask(); - virtual ReturnValue_t startTask(); + ReturnValue_t startTask() override; - virtual ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; - virtual uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); + ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep) override; - virtual ReturnValue_t checkSequence() const; + ReturnValue_t checkSequence() override; + + bool isEmpty() const override; /** * This static function can be used as #deadlineMissedFunc. diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index e1937df4..26b6f53e 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -26,12 +26,12 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { return NULL; } -ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { +ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) { ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - return addComponent(newObject); + return addComponent(newObject, opCode); } -ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) { +ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object, uint8_t opCode) { if (object == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" @@ -43,7 +43,7 @@ ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) { #endif return HasReturnvaluesIF::RETURN_FAILED; } - objectList.push_back(object); + objectList.emplace(object, opCode); object->setTaskIF(this); return HasReturnvaluesIF::RETURN_OK; @@ -54,6 +54,9 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { } ReturnValue_t PeriodicPosixTask::startTask(void) { + if (isEmpty()) { + return HasReturnvaluesIF::RETURN_FAILED; + } started = true; PosixThread::createTask(&taskEntryPoint, this); return HasReturnvaluesIF::RETURN_OK; @@ -64,15 +67,13 @@ void PeriodicPosixTask::taskFunctionality(void) { suspend(); } - for (auto const& object : objectList) { - object->initializeAfterTaskCreation(); - } + initObjsAfterTaskCreation(); uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); // The task's "infinite" inner loop is entered. while (1) { - for (auto const& object : objectList) { - object->performOperation(); + for (auto const& objOpCodePair : objectList) { + objOpCodePair.first->performOperation(objOpCodePair.second); } if (not PosixThread::delayUntil(&lastWakeTime, periodMs)) { @@ -84,3 +85,25 @@ void PeriodicPosixTask::taskFunctionality(void) { } uint32_t PeriodicPosixTask::getPeriodMs() const { return periodMs; } + +bool PeriodicPosixTask::isEmpty() const { return objectList.empty(); } + +ReturnValue_t PeriodicPosixTask::initObjsAfterTaskCreation() { + std::multiset uniqueObjects; + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + uint32_t count = 0; + for (const auto& obj : objectList) { + // Ensure that each unique object is initialized once. + if (uniqueObjects.find(obj.first) == uniqueObjects.end()) { + ReturnValue_t result = obj.first->initializeAfterTaskCreation(); + if (result != HasReturnvaluesIF::RETURN_OK) { + count++; + status = result; + } + uniqueObjects.emplace(obj.first); + } + } + if (count > 0) { + } + return status; +} diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 3cd9847a..1142c854 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include +#include #include "../../objectmanager/ObjectManagerIF.h" #include "../../tasks/ExecutableObjectIF.h" @@ -40,7 +40,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * @param object Id of the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(object_id_t object) override; + ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; /** * Adds an object to the list of objects to be executed. @@ -48,14 +48,20 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * @param object pointer to the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(ExecutableObjectIF* object) override; + ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; + ReturnValue_t initObjsAfterTaskCreation(); + + bool isEmpty() const override; + private: - typedef std::vector ObjectList; //!< Typedef for the List of objects. + //! Typedef for the List of objects. Will contain the objects to execute and their respective + //! op codes + using ObjectList = std::multiset>; /** * @brief This attribute holds a list of objects to be executed. */ diff --git a/src/fsfw/tasks/FixedSlotSequence.cpp b/src/fsfw/tasks/FixedSlotSequence.cpp index d4c67b4d..62c0e99c 100644 --- a/src/fsfw/tasks/FixedSlotSequence.cpp +++ b/src/fsfw/tasks/FixedSlotSequence.cpp @@ -164,3 +164,5 @@ ReturnValue_t FixedSlotSequence::intializeSequenceAfterTaskCreation() const { void FixedSlotSequence::addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList&)) { this->customCheckFunction = customCheckFunction; } + +bool FixedSlotSequence::isEmpty() const { return slotList.empty(); } diff --git a/src/fsfw/tasks/FixedSlotSequence.h b/src/fsfw/tasks/FixedSlotSequence.h index a287c5b2..5ece7126 100644 --- a/src/fsfw/tasks/FixedSlotSequence.h +++ b/src/fsfw/tasks/FixedSlotSequence.h @@ -159,6 +159,8 @@ class FixedSlotSequence { */ ReturnValue_t intializeSequenceAfterTaskCreation() const; + bool isEmpty() const; + protected: /** * @brief This list contains all PollingSlot objects, defining order and diff --git a/src/fsfw/tasks/FixedTimeslotTaskIF.h b/src/fsfw/tasks/FixedTimeslotTaskIF.h index 497db245..9d85ac4a 100644 --- a/src/fsfw/tasks/FixedTimeslotTaskIF.h +++ b/src/fsfw/tasks/FixedTimeslotTaskIF.h @@ -30,7 +30,7 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF { * Check whether the sequence is valid and perform all other required * initialization steps which are needed after task creation */ - virtual ReturnValue_t checkSequence() const = 0; + virtual ReturnValue_t checkSequence() = 0; }; #endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */ diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h index c78a32de..2ae268fc 100644 --- a/src/fsfw/tasks/PeriodicTaskIF.h +++ b/src/fsfw/tasks/PeriodicTaskIF.h @@ -31,7 +31,7 @@ class PeriodicTaskIF { * Add an object to the task. The object needs to implement ExecutableObjectIF * @return */ - virtual ReturnValue_t addComponent(object_id_t object) { + virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; }; @@ -41,13 +41,15 @@ class PeriodicTaskIF { * Add an object to the task. * @return */ - virtual ReturnValue_t addComponent(ExecutableObjectIF* object) { + virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; }; virtual ReturnValue_t sleepFor(uint32_t ms) = 0; virtual uint32_t getPeriodMs() const = 0; + + virtual bool isEmpty() const = 0; }; #endif /* PERIODICTASKIF_H_ */ diff --git a/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp index d8523558..941055ac 100644 --- a/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp +++ b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp @@ -67,7 +67,5 @@ TEST_CASE("Power Switcher", "[power-switcher]") { REQUIRE(not switcherUsingDummy.active()); } - SECTION("More Dummy Tests") { - - } + SECTION("More Dummy Tests") {} } From dba08fed7a00187ba204f46bc40424f7b87f3aea Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 14 May 2022 09:40:31 +0200 Subject: [PATCH 160/198] refactor task IF --- hal/src/fsfw_hal/linux/CommandExecutor.cpp | 4 +- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 9 ++-- hal/src/fsfw_hal/linux/spi/SpiComIF.h | 15 ++++--- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 4 +- src/fsfw/osal/linux/FixedTimeslotTask.h | 13 +++--- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 41 +++++++++++++++---- src/fsfw/osal/linux/PeriodicPosixTask.h | 14 +++++-- src/fsfw/tasks/FixedSlotSequence.cpp | 2 + src/fsfw/tasks/FixedSlotSequence.h | 2 + src/fsfw/tasks/FixedTimeslotTaskIF.h | 2 +- src/fsfw/tasks/PeriodicTaskIF.h | 6 ++- .../unit/power/testPowerSwitcher.cpp | 4 +- 12 files changed, 79 insertions(+), 37 deletions(-) diff --git a/hal/src/fsfw_hal/linux/CommandExecutor.cpp b/hal/src/fsfw_hal/linux/CommandExecutor.cpp index 54464be2..3887964d 100644 --- a/hal/src/fsfw_hal/linux/CommandExecutor.cpp +++ b/hal/src/fsfw_hal/linux/CommandExecutor.cpp @@ -208,6 +208,4 @@ ReturnValue_t CommandExecutor::executeBlocking() { return HasReturnvaluesIF::RETURN_OK; } -const std::vector& CommandExecutor::getReadVector() const { - return readVec; -} +const std::vector& CommandExecutor::getReadVector() const { return readVec; } diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index 12d95f0d..b4ed47f2 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -417,9 +417,7 @@ void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& spee } } -const std::string& SpiComIF::getSpiDev() const { - return dev; -} +const std::string& SpiComIF::getSpiDev() const { return dev; } void SpiComIF::updateLinePolarity(int spiFd) { clockUpdateTransfer.len = 0; @@ -428,3 +426,8 @@ void SpiComIF::updateLinePolarity(int spiFd) { utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed"); } } + +void SpiComIF::setMutexParams(MutexIF::TimeoutType timeoutType_, uint32_t timeoutMs_) { + timeoutType = timeoutType_; + timeoutMs = timeoutMs_; +} diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index 3d15009d..113b42b0 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -22,15 +22,17 @@ class SpiCookie; */ class SpiComIF : public DeviceCommunicationIF, public SystemObject { public: - static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI; + static constexpr dur_millis_t DEFAULT_MUTEX_TIMEOUT = 20; + + static constexpr uint8_t CLASS_ID = CLASS_ID::HAL_SPI; static constexpr ReturnValue_t OPENING_FILE_FAILED = - HasReturnvaluesIF::makeReturnCode(spiRetvalId, 0); + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0); /* Full duplex (ioctl) transfer failure */ static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED = - HasReturnvaluesIF::makeReturnCode(spiRetvalId, 1); + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1); /* Half duplex (read/write) transfer failure */ static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = - HasReturnvaluesIF::makeReturnCode(spiRetvalId, 2); + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2); SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF); @@ -45,6 +47,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { * the chip select must be driven from outside of the com if. */ MutexIF* getMutex(MutexIF::TimeoutType* timeoutType = nullptr, uint32_t* timeoutMs = nullptr); + void setMutexParams(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs); /** * Perform a regular send operation using Linux iotcl. This is public so it can be used @@ -59,6 +62,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { GpioIF* getGpioInterface(); void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); + void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const; /** * This updates the SPI clock default polarity. Only setting the mode does not update @@ -70,7 +74,6 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { * @param spiFd */ void updateLinePolarity(int spiFd); - void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const; const std::string& getSpiDev() const; void performSpiWiretapping(SpiCookie* spiCookie); @@ -91,7 +94,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { */ MutexIF* csMutex = nullptr; MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; - uint32_t timeoutMs = 20; + uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT; spi_ioc_transfer clockUpdateTransfer = {}; using SpiDeviceMap = std::unordered_map; diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp index a6337fb0..e5fe12e9 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp @@ -14,6 +14,8 @@ FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t st FixedTimeslotTask::~FixedTimeslotTask() {} +bool FixedTimeslotTask::isEmpty() const { return pst.isEmpty(); } + void* FixedTimeslotTask::taskEntryPoint(void* arg) { // The argument is re-interpreted as PollingTask. FixedTimeslotTask* originalTask(reinterpret_cast(arg)); @@ -50,7 +52,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotT return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkSequence() const { return pst.checkSequence(); } +ReturnValue_t FixedTimeslotTask::checkSequence() { return pst.checkSequence(); } void FixedTimeslotTask::taskFunctionality() { // Like FreeRTOS pthreads are running as soon as they are created diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.h b/src/fsfw/osal/linux/FixedTimeslotTask.h index 76b92db3..a5dc9032 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.h +++ b/src/fsfw/osal/linux/FixedTimeslotTask.h @@ -24,15 +24,18 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread { FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); virtual ~FixedTimeslotTask(); - virtual ReturnValue_t startTask(); + ReturnValue_t startTask() override; - virtual ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; - virtual uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); + ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep) override; - virtual ReturnValue_t checkSequence() const; + ReturnValue_t checkSequence() override; + + bool isEmpty() const override; /** * This static function can be used as #deadlineMissedFunc. diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index e1937df4..26b6f53e 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -26,12 +26,12 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { return NULL; } -ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { +ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) { ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - return addComponent(newObject); + return addComponent(newObject, opCode); } -ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) { +ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object, uint8_t opCode) { if (object == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" @@ -43,7 +43,7 @@ ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object) { #endif return HasReturnvaluesIF::RETURN_FAILED; } - objectList.push_back(object); + objectList.emplace(object, opCode); object->setTaskIF(this); return HasReturnvaluesIF::RETURN_OK; @@ -54,6 +54,9 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { } ReturnValue_t PeriodicPosixTask::startTask(void) { + if (isEmpty()) { + return HasReturnvaluesIF::RETURN_FAILED; + } started = true; PosixThread::createTask(&taskEntryPoint, this); return HasReturnvaluesIF::RETURN_OK; @@ -64,15 +67,13 @@ void PeriodicPosixTask::taskFunctionality(void) { suspend(); } - for (auto const& object : objectList) { - object->initializeAfterTaskCreation(); - } + initObjsAfterTaskCreation(); uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); // The task's "infinite" inner loop is entered. while (1) { - for (auto const& object : objectList) { - object->performOperation(); + for (auto const& objOpCodePair : objectList) { + objOpCodePair.first->performOperation(objOpCodePair.second); } if (not PosixThread::delayUntil(&lastWakeTime, periodMs)) { @@ -84,3 +85,25 @@ void PeriodicPosixTask::taskFunctionality(void) { } uint32_t PeriodicPosixTask::getPeriodMs() const { return periodMs; } + +bool PeriodicPosixTask::isEmpty() const { return objectList.empty(); } + +ReturnValue_t PeriodicPosixTask::initObjsAfterTaskCreation() { + std::multiset uniqueObjects; + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + uint32_t count = 0; + for (const auto& obj : objectList) { + // Ensure that each unique object is initialized once. + if (uniqueObjects.find(obj.first) == uniqueObjects.end()) { + ReturnValue_t result = obj.first->initializeAfterTaskCreation(); + if (result != HasReturnvaluesIF::RETURN_OK) { + count++; + status = result; + } + uniqueObjects.emplace(obj.first); + } + } + if (count > 0) { + } + return status; +} diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 3cd9847a..1142c854 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include +#include #include "../../objectmanager/ObjectManagerIF.h" #include "../../tasks/ExecutableObjectIF.h" @@ -40,7 +40,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * @param object Id of the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(object_id_t object) override; + ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; /** * Adds an object to the list of objects to be executed. @@ -48,14 +48,20 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * @param object pointer to the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(ExecutableObjectIF* object) override; + ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; + ReturnValue_t initObjsAfterTaskCreation(); + + bool isEmpty() const override; + private: - typedef std::vector ObjectList; //!< Typedef for the List of objects. + //! Typedef for the List of objects. Will contain the objects to execute and their respective + //! op codes + using ObjectList = std::multiset>; /** * @brief This attribute holds a list of objects to be executed. */ diff --git a/src/fsfw/tasks/FixedSlotSequence.cpp b/src/fsfw/tasks/FixedSlotSequence.cpp index d4c67b4d..62c0e99c 100644 --- a/src/fsfw/tasks/FixedSlotSequence.cpp +++ b/src/fsfw/tasks/FixedSlotSequence.cpp @@ -164,3 +164,5 @@ ReturnValue_t FixedSlotSequence::intializeSequenceAfterTaskCreation() const { void FixedSlotSequence::addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList&)) { this->customCheckFunction = customCheckFunction; } + +bool FixedSlotSequence::isEmpty() const { return slotList.empty(); } diff --git a/src/fsfw/tasks/FixedSlotSequence.h b/src/fsfw/tasks/FixedSlotSequence.h index a287c5b2..5ece7126 100644 --- a/src/fsfw/tasks/FixedSlotSequence.h +++ b/src/fsfw/tasks/FixedSlotSequence.h @@ -159,6 +159,8 @@ class FixedSlotSequence { */ ReturnValue_t intializeSequenceAfterTaskCreation() const; + bool isEmpty() const; + protected: /** * @brief This list contains all PollingSlot objects, defining order and diff --git a/src/fsfw/tasks/FixedTimeslotTaskIF.h b/src/fsfw/tasks/FixedTimeslotTaskIF.h index 497db245..9d85ac4a 100644 --- a/src/fsfw/tasks/FixedTimeslotTaskIF.h +++ b/src/fsfw/tasks/FixedTimeslotTaskIF.h @@ -30,7 +30,7 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF { * Check whether the sequence is valid and perform all other required * initialization steps which are needed after task creation */ - virtual ReturnValue_t checkSequence() const = 0; + virtual ReturnValue_t checkSequence() = 0; }; #endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */ diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h index c78a32de..2ae268fc 100644 --- a/src/fsfw/tasks/PeriodicTaskIF.h +++ b/src/fsfw/tasks/PeriodicTaskIF.h @@ -31,7 +31,7 @@ class PeriodicTaskIF { * Add an object to the task. The object needs to implement ExecutableObjectIF * @return */ - virtual ReturnValue_t addComponent(object_id_t object) { + virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; }; @@ -41,13 +41,15 @@ class PeriodicTaskIF { * Add an object to the task. * @return */ - virtual ReturnValue_t addComponent(ExecutableObjectIF* object) { + virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; }; virtual ReturnValue_t sleepFor(uint32_t ms) = 0; virtual uint32_t getPeriodMs() const = 0; + + virtual bool isEmpty() const = 0; }; #endif /* PERIODICTASKIF_H_ */ diff --git a/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp index d8523558..941055ac 100644 --- a/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp +++ b/tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp @@ -67,7 +67,5 @@ TEST_CASE("Power Switcher", "[power-switcher]") { REQUIRE(not switcherUsingDummy.active()); } - SECTION("More Dummy Tests") { - - } + SECTION("More Dummy Tests") {} } From bcd19045cc9f19d9fd0b61f991cb334c6315832a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 14 May 2022 11:33:43 +0200 Subject: [PATCH 161/198] refactored SPI mutex handling --- .../fsfw_hal/linux/spi/ManualCsLockGuard.h | 42 ++++++++++++++ hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 51 +++++++++-------- hal/src/fsfw_hal/linux/spi/SpiComIF.h | 8 +-- hal/src/fsfw_hal/linux/spi/SpiCookie.cpp | 14 +++++ hal/src/fsfw_hal/linux/spi/SpiCookie.h | 55 +++++++++++++------ 5 files changed, 123 insertions(+), 47 deletions(-) create mode 100644 hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h diff --git a/hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h b/hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h new file mode 100644 index 00000000..99131393 --- /dev/null +++ b/hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h @@ -0,0 +1,42 @@ +#pragma once + +#include "fsfw/ipc/MutexIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw_hal/common/gpio/GpioIF.h" + +class ManualCsLockWrapper : public HasReturnvaluesIF { + public: + ManualCsLockWrapper(MutexIF* lock, GpioIF* gpioIF, SpiCookie* cookie, + MutexIF::TimeoutType type = MutexIF::TimeoutType::BLOCKING, + uint32_t timeoutMs = 0) + : lock(lock), gpioIF(gpioIF), cookie(cookie), type(type), timeoutMs(timeoutMs) { + if (cookie == nullptr) { + // TODO: Error? Or maybe throw exception.. + return; + } + cookie->setCsLockManual(true); + lockResult = lock->lockMutex(type, timeoutMs); + if (lockResult != RETURN_OK) { + return; + } + gpioResult = gpioIF->pullLow(cookie->getChipSelectPin()); + } + + ~ManualCsLockWrapper() { + if (lockResult == RETURN_OK) { + lock->unlockMutex(); + } + if (gpioResult == RETURN_OK) { + gpioIF->pullHigh(cookie->getChipSelectPin()); + } + } + ReturnValue_t lockResult; + ReturnValue_t gpioResult; + + private: + MutexIF* lock; + GpioIF* gpioIF; + SpiCookie* cookie; + MutexIF::TimeoutType type; + uint32_t timeoutMs = 0; +}; diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index b4ed47f2..c370ee37 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -194,16 +194,22 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const bool fullDuplex = spiCookie->isFullDuplex(); gpioId_t gpioId = spiCookie->getChipSelectPin(); + bool csLockManual = spiCookie->getCsLockManual(); - /* Pull SPI CS low. For now, no support for active high given */ - if (gpioId != gpio::NO_GPIO) { - result = csMutex->lockMutex(timeoutType, timeoutMs); + MutexIF::TimeoutType csType; + dur_millis_t csTimeout = 0; + // Pull SPI CS low. For now, no support for active high given + if (gpioId != gpio::NO_GPIO and not csLockManual) { + spiCookie->getMutexParams(csType, csTimeout); + result = csMutex->lockMutex(csType, csTimeout); if (result != RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl; + sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code " + << "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec + << std::endl; #else - sif::printError("SpiComIF::sendMessage: Failed to lock mutex\n"); + sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result); #endif #endif return result; @@ -249,7 +255,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const } } - if (gpioId != gpio::NO_GPIO) { + if (gpioId != gpio::NO_GPIO and not csLockManual) { gpioComIF->pullHigh(gpioId); result = csMutex->unlockMutex(); if (result != RETURN_OK) { @@ -292,12 +298,22 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) { return result; } + bool csLockManual = spiCookie->getCsLockManual(); gpioId_t gpioId = spiCookie->getChipSelectPin(); - if (gpioId != gpio::NO_GPIO) { - result = csMutex->lockMutex(timeoutType, timeoutMs); + MutexIF::TimeoutType csType; + dur_millis_t csTimeout = 0; + if (gpioId != gpio::NO_GPIO and not csLockManual) { + spiCookie->getMutexParams(csType, csTimeout); + result = csMutex->lockMutex(csType, csTimeout); if (result != RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "SpiComIF::getSendSuccess: Failed to lock mutex" << std::endl; + sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code " + << "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec + << std::endl; +#else + sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result); +#endif #endif return result; } @@ -315,7 +331,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) { result = HALF_DUPLEX_TRANSFER_FAILED; } - if (gpioId != gpio::NO_GPIO) { + if (gpioId != gpio::NO_GPIO and not csLockManual) { gpioComIF->pullHigh(gpioId); result = csMutex->unlockMutex(); if (result != RETURN_OK) { @@ -346,15 +362,7 @@ ReturnValue_t SpiComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, return HasReturnvaluesIF::RETURN_OK; } -MutexIF* SpiComIF::getMutex(MutexIF::TimeoutType* timeoutType, uint32_t* timeoutMs) { - if (timeoutType != nullptr) { - *timeoutType = this->timeoutType; - } - if (timeoutMs != nullptr) { - *timeoutMs = this->timeoutMs; - } - return csMutex; -} +MutexIF* SpiComIF::getCsMutex() { return csMutex; } void SpiComIF::performSpiWiretapping(SpiCookie* spiCookie) { if (spiCookie == nullptr) { @@ -426,8 +434,3 @@ void SpiComIF::updateLinePolarity(int spiFd) { utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed"); } } - -void SpiComIF::setMutexParams(MutexIF::TimeoutType timeoutType_, uint32_t timeoutMs_) { - timeoutType = timeoutType_; - timeoutMs = timeoutMs_; -} diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index 113b42b0..52673457 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -22,8 +22,6 @@ class SpiCookie; */ class SpiComIF : public DeviceCommunicationIF, public SystemObject { public: - static constexpr dur_millis_t DEFAULT_MUTEX_TIMEOUT = 20; - static constexpr uint8_t CLASS_ID = CLASS_ID::HAL_SPI; static constexpr ReturnValue_t OPENING_FILE_FAILED = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0); @@ -46,7 +44,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { * @brief This function returns the mutex which can be used to protect the spi bus when * the chip select must be driven from outside of the com if. */ - MutexIF* getMutex(MutexIF::TimeoutType* timeoutType = nullptr, uint32_t* timeoutMs = nullptr); + MutexIF* getCsMutex(); void setMutexParams(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs); /** @@ -93,8 +91,8 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { * pulled high */ MutexIF* csMutex = nullptr; - MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; - uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT; + // MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + // uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT; spi_ioc_transfer clockUpdateTransfer = {}; using SpiDeviceMap = std::unordered_map; diff --git a/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp b/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp index 85f96f28..e61703e6 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp @@ -104,3 +104,17 @@ void SpiCookie::getCallback(spi::send_callback_function_t* callback, void** args *callback = this->sendCallback; *args = this->callbackArgs; } + +void SpiCookie::setCsLockManual(bool enable) { manualCsLock = enable; } + +bool SpiCookie::getCsLockManual() const { return manualCsLock; } + +void SpiCookie::getMutexParams(MutexIF::TimeoutType& csTimeoutType, dur_millis_t& csTimeout) const { + csTimeoutType = this->csTimeoutType; + csTimeout = this->csTimeout; +} + +void SpiCookie::setMutexParams(MutexIF::TimeoutType csTimeoutType, dur_millis_t csTimeout) { + this->csTimeoutType = csTimeoutType; + this->csTimeout = csTimeout; +} diff --git a/hal/src/fsfw_hal/linux/spi/SpiCookie.h b/hal/src/fsfw_hal/linux/spi/SpiCookie.h index d6d4078f..2104e2eb 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiCookie.h +++ b/hal/src/fsfw_hal/linux/spi/SpiCookie.h @@ -2,6 +2,8 @@ #define LINUX_SPI_SPICOOKIE_H_ #include +#include +#include #include #include "../../common/gpio/gpioDefinitions.h" @@ -20,6 +22,8 @@ */ class SpiCookie : public CookieIF { public: + static constexpr dur_millis_t DEFAULT_MUTEX_TIMEOUT = 20; + /** * Each SPI device will have a corresponding cookie. The cookie is used by the communication * interface and contains device specific information like the largest expected size to be @@ -137,9 +141,42 @@ class SpiCookie : public CookieIF { */ void activateCsDeselect(bool deselectCs, uint16_t delayUsecs); + void getMutexParams(MutexIF::TimeoutType& csTimeoutType, dur_millis_t& csTimeout) const; + void setMutexParams(MutexIF::TimeoutType csTimeoutType, dur_millis_t csTimeout); + + void setCsLockManual(bool enable); + bool getCsLockManual() const; + spi_ioc_transfer* getTransferStructHandle(); private: + address_t spiAddress; + gpioId_t chipSelectPin; + + spi::SpiComIfModes comIfMode; + + // Required for regular mode + const size_t maxSize; + spi::SpiModes spiMode; + /** + * If this is set to true, the SPI ComIF will not perform any mutex locking for the + * CS mechanism. The user is responsible to locking and unlocking the mutex for the + * whole duration of the transfers. + */ + bool manualCsLock = false; + uint32_t spiSpeed; + bool halfDuplex = false; + + MutexIF::TimeoutType csTimeoutType = MutexIF::TimeoutType::WAITING; + dur_millis_t csTimeout = DEFAULT_MUTEX_TIMEOUT; + + // Required for callback mode + spi::send_callback_function_t sendCallback = nullptr; + void* callbackArgs = nullptr; + + struct spi_ioc_transfer spiTransferStruct = {}; + UncommonParameters uncommonParameters; + /** * Internal constructor which initializes every field * @param spiAddress @@ -154,24 +191,6 @@ class SpiCookie : public CookieIF { SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed, spi::send_callback_function_t callback, void* args); - - address_t spiAddress; - gpioId_t chipSelectPin; - - spi::SpiComIfModes comIfMode; - - // Required for regular mode - const size_t maxSize; - spi::SpiModes spiMode; - uint32_t spiSpeed; - bool halfDuplex = false; - - // Required for callback mode - spi::send_callback_function_t sendCallback = nullptr; - void* callbackArgs = nullptr; - - struct spi_ioc_transfer spiTransferStruct = {}; - UncommonParameters uncommonParameters; }; #endif /* LINUX_SPI_SPICOOKIE_H_ */ From 55ed7ab93e816ea083a961018a9383dc6c8ff33f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 14 May 2022 16:58:28 +0200 Subject: [PATCH 162/198] important fix --- hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h b/hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h index 99131393..b282bcc0 100644 --- a/hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h +++ b/hal/src/fsfw_hal/linux/spi/ManualCsLockGuard.h @@ -23,12 +23,13 @@ class ManualCsLockWrapper : public HasReturnvaluesIF { } ~ManualCsLockWrapper() { - if (lockResult == RETURN_OK) { - lock->unlockMutex(); - } if (gpioResult == RETURN_OK) { gpioIF->pullHigh(cookie->getChipSelectPin()); } + cookie->setCsLockManual(false); + if (lockResult == RETURN_OK) { + lock->unlockMutex(); + } } ReturnValue_t lockResult; ReturnValue_t gpioResult; From 1e7032f89c0de428162826dff621e2f343a658f9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 May 2022 14:54:43 +0200 Subject: [PATCH 163/198] minor improvements for auto-formatter --- scripts/auto-formatter.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/auto-formatter.sh b/scripts/auto-formatter.sh index 7b67ee9d..405d1268 100755 --- a/scripts/auto-formatter.sh +++ b/scripts/auto-formatter.sh @@ -4,9 +4,10 @@ if [[ ! -f README.md ]]; then fi cmake_fmt="cmake-format" +file_selectors="-iname CMakeLists.txt" if command -v ${cmake_fmt} &> /dev/null; then - cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" - eval ${cmake_fmt_cmd} + ${cmake_fmt} -i CMakeLists.txt + find ./src ${file_selectors} | xargs ${cmake_fmt} -i else echo "No ${cmake_fmt} tool found, not formatting CMake files" fi @@ -14,9 +15,9 @@ fi cpp_format="clang-format" file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" if command -v ${cpp_format} &> /dev/null; then - find ./src ${file_selectors} | xargs clang-format --style=file -i - find ./hal ${file_selectors} | xargs clang-format --style=file -i - find ./tests ${file_selectors} | xargs clang-format --style=file -i + find ./src ${file_selectors} | xargs ${cpp_format} --style=file -i + find ./hal ${file_selectors} | xargs ${cpp_format} --style=file -i + find ./tests ${file_selectors} | xargs ${cpp_format} --style=file -i else echo "No ${cpp_format} tool found, not formatting C++/C files" fi From 7fee852dbd962849286bee9dc782ce7a6bedd37d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 May 2022 14:55:15 +0200 Subject: [PATCH 164/198] re-apply updated auto-formatter --- src/CMakeLists.txt | 9 +-- src/fsfw/CMakeLists.txt | 16 +++-- src/fsfw/action/CMakeLists.txt | 10 +-- src/fsfw/cfdp/CMakeLists.txt | 5 +- src/fsfw/cfdp/pdu/CMakeLists.txt | 62 +++++++++---------- src/fsfw/cfdp/tlv/CMakeLists.txt | 20 +++--- src/fsfw/container/CMakeLists.txt | 7 +-- src/fsfw/controller/CMakeLists.txt | 6 +- src/fsfw/coordinates/CMakeLists.txt | 7 +-- src/fsfw/datalinklayer/CMakeLists.txt | 23 ++++--- src/fsfw/datapool/CMakeLists.txt | 5 +- src/fsfw/datapoollocal/CMakeLists.txt | 14 ++--- .../datapoollocal/internal/CMakeLists.txt | 7 +-- src/fsfw/devicehandlers/CMakeLists.txt | 21 +++---- src/fsfw/events/CMakeLists.txt | 5 +- src/fsfw/events/eventmatching/CMakeLists.txt | 10 +-- src/fsfw/fdir/CMakeLists.txt | 9 +-- src/fsfw/globalfunctions/CMakeLists.txt | 21 +++---- src/fsfw/globalfunctions/math/CMakeLists.txt | 5 +- src/fsfw/health/CMakeLists.txt | 8 +-- src/fsfw/housekeeping/CMakeLists.txt | 7 +-- src/fsfw/internalerror/CMakeLists.txt | 5 +- src/fsfw/ipc/CMakeLists.txt | 9 +-- src/fsfw/memory/CMakeLists.txt | 7 +-- src/fsfw/modes/CMakeLists.txt | 6 +- src/fsfw/monitoring/CMakeLists.txt | 7 +-- src/fsfw/objectmanager/CMakeLists.txt | 6 +- src/fsfw/osal/CMakeLists.txt | 46 +++++++------- src/fsfw/osal/common/CMakeLists.txt | 19 ++---- src/fsfw/osal/freertos/CMakeLists.txt | 52 ++++++++-------- src/fsfw/osal/host/CMakeLists.txt | 36 +++++------ src/fsfw/osal/linux/CMakeLists.txt | 42 ++++++------- src/fsfw/osal/rtems/CMakeLists.txt | 37 +++++------ src/fsfw/osal/windows/CMakeLists.txt | 5 +- src/fsfw/parameters/CMakeLists.txt | 9 +-- src/fsfw/power/CMakeLists.txt | 12 ++-- src/fsfw/power/PowerSwitcherComponent.cpp | 35 +++++------ src/fsfw/power/PowerSwitcherComponent.h | 26 ++++---- src/fsfw/pus/CMakeLists.txt | 24 +++---- src/fsfw/rmap/CMakeLists.txt | 9 +-- src/fsfw/serialize/CMakeLists.txt | 5 +- src/fsfw/serviceinterface/CMakeLists.txt | 9 ++- src/fsfw/storagemanager/CMakeLists.txt | 10 +-- src/fsfw/subsystem/CMakeLists.txt | 8 +-- src/fsfw/subsystem/modes/CMakeLists.txt | 6 +- src/fsfw/tasks/CMakeLists.txt | 7 +-- src/fsfw/tcdistribution/CMakeLists.txt | 13 ++-- src/fsfw/thermal/CMakeLists.txt | 19 +++--- src/fsfw/timemanager/CMakeLists.txt | 11 +--- src/fsfw/tmstorage/CMakeLists.txt | 5 +- src/fsfw/tmtcpacket/CMakeLists.txt | 7 +-- src/fsfw/tmtcpacket/cfdp/CMakeLists.txt | 5 +- .../tmtcpacket/packetmatcher/CMakeLists.txt | 5 +- src/fsfw/tmtcpacket/pus/tc/CMakeLists.txt | 9 +-- src/fsfw/tmtcpacket/pus/tm/CMakeLists.txt | 18 +++--- src/fsfw/tmtcservices/CMakeLists.txt | 19 +++--- 56 files changed, 332 insertions(+), 493 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed2f2522..34f21c2f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,6 @@ -target_include_directories(${LIB_FSFW_NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} -) +target_include_directories(${LIB_FSFW_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(${LIB_FSFW_NAME} INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR} -) +target_include_directories(${LIB_FSFW_NAME} + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(fsfw) diff --git a/src/fsfw/CMakeLists.txt b/src/fsfw/CMakeLists.txt index efb9f6c7..1daad714 100644 --- a/src/fsfw/CMakeLists.txt +++ b/src/fsfw/CMakeLists.txt @@ -1,6 +1,4 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - version.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE version.cpp) # Core @@ -37,22 +35,22 @@ add_subdirectory(tmtcservices) # Optional if(FSFW_ADD_MONITORING) -add_subdirectory(monitoring) + add_subdirectory(monitoring) endif() if(FSFW_ADD_PUS) - add_subdirectory(pus) + add_subdirectory(pus) endif() if(FSFW_ADD_TMSTORAGE) - add_subdirectory(tmstorage) + add_subdirectory(tmstorage) endif() if(FSFW_ADD_COORDINATES) - add_subdirectory(coordinates) + add_subdirectory(coordinates) endif() if(FSFW_ADD_RMAP) - add_subdirectory(rmap) + add_subdirectory(rmap) endif() if(FSFW_ADD_DATALINKLAYER) - add_subdirectory(datalinklayer) + add_subdirectory(datalinklayer) endif() # OSAL diff --git a/src/fsfw/action/CMakeLists.txt b/src/fsfw/action/CMakeLists.txt index f9ac451d..7fb397af 100644 --- a/src/fsfw/action/CMakeLists.txt +++ b/src/fsfw/action/CMakeLists.txt @@ -1,7 +1,3 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - ActionHelper.cpp - ActionMessage.cpp - CommandActionHelper.cpp - SimpleActionHelper.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} PRIVATE ActionHelper.cpp ActionMessage.cpp + CommandActionHelper.cpp SimpleActionHelper.cpp) diff --git a/src/fsfw/cfdp/CMakeLists.txt b/src/fsfw/cfdp/CMakeLists.txt index 908dc32a..0b926a9a 100644 --- a/src/fsfw/cfdp/CMakeLists.txt +++ b/src/fsfw/cfdp/CMakeLists.txt @@ -1,7 +1,4 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - CFDPHandler.cpp - CFDPMessage.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE CFDPHandler.cpp CFDPMessage.cpp) add_subdirectory(pdu) add_subdirectory(tlv) diff --git a/src/fsfw/cfdp/pdu/CMakeLists.txt b/src/fsfw/cfdp/pdu/CMakeLists.txt index 931db306..4f345bdc 100644 --- a/src/fsfw/cfdp/pdu/CMakeLists.txt +++ b/src/fsfw/cfdp/pdu/CMakeLists.txt @@ -1,32 +1,30 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - PduConfig.cpp - VarLenField.cpp - HeaderSerializer.cpp - HeaderDeserializer.cpp - FileDirectiveDeserializer.cpp - FileDirectiveSerializer.cpp - - AckInfo.cpp - AckPduSerializer.cpp - AckPduDeserializer.cpp - EofInfo.cpp - EofPduSerializer.cpp - EofPduDeserializer.cpp - NakInfo.cpp - NakPduSerializer.cpp - NakPduDeserializer.cpp - FinishedInfo.cpp - FinishedPduSerializer.cpp - FinishedPduDeserializer.cpp - MetadataInfo.cpp - MetadataPduSerializer.cpp - MetadataPduDeserializer.cpp - KeepAlivePduSerializer.cpp - KeepAlivePduDeserializer.cpp - PromptPduSerializer.cpp - PromptPduDeserializer.cpp - - FileDataSerializer.cpp - FileDataDeserializer.cpp - FileDataInfo.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE PduConfig.cpp + VarLenField.cpp + HeaderSerializer.cpp + HeaderDeserializer.cpp + FileDirectiveDeserializer.cpp + FileDirectiveSerializer.cpp + AckInfo.cpp + AckPduSerializer.cpp + AckPduDeserializer.cpp + EofInfo.cpp + EofPduSerializer.cpp + EofPduDeserializer.cpp + NakInfo.cpp + NakPduSerializer.cpp + NakPduDeserializer.cpp + FinishedInfo.cpp + FinishedPduSerializer.cpp + FinishedPduDeserializer.cpp + MetadataInfo.cpp + MetadataPduSerializer.cpp + MetadataPduDeserializer.cpp + KeepAlivePduSerializer.cpp + KeepAlivePduDeserializer.cpp + PromptPduSerializer.cpp + PromptPduDeserializer.cpp + FileDataSerializer.cpp + FileDataDeserializer.cpp + FileDataInfo.cpp) diff --git a/src/fsfw/cfdp/tlv/CMakeLists.txt b/src/fsfw/cfdp/tlv/CMakeLists.txt index 24459cf8..cdf7b44a 100644 --- a/src/fsfw/cfdp/tlv/CMakeLists.txt +++ b/src/fsfw/cfdp/tlv/CMakeLists.txt @@ -1,10 +1,10 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - EntityIdTlv.cpp - FilestoreRequestTlv.cpp - FilestoreResponseTlv.cpp - Lv.cpp - Tlv.cpp - FlowLabelTlv.cpp - MessageToUserTlv.cpp - FaultHandlerOverrideTlv.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE EntityIdTlv.cpp + FilestoreRequestTlv.cpp + FilestoreResponseTlv.cpp + Lv.cpp + Tlv.cpp + FlowLabelTlv.cpp + MessageToUserTlv.cpp + FaultHandlerOverrideTlv.cpp) diff --git a/src/fsfw/container/CMakeLists.txt b/src/fsfw/container/CMakeLists.txt index 13eced1d..52087ff0 100644 --- a/src/fsfw/container/CMakeLists.txt +++ b/src/fsfw/container/CMakeLists.txt @@ -1,5 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - SharedRingBuffer.cpp - SimpleRingBuffer.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE SharedRingBuffer.cpp + SimpleRingBuffer.cpp) diff --git a/src/fsfw/controller/CMakeLists.txt b/src/fsfw/controller/CMakeLists.txt index 550acfcd..c8c000d8 100644 --- a/src/fsfw/controller/CMakeLists.txt +++ b/src/fsfw/controller/CMakeLists.txt @@ -1,4 +1,2 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - ControllerBase.cpp - ExtendedControllerBase.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE ControllerBase.cpp + ExtendedControllerBase.cpp) diff --git a/src/fsfw/coordinates/CMakeLists.txt b/src/fsfw/coordinates/CMakeLists.txt index a1fa1e52..15452b1c 100644 --- a/src/fsfw/coordinates/CMakeLists.txt +++ b/src/fsfw/coordinates/CMakeLists.txt @@ -1,5 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - CoordinateTransformations.cpp - Sgp4Propagator.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE CoordinateTransformations.cpp + Sgp4Propagator.cpp) diff --git a/src/fsfw/datalinklayer/CMakeLists.txt b/src/fsfw/datalinklayer/CMakeLists.txt index 148e7c5d..cc18088f 100644 --- a/src/fsfw/datalinklayer/CMakeLists.txt +++ b/src/fsfw/datalinklayer/CMakeLists.txt @@ -1,12 +1,11 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - Clcw.cpp - DataLinkLayer.cpp - Farm1StateLockout.cpp - Farm1StateOpen.cpp - Farm1StateWait.cpp - MapPacketExtraction.cpp - TcTransferFrame.cpp - TcTransferFrameLocal.cpp - VirtualChannelReception.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE Clcw.cpp + DataLinkLayer.cpp + Farm1StateLockout.cpp + Farm1StateOpen.cpp + Farm1StateWait.cpp + MapPacketExtraction.cpp + TcTransferFrame.cpp + TcTransferFrameLocal.cpp + VirtualChannelReception.cpp) diff --git a/src/fsfw/datapool/CMakeLists.txt b/src/fsfw/datapool/CMakeLists.txt index be4606aa..b2ac592c 100644 --- a/src/fsfw/datapool/CMakeLists.txt +++ b/src/fsfw/datapool/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - PoolDataSetBase.cpp - PoolEntry.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE PoolDataSetBase.cpp PoolEntry.cpp) diff --git a/src/fsfw/datapoollocal/CMakeLists.txt b/src/fsfw/datapoollocal/CMakeLists.txt index e2db39eb..749ef688 100644 --- a/src/fsfw/datapoollocal/CMakeLists.txt +++ b/src/fsfw/datapoollocal/CMakeLists.txt @@ -1,10 +1,6 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - LocalDataPoolManager.cpp - LocalDataSet.cpp - LocalPoolDataSetBase.cpp - LocalPoolObjectBase.cpp - SharedLocalDataSet.cpp -) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE LocalDataPoolManager.cpp LocalDataSet.cpp LocalPoolDataSetBase.cpp + LocalPoolObjectBase.cpp SharedLocalDataSet.cpp) -add_subdirectory(internal) \ No newline at end of file +add_subdirectory(internal) diff --git a/src/fsfw/datapoollocal/internal/CMakeLists.txt b/src/fsfw/datapoollocal/internal/CMakeLists.txt index 554f3b88..6585d06e 100644 --- a/src/fsfw/datapoollocal/internal/CMakeLists.txt +++ b/src/fsfw/datapoollocal/internal/CMakeLists.txt @@ -1,5 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - HasLocalDpIFUserAttorney.cpp - HasLocalDpIFManagerAttorney.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE HasLocalDpIFUserAttorney.cpp + HasLocalDpIFManagerAttorney.cpp) diff --git a/src/fsfw/devicehandlers/CMakeLists.txt b/src/fsfw/devicehandlers/CMakeLists.txt index 50c1008f..180a89da 100644 --- a/src/fsfw/devicehandlers/CMakeLists.txt +++ b/src/fsfw/devicehandlers/CMakeLists.txt @@ -1,11 +1,10 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - AssemblyBase.cpp - ChildHandlerBase.cpp - ChildHandlerFDIR.cpp - DeviceHandlerBase.cpp - DeviceHandlerFailureIsolation.cpp - DeviceHandlerMessage.cpp - DeviceTmReportingWrapper.cpp - HealthDevice.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE AssemblyBase.cpp + ChildHandlerBase.cpp + ChildHandlerFDIR.cpp + DeviceHandlerBase.cpp + DeviceHandlerFailureIsolation.cpp + DeviceHandlerMessage.cpp + DeviceTmReportingWrapper.cpp + HealthDevice.cpp) diff --git a/src/fsfw/events/CMakeLists.txt b/src/fsfw/events/CMakeLists.txt index 28eec772..704cca85 100644 --- a/src/fsfw/events/CMakeLists.txt +++ b/src/fsfw/events/CMakeLists.txt @@ -1,6 +1,3 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - EventManager.cpp - EventMessage.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE EventManager.cpp EventMessage.cpp) add_subdirectory(eventmatching) diff --git a/src/fsfw/events/eventmatching/CMakeLists.txt b/src/fsfw/events/eventmatching/CMakeLists.txt index 81ff9ed8..a9f9c7b3 100644 --- a/src/fsfw/events/eventmatching/CMakeLists.txt +++ b/src/fsfw/events/eventmatching/CMakeLists.txt @@ -1,7 +1,3 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - EventIdRangeMatcher.cpp - EventMatchTree.cpp - ReporterRangeMatcher.cpp - SeverityRangeMatcher.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} PRIVATE EventIdRangeMatcher.cpp EventMatchTree.cpp + ReporterRangeMatcher.cpp SeverityRangeMatcher.cpp) diff --git a/src/fsfw/fdir/CMakeLists.txt b/src/fsfw/fdir/CMakeLists.txt index f5ffbba8..d41ee2eb 100644 --- a/src/fsfw/fdir/CMakeLists.txt +++ b/src/fsfw/fdir/CMakeLists.txt @@ -1,6 +1,3 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - EventCorrelation.cpp - FailureIsolationBase.cpp - FaultCounter.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} PRIVATE EventCorrelation.cpp FailureIsolationBase.cpp + FaultCounter.cpp) diff --git a/src/fsfw/globalfunctions/CMakeLists.txt b/src/fsfw/globalfunctions/CMakeLists.txt index 5ccd3c4c..cfa02696 100644 --- a/src/fsfw/globalfunctions/CMakeLists.txt +++ b/src/fsfw/globalfunctions/CMakeLists.txt @@ -1,13 +1,12 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - arrayprinter.cpp - AsciiConverter.cpp - CRC.cpp - DleEncoder.cpp - PeriodicOperationDivider.cpp - timevalOperations.cpp - Type.cpp - bitutility.cpp -) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE arrayprinter.cpp + AsciiConverter.cpp + CRC.cpp + DleEncoder.cpp + PeriodicOperationDivider.cpp + timevalOperations.cpp + Type.cpp + bitutility.cpp) add_subdirectory(math) diff --git a/src/fsfw/globalfunctions/math/CMakeLists.txt b/src/fsfw/globalfunctions/math/CMakeLists.txt index a9c4ded7..1eeb69b5 100644 --- a/src/fsfw/globalfunctions/math/CMakeLists.txt +++ b/src/fsfw/globalfunctions/math/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - QuaternionOperations.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE QuaternionOperations.cpp) diff --git a/src/fsfw/health/CMakeLists.txt b/src/fsfw/health/CMakeLists.txt index d5f3ccd3..37e4ce48 100644 --- a/src/fsfw/health/CMakeLists.txt +++ b/src/fsfw/health/CMakeLists.txt @@ -1,6 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - HealthHelper.cpp - HealthMessage.cpp - HealthTable.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE HealthHelper.cpp HealthMessage.cpp + HealthTable.cpp) diff --git a/src/fsfw/housekeeping/CMakeLists.txt b/src/fsfw/housekeeping/CMakeLists.txt index fecad2e3..236d3204 100644 --- a/src/fsfw/housekeeping/CMakeLists.txt +++ b/src/fsfw/housekeeping/CMakeLists.txt @@ -1,5 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - HousekeepingMessage.cpp - PeriodicHousekeepingHelper.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE HousekeepingMessage.cpp + PeriodicHousekeepingHelper.cpp) diff --git a/src/fsfw/internalerror/CMakeLists.txt b/src/fsfw/internalerror/CMakeLists.txt index 2b383914..87d3c3f7 100644 --- a/src/fsfw/internalerror/CMakeLists.txt +++ b/src/fsfw/internalerror/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - InternalErrorReporter.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE InternalErrorReporter.cpp) diff --git a/src/fsfw/ipc/CMakeLists.txt b/src/fsfw/ipc/CMakeLists.txt index 3bfe510d..92b91f35 100644 --- a/src/fsfw/ipc/CMakeLists.txt +++ b/src/fsfw/ipc/CMakeLists.txt @@ -1,6 +1,3 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - CommandMessage.cpp - CommandMessageCleaner.cpp - MessageQueueMessage.cpp - MessageQueueBase.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} PRIVATE CommandMessage.cpp CommandMessageCleaner.cpp + MessageQueueMessage.cpp MessageQueueBase.cpp) diff --git a/src/fsfw/memory/CMakeLists.txt b/src/fsfw/memory/CMakeLists.txt index c713cd42..9e591bae 100644 --- a/src/fsfw/memory/CMakeLists.txt +++ b/src/fsfw/memory/CMakeLists.txt @@ -1,5 +1,2 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - MemoryHelper.cpp - MemoryMessage.cpp - GenericFileSystemMessage.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE MemoryHelper.cpp MemoryMessage.cpp + GenericFileSystemMessage.cpp) diff --git a/src/fsfw/modes/CMakeLists.txt b/src/fsfw/modes/CMakeLists.txt index 8e5c719b..4eef58e0 100644 --- a/src/fsfw/modes/CMakeLists.txt +++ b/src/fsfw/modes/CMakeLists.txt @@ -1,5 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - ModeHelper.cpp - ModeMessage.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE ModeHelper.cpp ModeMessage.cpp) diff --git a/src/fsfw/monitoring/CMakeLists.txt b/src/fsfw/monitoring/CMakeLists.txt index d26e807c..48f945b5 100644 --- a/src/fsfw/monitoring/CMakeLists.txt +++ b/src/fsfw/monitoring/CMakeLists.txt @@ -1,5 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - LimitViolationReporter.cpp - MonitoringMessage.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE LimitViolationReporter.cpp + MonitoringMessage.cpp) diff --git a/src/fsfw/objectmanager/CMakeLists.txt b/src/fsfw/objectmanager/CMakeLists.txt index 72aaec89..c71f43aa 100644 --- a/src/fsfw/objectmanager/CMakeLists.txt +++ b/src/fsfw/objectmanager/CMakeLists.txt @@ -1,5 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - ObjectManager.cpp - SystemObject.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE ObjectManager.cpp SystemObject.cpp) diff --git a/src/fsfw/osal/CMakeLists.txt b/src/fsfw/osal/CMakeLists.txt index f3c5cfad..50fd6102 100644 --- a/src/fsfw/osal/CMakeLists.txt +++ b/src/fsfw/osal/CMakeLists.txt @@ -1,35 +1,33 @@ # Check the OS_FSFW variable if(FSFW_OSAL MATCHES "freertos") - add_subdirectory(freertos) + add_subdirectory(freertos) elseif(FSFW_OSAL MATCHES "rtems") - add_subdirectory(rtems) + add_subdirectory(rtems) elseif(FSFW_OSAL MATCHES "linux") - add_subdirectory(linux) + add_subdirectory(linux) elseif(FSFW_OSAL MATCHES "host") - add_subdirectory(host) - if (WIN32) - add_subdirectory(windows) - elseif(UNIX) - # We still need to pull in some Linux specific sources - target_sources(${LIB_FSFW_NAME} PUBLIC - linux/tcpipHelpers.cpp - ) - endif () + add_subdirectory(host) + if(WIN32) + add_subdirectory(windows) + elseif(UNIX) + # We still need to pull in some Linux specific sources + target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp) + endif() else() - message(WARNING "The OS_FSFW variable was not set. Assuming host OS..") - # Not set. Assumuing this is a host build, try to determine host OS - if (WIN32) - add_subdirectory(host) - add_subdirectory(windows) - elseif (UNIX) - add_subdirectory(linux) - else () - # MacOS or other OSes have not been tested yet / are not supported. - message(FATAL_ERROR "The host OS could not be determined! Aborting.") - endif() + message(WARNING "The OS_FSFW variable was not set. Assuming host OS..") + # Not set. Assumuing this is a host build, try to determine host OS + if(WIN32) + add_subdirectory(host) + add_subdirectory(windows) + elseif(UNIX) + add_subdirectory(linux) + else() + # MacOS or other OSes have not been tested yet / are not supported. + message(FATAL_ERROR "The host OS could not be determined! Aborting.") + endif() endif() -add_subdirectory(common) \ No newline at end of file +add_subdirectory(common) diff --git a/src/fsfw/osal/common/CMakeLists.txt b/src/fsfw/osal/common/CMakeLists.txt index b7c8c033..c0814172 100644 --- a/src/fsfw/osal/common/CMakeLists.txt +++ b/src/fsfw/osal/common/CMakeLists.txt @@ -1,17 +1,10 @@ if(DEFINED WIN32 OR DEFINED UNIX) - target_sources(${LIB_FSFW_NAME} PRIVATE - tcpipCommon.cpp - TcpIpBase.cpp - UdpTcPollingTask.cpp - UdpTmTcBridge.cpp - TcpTmTcServer.cpp - TcpTmTcBridge.cpp - ) + target_sources( + ${LIB_FSFW_NAME} + PRIVATE tcpipCommon.cpp TcpIpBase.cpp UdpTcPollingTask.cpp + UdpTmTcBridge.cpp TcpTmTcServer.cpp TcpTmTcBridge.cpp) endif() if(WIN32) - target_link_libraries(${LIB_FSFW_NAME} PRIVATE - wsock32 - ws2_32 - ) -endif() \ No newline at end of file + target_link_libraries(${LIB_FSFW_NAME} PRIVATE wsock32 ws2_32) +endif() diff --git a/src/fsfw/osal/freertos/CMakeLists.txt b/src/fsfw/osal/freertos/CMakeLists.txt index 40bdcd0f..cb6ac55a 100644 --- a/src/fsfw/osal/freertos/CMakeLists.txt +++ b/src/fsfw/osal/freertos/CMakeLists.txt @@ -1,32 +1,30 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - Clock.cpp - FixedTimeslotTask.cpp - BinarySemaphore.cpp - BinSemaphUsingTask.cpp - CountingSemaphore.cpp - CountingSemaphUsingTask.cpp - MessageQueue.cpp - Mutex.cpp - MutexFactory.cpp - PeriodicTask.cpp - QueueFactory.cpp - SemaphoreFactory.cpp - TaskFactory.cpp - Timekeeper.cpp - TaskManagement.cpp - QueueMapManager.cpp -) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE Clock.cpp + FixedTimeslotTask.cpp + BinarySemaphore.cpp + BinSemaphUsingTask.cpp + CountingSemaphore.cpp + CountingSemaphUsingTask.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicTask.cpp + QueueFactory.cpp + SemaphoreFactory.cpp + TaskFactory.cpp + Timekeeper.cpp + TaskManagement.cpp + QueueMapManager.cpp) -# FreeRTOS is required to link the FSFW now. It is recommended to compile -# FreeRTOS as a static library and set LIB_OS_NAME to the target name of the +# FreeRTOS is required to link the FSFW now. It is recommended to compile +# FreeRTOS as a static library and set LIB_OS_NAME to the target name of the # library. if(NOT LIB_OS_NAME) - message(STATUS - "LIB_OS_NAME is empty. Make sure to include the FreeRTOS header path properly." - ) + message( + STATUS + "LIB_OS_NAME is empty. Make sure to include the FreeRTOS header path properly." + ) else() - target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${LIB_OS_NAME} - ) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${LIB_OS_NAME}) endif() diff --git a/src/fsfw/osal/host/CMakeLists.txt b/src/fsfw/osal/host/CMakeLists.txt index 8b11a531..95ab25c9 100644 --- a/src/fsfw/osal/host/CMakeLists.txt +++ b/src/fsfw/osal/host/CMakeLists.txt @@ -1,27 +1,23 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - Clock.cpp - FixedTimeslotTask.cpp - MessageQueue.cpp - Mutex.cpp - MutexFactory.cpp - PeriodicTask.cpp - QueueFactory.cpp - QueueMapManager.cpp - SemaphoreFactory.cpp - TaskFactory.cpp - taskHelpers.cpp -) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE Clock.cpp + FixedTimeslotTask.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicTask.cpp + QueueFactory.cpp + QueueMapManager.cpp + SemaphoreFactory.cpp + TaskFactory.cpp + taskHelpers.cpp) if(UNIX) find_package(Threads REQUIRED) - target_link_libraries(${LIB_FSFW_NAME} PRIVATE - ${CMAKE_THREAD_LIBS_INIT} - ) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${CMAKE_THREAD_LIBS_INIT}) if(NOT APPLE) - target_link_libraries(${LIB_FSFW_NAME} PRIVATE - rt - ) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE rt) endif() -endif() \ No newline at end of file +endif() diff --git a/src/fsfw/osal/linux/CMakeLists.txt b/src/fsfw/osal/linux/CMakeLists.txt index 2e88d6d0..72a62b86 100644 --- a/src/fsfw/osal/linux/CMakeLists.txt +++ b/src/fsfw/osal/linux/CMakeLists.txt @@ -1,29 +1,25 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - Clock.cpp - BinarySemaphore.cpp - CountingSemaphore.cpp - FixedTimeslotTask.cpp - InternalErrorCodes.cpp - MessageQueue.cpp - Mutex.cpp - MutexFactory.cpp - PeriodicPosixTask.cpp - PosixThread.cpp - QueueFactory.cpp - SemaphoreFactory.cpp - TaskFactory.cpp - tcpipHelpers.cpp - unixUtility.cpp - ) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE Clock.cpp + BinarySemaphore.cpp + CountingSemaphore.cpp + FixedTimeslotTask.cpp + InternalErrorCodes.cpp + MessageQueue.cpp + Mutex.cpp + MutexFactory.cpp + PeriodicPosixTask.cpp + PosixThread.cpp + QueueFactory.cpp + SemaphoreFactory.cpp + TaskFactory.cpp + tcpipHelpers.cpp + unixUtility.cpp) find_package(Threads REQUIRED) -target_link_libraries(${LIB_FSFW_NAME} PUBLIC - ${CMAKE_THREAD_LIBS_INIT} - ) +target_link_libraries(${LIB_FSFW_NAME} PUBLIC ${CMAKE_THREAD_LIBS_INIT}) if(NOT APPLE) - target_link_libraries(${LIB_FSFW_NAME} PUBLIC - rt - ) + target_link_libraries(${LIB_FSFW_NAME} PUBLIC rt) endif() diff --git a/src/fsfw/osal/rtems/CMakeLists.txt b/src/fsfw/osal/rtems/CMakeLists.txt index 734566a3..1b47e1b9 100644 --- a/src/fsfw/osal/rtems/CMakeLists.txt +++ b/src/fsfw/osal/rtems/CMakeLists.txt @@ -1,20 +1,17 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - Clock.cpp - CpuUsage.cpp - InitTask.cpp - InternalErrorCodes.cpp - MessageQueue.cpp - PeriodicTask.cpp - Mutex.cpp - MutexFactory.cpp - FixedTimeslotTask.cpp - QueueFactory.cpp - RtemsBasic.cpp - RTEMSTaskBase.cpp - TaskFactory.cpp - BinarySemaphore.cpp - SemaphoreFactory.cpp -) - - +target_sources( + ${LIB_FSFW_NAME} + PRIVATE Clock.cpp + CpuUsage.cpp + InitTask.cpp + InternalErrorCodes.cpp + MessageQueue.cpp + PeriodicTask.cpp + Mutex.cpp + MutexFactory.cpp + FixedTimeslotTask.cpp + QueueFactory.cpp + RtemsBasic.cpp + RTEMSTaskBase.cpp + TaskFactory.cpp + BinarySemaphore.cpp + SemaphoreFactory.cpp) diff --git a/src/fsfw/osal/windows/CMakeLists.txt b/src/fsfw/osal/windows/CMakeLists.txt index 36a54765..e961b25b 100644 --- a/src/fsfw/osal/windows/CMakeLists.txt +++ b/src/fsfw/osal/windows/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - tcpipHelpers.cpp - winTaskHelpers.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE tcpipHelpers.cpp winTaskHelpers.cpp) diff --git a/src/fsfw/parameters/CMakeLists.txt b/src/fsfw/parameters/CMakeLists.txt index fb5e4590..98a8085c 100644 --- a/src/fsfw/parameters/CMakeLists.txt +++ b/src/fsfw/parameters/CMakeLists.txt @@ -1,6 +1,3 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - ParameterHelper.cpp - ParameterMessage.cpp - ParameterWrapper.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} PRIVATE ParameterHelper.cpp ParameterMessage.cpp + ParameterWrapper.cpp) diff --git a/src/fsfw/power/CMakeLists.txt b/src/fsfw/power/CMakeLists.txt index e195b1c0..b4ab0006 100644 --- a/src/fsfw/power/CMakeLists.txt +++ b/src/fsfw/power/CMakeLists.txt @@ -1,8 +1,4 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - Fuse.cpp - PowerComponent.cpp - PowerSensor.cpp - PowerSwitcher.cpp - DummyPowerSwitcher.cpp - PowerSwitcherComponent.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE Fuse.cpp PowerComponent.cpp PowerSensor.cpp PowerSwitcher.cpp + DummyPowerSwitcher.cpp PowerSwitcherComponent.cpp) diff --git a/src/fsfw/power/PowerSwitcherComponent.cpp b/src/fsfw/power/PowerSwitcherComponent.cpp index 5dda02c3..9c1ed4cf 100644 --- a/src/fsfw/power/PowerSwitcherComponent.cpp +++ b/src/fsfw/power/PowerSwitcherComponent.cpp @@ -3,9 +3,12 @@ #include #include -PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t pwrSwitch) - : SystemObject(objectId), switcher(pwrSwitcher, pwrSwitch), modeHelper(this), - healthHelper(this, objectId) { +PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher, + power::Switch_t pwrSwitch) + : SystemObject(objectId), + switcher(pwrSwitcher, pwrSwitch), + modeHelper(this), + healthHelper(this, objectId) { queue = QueueFactory::instance()->createMessageQueue(); } @@ -25,12 +28,12 @@ ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) { continue; } } - if(switcher.active()) { + if (switcher.active()) { switcher.doStateMachine(); auto currState = switcher.getState(); if (currState == PowerSwitcher::SWITCH_IS_OFF) { setMode(MODE_OFF, 0); - } else if(currState == PowerSwitcher::SWITCH_IS_ON) { + } else if (currState == PowerSwitcher::SWITCH_IS_ON) { setMode(MODE_ON, 0); } } @@ -39,19 +42,17 @@ ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) { ReturnValue_t PowerSwitcherComponent::initialize() { ReturnValue_t result = modeHelper.initialize(); - if(result != HasReturnvaluesIF::RETURN_OK) { + if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = healthHelper.initialize(); - if(result != HasReturnvaluesIF::RETURN_OK) { + if (result != HasReturnvaluesIF::RETURN_OK) { return result; } return SystemObject::initialize(); } -MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { - return queue->getId(); -} +MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { return queue->getId(); } void PowerSwitcherComponent::getMode(Mode_t *mode, Submode_t *submode) { *mode = this->mode; @@ -64,25 +65,25 @@ ReturnValue_t PowerSwitcherComponent::setHealth(HealthState health) { } ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode) { + uint32_t *msToReachTheMode) { *msToReachTheMode = 5000; - if(mode != MODE_ON and mode != MODE_OFF) { + if (mode != MODE_ON and mode != MODE_OFF) { return TRANS_NOT_ALLOWED; } return RETURN_OK; } void PowerSwitcherComponent::startTransition(Mode_t mode, Submode_t submode) { - if(mode == MODE_OFF) { + if (mode == MODE_OFF) { switcher.turnOff(true); switcher.doStateMachine(); - if(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) { + if (switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) { setMode(MODE_OFF, 0); } } else if (mode == MODE_ON) { switcher.turnOn(true); switcher.doStateMachine(); - if(switcher.getState() == PowerSwitcher::SWITCH_IS_ON) { + if (switcher.getState() == PowerSwitcher::SWITCH_IS_ON) { setMode(MODE_ON, 0); } } @@ -103,6 +104,4 @@ void PowerSwitcherComponent::setMode(Mode_t newMode, Submode_t newSubmode) { announceMode(false); } -HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { - return healthHelper.getHealth(); -} +HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { return healthHelper.getHealth(); } diff --git a/src/fsfw/power/PowerSwitcherComponent.h b/src/fsfw/power/PowerSwitcherComponent.h index 3a075c12..a3ed640e 100644 --- a/src/fsfw/power/PowerSwitcherComponent.h +++ b/src/fsfw/power/PowerSwitcherComponent.h @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include class PowerSwitchIF; @@ -22,19 +22,17 @@ class PowerSwitchIF; * Commanding this component to MODE_OFF will cause the switcher to turn the switch off while * commanding in to MODE_ON will cause the switcher to turn the switch on. */ -class PowerSwitcherComponent: - public SystemObject, - public HasReturnvaluesIF, - public ExecutableObjectIF, - public HasModesIF, - public HasHealthIF { -public: - PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher, - power::Switch_t pwrSwitch); +class PowerSwitcherComponent : public SystemObject, + public HasReturnvaluesIF, + public ExecutableObjectIF, + public HasModesIF, + public HasHealthIF { + public: + PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher, + power::Switch_t pwrSwitch); -private: - - MessageQueueIF* queue = nullptr; + private: + MessageQueueIF *queue = nullptr; PowerSwitcher switcher; Mode_t mode = MODE_OFF; @@ -52,7 +50,7 @@ private: MessageQueueId_t getCommandQueue() const override; void getMode(Mode_t *mode, Submode_t *submode) override; ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode) override; + uint32_t *msToReachTheMode) override; void startTransition(Mode_t mode, Submode_t submode) override; void setToExternalControl() override; void announceMode(bool recursive) override; diff --git a/src/fsfw/pus/CMakeLists.txt b/src/fsfw/pus/CMakeLists.txt index 8b55adf0..35b35bea 100644 --- a/src/fsfw/pus/CMakeLists.txt +++ b/src/fsfw/pus/CMakeLists.txt @@ -1,12 +1,12 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - Service1TelecommandVerification.cpp - Service2DeviceAccess.cpp - Service3Housekeeping.cpp - Service5EventReporting.cpp - Service8FunctionManagement.cpp - Service9TimeManagement.cpp - Service17Test.cpp - Service20ParameterManagement.cpp - CService200ModeCommanding.cpp - CService201HealthCommanding.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE Service1TelecommandVerification.cpp + Service2DeviceAccess.cpp + Service3Housekeeping.cpp + Service5EventReporting.cpp + Service8FunctionManagement.cpp + Service9TimeManagement.cpp + Service17Test.cpp + Service20ParameterManagement.cpp + CService200ModeCommanding.cpp + CService201HealthCommanding.cpp) diff --git a/src/fsfw/rmap/CMakeLists.txt b/src/fsfw/rmap/CMakeLists.txt index 78c99e42..44184860 100644 --- a/src/fsfw/rmap/CMakeLists.txt +++ b/src/fsfw/rmap/CMakeLists.txt @@ -1,7 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - RMAP.cpp - RMAPCookie.cpp - RmapDeviceCommunicationIF.cpp -) - +target_sources(${LIB_FSFW_NAME} PRIVATE RMAP.cpp RMAPCookie.cpp + RmapDeviceCommunicationIF.cpp) diff --git a/src/fsfw/serialize/CMakeLists.txt b/src/fsfw/serialize/CMakeLists.txt index fc2387e8..5ac92d7f 100644 --- a/src/fsfw/serialize/CMakeLists.txt +++ b/src/fsfw/serialize/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - SerialBufferAdapter.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE SerialBufferAdapter.cpp) diff --git a/src/fsfw/serviceinterface/CMakeLists.txt b/src/fsfw/serviceinterface/CMakeLists.txt index 84c79177..df3f074e 100644 --- a/src/fsfw/serviceinterface/CMakeLists.txt +++ b/src/fsfw/serviceinterface/CMakeLists.txt @@ -1,5 +1,4 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - ServiceInterfaceStream.cpp - ServiceInterfaceBuffer.cpp - ServiceInterfacePrinter.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE ServiceInterfaceStream.cpp ServiceInterfaceBuffer.cpp + ServiceInterfacePrinter.cpp) diff --git a/src/fsfw/storagemanager/CMakeLists.txt b/src/fsfw/storagemanager/CMakeLists.txt index b8138cae..50ce50ed 100644 --- a/src/fsfw/storagemanager/CMakeLists.txt +++ b/src/fsfw/storagemanager/CMakeLists.txt @@ -1,7 +1,3 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - ConstStorageAccessor.cpp - StorageAccessor.cpp - LocalPool.cpp - PoolManager.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} PRIVATE ConstStorageAccessor.cpp StorageAccessor.cpp + LocalPool.cpp PoolManager.cpp) diff --git a/src/fsfw/subsystem/CMakeLists.txt b/src/fsfw/subsystem/CMakeLists.txt index 5c98ee70..164c90f7 100644 --- a/src/fsfw/subsystem/CMakeLists.txt +++ b/src/fsfw/subsystem/CMakeLists.txt @@ -1,7 +1,3 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - Subsystem.cpp - SubsystemBase.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE Subsystem.cpp SubsystemBase.cpp) -add_subdirectory(modes) \ No newline at end of file +add_subdirectory(modes) diff --git a/src/fsfw/subsystem/modes/CMakeLists.txt b/src/fsfw/subsystem/modes/CMakeLists.txt index 6ac6a293..ba57de2c 100644 --- a/src/fsfw/subsystem/modes/CMakeLists.txt +++ b/src/fsfw/subsystem/modes/CMakeLists.txt @@ -1,5 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - ModeSequenceMessage.cpp - ModeStore.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE ModeSequenceMessage.cpp ModeStore.cpp) diff --git a/src/fsfw/tasks/CMakeLists.txt b/src/fsfw/tasks/CMakeLists.txt index 1964bb4e..df69520a 100644 --- a/src/fsfw/tasks/CMakeLists.txt +++ b/src/fsfw/tasks/CMakeLists.txt @@ -1,5 +1,2 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - FixedSequenceSlot.cpp - FixedSlotSequence.cpp -) \ No newline at end of file +target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp + FixedSlotSequence.cpp) diff --git a/src/fsfw/tcdistribution/CMakeLists.txt b/src/fsfw/tcdistribution/CMakeLists.txt index 7118c38c..ab32c509 100644 --- a/src/fsfw/tcdistribution/CMakeLists.txt +++ b/src/fsfw/tcdistribution/CMakeLists.txt @@ -1,9 +1,4 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - CCSDSDistributor.cpp - PUSDistributor.cpp - TcDistributor.cpp - TcPacketCheckPUS.cpp - TcPacketCheckCFDP.cpp - CFDPDistributor.cpp -) - +target_sources( + ${LIB_FSFW_NAME} + PRIVATE CCSDSDistributor.cpp PUSDistributor.cpp TcDistributor.cpp + TcPacketCheckPUS.cpp TcPacketCheckCFDP.cpp CFDPDistributor.cpp) diff --git a/src/fsfw/thermal/CMakeLists.txt b/src/fsfw/thermal/CMakeLists.txt index ad532721..995ebc4d 100644 --- a/src/fsfw/thermal/CMakeLists.txt +++ b/src/fsfw/thermal/CMakeLists.txt @@ -1,10 +1,9 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - AbstractTemperatureSensor.cpp - Heater.cpp - RedundantHeater.cpp - ThermalComponentCore.cpp - ThermalComponent.cpp - ThermalModule.cpp - ThermalMonitorReporter.cpp -) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE AbstractTemperatureSensor.cpp + Heater.cpp + RedundantHeater.cpp + ThermalComponentCore.cpp + ThermalComponent.cpp + ThermalModule.cpp + ThermalMonitorReporter.cpp) diff --git a/src/fsfw/timemanager/CMakeLists.txt b/src/fsfw/timemanager/CMakeLists.txt index 00467772..c4f77395 100644 --- a/src/fsfw/timemanager/CMakeLists.txt +++ b/src/fsfw/timemanager/CMakeLists.txt @@ -1,8 +1,3 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - CCSDSTime.cpp - Countdown.cpp - Stopwatch.cpp - TimeMessage.cpp - TimeStamper.cpp - ClockCommon.cpp -) +target_sources( + ${LIB_FSFW_NAME} PRIVATE CCSDSTime.cpp Countdown.cpp Stopwatch.cpp + TimeMessage.cpp TimeStamper.cpp ClockCommon.cpp) diff --git a/src/fsfw/tmstorage/CMakeLists.txt b/src/fsfw/tmstorage/CMakeLists.txt index 7990d85a..80da7faf 100644 --- a/src/fsfw/tmstorage/CMakeLists.txt +++ b/src/fsfw/tmstorage/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - TmStoreMessage.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE TmStoreMessage.cpp) diff --git a/src/fsfw/tmtcpacket/CMakeLists.txt b/src/fsfw/tmtcpacket/CMakeLists.txt index e1deaba9..196ba752 100644 --- a/src/fsfw/tmtcpacket/CMakeLists.txt +++ b/src/fsfw/tmtcpacket/CMakeLists.txt @@ -1,8 +1,5 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - SpacePacket.cpp - SpacePacketBase.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE SpacePacket.cpp SpacePacketBase.cpp) add_subdirectory(cfdp) add_subdirectory(packetmatcher) -add_subdirectory(pus) \ No newline at end of file +add_subdirectory(pus) diff --git a/src/fsfw/tmtcpacket/cfdp/CMakeLists.txt b/src/fsfw/tmtcpacket/cfdp/CMakeLists.txt index 0b7ab18a..7d20aab8 100644 --- a/src/fsfw/tmtcpacket/cfdp/CMakeLists.txt +++ b/src/fsfw/tmtcpacket/cfdp/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - CFDPPacket.cpp - CFDPPacketStored.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE CFDPPacket.cpp CFDPPacketStored.cpp) diff --git a/src/fsfw/tmtcpacket/packetmatcher/CMakeLists.txt b/src/fsfw/tmtcpacket/packetmatcher/CMakeLists.txt index e9a8d03b..6ea94799 100644 --- a/src/fsfw/tmtcpacket/packetmatcher/CMakeLists.txt +++ b/src/fsfw/tmtcpacket/packetmatcher/CMakeLists.txt @@ -1,4 +1 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - PacketMatchTree.cpp -) +target_sources(${LIB_FSFW_NAME} PRIVATE PacketMatchTree.cpp) diff --git a/src/fsfw/tmtcpacket/pus/tc/CMakeLists.txt b/src/fsfw/tmtcpacket/pus/tc/CMakeLists.txt index dc611263..09c63bfd 100644 --- a/src/fsfw/tmtcpacket/pus/tc/CMakeLists.txt +++ b/src/fsfw/tmtcpacket/pus/tc/CMakeLists.txt @@ -1,6 +1,3 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - TcPacketPusBase.cpp - TcPacketPus.cpp - TcPacketStoredBase.cpp - TcPacketStoredPus.cpp -) +target_sources( + ${LIB_FSFW_NAME} PRIVATE TcPacketPusBase.cpp TcPacketPus.cpp + TcPacketStoredBase.cpp TcPacketStoredPus.cpp) diff --git a/src/fsfw/tmtcpacket/pus/tm/CMakeLists.txt b/src/fsfw/tmtcpacket/pus/tm/CMakeLists.txt index ace87820..ded74ce2 100644 --- a/src/fsfw/tmtcpacket/pus/tm/CMakeLists.txt +++ b/src/fsfw/tmtcpacket/pus/tm/CMakeLists.txt @@ -1,9 +1,9 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE - TmPacketStoredPusA.cpp - TmPacketStoredPusC.cpp - TmPacketPusA.cpp - TmPacketPusC.cpp - TmPacketStoredBase.cpp - TmPacketBase.cpp - TmPacketMinimal.cpp -) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE TmPacketStoredPusA.cpp + TmPacketStoredPusC.cpp + TmPacketPusA.cpp + TmPacketPusC.cpp + TmPacketStoredBase.cpp + TmPacketBase.cpp + TmPacketMinimal.cpp) diff --git a/src/fsfw/tmtcservices/CMakeLists.txt b/src/fsfw/tmtcservices/CMakeLists.txt index 96cf99b5..d2a3f4ed 100644 --- a/src/fsfw/tmtcservices/CMakeLists.txt +++ b/src/fsfw/tmtcservices/CMakeLists.txt @@ -1,10 +1,9 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - CommandingServiceBase.cpp - PusServiceBase.cpp - PusVerificationReport.cpp - TmTcBridge.cpp - TmTcMessage.cpp - VerificationReporter.cpp - SpacePacketParser.cpp -) \ No newline at end of file +target_sources( + ${LIB_FSFW_NAME} + PRIVATE CommandingServiceBase.cpp + PusServiceBase.cpp + PusVerificationReport.cpp + TmTcBridge.cpp + TmTcMessage.cpp + VerificationReporter.cpp + SpacePacketParser.cpp) From e1dd27b9dd98653b226b94fba99213785ae2b05a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 May 2022 13:15:32 +0200 Subject: [PATCH 165/198] cache the TCP client address now --- src/fsfw/osal/common/TcpTmTcServer.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index b9089245..b3017e01 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -109,8 +109,8 @@ TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); } using namespace tcpip; // If a connection is accepted, the corresponding socket will be assigned to the new socket socket_t connSocket = 0; - // sockaddr clientSockAddr = {}; - // socklen_t connectorSockAddrLen = 0; + sockaddr clientSockAddr = {}; + socklen_t connectorSockAddrLen = 0; int retval = 0; // Listen for connection requests permanently for lifetime of program @@ -121,8 +121,8 @@ TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); } continue; } - // connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); - connSocket = accept(listenerTcpSocket, nullptr, nullptr); + connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); + // connSocket = accept(listenerTcpSocket, nullptr, nullptr); if (connSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); @@ -137,6 +137,7 @@ TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); } if (retval != 0) { handleError(Protocol::TCP, ErrorSources::SHUTDOWN_CALL); } + closeSocket(connSocket); connSocket = 0; } From 14a1b4a7ac57080758b2a1931786ea69d82db780 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 May 2022 13:31:33 +0200 Subject: [PATCH 166/198] made auto-formatter even more re-usable --- scripts/auto-formatter.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/auto-formatter.sh b/scripts/auto-formatter.sh index 7b67ee9d..33f3fabc 100755 --- a/scripts/auto-formatter.sh +++ b/scripts/auto-formatter.sh @@ -12,11 +12,17 @@ else fi cpp_format="clang-format" +folder_list=( + "./src" + "./hal" + "./tests" +) file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" if command -v ${cpp_format} &> /dev/null; then - find ./src ${file_selectors} | xargs clang-format --style=file -i - find ./hal ${file_selectors} | xargs clang-format --style=file -i - find ./tests ${file_selectors} | xargs clang-format --style=file -i + echo "Auto-formatting ${dir} recursively" + for dir in ${allThreads[@]}; do + find ${dir} ${file_selectors} | xargs clang-format --style=file -i + done else echo "No ${cpp_format} tool found, not formatting C++/C files" fi From e8023886f60ba3af0a63279da8dbc0d3eb0939a7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 May 2022 13:31:56 +0200 Subject: [PATCH 167/198] made auto-formatter even more usable --- scripts/auto-formatter.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/auto-formatter.sh b/scripts/auto-formatter.sh index 33f3fabc..cec0b680 100755 --- a/scripts/auto-formatter.sh +++ b/scripts/auto-formatter.sh @@ -3,6 +3,12 @@ if [[ ! -f README.md ]]; then cd .. fi +folder_list=( + "./src" + "./hal" + "./tests" +) + cmake_fmt="cmake-format" if command -v ${cmake_fmt} &> /dev/null; then cmake_fmt_cmd="${cmake_fmt} -i CMakeLists.txt" @@ -12,15 +18,10 @@ else fi cpp_format="clang-format" -folder_list=( - "./src" - "./hal" - "./tests" -) file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp" if command -v ${cpp_format} &> /dev/null; then - echo "Auto-formatting ${dir} recursively" - for dir in ${allThreads[@]}; do + for dir in ${folder_list[@]}; do + echo "Auto-formatting ${dir} recursively" find ${dir} ${file_selectors} | xargs clang-format --style=file -i done else From f9c42d3583555a03ef9cb7477689c69c422d9a0d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 May 2022 18:12:05 +0200 Subject: [PATCH 168/198] vector as core container is ok --- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 7 ++++--- src/fsfw/osal/linux/PeriodicPosixTask.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index 26b6f53e..44d669df 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -1,6 +1,7 @@ #include "fsfw/osal/linux/PeriodicPosixTask.h" -#include +#include +#include #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/serviceinterface/ServiceInterface.h" @@ -23,7 +24,7 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { PeriodicPosixTask* originalTask(reinterpret_cast(arg)); // The task's functionality is called. originalTask->taskFunctionality(); - return NULL; + return nullptr; } ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) { @@ -43,7 +44,7 @@ ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object, uint8_ #endif return HasReturnvaluesIF::RETURN_FAILED; } - objectList.emplace(object, opCode); + objectList.push_back({object, opCode}); object->setTaskIF(this); return HasReturnvaluesIF::RETURN_OK; diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 1142c854..a3c6b187 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include +#include #include "../../objectmanager/ObjectManagerIF.h" #include "../../tasks/ExecutableObjectIF.h" @@ -61,7 +61,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { private: //! Typedef for the List of objects. Will contain the objects to execute and their respective //! op codes - using ObjectList = std::multiset>; + using ObjectList = std::vector>; /** * @brief This attribute holds a list of objects to be executed. */ From 18b342e94b59123b986fca3242ba375be3c6aefd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 May 2022 18:12:05 +0200 Subject: [PATCH 169/198] vector as core container is ok --- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 7 ++++--- src/fsfw/osal/linux/PeriodicPosixTask.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index 26b6f53e..44d669df 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -1,6 +1,7 @@ #include "fsfw/osal/linux/PeriodicPosixTask.h" -#include +#include +#include #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/serviceinterface/ServiceInterface.h" @@ -23,7 +24,7 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { PeriodicPosixTask* originalTask(reinterpret_cast(arg)); // The task's functionality is called. originalTask->taskFunctionality(); - return NULL; + return nullptr; } ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) { @@ -43,7 +44,7 @@ ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object, uint8_ #endif return HasReturnvaluesIF::RETURN_FAILED; } - objectList.emplace(object, opCode); + objectList.push_back({object, opCode}); object->setTaskIF(this); return HasReturnvaluesIF::RETURN_OK; diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 1142c854..a3c6b187 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include +#include #include "../../objectmanager/ObjectManagerIF.h" #include "../../tasks/ExecutableObjectIF.h" @@ -61,7 +61,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { private: //! Typedef for the List of objects. Will contain the objects to execute and their respective //! op codes - using ObjectList = std::multiset>; + using ObjectList = std::vector>; /** * @brief This attribute holds a list of objects to be executed. */ From 13cda86d23f8761a751b3a71a30b18ebcffbbe74 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 13:13:24 +0200 Subject: [PATCH 170/198] remove commented code --- src/fsfw/osal/common/TcpTmTcServer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index b3017e01..a8890006 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -122,7 +122,6 @@ TcpTmTcServer::~TcpTmTcServer() { closeSocket(listenerTcpSocket); } } connSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); - // connSocket = accept(listenerTcpSocket, nullptr, nullptr); if (connSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); From 7b3de873644150fe82cb54399b35c59c7134cd3c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 13:19:43 +0200 Subject: [PATCH 171/198] removed some changes which belong in separate PR --- hal/src/fsfw_hal/linux/CommandExecutor.cpp | 2 -- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 27 +++---------------- hal/src/fsfw_hal/linux/spi/SpiComIF.h | 30 ++++------------------ 3 files changed, 8 insertions(+), 51 deletions(-) diff --git a/hal/src/fsfw_hal/linux/CommandExecutor.cpp b/hal/src/fsfw_hal/linux/CommandExecutor.cpp index dcdd10ee..49c44ebf 100644 --- a/hal/src/fsfw_hal/linux/CommandExecutor.cpp +++ b/hal/src/fsfw_hal/linux/CommandExecutor.cpp @@ -205,5 +205,3 @@ ReturnValue_t CommandExecutor::executeBlocking() { } return HasReturnvaluesIF::RETURN_OK; } - -const std::vector& CommandExecutor::getReadVector() const { return readVec; } diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index 3c257f1f..dcf92b5d 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -401,33 +401,12 @@ void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) if (retval != 0) { utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed"); } -} - -void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const { - uint8_t tmpMode = 0; - int retval = ioctl(spiFd, SPI_IOC_RD_MODE, &tmpMode); - if (retval != 0) { - utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Reading SPI mode failed"); - } - mode = static_cast(tmpMode); - - retval = ioctl(spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); - if (retval != 0) { - utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Getting SPI speed failed"); - } -} - -const std::string& SpiComIF::getSpiDev() const { return dev; } - -void SpiComIF::updateLinePolarity(int spiFd) { + // This updates the SPI clock default polarity. Only setting the mode does not update + // the line state, which can be an issue on mode switches because the clock line will + // switch the state after the chip select is pulled low clockUpdateTransfer.len = 0; retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer); if (retval != 0) { utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed"); } } - -void SpiComIF::setMutexParams(MutexIF::TimeoutType timeoutType_, uint32_t timeoutMs_) { - timeoutType = timeoutType_; - timeoutMs = timeoutMs_; -} diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index 1400dcfc..357afa2f 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -22,17 +22,15 @@ class SpiCookie; */ class SpiComIF : public DeviceCommunicationIF, public SystemObject { public: - static constexpr dur_millis_t DEFAULT_MUTEX_TIMEOUT = 20; - - static constexpr uint8_t CLASS_ID = CLASS_ID::HAL_SPI; + static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI; static constexpr ReturnValue_t OPENING_FILE_FAILED = - HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0); + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 0); /* Full duplex (ioctl) transfer failure */ static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED = - HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1); + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 1); /* Half duplex (read/write) transfer failure */ static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = - HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2); + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 2); SpiComIF(object_id_t objectId, GpioIF* gpioComIF); @@ -47,7 +45,6 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { * the chip select must be driven from outside of the com if. */ MutexIF* getMutex(MutexIF::TimeoutType* timeoutType = nullptr, uint32_t* timeoutMs = nullptr); - void setMutexParams(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs); /** * Perform a regular send operation using Linux iotcl. This is public so it can be used @@ -62,23 +59,6 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { GpioIF* getGpioInterface(); void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed); -<<<<<<< Updated upstream -======= - void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const; - - /** - * This updates the SPI clock default polarity. Only setting the mode does not update - * the line state, which can be an issue on mode switches because the clock line will - * switch the state after the chip select is pulled low. - * - * It is recommended to call this function after #setSpiSpeedAndMode and after locking the - * CS mutex if the SPI bus has multiple SPI devices with different speed and SPI modes attached. - * @param spiFd - */ - void updateLinePolarity(int spiFd); - - const std::string& getSpiDev() const; ->>>>>>> Stashed changes void performSpiWiretapping(SpiCookie* spiCookie); ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); @@ -93,7 +73,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject { MutexIF* spiMutex = nullptr; MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; - uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT; + uint32_t timeoutMs = 20; spi_ioc_transfer clockUpdateTransfer = {}; using SpiDeviceMap = std::unordered_map; From e87b5a0207070ebe3125cd675a108cae29d5c2f0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 14:32:35 +0200 Subject: [PATCH 172/198] new base class for periodic tasks --- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 57 ++--------------------- src/fsfw/osal/linux/PeriodicPosixTask.h | 55 ++++------------------ src/fsfw/tasks/PeriodicTaskBase.cpp | 57 +++++++++++++++++++++++ src/fsfw/tasks/PeriodicTaskBase.h | 52 +++++++++++++++++++++ src/fsfw/tasks/PeriodicTaskIF.h | 24 +++++----- src/fsfw/tasks/TaskFactory.h | 2 +- src/fsfw/tasks/Typedef.h | 13 ------ src/fsfw/tasks/definitions.h | 13 ++++++ 8 files changed, 148 insertions(+), 125 deletions(-) create mode 100644 src/fsfw/tasks/PeriodicTaskBase.cpp create mode 100644 src/fsfw/tasks/PeriodicTaskBase.h delete mode 100644 src/fsfw/tasks/Typedef.h create mode 100644 src/fsfw/tasks/definitions.h diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index 44d669df..510ec59c 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -8,12 +8,10 @@ #include "fsfw/tasks/ExecutableObjectIF.h" PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, - uint32_t period_, void(deadlineMissedFunc_)()) + uint32_t period_, TaskDeadlineMissedFunction dlMissedFunc_) : PosixThread(name_, priority_, stackSize_), - objectList(), - started(false), - periodMs(period_), - deadlineMissedFunc(deadlineMissedFunc_) {} + PeriodicTaskBase(period_, dlMissedFunc_), + started(false) {} PeriodicPosixTask::~PeriodicPosixTask() { // Not Implemented @@ -27,31 +25,8 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { return nullptr; } -ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) { - ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - return addComponent(newObject, opCode); -} - -ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object, uint8_t opCode) { - if (object == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" - << " it implements ExecutableObjectIF!" << std::endl; -#else - sif::printError( - "PeriodicTask::addComponent: Invalid object. Make sure it " - "implements ExecutableObjectIF!\n"); -#endif - return HasReturnvaluesIF::RETURN_FAILED; - } - objectList.push_back({object, opCode}); - object->setTaskIF(this); - - return HasReturnvaluesIF::RETURN_OK; -} - ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { - return PosixThread::sleep((uint64_t)ms * 1000000); + return PosixThread::sleep(static_cast(ms * 1000000)); } ReturnValue_t PeriodicPosixTask::startTask(void) { @@ -84,27 +59,3 @@ void PeriodicPosixTask::taskFunctionality(void) { } } } - -uint32_t PeriodicPosixTask::getPeriodMs() const { return periodMs; } - -bool PeriodicPosixTask::isEmpty() const { return objectList.empty(); } - -ReturnValue_t PeriodicPosixTask::initObjsAfterTaskCreation() { - std::multiset uniqueObjects; - ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; - uint32_t count = 0; - for (const auto& obj : objectList) { - // Ensure that each unique object is initialized once. - if (uniqueObjects.find(obj.first) == uniqueObjects.end()) { - ReturnValue_t result = obj.first->initializeAfterTaskCreation(); - if (result != HasReturnvaluesIF::RETURN_OK) { - count++; - status = result; - } - uniqueObjects.emplace(obj.first); - } - } - if (count > 0) { - } - return status; -} diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index a3c6b187..3dcc6bcc 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -1,14 +1,17 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include - -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../tasks/ExecutableObjectIF.h" -#include "../../tasks/PeriodicTaskIF.h" #include "PosixThread.h" -class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { +#include + +#include "fsfw/objectmanager/ObjectManagerIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/tasks/PeriodicTaskIF.h" +#include "fsfw/tasks/PeriodicTaskBase.h" + + +class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase { public: /** * Create a generic periodic task. @@ -34,48 +37,16 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * to the system call. */ ReturnValue_t startTask() override; - /** - * Adds an object to the list of objects to be executed. - * The objects are executed in the order added. - * @param object Id of the object to add. - * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. - */ - ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; - - /** - * Adds an object to the list of objects to be executed. - * The objects are executed in the order added. - * @param object pointer to the object to add. - * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. - */ - ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; - - uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; - ReturnValue_t initObjsAfterTaskCreation(); - - bool isEmpty() const override; - private: - //! Typedef for the List of objects. Will contain the objects to execute and their respective - //! op codes - using ObjectList = std::vector>; - /** - * @brief This attribute holds a list of objects to be executed. - */ - ObjectList objectList; /** * @brief Flag to indicate that the task was started and is allowed to run */ bool started; - /** - * @brief Period of the task in milliseconds - */ - uint32_t periodMs; /** * @brief The function containing the actual functionality of the task. * @details The method sets and starts @@ -92,14 +63,6 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * of the child class. Needs a valid pointer to the derived class. */ static void* taskEntryPoint(void* arg); - /** - * @brief The pointer to the deadline-missed function. - * @details This pointer stores the function that is executed if the task's deadline is missed. - * So, each may react individually on a timing failure. The pointer may be - * NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution - * of the periodic task. - */ - void (*deadlineMissedFunc)(); }; #endif /* FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ */ diff --git a/src/fsfw/tasks/PeriodicTaskBase.cpp b/src/fsfw/tasks/PeriodicTaskBase.cpp new file mode 100644 index 00000000..606fee1e --- /dev/null +++ b/src/fsfw/tasks/PeriodicTaskBase.cpp @@ -0,0 +1,57 @@ +#include +#include "PeriodicTaskBase.h" + +#include + +PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_, + TaskDeadlineMissedFunction deadlineMissedFunc_) + : periodMs(periodMs_), deadlineMissedFunc(deadlineMissedFunc_) {} + +uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; } + +bool PeriodicTaskBase::isEmpty() const override { + return objectList.empty(); +} + +ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() { + std::multiset uniqueObjects; + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + uint32_t count = 0; + for (const auto& obj : objectList) { + // Ensure that each unique object is initialized once. + if (uniqueObjects.find(obj.first) == uniqueObjects.end()) { + ReturnValue_t result = obj.first->initializeAfterTaskCreation(); + if (result != HasReturnvaluesIF::RETURN_OK) { + count++; + status = result; + } + uniqueObjects.emplace(obj.first); + } + } + if (count > 0) { + } + return status; +} + +ReturnValue_t PeriodicTaskBase::addComponent(object_id_t object, uint8_t opCode) { + ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); + return addComponent(newObject, opCode); +} + +ReturnValue_t PeriodicTaskBase::addComponent(ExecutableObjectIF* object, uint8_t opCode) { + if (object == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" + << " it implements ExecutableObjectIF!" << std::endl; +#else + sif::printError( + "PeriodicTask::addComponent: Invalid object. Make sure it " + "implements ExecutableObjectIF!\n"); +#endif + return HasReturnvaluesIF::RETURN_FAILED; + } + objectList.push_back({object, opCode}); + object->setTaskIF(this); + + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h new file mode 100644 index 00000000..4b330426 --- /dev/null +++ b/src/fsfw/tasks/PeriodicTaskBase.h @@ -0,0 +1,52 @@ +#ifndef FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ +#define FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ + +#include "fsfw/tasks/PeriodicTaskIF.h" +#include "fsfw/tasks/definitions.h" +#include +#include + +class ExecutableObjectIF; + +class PeriodicTaskBase: public PeriodicTaskIF { +public: + PeriodicTaskBase(uint32_t periodMs, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr); + + ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; + ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; + + + uint32_t getPeriodMs() const override; + + bool isEmpty() const override; + + ReturnValue_t initObjsAfterTaskCreation(); + +protected: + + //! Typedef for the List of objects. Will contain the objects to execute and their respective + //! operation codes + using ObjectList = std::vector>; + /** + * @brief This attribute holds a list of objects to be executed. + */ + ObjectList objectList; + + /** + * @brief Period of the task in milliseconds + */ + uint32_t periodMs; + + /** + * @brief The pointer to the deadline-missed function. + * @details This pointer stores the function that is executed if the task's deadline is missed. + * So, each may react individually on a timing failure. The pointer may be + * NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution + * of the periodic task. + */ + TaskDeadlineMissedFunction deadlineMissedFunc = nullptr; +}; + + + +#endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */ diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h index 2ae268fc..076ef56e 100644 --- a/src/fsfw/tasks/PeriodicTaskIF.h +++ b/src/fsfw/tasks/PeriodicTaskIF.h @@ -1,11 +1,10 @@ #ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_ #define FRAMEWORK_TASK_PERIODICTASKIF_H_ -#include +#include "fsfw/objectmanager/SystemObjectIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" -#include "../objectmanager/SystemObjectIF.h" -#include "../timemanager/Clock.h" -class ExecutableObjectIF; +#include /** * New version of TaskIF @@ -26,20 +25,21 @@ class PeriodicTaskIF { virtual ReturnValue_t startTask() = 0; /** - * Add a component (object) to a periodic task. - * @param object - * Add an object to the task. The object needs to implement ExecutableObjectIF - * @return + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. The object needs to implement + * ExecutableObjectIF + * @param object Id of the object to add. + * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; }; /** - * Add an object to a periodic task. - * @param object - * Add an object to the task. - * @return + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. + * @param object pointer to the object to add. + * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; diff --git a/src/fsfw/tasks/TaskFactory.h b/src/fsfw/tasks/TaskFactory.h index fcd62678..828c533e 100644 --- a/src/fsfw/tasks/TaskFactory.h +++ b/src/fsfw/tasks/TaskFactory.h @@ -4,7 +4,7 @@ #include #include "FixedTimeslotTaskIF.h" -#include "Typedef.h" +#include "definitions.h" /** * Singleton Class that produces Tasks. diff --git a/src/fsfw/tasks/Typedef.h b/src/fsfw/tasks/Typedef.h deleted file mode 100644 index 1bb75131..00000000 --- a/src/fsfw/tasks/Typedef.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef FSFW_TASKS_TYPEDEF_H_ -#define FSFW_TASKS_TYPEDEF_H_ - -#include -#include - -typedef const char* TaskName; -typedef uint32_t TaskPriority; -typedef size_t TaskStackSize; -typedef double TaskPeriod; -typedef void (*TaskDeadlineMissedFunction)(); - -#endif /* FSFW_TASKS_TYPEDEF_H_ */ diff --git a/src/fsfw/tasks/definitions.h b/src/fsfw/tasks/definitions.h new file mode 100644 index 00000000..bca9b768 --- /dev/null +++ b/src/fsfw/tasks/definitions.h @@ -0,0 +1,13 @@ +#ifndef FSFW_TASKS_TYPEDEF_H_ +#define FSFW_TASKS_TYPEDEF_H_ + +#include +#include + +using TaskName = const char*; +using TaskPriority = uint32_t; +using TaskStackSize = size_t; +using TaskPeriod = double; +using TaskDeadlineMissedFunction = void (*)(); + +#endif /* FSFW_TASKS_TYPEDEF_H_ */ From 86ca4f246bbf2a8adb3e265f8c4f0b47fde0807d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 14:32:35 +0200 Subject: [PATCH 173/198] new base class for periodic tasks --- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 57 ++--------------------- src/fsfw/osal/linux/PeriodicPosixTask.h | 55 ++++------------------ src/fsfw/tasks/PeriodicTaskBase.cpp | 57 +++++++++++++++++++++++ src/fsfw/tasks/PeriodicTaskBase.h | 52 +++++++++++++++++++++ src/fsfw/tasks/PeriodicTaskIF.h | 24 +++++----- src/fsfw/tasks/TaskFactory.h | 2 +- src/fsfw/tasks/Typedef.h | 13 ------ src/fsfw/tasks/definitions.h | 13 ++++++ 8 files changed, 148 insertions(+), 125 deletions(-) create mode 100644 src/fsfw/tasks/PeriodicTaskBase.cpp create mode 100644 src/fsfw/tasks/PeriodicTaskBase.h delete mode 100644 src/fsfw/tasks/Typedef.h create mode 100644 src/fsfw/tasks/definitions.h diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index 44d669df..510ec59c 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -8,12 +8,10 @@ #include "fsfw/tasks/ExecutableObjectIF.h" PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, - uint32_t period_, void(deadlineMissedFunc_)()) + uint32_t period_, TaskDeadlineMissedFunction dlMissedFunc_) : PosixThread(name_, priority_, stackSize_), - objectList(), - started(false), - periodMs(period_), - deadlineMissedFunc(deadlineMissedFunc_) {} + PeriodicTaskBase(period_, dlMissedFunc_), + started(false) {} PeriodicPosixTask::~PeriodicPosixTask() { // Not Implemented @@ -27,31 +25,8 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { return nullptr; } -ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, uint8_t opCode) { - ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - return addComponent(newObject, opCode); -} - -ReturnValue_t PeriodicPosixTask::addComponent(ExecutableObjectIF* object, uint8_t opCode) { - if (object == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" - << " it implements ExecutableObjectIF!" << std::endl; -#else - sif::printError( - "PeriodicTask::addComponent: Invalid object. Make sure it " - "implements ExecutableObjectIF!\n"); -#endif - return HasReturnvaluesIF::RETURN_FAILED; - } - objectList.push_back({object, opCode}); - object->setTaskIF(this); - - return HasReturnvaluesIF::RETURN_OK; -} - ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { - return PosixThread::sleep((uint64_t)ms * 1000000); + return PosixThread::sleep(static_cast(ms * 1000000)); } ReturnValue_t PeriodicPosixTask::startTask(void) { @@ -84,27 +59,3 @@ void PeriodicPosixTask::taskFunctionality(void) { } } } - -uint32_t PeriodicPosixTask::getPeriodMs() const { return periodMs; } - -bool PeriodicPosixTask::isEmpty() const { return objectList.empty(); } - -ReturnValue_t PeriodicPosixTask::initObjsAfterTaskCreation() { - std::multiset uniqueObjects; - ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; - uint32_t count = 0; - for (const auto& obj : objectList) { - // Ensure that each unique object is initialized once. - if (uniqueObjects.find(obj.first) == uniqueObjects.end()) { - ReturnValue_t result = obj.first->initializeAfterTaskCreation(); - if (result != HasReturnvaluesIF::RETURN_OK) { - count++; - status = result; - } - uniqueObjects.emplace(obj.first); - } - } - if (count > 0) { - } - return status; -} diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index a3c6b187..3dcc6bcc 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -1,14 +1,17 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include - -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../tasks/ExecutableObjectIF.h" -#include "../../tasks/PeriodicTaskIF.h" #include "PosixThread.h" -class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { +#include + +#include "fsfw/objectmanager/ObjectManagerIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/tasks/PeriodicTaskIF.h" +#include "fsfw/tasks/PeriodicTaskBase.h" + + +class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase { public: /** * Create a generic periodic task. @@ -34,48 +37,16 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * to the system call. */ ReturnValue_t startTask() override; - /** - * Adds an object to the list of objects to be executed. - * The objects are executed in the order added. - * @param object Id of the object to add. - * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. - */ - ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; - - /** - * Adds an object to the list of objects to be executed. - * The objects are executed in the order added. - * @param object pointer to the object to add. - * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. - */ - ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; - - uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; - ReturnValue_t initObjsAfterTaskCreation(); - - bool isEmpty() const override; - private: - //! Typedef for the List of objects. Will contain the objects to execute and their respective - //! op codes - using ObjectList = std::vector>; - /** - * @brief This attribute holds a list of objects to be executed. - */ - ObjectList objectList; /** * @brief Flag to indicate that the task was started and is allowed to run */ bool started; - /** - * @brief Period of the task in milliseconds - */ - uint32_t periodMs; /** * @brief The function containing the actual functionality of the task. * @details The method sets and starts @@ -92,14 +63,6 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { * of the child class. Needs a valid pointer to the derived class. */ static void* taskEntryPoint(void* arg); - /** - * @brief The pointer to the deadline-missed function. - * @details This pointer stores the function that is executed if the task's deadline is missed. - * So, each may react individually on a timing failure. The pointer may be - * NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution - * of the periodic task. - */ - void (*deadlineMissedFunc)(); }; #endif /* FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ */ diff --git a/src/fsfw/tasks/PeriodicTaskBase.cpp b/src/fsfw/tasks/PeriodicTaskBase.cpp new file mode 100644 index 00000000..606fee1e --- /dev/null +++ b/src/fsfw/tasks/PeriodicTaskBase.cpp @@ -0,0 +1,57 @@ +#include +#include "PeriodicTaskBase.h" + +#include + +PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_, + TaskDeadlineMissedFunction deadlineMissedFunc_) + : periodMs(periodMs_), deadlineMissedFunc(deadlineMissedFunc_) {} + +uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; } + +bool PeriodicTaskBase::isEmpty() const override { + return objectList.empty(); +} + +ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() { + std::multiset uniqueObjects; + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + uint32_t count = 0; + for (const auto& obj : objectList) { + // Ensure that each unique object is initialized once. + if (uniqueObjects.find(obj.first) == uniqueObjects.end()) { + ReturnValue_t result = obj.first->initializeAfterTaskCreation(); + if (result != HasReturnvaluesIF::RETURN_OK) { + count++; + status = result; + } + uniqueObjects.emplace(obj.first); + } + } + if (count > 0) { + } + return status; +} + +ReturnValue_t PeriodicTaskBase::addComponent(object_id_t object, uint8_t opCode) { + ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); + return addComponent(newObject, opCode); +} + +ReturnValue_t PeriodicTaskBase::addComponent(ExecutableObjectIF* object, uint8_t opCode) { + if (object == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" + << " it implements ExecutableObjectIF!" << std::endl; +#else + sif::printError( + "PeriodicTask::addComponent: Invalid object. Make sure it " + "implements ExecutableObjectIF!\n"); +#endif + return HasReturnvaluesIF::RETURN_FAILED; + } + objectList.push_back({object, opCode}); + object->setTaskIF(this); + + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h new file mode 100644 index 00000000..4b330426 --- /dev/null +++ b/src/fsfw/tasks/PeriodicTaskBase.h @@ -0,0 +1,52 @@ +#ifndef FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ +#define FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ + +#include "fsfw/tasks/PeriodicTaskIF.h" +#include "fsfw/tasks/definitions.h" +#include +#include + +class ExecutableObjectIF; + +class PeriodicTaskBase: public PeriodicTaskIF { +public: + PeriodicTaskBase(uint32_t periodMs, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr); + + ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; + ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; + + + uint32_t getPeriodMs() const override; + + bool isEmpty() const override; + + ReturnValue_t initObjsAfterTaskCreation(); + +protected: + + //! Typedef for the List of objects. Will contain the objects to execute and their respective + //! operation codes + using ObjectList = std::vector>; + /** + * @brief This attribute holds a list of objects to be executed. + */ + ObjectList objectList; + + /** + * @brief Period of the task in milliseconds + */ + uint32_t periodMs; + + /** + * @brief The pointer to the deadline-missed function. + * @details This pointer stores the function that is executed if the task's deadline is missed. + * So, each may react individually on a timing failure. The pointer may be + * NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution + * of the periodic task. + */ + TaskDeadlineMissedFunction deadlineMissedFunc = nullptr; +}; + + + +#endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */ diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h index 2ae268fc..076ef56e 100644 --- a/src/fsfw/tasks/PeriodicTaskIF.h +++ b/src/fsfw/tasks/PeriodicTaskIF.h @@ -1,11 +1,10 @@ #ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_ #define FRAMEWORK_TASK_PERIODICTASKIF_H_ -#include +#include "fsfw/objectmanager/SystemObjectIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" -#include "../objectmanager/SystemObjectIF.h" -#include "../timemanager/Clock.h" -class ExecutableObjectIF; +#include /** * New version of TaskIF @@ -26,20 +25,21 @@ class PeriodicTaskIF { virtual ReturnValue_t startTask() = 0; /** - * Add a component (object) to a periodic task. - * @param object - * Add an object to the task. The object needs to implement ExecutableObjectIF - * @return + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. The object needs to implement + * ExecutableObjectIF + * @param object Id of the object to add. + * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ virtual ReturnValue_t addComponent(object_id_t object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; }; /** - * Add an object to a periodic task. - * @param object - * Add an object to the task. - * @return + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. + * @param object pointer to the object to add. + * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ virtual ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode = 0) { return HasReturnvaluesIF::RETURN_FAILED; diff --git a/src/fsfw/tasks/TaskFactory.h b/src/fsfw/tasks/TaskFactory.h index fcd62678..828c533e 100644 --- a/src/fsfw/tasks/TaskFactory.h +++ b/src/fsfw/tasks/TaskFactory.h @@ -4,7 +4,7 @@ #include #include "FixedTimeslotTaskIF.h" -#include "Typedef.h" +#include "definitions.h" /** * Singleton Class that produces Tasks. diff --git a/src/fsfw/tasks/Typedef.h b/src/fsfw/tasks/Typedef.h deleted file mode 100644 index 1bb75131..00000000 --- a/src/fsfw/tasks/Typedef.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef FSFW_TASKS_TYPEDEF_H_ -#define FSFW_TASKS_TYPEDEF_H_ - -#include -#include - -typedef const char* TaskName; -typedef uint32_t TaskPriority; -typedef size_t TaskStackSize; -typedef double TaskPeriod; -typedef void (*TaskDeadlineMissedFunction)(); - -#endif /* FSFW_TASKS_TYPEDEF_H_ */ diff --git a/src/fsfw/tasks/definitions.h b/src/fsfw/tasks/definitions.h new file mode 100644 index 00000000..bca9b768 --- /dev/null +++ b/src/fsfw/tasks/definitions.h @@ -0,0 +1,13 @@ +#ifndef FSFW_TASKS_TYPEDEF_H_ +#define FSFW_TASKS_TYPEDEF_H_ + +#include +#include + +using TaskName = const char*; +using TaskPriority = uint32_t; +using TaskStackSize = size_t; +using TaskPeriod = double; +using TaskDeadlineMissedFunction = void (*)(); + +#endif /* FSFW_TASKS_TYPEDEF_H_ */ From b1e30ae9ff5c89ab6c628758a01d3fd274dd1d37 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 14:39:37 +0200 Subject: [PATCH 174/198] minor bugfix --- src/fsfw/tasks/CMakeLists.txt | 1 + src/fsfw/tasks/PeriodicTaskBase.cpp | 2 +- src/fsfw/tasks/PeriodicTaskBase.h | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/tasks/CMakeLists.txt b/src/fsfw/tasks/CMakeLists.txt index 1964bb4e..5c2d6b1c 100644 --- a/src/fsfw/tasks/CMakeLists.txt +++ b/src/fsfw/tasks/CMakeLists.txt @@ -2,4 +2,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp FixedSlotSequence.cpp + PeriodicTaskBase.cpp ) \ No newline at end of file diff --git a/src/fsfw/tasks/PeriodicTaskBase.cpp b/src/fsfw/tasks/PeriodicTaskBase.cpp index 606fee1e..87745b14 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.cpp +++ b/src/fsfw/tasks/PeriodicTaskBase.cpp @@ -9,7 +9,7 @@ PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_, uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; } -bool PeriodicTaskBase::isEmpty() const override { +bool PeriodicTaskBase::isEmpty() const { return objectList.empty(); } diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h index 4b330426..cc4eae4b 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.h +++ b/src/fsfw/tasks/PeriodicTaskBase.h @@ -15,7 +15,6 @@ public: ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; - uint32_t getPeriodMs() const override; bool isEmpty() const override; From b47eb0a7ff7445f078413c63588c7145ef2891fb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 14:39:37 +0200 Subject: [PATCH 175/198] minor bugfix --- src/fsfw/tasks/CMakeLists.txt | 3 ++- src/fsfw/tasks/PeriodicTaskBase.cpp | 2 +- src/fsfw/tasks/PeriodicTaskBase.h | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsfw/tasks/CMakeLists.txt b/src/fsfw/tasks/CMakeLists.txt index df69520a..537320b7 100644 --- a/src/fsfw/tasks/CMakeLists.txt +++ b/src/fsfw/tasks/CMakeLists.txt @@ -1,2 +1,3 @@ target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp - FixedSlotSequence.cpp) + FixedSlotSequence.cpp + PeriodicTaskBase.cpp) diff --git a/src/fsfw/tasks/PeriodicTaskBase.cpp b/src/fsfw/tasks/PeriodicTaskBase.cpp index 606fee1e..87745b14 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.cpp +++ b/src/fsfw/tasks/PeriodicTaskBase.cpp @@ -9,7 +9,7 @@ PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_, uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; } -bool PeriodicTaskBase::isEmpty() const override { +bool PeriodicTaskBase::isEmpty() const { return objectList.empty(); } diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h index 4b330426..cc4eae4b 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.h +++ b/src/fsfw/tasks/PeriodicTaskBase.h @@ -15,7 +15,6 @@ public: ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; - uint32_t getPeriodMs() const override; bool isEmpty() const override; From 1886da0d3f8360693d8bc60eebc39f3169805dbb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 15:42:18 +0200 Subject: [PATCH 176/198] refactoring host osal --- src/fsfw/osal/host/PeriodicTask.cpp | 32 +++---------- src/fsfw/osal/host/PeriodicTask.h | 55 +++-------------------- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 12 ++--- src/fsfw/osal/linux/FixedTimeslotTask.h | 11 +++-- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 15 ++++--- src/fsfw/osal/linux/PeriodicPosixTask.h | 11 +++-- src/fsfw/osal/linux/PosixThread.h | 30 ++++++------- src/fsfw/osal/linux/TaskFactory.cpp | 4 +- src/fsfw/tasks/CMakeLists.txt | 6 +-- src/fsfw/tasks/PeriodicTaskBase.cpp | 14 +++--- src/fsfw/tasks/PeriodicTaskBase.h | 31 +++++++------ src/fsfw/tasks/PeriodicTaskIF.h | 4 +- 12 files changed, 83 insertions(+), 142 deletions(-) diff --git a/src/fsfw/osal/host/PeriodicTask.cpp b/src/fsfw/osal/host/PeriodicTask.cpp index cdcfafa6..ed4ef3f1 100644 --- a/src/fsfw/osal/host/PeriodicTask.cpp +++ b/src/fsfw/osal/host/PeriodicTask.cpp @@ -20,8 +20,8 @@ #endif PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack, - TaskPeriod setPeriod, void (*setDeadlineMissedFunc)()) - : started(false), taskName(name), period(setPeriod), deadlineMissedFunc(setDeadlineMissedFunc) { + TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_) + : PeriodicTaskBase(setPeriod, dlmFunc_), started(false), taskName(name) { // It is probably possible to set task priorities by using the native // task handles for Windows / Linux mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this); @@ -75,9 +75,7 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) { } void PeriodicTask::taskFunctionality() { - for (const auto& object : objectList) { - object->initializeAfterTaskCreation(); - } + initObjsAfterTaskCreation(); std::chrono::milliseconds periodChrono(static_cast(period * 1000)); auto currentStartTime{std::chrono::duration_cast( @@ -89,33 +87,17 @@ void PeriodicTask::taskFunctionality() { if (terminateThread.load()) { break; } - for (const auto& object : objectList) { - object->performOperation(); + for (const auto& objectPair : objectList) { + objectPair.first->performOperation(objectPair.second); } if (not delayForInterval(¤tStartTime, periodChrono)) { - if (deadlineMissedFunc != nullptr) { - this->deadlineMissedFunc(); + if (dlmFunc != nullptr) { + this->dlmFunc(); } } } } -ReturnValue_t PeriodicTask::addComponent(object_id_t object) { - ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); - return addComponent(newObject); -} - -ReturnValue_t PeriodicTask::addComponent(ExecutableObjectIF* object) { - if (object == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } - object->setTaskIF(this); - objectList.push_back(object); - return HasReturnvaluesIF::RETURN_OK; -} - -uint32_t PeriodicTask::getPeriodMs() const { return period * 1000; } - bool PeriodicTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval) { bool shouldDelay = false; // Get current wakeup time diff --git a/src/fsfw/osal/host/PeriodicTask.h b/src/fsfw/osal/host/PeriodicTask.h index 6c4d5e8b..a565c584 100644 --- a/src/fsfw/osal/host/PeriodicTask.h +++ b/src/fsfw/osal/host/PeriodicTask.h @@ -6,9 +6,9 @@ #include #include -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../tasks/PeriodicTaskIF.h" -#include "../../tasks/Typedef.h" +#include "fsfw/objectmanager/ObjectManagerIF.h" +#include "fsfw/tasks/PeriodicTaskBase.h" +#include "fsfw/tasks/definitions.h" class ExecutableObjectIF; @@ -19,7 +19,7 @@ class ExecutableObjectIF; * * @ingroup task_handling */ -class PeriodicTask : public PeriodicTaskIF { +class PeriodicTask : public PeriodicTaskBase { public: /** * @brief Standard constructor of the class. @@ -34,7 +34,7 @@ class PeriodicTask : public PeriodicTaskIF { * assigned. */ PeriodicTask(const char* name, TaskPriority setPriority, TaskStackSize setStack, - TaskPeriod setPeriod, void (*setDeadlineMissedFunc)()); + TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc); /** * @brief Currently, the executed object's lifetime is not coupled with * the task object's lifetime, so the destructor is empty. @@ -49,62 +49,19 @@ class PeriodicTask : public PeriodicTaskIF { * to the system call. */ ReturnValue_t startTask(void); - /** - * Adds an object to the list of objects to be executed. - * The objects are executed in the order added. - * @param object Id of the object to add. - * @return - * -@c RETURN_OK on success - * -@c RETURN_FAILED if the object could not be added. - */ - ReturnValue_t addComponent(object_id_t object); - - /** - * Adds an object to the list of objects to be executed. - * The objects are executed in the order added. - * @param object pointer to the object to add. - * @return - * -@c RETURN_OK on success - * -@c RETURN_FAILED if the object could not be added. - */ - ReturnValue_t addComponent(ExecutableObjectIF* object); - - uint32_t getPeriodMs() const; ReturnValue_t sleepFor(uint32_t ms); protected: using chron_ms = std::chrono::milliseconds; bool started; - //!< Typedef for the List of objects. - typedef std::vector ObjectList; std::thread mainThread; std::atomic terminateThread{false}; - /** - * @brief This attribute holds a list of objects to be executed. - */ - ObjectList objectList; - std::condition_variable initCondition; std::mutex initMutex; std::string taskName; - /** - * @brief The period of the task. - * @details - * The period determines the frequency of the task's execution. - * It is expressed in clock ticks. - */ - TaskPeriod period; - /** - * @brief The pointer to the deadline-missed function. - * @details - * This pointer stores the function that is executed if the task's deadline - * is missed. So, each may react individually on a timing failure. - * The pointer may be NULL, then nothing happens on missing the deadline. - * The deadline is equal to the next execution of the periodic task. - */ - void (*deadlineMissedFunc)(void); + /** * @brief This is the function executed in the new task's context. * @details diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp index d1fccdf9..4d912a40 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp @@ -9,8 +9,10 @@ uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, - uint32_t periodMs_) - : PosixThread(name_, priority_, stackSize_), pst(periodMs_), started(false) {} + TaskPeriod periodSeconds_) + : posixThread(name_, priority_, stackSize_), + pst(static_cast(periodSeconds_ * 1000)), + started(false) {} FixedTimeslotTask::~FixedTimeslotTask() {} @@ -26,7 +28,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) { ReturnValue_t FixedTimeslotTask::startTask() { started = true; - createTask(&taskEntryPoint, this); + posixThread.createTask(&taskEntryPoint, this); return HasReturnvaluesIF::RETURN_OK; } @@ -57,13 +59,13 @@ ReturnValue_t FixedTimeslotTask::checkSequence() { return pst.checkSequence(); } void FixedTimeslotTask::taskFunctionality() { // Like FreeRTOS pthreads are running as soon as they are created if (!started) { - suspend(); + posixThread.suspend(); } pst.intializeSequenceAfterTaskCreation(); // The start time for the first entry is read. - uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); + uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs(); uint64_t interval = pst.getIntervalToNextSlotMs(); // The task's "infinite" inner loop is entered. diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.h b/src/fsfw/osal/linux/FixedTimeslotTask.h index a5dc9032..ecce7321 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.h +++ b/src/fsfw/osal/linux/FixedTimeslotTask.h @@ -3,11 +3,12 @@ #include -#include "../../tasks/FixedSlotSequence.h" -#include "../../tasks/FixedTimeslotTaskIF.h" #include "PosixThread.h" +#include "fsfw/tasks/FixedSlotSequence.h" +#include "fsfw/tasks/FixedTimeslotTaskIF.h" +#include "fsfw/tasks/definitions.h" -class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread { +class FixedTimeslotTask : public FixedTimeslotTaskIF { public: /** * Create a generic periodic task. @@ -21,7 +22,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread { * @param period_ * @param deadlineMissedFunc_ */ - FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); + FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod periodSeconds_); virtual ~FixedTimeslotTask(); ReturnValue_t startTask() override; @@ -59,6 +60,8 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF, public PosixThread { virtual void taskFunctionality(); private: + PosixThread posixThread; + /** * @brief This is the entry point in a new thread. * diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index 510ec59c..f52067f1 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -1,16 +1,16 @@ #include "fsfw/osal/linux/PeriodicPosixTask.h" -#include #include +#include #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/tasks/ExecutableObjectIF.h" PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, - uint32_t period_, TaskDeadlineMissedFunction dlMissedFunc_) - : PosixThread(name_, priority_, stackSize_), - PeriodicTaskBase(period_, dlMissedFunc_), + TaskPeriod period_, TaskDeadlineMissedFunction dlMissedFunc_) + : PeriodicTaskBase(period_, dlMissedFunc_), + posixThread(name_, priority_, stackSize_), started(false) {} PeriodicPosixTask::~PeriodicPosixTask() { @@ -34,18 +34,19 @@ ReturnValue_t PeriodicPosixTask::startTask(void) { return HasReturnvaluesIF::RETURN_FAILED; } started = true; - PosixThread::createTask(&taskEntryPoint, this); + posixThread.createTask(&taskEntryPoint, this); return HasReturnvaluesIF::RETURN_OK; } void PeriodicPosixTask::taskFunctionality(void) { if (not started) { - suspend(); + posixThread.suspend(); } initObjsAfterTaskCreation(); - uint64_t lastWakeTime = getCurrentMonotonicTimeMs(); + uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs(); + uint64_t periodMs = getPeriodMs(); // The task's "infinite" inner loop is entered. while (1) { for (auto const& objOpCodePair : objectList) { diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 3dcc6bcc..3ab79ed0 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -1,17 +1,15 @@ #ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ #define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_ -#include "PosixThread.h" - #include +#include "PosixThread.h" #include "fsfw/objectmanager/ObjectManagerIF.h" #include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw/tasks/PeriodicTaskIF.h" #include "fsfw/tasks/PeriodicTaskBase.h" +#include "fsfw/tasks/PeriodicTaskIF.h" - -class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase { +class PeriodicPosixTask : public PeriodicTaskBase { public: /** * Create a generic periodic task. @@ -25,7 +23,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase { * @param period_ * @param deadlineMissedFunc_ */ - PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, + PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_, void (*deadlineMissedFunc_)()); virtual ~PeriodicPosixTask(); @@ -41,6 +39,7 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskBase { ReturnValue_t sleepFor(uint32_t ms) override; private: + PosixThread posixThread; /** * @brief Flag to indicate that the task was started and is allowed to run diff --git a/src/fsfw/osal/linux/PosixThread.h b/src/fsfw/osal/linux/PosixThread.h index 69c6c5b7..78fdfa2b 100644 --- a/src/fsfw/osal/linux/PosixThread.h +++ b/src/fsfw/osal/linux/PosixThread.h @@ -35,6 +35,21 @@ class PosixThread { */ void resume(); + /** + * @brief Function that has to be called by derived class because the + * derived class pointer has to be valid as argument. + * @details + * This function creates a pthread with the given parameters. As the + * function requires a pointer to the derived object it has to be called + * after the this pointer of the derived object is valid. + * Sets the taskEntryPoint as function to be called by new a thread. + * @param fnc_ Function which will be executed by the thread. + * @param arg_ + * argument of the taskEntryPoint function, needs to be this pointer + * of derived class + */ + void createTask(void* (*fnc_)(void*), void* arg_); + /** * Delay function similar to FreeRtos delayUntil function * @@ -55,21 +70,6 @@ class PosixThread { protected: pthread_t thread; - /** - * @brief Function that has to be called by derived class because the - * derived class pointer has to be valid as argument. - * @details - * This function creates a pthread with the given parameters. As the - * function requires a pointer to the derived object it has to be called - * after the this pointer of the derived object is valid. - * Sets the taskEntryPoint as function to be called by new a thread. - * @param fnc_ Function which will be executed by the thread. - * @param arg_ - * argument of the taskEntryPoint function, needs to be this pointer - * of derived class - */ - void createTask(void* (*fnc_)(void*), void* arg_); - private: char name[PTHREAD_MAX_NAMELEN]; int priority; diff --git a/src/fsfw/osal/linux/TaskFactory.cpp b/src/fsfw/osal/linux/TaskFactory.cpp index 8503039f..b9e7eb28 100644 --- a/src/fsfw/osal/linux/TaskFactory.cpp +++ b/src/fsfw/osal/linux/TaskFactory.cpp @@ -15,14 +15,14 @@ TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } PeriodicTaskIF* TaskFactory::createPeriodicTask( TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { - return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_ * 1000, + return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_, deadLineMissedFunction_); } FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask( TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { - return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_ * 1000); + return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_); } ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { diff --git a/src/fsfw/tasks/CMakeLists.txt b/src/fsfw/tasks/CMakeLists.txt index 537320b7..6128c272 100644 --- a/src/fsfw/tasks/CMakeLists.txt +++ b/src/fsfw/tasks/CMakeLists.txt @@ -1,3 +1,3 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp - FixedSlotSequence.cpp - PeriodicTaskBase.cpp) +target_sources( + ${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp FixedSlotSequence.cpp + PeriodicTaskBase.cpp) diff --git a/src/fsfw/tasks/PeriodicTaskBase.cpp b/src/fsfw/tasks/PeriodicTaskBase.cpp index 87745b14..021ba7b5 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.cpp +++ b/src/fsfw/tasks/PeriodicTaskBase.cpp @@ -1,17 +1,15 @@ -#include #include "PeriodicTaskBase.h" +#include + #include -PeriodicTaskBase::PeriodicTaskBase(uint32_t periodMs_, - TaskDeadlineMissedFunction deadlineMissedFunc_) - : periodMs(periodMs_), deadlineMissedFunc(deadlineMissedFunc_) {} +PeriodicTaskBase::PeriodicTaskBase(TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_) + : period(period), dlmFunc(dlmFunc_) {} -uint32_t PeriodicTaskBase::getPeriodMs() const { return periodMs; } +uint32_t PeriodicTaskBase::getPeriodMs() const { return static_cast(period * 1000); } -bool PeriodicTaskBase::isEmpty() const { - return objectList.empty(); -} +bool PeriodicTaskBase::isEmpty() const { return objectList.empty(); } ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() { std::multiset uniqueObjects; diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h index cc4eae4b..a262a2d4 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.h +++ b/src/fsfw/tasks/PeriodicTaskBase.h @@ -1,16 +1,17 @@ #ifndef FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ #define FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ +#include +#include + #include "fsfw/tasks/PeriodicTaskIF.h" #include "fsfw/tasks/definitions.h" -#include -#include class ExecutableObjectIF; -class PeriodicTaskBase: public PeriodicTaskIF { -public: - PeriodicTaskBase(uint32_t periodMs, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr); +class PeriodicTaskBase : public PeriodicTaskIF { + public: + PeriodicTaskBase(TaskPeriod period, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr); ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; @@ -21,8 +22,7 @@ public: ReturnValue_t initObjsAfterTaskCreation(); -protected: - + protected: //! Typedef for the List of objects. Will contain the objects to execute and their respective //! operation codes using ObjectList = std::vector>; @@ -32,20 +32,19 @@ protected: ObjectList objectList; /** - * @brief Period of the task in milliseconds + * @brief Period of task in floating point seconds */ - uint32_t periodMs; + TaskPeriod period; /** * @brief The pointer to the deadline-missed function. - * @details This pointer stores the function that is executed if the task's deadline is missed. - * So, each may react individually on a timing failure. The pointer may be - * NULL, then nothing happens on missing the deadline. The deadline is equal to the next execution - * of the periodic task. + * @details + * This pointer stores the function that is executed if the task's deadline + * is missed. So, each may react individually on a timing failure. + * The pointer may be NULL, then nothing happens on missing the deadline. + * The deadline is equal to the next execution of the periodic task. */ - TaskDeadlineMissedFunction deadlineMissedFunc = nullptr; + TaskDeadlineMissedFunction dlmFunc = nullptr; }; - - #endif /* FSFW_SRC_FSFW_TASKS_PERIODICTASKBASE_H_ */ diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h index 076ef56e..ec25faa8 100644 --- a/src/fsfw/tasks/PeriodicTaskIF.h +++ b/src/fsfw/tasks/PeriodicTaskIF.h @@ -1,11 +1,11 @@ #ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_ #define FRAMEWORK_TASK_PERIODICTASKIF_H_ +#include + #include "fsfw/objectmanager/SystemObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h" -#include - /** * New version of TaskIF * Follows RAII principles, i.e. there's no create or delete method. From 64e7d4bb5e61c5ce2ece0bedddaffde086d7fe99 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 18:15:31 +0200 Subject: [PATCH 177/198] continued refactoring --- src/fsfw/osal/host/FixedTimeslotTask.cpp | 19 ++++++------ src/fsfw/osal/host/FixedTimeslotTask.h | 38 ++++++++++-------------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/fsfw/osal/host/FixedTimeslotTask.cpp b/src/fsfw/osal/host/FixedTimeslotTask.cpp index 07853938..0c4acf8e 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/host/FixedTimeslotTask.cpp @@ -22,12 +22,12 @@ FixedTimeslotTask::FixedTimeslotTask(const char* name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod setPeriod, - void (*setDeadlineMissedFunc)()) + TaskDeadlineMissedFunction dlmFunc_) : started(false), - pollingSeqTable(setPeriod * 1000), + pollingSeqTable(static_cast(setPeriod * 1000)), taskName(name), period(setPeriod), - deadlineMissedFunc(setDeadlineMissedFunc) { + dlmFunc(dlmFunc_) { // It is propably possible to set task priorities by using the native // task handles for Windows / Linux mainThread = std::thread(&FixedTimeslotTask::taskEntryPoint, this, this); @@ -39,7 +39,7 @@ FixedTimeslotTask::FixedTimeslotTask(const char* name, TaskPriority setPriority, tasks::insertTaskName(mainThread.get_id(), taskName); } -FixedTimeslotTask::~FixedTimeslotTask(void) { +FixedTimeslotTask::~FixedTimeslotTask() { // Do not delete objects, we were responsible for ptrs only. terminateThread = true; if (mainThread.joinable()) { @@ -48,7 +48,7 @@ FixedTimeslotTask::~FixedTimeslotTask(void) { } void FixedTimeslotTask::taskEntryPoint(void* argument) { - FixedTimeslotTask* originalTask(reinterpret_cast(argument)); + auto* originalTask(reinterpret_cast(argument)); if (not originalTask->started) { // we have to suspend/block here until the task is started. @@ -114,8 +114,7 @@ void FixedTimeslotTask::taskFunctionality() { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { - ExecutableObjectIF* executableObject = - ObjectManager::instance()->get(componentId); + auto* executableObject = ObjectManager::instance()->get(componentId); if (executableObject != nullptr) { pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep, executableObject, this); return HasReturnvaluesIF::RETURN_OK; @@ -133,9 +132,9 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotT return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkSequence() const { return pollingSeqTable.checkSequence(); } +ReturnValue_t FixedTimeslotTask::checkSequence() { return pollingSeqTable.checkSequence(); } -uint32_t FixedTimeslotTask::getPeriodMs() const { return period * 1000; } +uint32_t FixedTimeslotTask::getPeriodMs() const { return static_cast(period * 1000); } bool FixedTimeslotTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval) { bool shouldDelay = false; @@ -176,3 +175,5 @@ bool FixedTimeslotTask::delayForInterval(chron_ms* previousWakeTimeMs, const chr (*previousWakeTimeMs) = currentStartTime; return false; } + +bool FixedTimeslotTask::isEmpty() const { return pollingSeqTable.isEmpty() }; diff --git a/src/fsfw/osal/host/FixedTimeslotTask.h b/src/fsfw/osal/host/FixedTimeslotTask.h index cdbc6f23..69c84c75 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.h +++ b/src/fsfw/osal/host/FixedTimeslotTask.h @@ -6,10 +6,10 @@ #include #include -#include "../../objectmanager/ObjectManagerIF.h" -#include "../../tasks/FixedSlotSequence.h" -#include "../../tasks/FixedTimeslotTaskIF.h" -#include "../../tasks/Typedef.h" +#include "fsfw/objectmanager/ObjectManagerIF.h" +#include "fsfw/tasks/FixedSlotSequence.h" +#include "fsfw/tasks/FixedTimeslotTaskIF.h" +#include "fsfw/tasks/definitions.h" class ExecutableObjectIF; @@ -39,7 +39,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * @brief Currently, the executed object's lifetime is not coupled with * the task object's lifetime, so the destructor is empty. */ - virtual ~FixedTimeslotTask(void); + ~FixedTimeslotTask() override; /** * @brief The method to start the task. @@ -48,7 +48,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * The address of the task object is passed as an argument * to the system call. */ - ReturnValue_t startTask(void); + ReturnValue_t startTask() override; /** * Add timeslot to the polling sequence table. @@ -57,22 +57,23 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * @param executionStep * @return */ - ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); + ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) override; - ReturnValue_t checkSequence() const override; + ReturnValue_t checkSequence() override; - uint32_t getPeriodMs() const; + ReturnValue_t sleepFor(uint32_t ms) override; + uint32_t getPeriodMs() const override; - ReturnValue_t sleepFor(uint32_t ms); + bool isEmpty() const override; protected: using chron_ms = std::chrono::milliseconds; bool started; - //!< Typedef for the List of objects. - typedef std::vector ObjectList; + std::thread mainThread; std::atomic terminateThread{false}; + TaskDeadlineMissedFunction dlmFunc = nullptr; //! Polling sequence table which contains the object to execute //! and information like the timeslots and the passed execution step. @@ -89,15 +90,6 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { */ TaskPeriod period; - /** - * @brief The pointer to the deadline-missed function. - * @details - * This pointer stores the function that is executed if the task's deadline - * is missed. So, each may react individually on a timing failure. - * The pointer may be NULL, then nothing happens on missing the deadline. - * The deadline is equal to the next execution of the periodic task. - */ - void (*deadlineMissedFunc)(void); /** * @brief This is the function executed in the new task's context. * @details @@ -117,9 +109,9 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * the checkAndRestartPeriod system call blocks the task until the next * period. On missing the deadline, the deadlineMissedFunction is executed. */ - void taskFunctionality(void); + void taskFunctionality(); - bool delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval); + bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval); }; #endif /* FRAMEWORK_OSAL_HOST_FIXEDTIMESLOTTASK_H_ */ From 08f1ebf9fc1fac2bdada7005b8dad54f55bf2429 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 May 2022 23:45:38 +0200 Subject: [PATCH 178/198] continued refactoring --- src/fsfw/osal/host/FixedTimeslotTask.cpp | 2 +- src/fsfw/osal/host/FixedTimeslotTask.h | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/fsfw/osal/host/FixedTimeslotTask.cpp b/src/fsfw/osal/host/FixedTimeslotTask.cpp index 0c4acf8e..02570f68 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/host/FixedTimeslotTask.cpp @@ -176,4 +176,4 @@ bool FixedTimeslotTask::delayForInterval(chron_ms* previousWakeTimeMs, const chr return false; } -bool FixedTimeslotTask::isEmpty() const { return pollingSeqTable.isEmpty() }; +bool FixedTimeslotTask::isEmpty() const { return pollingSeqTable.isEmpty(); } diff --git a/src/fsfw/osal/host/FixedTimeslotTask.h b/src/fsfw/osal/host/FixedTimeslotTask.h index 69c84c75..fa7c688d 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.h +++ b/src/fsfw/osal/host/FixedTimeslotTask.h @@ -73,7 +73,6 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { std::thread mainThread; std::atomic terminateThread{false}; - TaskDeadlineMissedFunction dlmFunc = nullptr; //! Polling sequence table which contains the object to execute //! and information like the timeslots and the passed execution step. @@ -89,7 +88,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * It is expressed in clock ticks. */ TaskPeriod period; - + TaskDeadlineMissedFunction dlmFunc = nullptr; /** * @brief This is the function executed in the new task's context. * @details @@ -111,7 +110,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { */ void taskFunctionality(); - bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval); + static bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval); }; #endif /* FRAMEWORK_OSAL_HOST_FIXEDTIMESLOTTASK_H_ */ From 3a162907076f6b0ce592f0282cb786e71ba3eae4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 19 May 2022 00:44:34 +0200 Subject: [PATCH 179/198] refactored and tested hosted and linux task IF --- src/fsfw/osal/host/FixedTimeslotTask.cpp | 23 +++------- src/fsfw/osal/host/FixedTimeslotTask.h | 27 +++--------- src/fsfw/osal/host/PeriodicTask.cpp | 9 +--- src/fsfw/osal/host/PeriodicTask.h | 12 ++--- src/fsfw/osal/host/TaskFactory.cpp | 4 +- src/fsfw/osal/host/taskHelpers.cpp | 2 +- src/fsfw/osal/host/taskHelpers.h | 2 +- src/fsfw/osal/linux/FixedTimeslotTask.cpp | 53 ++++++----------------- src/fsfw/osal/linux/FixedTimeslotTask.h | 24 +++------- src/fsfw/osal/linux/PeriodicPosixTask.cpp | 32 +++++--------- src/fsfw/osal/linux/PeriodicPosixTask.h | 6 +-- src/fsfw/osal/linux/TaskFactory.cpp | 5 ++- src/fsfw/tasks/CMakeLists.txt | 2 +- src/fsfw/tasks/FixedSlotSequence.h | 2 +- src/fsfw/tasks/FixedTimeslotTaskBase.cpp | 29 +++++++++++++ src/fsfw/tasks/FixedTimeslotTaskBase.h | 44 +++++++++++++++++++ src/fsfw/tasks/FixedTimeslotTaskIF.h | 2 +- src/fsfw/tasks/PeriodicTaskBase.cpp | 18 ++++++-- src/fsfw/tasks/PeriodicTaskBase.h | 7 +-- src/fsfw/tasks/PeriodicTaskIF.h | 2 +- src/fsfw/tasks/definitions.h | 2 +- 21 files changed, 160 insertions(+), 147 deletions(-) create mode 100644 src/fsfw/tasks/FixedTimeslotTaskBase.cpp create mode 100644 src/fsfw/tasks/FixedTimeslotTaskBase.h diff --git a/src/fsfw/osal/host/FixedTimeslotTask.cpp b/src/fsfw/osal/host/FixedTimeslotTask.cpp index 02570f68..931e6a22 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/host/FixedTimeslotTask.cpp @@ -3,9 +3,7 @@ #include #include -#include "fsfw/ipc/MutexFactory.h" #include "fsfw/objectmanager/ObjectManager.h" -#include "fsfw/osal/host/FixedTimeslotTask.h" #include "fsfw/osal/host/Mutex.h" #include "fsfw/osal/host/taskHelpers.h" #include "fsfw/platform.h" @@ -23,11 +21,7 @@ FixedTimeslotTask::FixedTimeslotTask(const char* name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod setPeriod, TaskDeadlineMissedFunction dlmFunc_) - : started(false), - pollingSeqTable(static_cast(setPeriod * 1000)), - taskName(name), - period(setPeriod), - dlmFunc(dlmFunc_) { + : FixedTimeslotTaskBase(setPeriod, dlmFunc_), started(false), taskName(name) { // It is propably possible to set task priorities by using the native // task handles for Windows / Linux mainThread = std::thread(&FixedTimeslotTask::taskEntryPoint, this, this); @@ -80,7 +74,7 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { return HasReturnvaluesIF::RETURN_OK; } -void FixedTimeslotTask::taskFunctionality() { +[[noreturn]] void FixedTimeslotTask::taskFunctionality() { pollingSeqTable.intializeSequenceAfterTaskCreation(); // A local iterator for the Polling Sequence Table is created to @@ -106,8 +100,11 @@ void FixedTimeslotTask::taskFunctionality() { // we need to wait before executing the current slot // this gives us the time to wait: interval = chron_ms(this->pollingSeqTable.getIntervalToPreviousSlotMs()); - delayForInterval(¤tStartTime, interval); - // TODO deadline missed check + if (not delayForInterval(¤tStartTime, interval)) { + if (dlmFunc != nullptr) { + dlmFunc(); + } + } } } } @@ -132,10 +129,6 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotT return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkSequence() { return pollingSeqTable.checkSequence(); } - -uint32_t FixedTimeslotTask::getPeriodMs() const { return static_cast(period * 1000); } - bool FixedTimeslotTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval) { bool shouldDelay = false; // Get current wakeup time @@ -175,5 +168,3 @@ bool FixedTimeslotTask::delayForInterval(chron_ms* previousWakeTimeMs, const chr (*previousWakeTimeMs) = currentStartTime; return false; } - -bool FixedTimeslotTask::isEmpty() const { return pollingSeqTable.isEmpty(); } diff --git a/src/fsfw/osal/host/FixedTimeslotTask.h b/src/fsfw/osal/host/FixedTimeslotTask.h index fa7c688d..d85ad34c 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.h +++ b/src/fsfw/osal/host/FixedTimeslotTask.h @@ -8,7 +8,7 @@ #include "fsfw/objectmanager/ObjectManagerIF.h" #include "fsfw/tasks/FixedSlotSequence.h" -#include "fsfw/tasks/FixedTimeslotTaskIF.h" +#include "fsfw/tasks/FixedTimeslotTaskBase.h" #include "fsfw/tasks/definitions.h" class ExecutableObjectIF; @@ -19,7 +19,7 @@ class ExecutableObjectIF; * @details * @ingroup task_handling */ -class FixedTimeslotTask : public FixedTimeslotTaskIF { +class FixedTimeslotTask : public FixedTimeslotTaskBase { public: /** * @brief Standard constructor of the class. @@ -57,14 +57,10 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * @param executionStep * @return */ - ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) override; - - ReturnValue_t checkSequence() override; + ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep) override; ReturnValue_t sleepFor(uint32_t ms) override; - uint32_t getPeriodMs() const override; - - bool isEmpty() const override; protected: using chron_ms = std::chrono::milliseconds; @@ -74,21 +70,10 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { std::thread mainThread; std::atomic terminateThread{false}; - //! Polling sequence table which contains the object to execute - //! and information like the timeslots and the passed execution step. - FixedSlotSequence pollingSeqTable; - std::condition_variable initCondition; std::mutex initMutex; std::string taskName; - /** - * @brief The period of the task. - * @details - * The period determines the frequency of the task's execution. - * It is expressed in clock ticks. - */ - TaskPeriod period; - TaskDeadlineMissedFunction dlmFunc = nullptr; + /** * @brief This is the function executed in the new task's context. * @details @@ -108,7 +93,7 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * the checkAndRestartPeriod system call blocks the task until the next * period. On missing the deadline, the deadlineMissedFunction is executed. */ - void taskFunctionality(); + [[noreturn]] void taskFunctionality(); static bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval); }; diff --git a/src/fsfw/osal/host/PeriodicTask.cpp b/src/fsfw/osal/host/PeriodicTask.cpp index ed4ef3f1..1f18d335 100644 --- a/src/fsfw/osal/host/PeriodicTask.cpp +++ b/src/fsfw/osal/host/PeriodicTask.cpp @@ -3,13 +3,10 @@ #include #include -#include "fsfw/ipc/MutexFactory.h" -#include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/osal/host/Mutex.h" #include "fsfw/osal/host/taskHelpers.h" #include "fsfw/platform.h" #include "fsfw/serviceinterface/ServiceInterface.h" -#include "fsfw/tasks/ExecutableObjectIF.h" #if defined(PLATFORM_WIN) #include @@ -33,7 +30,7 @@ PeriodicTask::PeriodicTask(const char* name, TaskPriority setPriority, TaskStack tasks::insertTaskName(mainThread.get_id(), taskName); } -PeriodicTask::~PeriodicTask(void) { +PeriodicTask::~PeriodicTask() { // Do not delete objects, we were responsible for ptrs only. terminateThread = true; if (mainThread.joinable()) { @@ -42,7 +39,7 @@ PeriodicTask::~PeriodicTask(void) { } void PeriodicTask::taskEntryPoint(void* argument) { - PeriodicTask* originalTask(reinterpret_cast(argument)); + auto* originalTask(reinterpret_cast(argument)); if (not originalTask->started) { // we have to suspend/block here until the task is started. @@ -80,8 +77,6 @@ void PeriodicTask::taskFunctionality() { std::chrono::milliseconds periodChrono(static_cast(period * 1000)); auto currentStartTime{std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch())}; - auto nextStartTime{currentStartTime}; - /* Enter the loop that defines the task behavior. */ for (;;) { if (terminateThread.load()) { diff --git a/src/fsfw/osal/host/PeriodicTask.h b/src/fsfw/osal/host/PeriodicTask.h index a565c584..6fdaae4e 100644 --- a/src/fsfw/osal/host/PeriodicTask.h +++ b/src/fsfw/osal/host/PeriodicTask.h @@ -39,7 +39,7 @@ class PeriodicTask : public PeriodicTaskBase { * @brief Currently, the executed object's lifetime is not coupled with * the task object's lifetime, so the destructor is empty. */ - virtual ~PeriodicTask(void); + ~PeriodicTask() override; /** * @brief The method to start the task. @@ -48,9 +48,9 @@ class PeriodicTask : public PeriodicTaskBase { * The address of the task object is passed as an argument * to the system call. */ - ReturnValue_t startTask(void); + ReturnValue_t startTask() override; - ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; protected: using chron_ms = std::chrono::milliseconds; @@ -81,9 +81,9 @@ class PeriodicTask : public PeriodicTaskBase { * the checkAndRestartPeriod system call blocks the task until the next * period. On missing the deadline, the deadlineMissedFunction is executed. */ - void taskFunctionality(void); + void taskFunctionality(); - bool delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms interval); + static bool delayForInterval(chron_ms* previousWakeTimeMs, chron_ms interval); }; -#endif /* PERIODICTASK_H_ */ +#endif /* FRAMEWORK_OSAL_HOST_PERIODICTASK_H_ */ diff --git a/src/fsfw/osal/host/TaskFactory.cpp b/src/fsfw/osal/host/TaskFactory.cpp index 6e74fd57..ec4c1554 100644 --- a/src/fsfw/osal/host/TaskFactory.cpp +++ b/src/fsfw/osal/host/TaskFactory.cpp @@ -14,9 +14,9 @@ TaskFactory* TaskFactory::factoryInstance = new TaskFactory(); // Not used for the host implementation for now because C++ thread abstraction is used const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = 0; -TaskFactory::TaskFactory() {} +TaskFactory::TaskFactory() = default; -TaskFactory::~TaskFactory() {} +TaskFactory::~TaskFactory() = default; TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } diff --git a/src/fsfw/osal/host/taskHelpers.cpp b/src/fsfw/osal/host/taskHelpers.cpp index aba2948a..432cf30c 100644 --- a/src/fsfw/osal/host/taskHelpers.cpp +++ b/src/fsfw/osal/host/taskHelpers.cpp @@ -6,7 +6,7 @@ std::mutex nameMapLock; std::map taskNameMap; -ReturnValue_t tasks::insertTaskName(std::thread::id threadId, std::string taskName) { +ReturnValue_t tasks::insertTaskName(std::thread::id threadId, const std::string& taskName) { std::lock_guard lg(nameMapLock); auto returnPair = taskNameMap.emplace(threadId, taskName); if (not returnPair.second) { diff --git a/src/fsfw/osal/host/taskHelpers.h b/src/fsfw/osal/host/taskHelpers.h index cf553011..13a71d16 100644 --- a/src/fsfw/osal/host/taskHelpers.h +++ b/src/fsfw/osal/host/taskHelpers.h @@ -7,7 +7,7 @@ namespace tasks { -ReturnValue_t insertTaskName(std::thread::id threadId, std::string taskName); +ReturnValue_t insertTaskName(std::thread::id threadId, const std::string& taskName); std::string getTaskName(std::thread::id threadId); } // namespace tasks diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.cpp b/src/fsfw/osal/linux/FixedTimeslotTask.cpp index 4d912a40..c2823b00 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/linux/FixedTimeslotTask.cpp @@ -1,26 +1,21 @@ #include "fsfw/osal/linux/FixedTimeslotTask.h" -#include +#include -#include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/serviceinterface/ServiceInterface.h" uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; -FixedTimeslotTask::FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, - TaskPeriod periodSeconds_) - : posixThread(name_, priority_, stackSize_), - pst(static_cast(periodSeconds_ * 1000)), +FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_, + TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_) + : FixedTimeslotTaskBase(periodSeconds_, dlmFunc_), + posixThread(name_, priority_, stackSize_), started(false) {} -FixedTimeslotTask::~FixedTimeslotTask() {} - -bool FixedTimeslotTask::isEmpty() const { return pst.isEmpty(); } - void* FixedTimeslotTask::taskEntryPoint(void* arg) { // The argument is re-interpreted as PollingTask. - FixedTimeslotTask* originalTask(reinterpret_cast(arg)); + auto* originalTask(reinterpret_cast(arg)); // The task's functionality is called. originalTask->taskFunctionality(); return nullptr; @@ -36,45 +31,25 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { return PosixThread::sleep((uint64_t)ms * 1000000); } -uint32_t FixedTimeslotTask::getPeriodMs() const { return pst.getLengthMs(); } - -ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, - int8_t executionStep) { - ExecutableObjectIF* executableObject = - ObjectManager::instance()->get(componentId); - if (executableObject != nullptr) { - pst.addSlot(componentId, slotTimeMs, executionStep, executableObject, this); - return HasReturnvaluesIF::RETURN_OK; - } - -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Component " << std::hex << componentId << " not found, not adding it to pst" - << std::dec << std::endl; -#endif - return HasReturnvaluesIF::RETURN_FAILED; -} - -ReturnValue_t FixedTimeslotTask::checkSequence() { return pst.checkSequence(); } - -void FixedTimeslotTask::taskFunctionality() { +[[noreturn]] void FixedTimeslotTask::taskFunctionality() { // Like FreeRTOS pthreads are running as soon as they are created if (!started) { posixThread.suspend(); } - pst.intializeSequenceAfterTaskCreation(); + pollingSeqTable.intializeSequenceAfterTaskCreation(); // The start time for the first entry is read. - uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs(); - uint64_t interval = pst.getIntervalToNextSlotMs(); + uint64_t lastWakeTime = PosixThread::getCurrentMonotonicTimeMs(); + uint32_t interval = 0; // The task's "infinite" inner loop is entered. - while (1) { - if (pst.slotFollowsImmediately()) { + while (true) { + if (pollingSeqTable.slotFollowsImmediately()) { // Do nothing } else { // The interval for the next polling slot is selected. - interval = this->pst.getIntervalToPreviousSlotMs(); + interval = pollingSeqTable.getIntervalToPreviousSlotMs(); // The period is checked and restarted with the new interval. // If the deadline was missed, the deadlineMissedFunc is called. if (!PosixThread::delayUntil(&lastWakeTime, interval)) { @@ -83,7 +58,7 @@ void FixedTimeslotTask::taskFunctionality() { } } // The device handler for this slot is executed and the next one is chosen. - this->pst.executeAndAdvance(); + pollingSeqTable.executeAndAdvance(); } } diff --git a/src/fsfw/osal/linux/FixedTimeslotTask.h b/src/fsfw/osal/linux/FixedTimeslotTask.h index ecce7321..d6c7c0fb 100644 --- a/src/fsfw/osal/linux/FixedTimeslotTask.h +++ b/src/fsfw/osal/linux/FixedTimeslotTask.h @@ -5,10 +5,10 @@ #include "PosixThread.h" #include "fsfw/tasks/FixedSlotSequence.h" -#include "fsfw/tasks/FixedTimeslotTaskIF.h" +#include "fsfw/tasks/FixedTimeslotTaskBase.h" #include "fsfw/tasks/definitions.h" -class FixedTimeslotTask : public FixedTimeslotTaskIF { +class FixedTimeslotTask : public FixedTimeslotTaskBase { public: /** * Create a generic periodic task. @@ -22,22 +22,14 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * @param period_ * @param deadlineMissedFunc_ */ - FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod periodSeconds_); - virtual ~FixedTimeslotTask(); + FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_, + TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_); + ~FixedTimeslotTask() override = default; ReturnValue_t startTask() override; ReturnValue_t sleepFor(uint32_t ms) override; - uint32_t getPeriodMs() const override; - - ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, - int8_t executionStep) override; - - ReturnValue_t checkSequence() override; - - bool isEmpty() const override; - /** * This static function can be used as #deadlineMissedFunc. * It counts missedDeadlines and prints the number of missed deadlines every 10th time. @@ -57,10 +49,11 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * It links the functionalities provided by FixedSlotSequence with the * OS's System Calls to keep the timing of the periods. */ - virtual void taskFunctionality(); + [[noreturn]] virtual void taskFunctionality(); private: PosixThread posixThread; + bool started; /** * @brief This is the entry point in a new thread. @@ -74,9 +67,6 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { * arbitrary data. */ static void* taskEntryPoint(void* arg); - FixedSlotSequence pst; - - bool started; }; #endif /* FSFW_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ */ diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.cpp b/src/fsfw/osal/linux/PeriodicPosixTask.cpp index f52067f1..09b106ed 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.cpp +++ b/src/fsfw/osal/linux/PeriodicPosixTask.cpp @@ -1,35 +1,27 @@ -#include "fsfw/osal/linux/PeriodicPosixTask.h" +#include "PeriodicPosixTask.h" -#include -#include - -#include "fsfw/objectmanager/ObjectManager.h" -#include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/serviceinterface.h" #include "fsfw/tasks/ExecutableObjectIF.h" PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, - TaskPeriod period_, TaskDeadlineMissedFunction dlMissedFunc_) - : PeriodicTaskBase(period_, dlMissedFunc_), + TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_) + : PeriodicTaskBase(period_, dlmFunc_), posixThread(name_, priority_, stackSize_), started(false) {} -PeriodicPosixTask::~PeriodicPosixTask() { - // Not Implemented -} - void* PeriodicPosixTask::taskEntryPoint(void* arg) { // The argument is re-interpreted as PollingTask. - PeriodicPosixTask* originalTask(reinterpret_cast(arg)); + auto* originalTask(reinterpret_cast(arg)); // The task's functionality is called. originalTask->taskFunctionality(); return nullptr; } ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { - return PosixThread::sleep(static_cast(ms * 1000000)); + return PosixThread::sleep(static_cast(ms) * 1000000); } -ReturnValue_t PeriodicPosixTask::startTask(void) { +ReturnValue_t PeriodicPosixTask::startTask() { if (isEmpty()) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -38,24 +30,24 @@ ReturnValue_t PeriodicPosixTask::startTask(void) { return HasReturnvaluesIF::RETURN_OK; } -void PeriodicPosixTask::taskFunctionality(void) { +[[noreturn]] void PeriodicPosixTask::taskFunctionality() { if (not started) { posixThread.suspend(); } initObjsAfterTaskCreation(); - uint64_t lastWakeTime = posixThread.getCurrentMonotonicTimeMs(); + uint64_t lastWakeTime = PosixThread::getCurrentMonotonicTimeMs(); uint64_t periodMs = getPeriodMs(); // The task's "infinite" inner loop is entered. - while (1) { + while (true) { for (auto const& objOpCodePair : objectList) { objOpCodePair.first->performOperation(objOpCodePair.second); } if (not PosixThread::delayUntil(&lastWakeTime, periodMs)) { - if (this->deadlineMissedFunc != nullptr) { - this->deadlineMissedFunc(); + if (dlmFunc != nullptr) { + dlmFunc(); } } } diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 3ab79ed0..085c10b9 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -24,8 +24,8 @@ class PeriodicPosixTask : public PeriodicTaskBase { * @param deadlineMissedFunc_ */ PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_, - void (*deadlineMissedFunc_)()); - virtual ~PeriodicPosixTask(); + TaskDeadlineMissedFunction dlmFunc_); + ~PeriodicPosixTask() override = default; /** * @brief The method to start the task. @@ -54,7 +54,7 @@ class PeriodicPosixTask : public PeriodicTaskBase { * will be blocked until the next period. On missing the deadline, the deadlineMissedFunction is * executed. */ - virtual void taskFunctionality(void); + [[noreturn]] virtual void taskFunctionality(); /** * @brief This is the entry point in a new thread. * diff --git a/src/fsfw/osal/linux/TaskFactory.cpp b/src/fsfw/osal/linux/TaskFactory.cpp index b9e7eb28..a28e685d 100644 --- a/src/fsfw/osal/linux/TaskFactory.cpp +++ b/src/fsfw/osal/linux/TaskFactory.cpp @@ -8,7 +8,7 @@ // TODO: Different variant than the lazy loading in QueueFactory. What's better and why? TaskFactory* TaskFactory::factoryInstance = new TaskFactory(); -TaskFactory::~TaskFactory() {} +TaskFactory::~TaskFactory() = default; TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } @@ -22,7 +22,8 @@ PeriodicTaskIF* TaskFactory::createPeriodicTask( FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask( TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { - return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_); + return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_, + deadLineMissedFunction_); } ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { diff --git a/src/fsfw/tasks/CMakeLists.txt b/src/fsfw/tasks/CMakeLists.txt index 6128c272..1d4ab4e1 100644 --- a/src/fsfw/tasks/CMakeLists.txt +++ b/src/fsfw/tasks/CMakeLists.txt @@ -1,3 +1,3 @@ target_sources( ${LIB_FSFW_NAME} PRIVATE FixedSequenceSlot.cpp FixedSlotSequence.cpp - PeriodicTaskBase.cpp) + PeriodicTaskBase.cpp FixedTimeslotTaskBase.cpp) diff --git a/src/fsfw/tasks/FixedSlotSequence.h b/src/fsfw/tasks/FixedSlotSequence.h index 5ece7126..838963c1 100644 --- a/src/fsfw/tasks/FixedSlotSequence.h +++ b/src/fsfw/tasks/FixedSlotSequence.h @@ -35,7 +35,7 @@ class FixedSlotSequence { * @brief The constructor of the FixedSlotSequence object. * @param setLength The period length, expressed in ms. */ - FixedSlotSequence(uint32_t setLengthMs); + explicit FixedSlotSequence(uint32_t setLengthMs); /** * @brief The destructor of the FixedSlotSequence object. diff --git a/src/fsfw/tasks/FixedTimeslotTaskBase.cpp b/src/fsfw/tasks/FixedTimeslotTaskBase.cpp new file mode 100644 index 00000000..26726582 --- /dev/null +++ b/src/fsfw/tasks/FixedTimeslotTaskBase.cpp @@ -0,0 +1,29 @@ +#include "FixedTimeslotTaskBase.h" + +#include "fsfw/objectmanager/ObjectManager.h" + +FixedTimeslotTaskBase::FixedTimeslotTaskBase(TaskPeriod period_, + TaskDeadlineMissedFunction dlmFunc_) + : pollingSeqTable(getPeriodMs()), period(period_), dlmFunc(dlmFunc_) {} +uint32_t FixedTimeslotTaskBase::getPeriodMs() const { return static_cast(period * 1000); } + +bool FixedTimeslotTaskBase::isEmpty() const { return pollingSeqTable.isEmpty(); } + +ReturnValue_t FixedTimeslotTaskBase::checkSequence() { return pollingSeqTable.checkSequence(); } + +ReturnValue_t FixedTimeslotTaskBase::addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep) { + auto* executableObject = ObjectManager::instance()->get(componentId); + if (executableObject != nullptr) { + pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep, executableObject, this); + return HasReturnvaluesIF::RETURN_OK; + } + +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "Component 0x" << std::hex << std::setw(8) << std::setfill('0') << componentId + << std::setfill(' ') << " not found, not adding it to PST" << std::dec << std::endl; +#else + sif::printError("Component 0x%08x not found, not adding it to PST\n"); +#endif + return HasReturnvaluesIF::RETURN_FAILED; +} diff --git a/src/fsfw/tasks/FixedTimeslotTaskBase.h b/src/fsfw/tasks/FixedTimeslotTaskBase.h new file mode 100644 index 00000000..91a4f649 --- /dev/null +++ b/src/fsfw/tasks/FixedTimeslotTaskBase.h @@ -0,0 +1,44 @@ +#ifndef FSFW_EXAMPLE_HOSTED_FIXEDTIMESLOTTASKBASE_H +#define FSFW_EXAMPLE_HOSTED_FIXEDTIMESLOTTASKBASE_H + +#include "FixedSlotSequence.h" +#include "FixedTimeslotTaskIF.h" +#include "definitions.h" + +class FixedTimeslotTaskBase : public FixedTimeslotTaskIF { + public: + explicit FixedTimeslotTaskBase(TaskPeriod period, TaskDeadlineMissedFunction dlmFunc = nullptr); + ~FixedTimeslotTaskBase() override = default; + ; + + protected: + //! Polling sequence table which contains the object to execute + //! and information like the timeslots and the passed execution step. + FixedSlotSequence pollingSeqTable; + + /** + * @brief Period of task in floating point seconds + */ + TaskPeriod period; + + /** + * @brief The pointer to the deadline-missed function. + * @details + * This pointer stores the function that is executed if the task's deadline + * is missed. So, each may react individually on a timing failure. + * The pointer may be NULL, then nothing happens on missing the deadline. + * The deadline is equal to the next execution of the periodic task. + */ + TaskDeadlineMissedFunction dlmFunc = nullptr; + + ReturnValue_t checkSequence() override; + + [[nodiscard]] uint32_t getPeriodMs() const override; + + [[nodiscard]] bool isEmpty() const override; + + ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep) override; +}; + +#endif // FSFW_EXAMPLE_HOSTED_FIXEDTIMESLOTTASKBASE_H diff --git a/src/fsfw/tasks/FixedTimeslotTaskIF.h b/src/fsfw/tasks/FixedTimeslotTaskIF.h index 9d85ac4a..dec382c3 100644 --- a/src/fsfw/tasks/FixedTimeslotTaskIF.h +++ b/src/fsfw/tasks/FixedTimeslotTaskIF.h @@ -11,7 +11,7 @@ */ class FixedTimeslotTaskIF : public PeriodicTaskIF { public: - virtual ~FixedTimeslotTaskIF() {} + ~FixedTimeslotTaskIF() override = default; static constexpr ReturnValue_t SLOT_LIST_EMPTY = HasReturnvaluesIF::makeReturnCode(CLASS_ID::FIXED_SLOT_TASK_IF, 0); diff --git a/src/fsfw/tasks/PeriodicTaskBase.cpp b/src/fsfw/tasks/PeriodicTaskBase.cpp index 021ba7b5..cc8784d9 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.cpp +++ b/src/fsfw/tasks/PeriodicTaskBase.cpp @@ -1,11 +1,21 @@ #include "PeriodicTaskBase.h" -#include - #include +#include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw/serviceinterface.h" + PeriodicTaskBase::PeriodicTaskBase(TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_) - : period(period), dlmFunc(dlmFunc_) {} + : period(period_), dlmFunc(dlmFunc_) { + // Hints at configuration error + if (PeriodicTaskBase::getPeriodMs() <= 1) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "Passed task period 0 or smaller than 1 ms" << std::endl; +#else + sif::printWarning("Passed task period 0 or smaller than 1ms\n"); +#endif + } +} uint32_t PeriodicTaskBase::getPeriodMs() const { return static_cast(period * 1000); } @@ -32,7 +42,7 @@ ReturnValue_t PeriodicTaskBase::initObjsAfterTaskCreation() { } ReturnValue_t PeriodicTaskBase::addComponent(object_id_t object, uint8_t opCode) { - ExecutableObjectIF* newObject = ObjectManager::instance()->get(object); + auto* newObject = ObjectManager::instance()->get(object); return addComponent(newObject, opCode); } diff --git a/src/fsfw/tasks/PeriodicTaskBase.h b/src/fsfw/tasks/PeriodicTaskBase.h index a262a2d4..68791fb8 100644 --- a/src/fsfw/tasks/PeriodicTaskBase.h +++ b/src/fsfw/tasks/PeriodicTaskBase.h @@ -11,14 +11,15 @@ class ExecutableObjectIF; class PeriodicTaskBase : public PeriodicTaskIF { public: - PeriodicTaskBase(TaskPeriod period, TaskDeadlineMissedFunction deadlineMissedFunc = nullptr); + explicit PeriodicTaskBase(TaskPeriod period, + TaskDeadlineMissedFunction deadlineMissedFunc = nullptr); ReturnValue_t addComponent(object_id_t object, uint8_t opCode) override; ReturnValue_t addComponent(ExecutableObjectIF* object, uint8_t opCode) override; - uint32_t getPeriodMs() const override; + [[nodiscard]] uint32_t getPeriodMs() const override; - bool isEmpty() const override; + [[nodiscard]] bool isEmpty() const override; ReturnValue_t initObjsAfterTaskCreation(); diff --git a/src/fsfw/tasks/PeriodicTaskIF.h b/src/fsfw/tasks/PeriodicTaskIF.h index ec25faa8..a6d6a6d6 100644 --- a/src/fsfw/tasks/PeriodicTaskIF.h +++ b/src/fsfw/tasks/PeriodicTaskIF.h @@ -17,7 +17,7 @@ class PeriodicTaskIF { /** * @brief A virtual destructor as it is mandatory for interfaces. */ - virtual ~PeriodicTaskIF() {} + virtual ~PeriodicTaskIF() = default; /** * @brief With the startTask method, a created task can be started * for the first time. diff --git a/src/fsfw/tasks/definitions.h b/src/fsfw/tasks/definitions.h index bca9b768..586884b6 100644 --- a/src/fsfw/tasks/definitions.h +++ b/src/fsfw/tasks/definitions.h @@ -5,7 +5,7 @@ #include using TaskName = const char*; -using TaskPriority = uint32_t; +using TaskPriority = int; using TaskStackSize = size_t; using TaskPeriod = double; using TaskDeadlineMissedFunction = void (*)(); From d0fc360697e0fae7ccb4b827b8bc3d0398c342bc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 20 May 2022 08:34:14 +0200 Subject: [PATCH 180/198] apply afmt --- src/fsfw/objectmanager/frameworkObjects.h | 1 + src/fsfw/pus/Service11TelecommandScheduling.h | 48 +++++++------------ .../pus/Service11TelecommandScheduling.tpp | 48 +++++++++++-------- 3 files changed, 44 insertions(+), 53 deletions(-) diff --git a/src/fsfw/objectmanager/frameworkObjects.h b/src/fsfw/objectmanager/frameworkObjects.h index cc233c0f..cddc6ba2 100644 --- a/src/fsfw/objectmanager/frameworkObjects.h +++ b/src/fsfw/objectmanager/frameworkObjects.h @@ -14,6 +14,7 @@ enum framework_objects : object_id_t { PUS_SERVICE_5_EVENT_REPORTING = 0x53000005, PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008, PUS_SERVICE_9_TIME_MGMT = 0x53000009, + PUS_SERVICE_11_TC_SCHEDULER = 0x53000011, PUS_SERVICE_17_TEST = 0x53000017, PUS_SERVICE_20_PARAMETERS = 0x53000020, PUS_SERVICE_200_MODE_MGMT = 0x53000200, diff --git a/src/fsfw/pus/Service11TelecommandScheduling.h b/src/fsfw/pus/Service11TelecommandScheduling.h index 5e446b07..9a8be603 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.h +++ b/src/fsfw/pus/Service11TelecommandScheduling.h @@ -45,19 +45,17 @@ class Service11TelecommandScheduling final : public PusServiceBase { HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3); // The types of PUS-11 subservices - enum Subservice : uint8_t { - ENABLE_SCHEDULING = 1, - DISABLE_SCHEDULING = 2, - RESET_SCHEDULING = 3, - INSERT_ACTIVITY = 4, - DELETE_ACTIVITY = 5, - FILTER_DELETE_ACTIVITY = 6, - TIMESHIFT_ACTIVITY = 7, - FILTER_TIMESHIFT_ACTIVITY = 8, - DETAIL_REPORT = 9, - TIMEBASE_SCHEDULE_DETAIL_REPORT = 10, - TIMESHIFT_ALL_SCHEDULE_ACTIVITIES = 15 - }; + enum [[maybe_unused]] Subservice : uint8_t{ENABLE_SCHEDULING = 1, + DISABLE_SCHEDULING = 2, + RESET_SCHEDULING = 3, + INSERT_ACTIVITY = 4, + DELETE_ACTIVITY = 5, + FILTER_DELETE_ACTIVITY = 6, + TIMESHIFT_ACTIVITY = 7, + FILTER_TIMESHIFT_ACTIVITY = 8, + DETAIL_REPORT = 9, + TIMEBASE_SCHEDULE_DETAIL_REPORT = 10, + TIMESHIFT_ALL_SCHEDULE_ACTIVITIES = 15}; // The types of time windows for TC[11,6] and TC[11,8], as defined in ECSS-E-ST-70-41C, // requirement 8.11.3c (p. 507) @@ -73,7 +71,7 @@ class Service11TelecommandScheduling final : public PusServiceBase { uint16_t releaseTimeMarginSeconds = DEFAULT_RELEASE_TIME_MARGIN, bool debugMode = false); - ~Service11TelecommandScheduling(); + ~Service11TelecommandScheduling() override; /** PusServiceBase overrides */ ReturnValue_t handleRequest(uint8_t subservice) override; @@ -82,8 +80,8 @@ class Service11TelecommandScheduling final : public PusServiceBase { private: struct TelecommandStruct { - uint64_t requestId; - uint32_t seconds; + uint64_t requestId{}; + uint32_t seconds{}; store_address_t storeAddr; // uint16 }; @@ -92,9 +90,6 @@ class Service11TelecommandScheduling final : public PusServiceBase { // minimum release time offset to insert into schedule const uint16_t RELEASE_TIME_MARGIN_SECONDS = 5; - // the maximum amount of stored TCs is defined here - static constexpr uint16_t MAX_STORED_TELECOMMANDS = 500; - bool debugMode = false; StorageManagerIF* tcStore = nullptr; AcceptsTelecommandsIF* tcRecipient = nullptr; @@ -139,17 +134,6 @@ class Service11TelecommandScheduling final : public PusServiceBase { */ ReturnValue_t doFilterTimeshiftActivity(const uint8_t* data, size_t size); - /** - * @brief Deserializes a generic type from a payload buffer by using the FSFW - * SerializeAdapter Interface. - * @param output Output to be deserialized - * @param buf Payload buffer (application data) - * @param bufsize Remaining size of payload buffer (application data size) - * @return RETURN_OK if successful - */ - template - ReturnValue_t deserializeViaFsfwInterface(T& output, const uint8_t* buf, size_t bufsize); - /** * @brief Extracts the Request ID from the Application Data of a TC by utilizing a ctor of the * class TcPacketPus. @@ -177,7 +161,7 @@ class Service11TelecommandScheduling final : public PusServiceBase { * @param ssc Source Sequence Count * @return Request ID */ - uint64_t buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const; + [[nodiscard]] uint64_t buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const; /** * @brief Gets the filter range for filter TCs from a data packet @@ -194,7 +178,7 @@ class Service11TelecommandScheduling final : public PusServiceBase { /** * @brief Prints content of multimap. Use for simple debugging only. */ - void debugPrintMultimapContent(void) const; + void debugPrintMultimapContent() const; }; #include "Service11TelecommandScheduling.tpp" diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index c72e6631..41c36200 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -1,11 +1,12 @@ #pragma once -#include -#include -#include - #include +#include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw/serialize/SerializeAdapter.h" +#include "fsfw/serviceinterface.h" +#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" + static constexpr auto DEF_END = SerializeIF::Endianness::BIG; template @@ -18,7 +19,7 @@ inline Service11TelecommandScheduling::Service11TelecommandScheduli tcRecipient(tcRecipient) {} template -inline Service11TelecommandScheduling::~Service11TelecommandScheduling() {} +inline Service11TelecommandScheduling::~Service11TelecommandScheduling() = default; template inline ReturnValue_t Service11TelecommandScheduling::handleRequest( @@ -404,7 +405,6 @@ inline ReturnValue_t Service11TelecommandScheduling::doFilterTimesh // and then insert it again as new entry telecommandMap.insert(std::make_pair(tempKey, tempTc)); shiftedItemsCount++; - continue; } if (debugMode) { @@ -463,9 +463,9 @@ template inline uint64_t Service11TelecommandScheduling::buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const { - uint64_t sourceId64 = static_cast(sourceId); - uint64_t apid64 = static_cast(apid); - uint64_t ssc64 = static_cast(ssc); + auto sourceId64 = static_cast(sourceId); + auto apid64 = static_cast(apid); + auto ssc64 = static_cast(ssc); return (sourceId64 << 32) | (apid64 << 16) | ssc64; } @@ -483,7 +483,7 @@ inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFr if (typeRaw > 3) { return INVALID_TYPE_TIME_WINDOW; } - TypeOfTimeWindow type = static_cast(typeRaw); + auto type = static_cast(typeRaw); // we now have the type of delete activity - so now we set the range to delete, // according to the type of time window. @@ -558,7 +558,10 @@ inline ReturnValue_t Service11TelecommandScheduling::getMapFilterFr // additional security check, this should never be true if (itBegin->first > itEnd->first) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 +#else sif::printError("11::GetMapFilterFromData: itBegin > itEnd\n"); +#endif return RETURN_FAILED; } @@ -580,19 +583,22 @@ inline ReturnValue_t Service11TelecommandScheduling::handleInvalidD } template -inline void Service11TelecommandScheduling::debugPrintMultimapContent(void) const { +inline void Service11TelecommandScheduling::debugPrintMultimapContent() const { + for (const auto &dit : telecommandMap) { #if FSFW_DISABLE_PRINTOUT == 0 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content" - << std::endl; - sif::debug << "[" << dit->first << "]: Request ID: " << dit->second.requestId << " | " - << "Store Address: " << dit->second.storeAddr << std::endl; + sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content" + << std::endl; + sif::debug << "[" << dit.first << "]: Request ID: " << dit.second.requestId << " | " + << "Store Address: " << dit.second.storeAddr.raw << std::endl; #else - sif::printDebug("Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content\n"); - for (auto dit = telecommandMap.begin(); dit != telecommandMap.end(); ++dit) { - sif::printDebug("[%d]: Request ID: %d | Store Address: %d\n", dit->first, - dit->second.requestId, dit->second.storeAddr); + sif::printDebug( + "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content\n"); + for (auto dit = telecommandMap.begin(); dit != telecommandMap.end(); ++dit) { + sif::printDebug("[%d]: Request ID: %d | Store Address: %d\n", dit->first, + dit->second.requestId, dit->second.storeAddr); + } +#endif +#endif } -#endif -#endif } From dac700b80a98d9bfb5a9153c47589ce72c9381fc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 20 May 2022 08:59:06 +0200 Subject: [PATCH 181/198] static STORE renamed --- .../tmtcpacket/pus/tc/TcPacketStoredBase.cpp | 22 ++++++++++--------- .../tmtcpacket/pus/tc/TcPacketStoredBase.h | 6 ++--- src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h | 2 +- .../tmtcpacket/pus/tc/TcPacketStoredPus.cpp | 12 +++++----- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.cpp b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.cpp index 8cc38c5f..22918526 100644 --- a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.cpp +++ b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.cpp @@ -6,20 +6,20 @@ #include "fsfw/objectmanager/frameworkObjects.h" #include "fsfw/serviceinterface/ServiceInterface.h" -StorageManagerIF* TcPacketStoredBase::store = nullptr; +StorageManagerIF* TcPacketStoredBase::STORE = nullptr; TcPacketStoredBase::TcPacketStoredBase() { this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; - this->checkAndSetStore(); + TcPacketStoredBase::checkAndSetStore(); } -TcPacketStoredBase::~TcPacketStoredBase() {} +TcPacketStoredBase::~TcPacketStoredBase() = default; ReturnValue_t TcPacketStoredBase::getData(const uint8_t** dataPtr, size_t* dataSize) { - auto result = this->store->getData(storeAddress, dataPtr, dataSize); + auto result = TcPacketStoredBase::STORE->getData(storeAddress, dataPtr, dataSize); if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TcPacketStoredBase: Could not get data!" << std::endl; + sif::warning << "TcPacketStoredBase: Could not get data" << std::endl; #else sif::printWarning("TcPacketStoredBase: Could not get data!\n"); #endif @@ -28,11 +28,13 @@ ReturnValue_t TcPacketStoredBase::getData(const uint8_t** dataPtr, size_t* dataS } bool TcPacketStoredBase::checkAndSetStore() { - if (this->store == nullptr) { - this->store = ObjectManager::instance()->get(objects::TC_STORE); - if (this->store == nullptr) { + if (TcPacketStoredBase::STORE == nullptr) { + TcPacketStoredBase::STORE = ObjectManager::instance()->get(objects::TC_STORE); + if (TcPacketStoredBase::STORE == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcPacketStoredBase::TcPacketStoredBase: TC Store not found!" << std::endl; + sif::error << "TcPacketStoredBase::TcPacketStoredBase: TC Store not found" << std::endl; +#else + sif::printError("TcPacketStoredBase::TcPacketStoredBase: TC Store not found\n"); #endif return false; } @@ -47,7 +49,7 @@ void TcPacketStoredBase::setStoreAddress(store_address_t setAddress, size_t tempSize; ReturnValue_t status = StorageManagerIF::RETURN_FAILED; if (this->checkAndSetStore()) { - status = this->store->getData(this->storeAddress, &tempData, &tempSize); + status = TcPacketStoredBase::STORE->getData(this->storeAddress, &tempData, &tempSize); } if (status == StorageManagerIF::RETURN_OK) { diff --git a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.h b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.h index 86f0d94e..ece0e482 100644 --- a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.h +++ b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.h @@ -65,7 +65,7 @@ class TcPacketStoredBase : public TcPacketStoredIF { * call tries to set it and throws an error message in case of failures. * The default store is objects::TC_STORE. */ - static StorageManagerIF* store; + static StorageManagerIF* STORE; /** * The address where the packet data of the object instance is stored. */ @@ -77,7 +77,7 @@ class TcPacketStoredBase : public TcPacketStoredIF { * @return @li @c true if the store is linked or could be created. * @li @c false otherwise. */ - bool checkAndSetStore(); + static bool checkAndSetStore(); }; -#endif /* TMTCPACKET_PUS_TcPacketStoredBase_H_ */ +#endif /* TMTCPACKET_PUS_TCPACKETSTORED_H_ */ diff --git a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h index ac4019cd..4baeb3c5 100644 --- a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h +++ b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h @@ -9,7 +9,7 @@ class TcPacketStoredIF { public: - virtual ~TcPacketStoredIF(){}; + virtual ~TcPacketStoredIF()= default;; /** * With this call, the stored packet can be set to another packet in a store. This is useful diff --git a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredPus.cpp b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredPus.cpp index 153ad863..643c2ecc 100644 --- a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredPus.cpp +++ b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredPus.cpp @@ -14,8 +14,8 @@ TcPacketStoredPus::TcPacketStoredPus(uint16_t apid, uint8_t service, uint8_t sub } uint8_t* pData = nullptr; ReturnValue_t returnValue = - this->store->getFreeElement(&this->storeAddress, (TC_PACKET_MIN_SIZE + size), &pData); - if (returnValue != this->store->RETURN_OK) { + this->STORE->getFreeElement(&this->storeAddress, (TC_PACKET_MIN_SIZE + size), &pData); + if (returnValue != this->STORE->RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TcPacketStoredBase: Could not get free element from store!" << std::endl; #endif @@ -44,19 +44,19 @@ TcPacketStoredPus::TcPacketStoredPus(const uint8_t* data, size_t size) : TcPacke return; } if (this->checkAndSetStore()) { - ReturnValue_t status = store->addData(&storeAddress, data, size); + ReturnValue_t status = STORE->addData(&storeAddress, data, size); if (status != HasReturnvaluesIF::RETURN_OK) { this->setData(nullptr, size); } const uint8_t* storePtr = nullptr; // Repoint base data pointer to the data in the store. - store->getData(storeAddress, &storePtr, &size); + STORE->getData(storeAddress, &storePtr, &size); this->setData(const_cast(storePtr), size); } } ReturnValue_t TcPacketStoredPus::deletePacket() { - ReturnValue_t result = this->store->deleteData(this->storeAddress); + ReturnValue_t result = this->STORE->deleteData(this->storeAddress); this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; // To circumvent size checks this->setData(nullptr, -1); @@ -68,7 +68,7 @@ TcPacketPusBase* TcPacketStoredPus::getPacketBase() { return this; } bool TcPacketStoredPus::isSizeCorrect() { const uint8_t* temp_data = nullptr; size_t temp_size; - ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, &temp_size); + ReturnValue_t status = this->STORE->getData(this->storeAddress, &temp_data, &temp_size); if (status == StorageManagerIF::RETURN_OK) { if (this->getFullSize() == temp_size) { return true; From 8e2597f609f54d7b4fe58183a3ff955cc5930cc7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 20 May 2022 11:09:03 +0200 Subject: [PATCH 182/198] clang-format --- src/fsfw/pus/Service5EventReporting.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/pus/Service5EventReporting.cpp b/src/fsfw/pus/Service5EventReporting.cpp index 4517bc26..987217dc 100644 --- a/src/fsfw/pus/Service5EventReporting.cpp +++ b/src/fsfw/pus/Service5EventReporting.cpp @@ -86,8 +86,8 @@ ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) { // In addition to the default PUSServiceBase initialization, this service needs // to be registered to the event manager to listen for events. ReturnValue_t Service5EventReporting::initialize() { - EventManagerIF* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); - if (manager == NULL) { + auto* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); + if (manager == nullptr) { return RETURN_FAILED; } // register Service 5 as listener for events From 0b53b4873fc4f7773a9ec59a985369794ceef3a6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 20 May 2022 11:20:31 +0200 Subject: [PATCH 183/198] bugfix for srv11 --- src/fsfw/pus/Service11TelecommandScheduling.tpp | 4 +--- src/fsfw/tcdistribution/PUSDistributor.cpp | 10 ++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index 41c36200..5ee08194 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -117,8 +117,6 @@ template inline ReturnValue_t Service11TelecommandScheduling::doInsertActivity( const uint8_t *data, size_t size) { uint32_t timestamp = 0; - const uint8_t *initData = data; - size_t initSz = size; ReturnValue_t result = SerializeAdapter::deSerialize(×tamp, &data, &size, DEF_END); if (result != RETURN_OK) { return result; @@ -143,7 +141,7 @@ inline ReturnValue_t Service11TelecommandScheduling::doInsertActivi // store currentPacket and receive the store address store_address_t addr{}; - if (tcStore->addData(&addr, initData, initSz) != RETURN_OK || + if (tcStore->addData(&addr, data, size) != RETURN_OK || addr.raw == storeId::INVALID_STORE_ADDRESS) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "Service11TelecommandScheduling::doInsertActivity: Adding data to TC Store failed" diff --git a/src/fsfw/tcdistribution/PUSDistributor.cpp b/src/fsfw/tcdistribution/PUSDistributor.cpp index aadecd69..5c02145d 100644 --- a/src/fsfw/tcdistribution/PUSDistributor.cpp +++ b/src/fsfw/tcdistribution/PUSDistributor.cpp @@ -15,7 +15,7 @@ PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} -PUSDistributor::~PUSDistributor() {} +PUSDistributor::~PUSDistributor() = default; PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { #if FSFW_CPP_OSTREAM_ENABLED == 1 && PUS_DISTRIBUTOR_DEBUGGING == 1 @@ -23,7 +23,7 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { sif::debug << "PUSDistributor::handlePacket received: " << storeId.poolIndex << ", " << storeId.packetIndex << std::endl; #endif - TcMqMapIter queueMapIt = this->queueMap.end(); + auto queueMapIt = this->queueMap.end(); if (this->currentPacket == nullptr) { return queueMapIt; } @@ -49,9 +49,7 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { << " error" << std::endl; #else sif::printWarning( - "PUSDistributor::handlePacket: Packet format invalid, " - "%s error\n", - keyword); + "PUSDistributor::handlePacket: Packet format invalid, %s error\n", keyword); #endif #endif } @@ -133,7 +131,7 @@ ReturnValue_t PUSDistributor::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - CCSDSDistributorIF* ccsdsDistributor = + auto* ccsdsDistributor = ObjectManager::instance()->get(packetSource); if (ccsdsDistributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 From c0292f072e77beaf7760753c86d0e57bbfa90409 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 20 May 2022 20:52:36 +0200 Subject: [PATCH 184/198] warning printout correction --- src/fsfw/osal/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/osal/CMakeLists.txt b/src/fsfw/osal/CMakeLists.txt index f3c5cfad..8fa353c6 100644 --- a/src/fsfw/osal/CMakeLists.txt +++ b/src/fsfw/osal/CMakeLists.txt @@ -18,7 +18,7 @@ elseif(FSFW_OSAL MATCHES "host") else() - message(WARNING "The OS_FSFW variable was not set. Assuming host OS..") + message(WARNING "${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..") # Not set. Assumuing this is a host build, try to determine host OS if (WIN32) add_subdirectory(host) From b8b7756a3e4f92ff1d8abd80f4be3eb5566f71fd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 22 May 2022 14:32:48 +0200 Subject: [PATCH 185/198] fix host OSAL --- src/fsfw/osal/host/FixedTimeslotTask.cpp | 4 +++- src/fsfw/osal/host/FixedTimeslotTask.h | 4 +++- src/fsfw/osal/host/PeriodicTask.cpp | 2 ++ src/fsfw/osal/host/PeriodicTask.h | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/fsfw/osal/host/FixedTimeslotTask.cpp b/src/fsfw/osal/host/FixedTimeslotTask.cpp index 07853938..bb3ffe35 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.cpp +++ b/src/fsfw/osal/host/FixedTimeslotTask.cpp @@ -133,7 +133,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotT return HasReturnvaluesIF::RETURN_FAILED; } -ReturnValue_t FixedTimeslotTask::checkSequence() const { return pollingSeqTable.checkSequence(); } +ReturnValue_t FixedTimeslotTask::checkSequence() { return pollingSeqTable.checkSequence(); } uint32_t FixedTimeslotTask::getPeriodMs() const { return period * 1000; } @@ -176,3 +176,5 @@ bool FixedTimeslotTask::delayForInterval(chron_ms* previousWakeTimeMs, const chr (*previousWakeTimeMs) = currentStartTime; return false; } + +bool FixedTimeslotTask::isEmpty() const { return pollingSeqTable.isEmpty(); } diff --git a/src/fsfw/osal/host/FixedTimeslotTask.h b/src/fsfw/osal/host/FixedTimeslotTask.h index cdbc6f23..dac33871 100644 --- a/src/fsfw/osal/host/FixedTimeslotTask.h +++ b/src/fsfw/osal/host/FixedTimeslotTask.h @@ -59,12 +59,14 @@ class FixedTimeslotTask : public FixedTimeslotTaskIF { */ ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); - ReturnValue_t checkSequence() const override; + ReturnValue_t checkSequence() override; uint32_t getPeriodMs() const; ReturnValue_t sleepFor(uint32_t ms); + bool isEmpty() const override; + protected: using chron_ms = std::chrono::milliseconds; diff --git a/src/fsfw/osal/host/PeriodicTask.cpp b/src/fsfw/osal/host/PeriodicTask.cpp index cdcfafa6..23736b96 100644 --- a/src/fsfw/osal/host/PeriodicTask.cpp +++ b/src/fsfw/osal/host/PeriodicTask.cpp @@ -156,3 +156,5 @@ bool PeriodicTask::delayForInterval(chron_ms* previousWakeTimeMs, const chron_ms (*previousWakeTimeMs) = currentStartTime; return false; } + +bool PeriodicTask::isEmpty() const { return objectList.empty(); } diff --git a/src/fsfw/osal/host/PeriodicTask.h b/src/fsfw/osal/host/PeriodicTask.h index 6c4d5e8b..463ab379 100644 --- a/src/fsfw/osal/host/PeriodicTask.h +++ b/src/fsfw/osal/host/PeriodicTask.h @@ -73,6 +73,7 @@ class PeriodicTask : public PeriodicTaskIF { ReturnValue_t sleepFor(uint32_t ms); + bool isEmpty() const override; protected: using chron_ms = std::chrono::milliseconds; bool started; From 34658ef7dba9d6ae67b7b433088fe4b3c901c1f5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 24 May 2022 10:40:25 +0200 Subject: [PATCH 186/198] afmt --- src/fsfw/pus/Service11TelecommandScheduling.h | 24 ++++++++++--------- src/fsfw/tcdistribution/PUSDistributor.cpp | 7 +++--- src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h | 3 ++- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.h b/src/fsfw/pus/Service11TelecommandScheduling.h index 9a8be603..f11c8bd1 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.h +++ b/src/fsfw/pus/Service11TelecommandScheduling.h @@ -45,17 +45,19 @@ class Service11TelecommandScheduling final : public PusServiceBase { HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3); // The types of PUS-11 subservices - enum [[maybe_unused]] Subservice : uint8_t{ENABLE_SCHEDULING = 1, - DISABLE_SCHEDULING = 2, - RESET_SCHEDULING = 3, - INSERT_ACTIVITY = 4, - DELETE_ACTIVITY = 5, - FILTER_DELETE_ACTIVITY = 6, - TIMESHIFT_ACTIVITY = 7, - FILTER_TIMESHIFT_ACTIVITY = 8, - DETAIL_REPORT = 9, - TIMEBASE_SCHEDULE_DETAIL_REPORT = 10, - TIMESHIFT_ALL_SCHEDULE_ACTIVITIES = 15}; + enum Subservice : uint8_t { + ENABLE_SCHEDULING = 1, + DISABLE_SCHEDULING = 2, + RESET_SCHEDULING = 3, + INSERT_ACTIVITY = 4, + DELETE_ACTIVITY = 5, + FILTER_DELETE_ACTIVITY = 6, + TIMESHIFT_ACTIVITY = 7, + FILTER_TIMESHIFT_ACTIVITY = 8, + DETAIL_REPORT = 9, + TIMEBASE_SCHEDULE_DETAIL_REPORT = 10, + TIMESHIFT_ALL_SCHEDULE_ACTIVITIES = 15 + }; // The types of time windows for TC[11,6] and TC[11,8], as defined in ECSS-E-ST-70-41C, // requirement 8.11.3c (p. 507) diff --git a/src/fsfw/tcdistribution/PUSDistributor.cpp b/src/fsfw/tcdistribution/PUSDistributor.cpp index 5c02145d..dad002a1 100644 --- a/src/fsfw/tcdistribution/PUSDistributor.cpp +++ b/src/fsfw/tcdistribution/PUSDistributor.cpp @@ -48,8 +48,8 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() { sif::warning << "PUSDistributor::handlePacket: Packet format invalid, " << keyword << " error" << std::endl; #else - sif::printWarning( - "PUSDistributor::handlePacket: Packet format invalid, %s error\n", keyword); + sif::printWarning("PUSDistributor::handlePacket: Packet format invalid, %s error\n", + keyword); #endif #endif } @@ -131,8 +131,7 @@ ReturnValue_t PUSDistributor::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - auto* ccsdsDistributor = - ObjectManager::instance()->get(packetSource); + auto* ccsdsDistributor = ObjectManager::instance()->get(packetSource); if (ccsdsDistributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "PUSDistributor::initialize: Packet source invalid" << std::endl; diff --git a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h index 4baeb3c5..7ac8c331 100644 --- a/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h +++ b/src/fsfw/tmtcpacket/pus/tc/TcPacketStoredIF.h @@ -9,7 +9,8 @@ class TcPacketStoredIF { public: - virtual ~TcPacketStoredIF()= default;; + virtual ~TcPacketStoredIF() = default; + ; /** * With this call, the stored packet can be set to another packet in a store. This is useful From e60a665de4d53bee65f782c099e7a739e366d594 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 24 May 2022 11:52:29 +0200 Subject: [PATCH 187/198] added 3 new subservices --- src/fsfw/events/fwSubsystemIdRanges.h | 1 + src/fsfw/pus/Service11TelecommandScheduling.h | 15 ++++ .../pus/Service11TelecommandScheduling.tpp | 80 ++++++++++++++----- src/fsfw/tmtcservices/AcceptsTelecommandsIF.h | 4 +- 4 files changed, 79 insertions(+), 21 deletions(-) diff --git a/src/fsfw/events/fwSubsystemIdRanges.h b/src/fsfw/events/fwSubsystemIdRanges.h index 21123600..fa4351e9 100644 --- a/src/fsfw/events/fwSubsystemIdRanges.h +++ b/src/fsfw/events/fwSubsystemIdRanges.h @@ -27,6 +27,7 @@ enum : uint8_t { PUS_SERVICE_6 = 86, PUS_SERVICE_8 = 88, PUS_SERVICE_9 = 89, + PUS_SERVICE_11 = 91, PUS_SERVICE_17 = 97, PUS_SERVICE_23 = 103, MGM_LIS3MDL = 106, diff --git a/src/fsfw/pus/Service11TelecommandScheduling.h b/src/fsfw/pus/Service11TelecommandScheduling.h index f11c8bd1..0fed8bca 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.h +++ b/src/fsfw/pus/Service11TelecommandScheduling.h @@ -44,6 +44,12 @@ class Service11TelecommandScheduling final : public PusServiceBase { static constexpr ReturnValue_t INVALID_RELATIVE_TIME = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3); + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11; + + //! [EXPORT] : [COMMENT] Deletion of a TC from the map failed. + //! P1: First 32 bit of request ID, P2. Last 32 bit of Request ID + static constexpr Event TC_DELETION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); + // The types of PUS-11 subservices enum Subservice : uint8_t { ENABLE_SCHEDULING = 1, @@ -75,6 +81,9 @@ class Service11TelecommandScheduling final : public PusServiceBase { ~Service11TelecommandScheduling() override; + void enableExpiredTcDeletion(); + void disableExpiredTcDeletion(); + /** PusServiceBase overrides */ ReturnValue_t handleRequest(uint8_t subservice) override; ReturnValue_t performService() override; @@ -92,6 +101,11 @@ class Service11TelecommandScheduling final : public PusServiceBase { // minimum release time offset to insert into schedule const uint16_t RELEASE_TIME_MARGIN_SECONDS = 5; + /** + * By default, the scheduling will be disabled. This is a standard requirement + */ + bool schedulingEnabled = false; + bool deleteExpiredTcWhenDisabled = true; bool debugMode = false; StorageManagerIF* tcStore = nullptr; AcceptsTelecommandsIF* tcRecipient = nullptr; @@ -106,6 +120,7 @@ class Service11TelecommandScheduling final : public PusServiceBase { TelecommandMap telecommandMap; + ReturnValue_t handleResetCommand(); /** * @brief Logic to be performed on an incoming TC[11,4]. * @return RETURN_OK if successful diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index 5ee08194..9304dbf1 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -38,6 +38,17 @@ inline ReturnValue_t Service11TelecommandScheduling::handleRequest( return handleInvalidData("handleRequest"); } switch (subservice) { + case Subservice::ENABLE_SCHEDULING: { + schedulingEnabled = true; + break; + } + case Subservice::DISABLE_SCHEDULING: { + schedulingEnabled = false; + break; + } + case Subservice::RESET_SCHEDULING: { + return handleResetCommand(); + } case Subservice::INSERT_ACTIVITY: return doInsertActivity(data, size); case Subservice::DELETE_ACTIVITY: @@ -49,41 +60,42 @@ inline ReturnValue_t Service11TelecommandScheduling::handleRequest( case Subservice::FILTER_TIMESHIFT_ACTIVITY: return doFilterTimeshiftActivity(data, size); default: - break; + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; } - - return HasReturnvaluesIF::RETURN_FAILED; + return RETURN_OK; } template inline ReturnValue_t Service11TelecommandScheduling::performService() { - // DEBUG - // DebugPrintMultimapContent(); - + if (not schedulingEnabled) { + return RETURN_OK; + } // get current time as UNIX timestamp timeval tNow = {}; Clock::getClock_timeval(&tNow); + // TODO: Optionally limit the max number of released TCs per cycle? // NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg // does not work in this case as we are deleting the current element here. for (auto it = telecommandMap.begin(); it != telecommandMap.end();) { if (it->first <= tNow.tv_sec) { - // release tc - TmTcMessage releaseMsg(it->second.storeAddr); - auto sendRet = this->requestQueue->sendMessage(recipientMsgQueueId, &releaseMsg, false); + if (schedulingEnabled) { + // release tc + TmTcMessage releaseMsg(it->second.storeAddr); + auto sendRet = this->requestQueue->sendMessage(recipientMsgQueueId, &releaseMsg, false); - if (sendRet != HasReturnvaluesIF::RETURN_OK) { - return sendRet; - } - - telecommandMap.erase(it++); - - if (debugMode) { + if (sendRet != HasReturnvaluesIF::RETURN_OK) { + return sendRet; + } + if (debugMode) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "Released TC & erased it from TC map" << std::endl; + sif::info << "Released TC & erased it from TC map" << std::endl; #else - sif::printInfo("Released TC & erased it from TC map\n"); + sif::printInfo("Released TC & erased it from TC map\n"); #endif + } + } else if (deleteExpiredTcWhenDisabled) { + telecommandMap.erase(it++); } continue; } @@ -113,6 +125,26 @@ inline ReturnValue_t Service11TelecommandScheduling::initialize() { return res; } +template +inline ReturnValue_t Service11TelecommandScheduling::handleResetCommand() { + for (auto it = telecommandMap.begin(); it != telecommandMap.end(); it++) { + ReturnValue_t result = tcStore->deleteData(it->second.storeAddr); + if (result != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + // This should not happen + sif::warning << "Service11TelecommandScheduling::handleRequestDeleting: Deletion failed" + << std::endl; +#else + sif::printWarning("Service11TelecommandScheduling::handleRequestDeleting: Deletion failed\n"); +#endif + triggerEvent(TC_DELETION_FAILED, (it->second.requestId >> 32) & 0xffffffff, + it->second.requestId & 0xffffffff); + } + } + telecommandMap.clear(); + return RETURN_OK; +} + template inline ReturnValue_t Service11TelecommandScheduling::doInsertActivity( const uint8_t *data, size_t size) { @@ -582,7 +614,7 @@ inline ReturnValue_t Service11TelecommandScheduling::handleInvalidD template inline void Service11TelecommandScheduling::debugPrintMultimapContent() const { - for (const auto &dit : telecommandMap) { + for ([[maybe_unused]] const auto &dit : telecommandMap) { #if FSFW_DISABLE_PRINTOUT == 0 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "Service11TelecommandScheduling::debugPrintMultimapContent: Multimap Content" @@ -600,3 +632,13 @@ inline void Service11TelecommandScheduling::debugPrintMultimapConte #endif } } + +template +inline void Service11TelecommandScheduling::enableExpiredTcDeletion() { + deleteExpiredTcWhenDisabled = true; +} + +template +inline void Service11TelecommandScheduling::disableExpiredTcDeletion() { + deleteExpiredTcWhenDisabled = false; +} diff --git a/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h b/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h index 4186f4df..e18a4f3a 100644 --- a/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h +++ b/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_ #define FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_ -#include "../ipc/MessageQueueSenderIF.h" +#include "fsfw/ipc/MessageQueueSenderIF.h" /** * @brief This interface is implemented by classes that are sinks for @@ -20,7 +20,7 @@ class AcceptsTelecommandsIF { /** * @brief The virtual destructor as it is mandatory for C++ interfaces. */ - virtual ~AcceptsTelecommandsIF() {} + virtual ~AcceptsTelecommandsIF() = default; /** * @brief Getter for the service id. * @details Any receiving service (at least any PUS service) shall have a From f7cde800880f17bcfbed77aa4cd66fcb2a9b1ee3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 24 May 2022 14:32:35 +0200 Subject: [PATCH 188/198] added missing delete --- src/fsfw/pus/Service11TelecommandScheduling.tpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index 9304dbf1..cb43e8e8 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -94,6 +94,7 @@ inline ReturnValue_t Service11TelecommandScheduling::performService sif::printInfo("Released TC & erased it from TC map\n"); #endif } + telecommandMap.erase(it++); } else if (deleteExpiredTcWhenDisabled) { telecommandMap.erase(it++); } From e59f1f26bf672fe3256499ca2859aa32a0b72e5a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 24 May 2022 14:33:18 +0200 Subject: [PATCH 189/198] return end iterator instead of crashing --- src/fsfw/tcdistribution/CCSDSDistributor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fsfw/tcdistribution/CCSDSDistributor.cpp b/src/fsfw/tcdistribution/CCSDSDistributor.cpp index 3f4bbee3..628dd8d0 100644 --- a/src/fsfw/tcdistribution/CCSDSDistributor.cpp +++ b/src/fsfw/tcdistribution/CCSDSDistributor.cpp @@ -9,7 +9,7 @@ CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId) : TcDistributor(setObjectId), defaultApid(setDefaultApid) {} -CCSDSDistributor::~CCSDSDistributor() {} +CCSDSDistributor::~CCSDSDistributor() = default; TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { #if CCSDS_DISTRIBUTOR_DEBUGGING == 1 @@ -38,6 +38,7 @@ TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { " store failed!\n"); #endif #endif + return queueMap.end(); } SpacePacketBase currentPacket(packet); @@ -45,7 +46,7 @@ TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex << currentPacket.getAPID() << std::dec << std::endl; #endif - TcMqMapIter position = this->queueMap.find(currentPacket.getAPID()); + auto position = this->queueMap.find(currentPacket.getAPID()); if (position != this->queueMap.end()) { return position; } else { From 24069dfd78a5905b3e327fab3528baacbc913757 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 24 May 2022 16:22:27 +0200 Subject: [PATCH 190/198] removed [[maybe_unused]] --- src/fsfw/pus/Service11TelecommandScheduling.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.h b/src/fsfw/pus/Service11TelecommandScheduling.h index 9a8be603..45a7c26b 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.h +++ b/src/fsfw/pus/Service11TelecommandScheduling.h @@ -45,7 +45,7 @@ class Service11TelecommandScheduling final : public PusServiceBase { HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3); // The types of PUS-11 subservices - enum [[maybe_unused]] Subservice : uint8_t{ENABLE_SCHEDULING = 1, + enum Subservice : uint8_t{ENABLE_SCHEDULING = 1, DISABLE_SCHEDULING = 2, RESET_SCHEDULING = 3, INSERT_ACTIVITY = 4, From c8355251967009559ea790b63c3ebfc67a27efef Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 25 May 2022 09:56:32 +0200 Subject: [PATCH 191/198] added cast for PUS11 --- src/fsfw/pus/Service11TelecommandScheduling.tpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/pus/Service11TelecommandScheduling.tpp b/src/fsfw/pus/Service11TelecommandScheduling.tpp index 5ee08194..564a11fc 100644 --- a/src/fsfw/pus/Service11TelecommandScheduling.tpp +++ b/src/fsfw/pus/Service11TelecommandScheduling.tpp @@ -67,7 +67,7 @@ inline ReturnValue_t Service11TelecommandScheduling::performService // NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg // does not work in this case as we are deleting the current element here. for (auto it = telecommandMap.begin(); it != telecommandMap.end();) { - if (it->first <= tNow.tv_sec) { + if (it->first <= static_cast(tNow.tv_sec)) { // release tc TmTcMessage releaseMsg(it->second.storeAddr); auto sendRet = this->requestQueue->sendMessage(recipientMsgQueueId, &releaseMsg, false); From 8cfe848dfef41bfc845b4b5c2e6273ac3735400e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 25 May 2022 14:30:00 +0200 Subject: [PATCH 192/198] service 3 and local HK man improvements --- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 5 +++++ src/fsfw/ipc/CommandMessageIF.h | 2 +- src/fsfw/pus/Service3Housekeeping.cpp | 15 ++++++++++----- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index 781d8f71..dec64b81 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -577,6 +577,9 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me CommandMessage reply; if (result != HasReturnvaluesIF::RETURN_OK) { + if(result == WRONG_HK_PACKET_TYPE) { + printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage", WRONG_HK_PACKET_TYPE); + } HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result); } else { HousekeepingMessage::setHkRequestSuccessReply(&reply, sid); @@ -834,6 +837,8 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType, errorPrint = "Dataset not found"; } else if (error == POOLOBJECT_NOT_FOUND) { errorPrint = "Pool Object not found"; + } else if (error == WRONG_HK_PACKET_TYPE) { + errorPrint = "Wrong Packet Type"; } else if (error == HasReturnvaluesIF::RETURN_FAILED) { if (outputType == sif::OutputTypes::OUT_WARNING) { errorPrint = "Generic Warning"; diff --git a/src/fsfw/ipc/CommandMessageIF.h b/src/fsfw/ipc/CommandMessageIF.h index aea08203..3c31a184 100644 --- a/src/fsfw/ipc/CommandMessageIF.h +++ b/src/fsfw/ipc/CommandMessageIF.h @@ -34,7 +34,7 @@ class CommandMessageIF { static const Command_t CMD_NONE = MAKE_COMMAND_ID(0); static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1); //! Reply indicating that the current command was rejected, - //! par1 should contain the error code + //! Parameter 1 should contain the error code static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2); virtual ~CommandMessageIF(){}; diff --git a/src/fsfw/pus/Service3Housekeeping.cpp b/src/fsfw/pus/Service3Housekeeping.cpp index cce8fc91..85c3762f 100644 --- a/src/fsfw/pus/Service3Housekeeping.cpp +++ b/src/fsfw/pus/Service3Housekeeping.cpp @@ -208,7 +208,7 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply, ReturnValue_t error = HasReturnvaluesIF::RETURN_FAILED; HousekeepingMessage::getHkRequestFailureReply(reply, &error); failureParameter2 = error; - return CommandingServiceBase::EXECUTION_COMPLETE; + return RETURN_FAILED; } default: @@ -248,19 +248,23 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) { case (HousekeepingMessage::HK_REQUEST_FAILURE): { break; } + case(CommandMessage::REPLY_REJECTED): { + sif::warning << "Service3Housekeeping::handleUnrequestedReply: Unexpected reply " + "rejected with error code" << reply->getParameter() << std::endl; + break; + } default: { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "Service3Housekeeping::handleUnrequestedReply: Invalid reply with reply " - "command " - << command << "!" << std::endl; + "command " << command << "" << std::endl; #else sif::printWarning( "Service3Housekeeping::handleUnrequestedReply: Invalid reply with " - "reply command %hu!\n", + "reply command %hu\n", command); #endif - return; + break; } } @@ -275,6 +279,7 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) { "Could not generate reply!\n"); #endif } + CommandingServiceBase::handleUnrequestedReply(reply); } MessageQueueId_t Service3Housekeeping::getHkQueue() const { return commandQueue->getId(); } From ac62443f318f62a15812eb2b382a38b3ec84d960 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 25 May 2022 14:30:58 +0200 Subject: [PATCH 193/198] use better type for stored limit --- src/fsfw/tmtcservices/TmTcBridge.cpp | 2 +- src/fsfw/tmtcservices/TmTcBridge.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fsfw/tmtcservices/TmTcBridge.cpp b/src/fsfw/tmtcservices/TmTcBridge.cpp index cc6ec599..4fa07c14 100644 --- a/src/fsfw/tmtcservices/TmTcBridge.cpp +++ b/src/fsfw/tmtcservices/TmTcBridge.cpp @@ -36,7 +36,7 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(uint8_t sentPacketsPerC } } -ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored) { +ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored) { if (maxNumberOfPacketsStored <= LIMIT_DOWNLINK_PACKETS_STORED) { this->maxNumberOfPacketsStored = maxNumberOfPacketsStored; return RETURN_OK; diff --git a/src/fsfw/tmtcservices/TmTcBridge.h b/src/fsfw/tmtcservices/TmTcBridge.h index 81d8e5d8..679ab2ef 100644 --- a/src/fsfw/tmtcservices/TmTcBridge.h +++ b/src/fsfw/tmtcservices/TmTcBridge.h @@ -18,7 +18,7 @@ class TmTcBridge : public AcceptsTelemetryIF, public: static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15; - static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 200; + static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 1000; static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5; static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10; @@ -43,7 +43,7 @@ class TmTcBridge : public AcceptsTelemetryIF, * @return -@c RETURN_OK if value was set successfully * -@c RETURN_FAILED otherwise, stored value stays the same */ - ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored); + ReturnValue_t setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored); /** * This will set up the bridge to overwrite old data in the FIFO. @@ -152,7 +152,7 @@ class TmTcBridge : public AcceptsTelemetryIF, */ DynamicFIFO* tmFifo = nullptr; uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; - uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; + unsigned int maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; #endif /* FSFW_TMTCSERVICES_TMTCBRIDGE_H_ */ From 3749f31ab46d32d4c9fd95bef031fe5f3bf39d3e Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 26 May 2022 02:03:39 +0200 Subject: [PATCH 194/198] disable pending commands and replies in MODE_OFF transition --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 25 +++++++++++++++++++ src/fsfw/devicehandlers/DeviceHandlerBase.h | 5 ++++ 2 files changed, 30 insertions(+) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 69baf54f..e0b50733 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -572,6 +572,9 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) { mode = newMode; modeChanged(); setNormalDatapoolEntriesInvalid(); + if (newMode == MODE_OFF) { + disableCommandsAndReplies(); + } if (!isTransitionalMode()) { modeHelper.modeChanged(newMode, newSubmode); announceMode(false); @@ -1482,6 +1485,9 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) { auto iter = deviceReplyMap.find(sid.ownerSetId); + if (sid.objectId == 0x44140014) { + sif::debug << "HK message for IMTQ" << std::endl; + } if (iter != deviceReplyMap.end()) { return iter->second.dataSet; } else { @@ -1567,3 +1573,22 @@ void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; } void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) { this->powerSwitcher = switcher; } + +void DeviceHandlerBase::disableCommandsAndReplies() { + for (auto& command : deviceCommandMap) { + if (command.second.isExecuting) { + command.second.isExecuting = false; + } + } + for (auto& reply : deviceReplyMap) { + if (!reply.second.periodic) { + if (reply.second.countdown != nullptr) { + reply.second.countdown->timeOut(); + } + else { + reply.second.delayCycles = 0; + } + reply.second.active = false; + } + } +} diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 34171067..58e54da0 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -1325,6 +1325,11 @@ class DeviceHandlerBase : public DeviceHandlerIF, void printWarningOrError(sif::OutputTypes errorType, const char *functionName, ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED, const char *errorPrint = nullptr); + + /** + * @brief Disables all commands and replies when device is set to MODE_OFF + */ + void disableCommandsAndReplies(); }; #endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ From ab68817e9a8254c793239313e169862ceb65b9c4 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 26 May 2022 02:06:05 +0200 Subject: [PATCH 195/198] removed debugging printout --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index e0b50733..f6e8578b 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -1485,9 +1485,6 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) { auto iter = deviceReplyMap.find(sid.ownerSetId); - if (sid.objectId == 0x44140014) { - sif::debug << "HK message for IMTQ" << std::endl; - } if (iter != deviceReplyMap.end()) { return iter->second.dataSet; } else { From 95a64e1da3bb6d334c58c9ba78747bcdaccd5a8b Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 27 May 2022 13:04:21 +0200 Subject: [PATCH 196/198] wrong initialization order --- src/fsfw/tasks/FixedTimeslotTaskBase.cpp | 2 +- src/fsfw/tasks/FixedTimeslotTaskBase.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fsfw/tasks/FixedTimeslotTaskBase.cpp b/src/fsfw/tasks/FixedTimeslotTaskBase.cpp index 26726582..05c08109 100644 --- a/src/fsfw/tasks/FixedTimeslotTaskBase.cpp +++ b/src/fsfw/tasks/FixedTimeslotTaskBase.cpp @@ -4,7 +4,7 @@ FixedTimeslotTaskBase::FixedTimeslotTaskBase(TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_) - : pollingSeqTable(getPeriodMs()), period(period_), dlmFunc(dlmFunc_) {} + : period(period_), pollingSeqTable(getPeriodMs()), dlmFunc(dlmFunc_) {} uint32_t FixedTimeslotTaskBase::getPeriodMs() const { return static_cast(period * 1000); } bool FixedTimeslotTaskBase::isEmpty() const { return pollingSeqTable.isEmpty(); } diff --git a/src/fsfw/tasks/FixedTimeslotTaskBase.h b/src/fsfw/tasks/FixedTimeslotTaskBase.h index 91a4f649..6f08e3fe 100644 --- a/src/fsfw/tasks/FixedTimeslotTaskBase.h +++ b/src/fsfw/tasks/FixedTimeslotTaskBase.h @@ -12,15 +12,15 @@ class FixedTimeslotTaskBase : public FixedTimeslotTaskIF { ; protected: - //! Polling sequence table which contains the object to execute - //! and information like the timeslots and the passed execution step. - FixedSlotSequence pollingSeqTable; - /** * @brief Period of task in floating point seconds */ TaskPeriod period; + //! Polling sequence table which contains the object to execute + //! and information like the timeslots and the passed execution step. + FixedSlotSequence pollingSeqTable; + /** * @brief The pointer to the deadline-missed function. * @details From cda81fc8415c3873c035aa7ebbfa3fe93d519f08 Mon Sep 17 00:00:00 2001 From: Cleanroom Laptop L15 Date: Fri, 3 Jun 2022 18:05:38 +0200 Subject: [PATCH 197/198] enable hk --- hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp | 1 + hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp | 1 + hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index 94e1331c..3dd19275 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -252,6 +252,7 @@ ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(localpool::DataPool &l localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry({0.0})); localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry({0.0})); localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry({0.0})); + poolManager.subscribeForPeriodicPacket(dataset.getSid(), false, 10.0, false); return HasReturnvaluesIF::RETURN_OK; } diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index a13ae791..ee45056a 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -475,6 +475,7 @@ ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool(localpool::DataPool &lo localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Y, new PoolEntry({0.0})); localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Z, new PoolEntry({0.0})); localDataPoolMap.emplace(MGMLIS3MDL::TEMPERATURE_CELCIUS, new PoolEntry({0.0})); + poolManager.subscribeForPeriodicPacket(dataset.getSid(), false, 10.0, false); return HasReturnvaluesIF::RETURN_OK; } diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index f9929d63..3396ea15 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -312,6 +312,7 @@ ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &loc localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_X, new PoolEntry({0.0})); localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Y, new PoolEntry({0.0})); localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Z, new PoolEntry({0.0})); + poolManager.subscribeForPeriodicPacket(primaryDataset.getSid(), false, 10.0, false); return HasReturnvaluesIF::RETURN_OK; } From af890c62187f4c7833ec60847bdd793babb00137 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 16 Jun 2022 07:55:57 +0200 Subject: [PATCH 198/198] corrected warning text --- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index dec64b81..c76134b3 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -699,9 +699,9 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) { if (result != HasReturnvaluesIF::RETURN_OK) { /* Configuration error */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "LocalDataPoolManager::performHkOperation: HK generation failed." << std::endl; + sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed." << std::endl; #else - sif::printWarning("LocalDataPoolManager::performHkOperation: HK generation failed.\n"); + sif::printWarning("LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n"); #endif } }