Merge pull request 'new monotonic clock API' (#128) from feature_monotonic_clock_api into develop
Reviewed-on: #128 Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
This commit is contained in:
commit
2c5af91db1
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixes
|
||||
|
||||
- Add monotonic watchdog Clock API and use it in `Countdown` and `Stopwatch` class.
|
||||
- Bugfix in `Service11TelecommandScheduling` which allowed commands
|
||||
time tagged in the past to be inserted.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/738
|
||||
|
@ -47,7 +47,32 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
ReturnValue_t Clock::getClockMonotonic(timeval* time) {
|
||||
#if defined(PLATFORM_WIN)
|
||||
// TODO: Implement with std::chrono::steady_clock.. or in some other way. I am not even sure
|
||||
// whether this is possible with steady_clock. The conversion we have to do here just to be
|
||||
// generic is kind of awkward..
|
||||
return returnvalue::FAILED;
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
timespec timeMonotonic;
|
||||
int status = clock_gettime(CLOCK_MONOTONIC_RAW, &timeMonotonic);
|
||||
if (status != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
time->tv_sec = timeMonotonic.tv_sec;
|
||||
time->tv_usec = timeMonotonic.tv_nsec / 1000.0;
|
||||
return returnvalue::OK;
|
||||
#else
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::getUptime: Not implemented for found OS!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("Clock::getUptime: Not implemented for found OS!\n");
|
||||
#endif
|
||||
return returnvalue::FAILED;
|
||||
#endif
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock(timeval* time) {
|
||||
#if defined(PLATFORM_WIN)
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto secondsChrono = std::chrono::time_point_cast<std::chrono::seconds>(now);
|
||||
@ -75,6 +100,10 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
#endif
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
return Clock::getClock(time);
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
if (time == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
|
@ -42,7 +42,7 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
ReturnValue_t Clock::getClock(timeval *time) {
|
||||
timespec timeUnix{};
|
||||
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
|
||||
if (status != 0) {
|
||||
@ -53,6 +53,10 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
return Clock::getClock(time);
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
timeval timeVal{};
|
||||
ReturnValue_t result = getClock_timeval(&timeVal);
|
||||
@ -64,6 +68,17 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClockMonotonic(timeval *time) {
|
||||
timespec timeMonotonic{};
|
||||
int status = clock_gettime(CLOCK_MONOTONIC_RAW, &timeMonotonic);
|
||||
if (status != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
time->tv_sec = timeMonotonic.tv_sec;
|
||||
time->tv_usec = timeMonotonic.tv_nsec / 1000.0;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
timeval uptime{};
|
||||
auto result = getUptime(&uptime);
|
||||
|
@ -49,6 +49,13 @@ class Clock {
|
||||
* @return -@c returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
||||
*/
|
||||
static ReturnValue_t setClock(const timeval *time);
|
||||
|
||||
/**
|
||||
* @deprecated Use getClock instead, which does the same.
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
static ReturnValue_t getClock_timeval(timeval *time);
|
||||
/**
|
||||
* This system call returns the current system clock in timeval format.
|
||||
* The timval format has the fields @c tv_sec with seconds and @c tv_usec with
|
||||
@ -56,7 +63,18 @@ class Clock {
|
||||
* @param time A pointer to a timeval struct where the current time is stored.
|
||||
* @return @c returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
||||
*/
|
||||
static ReturnValue_t getClock_timeval(timeval *time);
|
||||
static ReturnValue_t getClock(timeval *time);
|
||||
|
||||
/**
|
||||
* Retrieve a monotonic clock. This clock this is also more suited for measuring elapsed times
|
||||
* between two time points, but less suited when the absolute time is required.
|
||||
*
|
||||
* Implementation example: A generic UNIX implementation can use CLOCK_MONOTONIC_RAW with
|
||||
* `clock_gettime`.
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
static ReturnValue_t getClockMonotonic(timeval *time);
|
||||
|
||||
/**
|
||||
* Get the time since boot in a timeval struct
|
||||
|
@ -16,7 +16,7 @@ Countdown::~Countdown() = default;
|
||||
ReturnValue_t Countdown::setTimeout(uint32_t milliseconds) {
|
||||
timeout.tv_sec = milliseconds / 1000;
|
||||
timeout.tv_usec = (milliseconds % 1000) * 1000;
|
||||
return Clock::getClock_timeval(&startTime);
|
||||
return Clock::getClockMonotonic(&startTime);
|
||||
}
|
||||
|
||||
bool Countdown::hasTimedOut() const {
|
||||
@ -48,7 +48,7 @@ uint32_t Countdown::timevalToMs(timeval &tv) { return tv.tv_sec * 1000 + tv.tv_u
|
||||
|
||||
ReturnValue_t Countdown::setTimeoutTv(timeval tv) {
|
||||
timeout = tv;
|
||||
return Clock::getClock_timeval(&startTime);
|
||||
return Clock::getClockMonotonic(&startTime);
|
||||
}
|
||||
|
||||
uint32_t Countdown::getTimeoutMs() const { return timeout.tv_sec * 1000 + timeout.tv_usec / 1000; }
|
||||
@ -57,6 +57,6 @@ timeval Countdown::getTimeout() const { return timeout; }
|
||||
|
||||
timeval Countdown::getCurrentTime() const {
|
||||
timeval currentTime{};
|
||||
Clock::getClock_timeval(¤tTime);
|
||||
Clock::getClockMonotonic(¤tTime);
|
||||
return currentTime;
|
||||
}
|
||||
|
@ -9,10 +9,10 @@
|
||||
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
|
||||
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
|
||||
// Measures start time on initialization.
|
||||
Clock::getClock_timeval(&startTime);
|
||||
Clock::getClockMonotonic(&startTime);
|
||||
}
|
||||
|
||||
void Stopwatch::start() { Clock::getUptime(&startTime); }
|
||||
void Stopwatch::start() { Clock::getClockMonotonic(&startTime); }
|
||||
|
||||
dur_millis_t Stopwatch::stop(bool display) {
|
||||
stopInternal();
|
||||
@ -63,6 +63,6 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
|
||||
|
||||
void Stopwatch::stopInternal() {
|
||||
timeval endTime;
|
||||
Clock::getClock_timeval(&endTime);
|
||||
Clock::getClockMonotonic(&endTime);
|
||||
elapsedTime = endTime - startTime;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user