From 9ce59d3c750e74e81c04a0a740c6994c48674b5c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Mar 2022 17:54:09 +0100 Subject: [PATCH 01/14] 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 99e8a56ad..e9afff2e3 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 e5749b19f..18407362e 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 02/14] 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 18407362e..87b884970 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 03/14] 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 c5132cbb0..6a0a8e778 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 9de41e097..19c980d09 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 04/14] 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 6a0a8e778..d4f4f3310 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 05/14] 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 d4f4f3310..9ebd1d790 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 06/14] 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 050839684..cabf7d812 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 d0acdfdf0..b4fd73f6c 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 61eb970ff..a3480b56b 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 06b0c1d8d..fe0afb46f 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 e9afff2e3..75c898e52 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 87b884970..c24dd7814 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 79f847bff..348b99fc7 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 000000000..92242ed99 --- /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 293be2e85..030d363b8 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 000000000..ff530832b --- /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 2e80487aa..2bf6aaf07 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 07/14] 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 b4fd73f6c..19e120b39 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 a3480b56b..534e7e22c 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 fe0afb46f..831c67d43 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 c24dd7814..ca8b12a44 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 926e465ff..e4a62002e 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 7cddf1938..bb4d0399a 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 92242ed99..347d2204e 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 ff530832b..f7c63cce6 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 2bf6aaf07..6970b193c 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 92a930dcc..2967dfa54 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 08/14] 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 f7c63cce6..38ec39156 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 09/14] 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 6970b193c..ce54d2f11 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 10/14] 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 ce54d2f11..a43ff8ab0 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 dd90980520709e554e8b743c9e214c1a84460a3f Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 25 Apr 2022 14:19:03 +0200 Subject: [PATCH 11/14] 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 3b9a21f7f..287699bf3 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 12/14] 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 287699bf3..f46ad3865 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 7d49e6e20..fcc9c7753 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 13/14] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2091ed75d..87927357b 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 5b7ca8c13c4a4a75a32af9b5beadbb310e43516c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 27 Apr 2022 08:39:21 +0200 Subject: [PATCH 14/14] 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 5181a862e..3d28c5c6c 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 52b6dc07b..644b488dd 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 aa2dd2146..3fedc9d44 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 6053bd438..781d8f71f 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 0e2802ac1..dd9bd5d7d 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 1b0934ff3..c43670ed5 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 8313f69ac..942b61217 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 d7b6889b6..9532b2d61 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 00dfea680..ee3479aaa 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 bb4f26a10..4020c6dcc 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 8614d101b..108ec797d 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 4648fdfa5..bb31a5087 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 24ce4af1e..9f47dfc61 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 c3d08a86e..4236593ef 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;