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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
42ecc7caf1
commit
f0e7e8b523
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user