From f0e7e8b523a9c6b1097b3b749def9c8b10eeeb19 Mon Sep 17 00:00:00 2001 From: Tobias Baumgartl Date: Thu, 24 Sep 2026 22:48:16 +0200 Subject: [PATCH] fix: do not mix an epoch offset into the FreeRTOS monotonic clock getClockMonotonic added monotonicClockOffset on top of the uptime. That offset is indeterminate until the first setClock call and jumps when it is latched, so every Countdown and Stopwatch armed before that point either expires immediately or measures against garbage. The monotonicity came from the uptime alone, the offset only made the value look epoch based. The Linux and host implementations return CLOCK_MONOTONIC_RAW with no offset, so this also makes the OSALs agree. All users take differences only: Countdown, Stopwatch and PeriodicHelper. Also drops the Clock statics monotonicClockInitialized and monotonicClockOffset, which were declared but never defined or used. Co-Authored-By: Claude Opus 5 --- src/fsfw/osal/freertos/Clock.cpp | 4 +++- src/fsfw/osal/freertos/Timekeeper.cpp | 10 +--------- src/fsfw/osal/freertos/Timekeeper.h | 6 ------ src/fsfw/timemanager/Clock.h | 2 -- 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/fsfw/osal/freertos/Clock.cpp b/src/fsfw/osal/freertos/Clock.cpp index 8c7f36c2..f1903969 100644 --- a/src/fsfw/osal/freertos/Clock.cpp +++ b/src/fsfw/osal/freertos/Clock.cpp @@ -48,7 +48,9 @@ ReturnValue_t Clock::getClock(timeval* time) { } ReturnValue_t Clock::getClockMonotonic(timeval* time) { - *time = Timekeeper::instance()->getMonotonicClockOffset() + getUptime(); + // Ticks since scheduler start, with no epoch offset on top. Same contract as the Linux and + // host implementations, which return CLOCK_MONOTONIC_RAW: only differences are meaningful. + *time = getUptime(); return returnvalue::OK; } diff --git a/src/fsfw/osal/freertos/Timekeeper.cpp b/src/fsfw/osal/freertos/Timekeeper.cpp index 078d88cb..6649e099 100644 --- a/src/fsfw/osal/freertos/Timekeeper.cpp +++ b/src/fsfw/osal/freertos/Timekeeper.cpp @@ -17,13 +17,7 @@ Timekeeper* Timekeeper::instance() { return myinstance; } -void Timekeeper::setOffset(const timeval& offset) { - if (not monotonicClockInitialized) { - this->monotonicClockOffset = offset; - monotonicClockInitialized = true; - } - this->offset = offset; -} +void Timekeeper::setOffset(const timeval& offset) { this->offset = offset; } timeval Timekeeper::ticksToTimeval(TickType_t ticks) { timeval uptime; @@ -39,5 +33,3 @@ timeval Timekeeper::ticksToTimeval(TickType_t ticks) { } TickType_t Timekeeper::getTicks() { return xTaskGetTickCount(); } - -const timeval Timekeeper::getMonotonicClockOffset() const { return monotonicClockOffset; } diff --git a/src/fsfw/osal/freertos/Timekeeper.h b/src/fsfw/osal/freertos/Timekeeper.h index f7970bc8..9068b902 100644 --- a/src/fsfw/osal/freertos/Timekeeper.h +++ b/src/fsfw/osal/freertos/Timekeeper.h @@ -18,14 +18,9 @@ class Timekeeper { Timekeeper(); timeval offset; - // Set when offset is initialized the first time - timeval monotonicClockOffset; - bool monotonicClockInitialized = false; static Timekeeper* myinstance; - void setMonotonicClockOffset(const timeval& monotonicClockOffset); - public: static Timekeeper* instance(); virtual ~Timekeeper(); @@ -39,7 +34,6 @@ class Timekeeper { const timeval& getOffset() const; void setOffset(const timeval& offset); - const timeval getMonotonicClockOffset() const; }; #endif /* FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ */ diff --git a/src/fsfw/timemanager/Clock.h b/src/fsfw/timemanager/Clock.h index e9c1dd05..6fe6486c 100644 --- a/src/fsfw/timemanager/Clock.h +++ b/src/fsfw/timemanager/Clock.h @@ -192,8 +192,6 @@ class Clock { static MutexIF *timeMutex; static uint16_t leapSeconds; static bool leapSecondsSet; - static bool monotonicClockInitialized; - static timeval monotonicClockOffset; }; #endif /* FSFW_TIMEMANAGER_CLOCK_H_ */