mueller_stopwatch #30
@ -3,8 +3,11 @@
|
||||
#include <stdlib.h>
|
||||
#include "Timekeeper.h"
|
||||
|
||||
extern "C" {
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
}
|
||||
|
||||
|
||||
//TODO sanitize input?
|
||||
//TODO much of this code can be reused for tick-only systems
|
||||
@ -56,7 +59,6 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
TickType_t ticksSinceStart = xTaskGetTickCount();
|
||||
|
||||
return Timekeeper::ticksToTimeval(ticksSinceStart);
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,24 @@
|
||||
#include "Timekeeper.h"
|
||||
#include <FreeRTOSConfig.h>
|
||||
/**
|
||||
|
||||
* @file Timekeeper.cpp
|
||||
* @date
|
||||
*/
|
||||
|
||||
Timekeeper::Timekeeper() :
|
||||
offset( { 0, 0 }) {
|
||||
// TODO Auto-generated constructor stub
|
||||
#include <framework/osal/FreeRTOS/Timekeeper.h>
|
||||
|
||||
extern "C" {
|
||||
#include <task.h>
|
||||
}
|
||||
|
||||
Timekeeper * Timekeeper::myinstance = NULL;
|
||||
Timekeeper * Timekeeper::myinstance = nullptr;
|
||||
|
||||
Timekeeper::Timekeeper() : offset( { 0, 0 }) {}
|
||||
|
||||
const timeval& Timekeeper::getOffset() const {
|
||||
return offset;
|
||||
}
|
||||
|
||||
Timekeeper* Timekeeper::instance() {
|
||||
if (myinstance == NULL) {
|
||||
if (myinstance == nullptr) {
|
||||
myinstance = new Timekeeper();
|
||||
}
|
||||
return myinstance;
|
||||
@ -24,9 +28,7 @@ void Timekeeper::setOffset(const timeval& offset) {
|
||||
this->offset = offset;
|
||||
}
|
||||
|
||||
Timekeeper::~Timekeeper() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
Timekeeper::~Timekeeper() {}
|
||||
|
||||
timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
|
||||
timeval uptime;
|
||||
@ -40,3 +42,7 @@ timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
|
||||
|
||||
return uptime;
|
||||
}
|
||||
|
||||
TickType_t Timekeeper::getTicks() {
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
|
@ -2,8 +2,10 @@
|
||||
#define FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_
|
||||
|
||||
#include <framework/timemanager/Clock.h>
|
||||
|
||||
extern "C" {
|
||||
#include <FreeRTOS.h>
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A Class to basically store the time difference between uptime and UTC
|
||||
@ -25,6 +27,11 @@ public:
|
||||
virtual ~Timekeeper();
|
||||
|
||||
static timeval ticksToTimeval(TickType_t ticks);
|
||||
/**
|
||||
* Get elapsed time in system ticks.
|
||||
* @return
|
||||
*/
|
||||
static TickType_t getTicks();
|
||||
|
||||
const timeval& getOffset() const;
|
||||
void setOffset(const timeval& offset);
|
||||
|
@ -7,7 +7,8 @@
|
||||
#include <framework/ipc/MutexFactory.h>
|
||||
#include <framework/globalfunctions/timevalOperations.h>
|
||||
|
||||
|
||||
typedef uint32_t millis_t;
|
||||
gaisser
commented
Where are does types used? Where are does types used?
muellerr
commented
stopwatch. could also be used somewhere else, is more explicit in my opinion. maybe also use it instead of uint32_t for all milliseconds related stuff? stopwatch. could also be used somewhere else, is more explicit in my opinion. maybe also use it instead of uint32_t for all milliseconds related stuff?
gaisser
commented
Hm I think we should stick with timeval and the types defined there. Someday this might be replaced by timespec and uint32_t will be to small anyway. Hm I think we should stick with timeval and the types defined there. Someday this might be replaced by timespec and uint32_t will be to small anyway.
|
||||
typedef float seconds_t;
|
||||
gaisser
commented
Seconds are converted to double in timevalOperations::toDouble(elapsedTime), this would not fit to the float type. Seconds are converted to double in timevalOperations::toDouble(elapsedTime), this would not fit to the float type.
muellerr
commented
second is double now second is double now
gaisser
commented
I still don't think that those typedefs are a good idea. Maybe we should stick to the types timeval or timespec uses or even use the types C++11 uses in duration Link. I still don't think that those typedefs are a good idea. Maybe we should stick to the types timeval or timespec uses or even use the types C++11 uses in duration [Link](https://www.cplusplus.com/reference/chrono/duration/).
muellerr
commented
Hmmm.. it just makes it a bit mor explicit. I guess you mean for example time_t ? These typedefs were inteded to explicitely be used everywhere uint32_t is used to pass around millisecond values. The new C++ types are a bit more complicated but the clock library will become more powerful soon anyway. I started to play around with the chrono library. Hmmm.. it just makes it a bit mor explicit. I guess you mean for example time_t ?
These typedefs were inteded to explicitely be used everywhere uint32_t is used to pass around millisecond values.
The new C++ types are a bit more complicated but the clock library will become more powerful soon anyway. I started to play around with the chrono library.
Maybe continue using uint32_t for now?
muellerr
commented
instead of writing something like uint32_t lockTimeout, I could write millis_t lockTimeout for example instead of writing something like uint32_t lockTimeout, I could write millis_t lockTimeout for example
|
||||
|
||||
class Clock {
|
||||
public:
|
||||
|
61
timemanager/Stopwatch.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @file Stopwatch.cpp
|
||||
*
|
||||
* @date 08.04.2020
|
||||
*/
|
||||
|
||||
#include <framework/timemanager/Stopwatch.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <iomanip>
|
||||
|
||||
Stopwatch::Stopwatch(bool displayOnDestruction,
|
||||
StopwatchDisplayMode displayMode): displayMode(displayMode),
|
||||
displayOnDestruction(displayOnDestruction) {
|
||||
// Measures start time on initialization.
|
||||
Clock::getUptime(&startTime);
|
||||
}
|
||||
|
||||
void Stopwatch::start() {
|
||||
startTime = Clock::getUptime();
|
||||
}
|
||||
|
||||
millis_t Stopwatch::stop() {
|
||||
stopInternal();
|
||||
return elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000;
|
||||
}
|
||||
|
||||
seconds_t Stopwatch::stopSeconds() {
|
||||
gaisser
commented
Here a float is returned but a double is calculated. Here a float is returned but a double is calculated.
|
||||
stopInternal();
|
||||
return timevalOperations::toDouble(elapsedTime);
|
||||
}
|
||||
|
||||
void Stopwatch::display() {
|
||||
if(displayMode == StopwatchDisplayMode::MILLIS) {
|
||||
info << "Stopwatch: Operation took " << elapsedTime.tv_sec * 1000 +
|
||||
elapsedTime.tv_usec * 1000 << " milliseconds" << std::endl;
|
||||
}
|
||||
else if(displayMode == StopwatchDisplayMode::SECONDS) {
|
||||
info <<"Stopwatch: Operation took " << std::setprecision(3)
|
||||
<< std::fixed << timevalOperations::toDouble(elapsedTime)
|
||||
<< " seconds" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Stopwatch::~Stopwatch() {
|
||||
if(displayOnDestruction) {
|
||||
stopInternal();
|
||||
display();
|
||||
}
|
||||
}
|
||||
|
||||
void Stopwatch::setDisplayMode(StopwatchDisplayMode displayMode) {
|
||||
this->displayMode = displayMode;
|
||||
}
|
||||
|
||||
StopwatchDisplayMode Stopwatch::getDisplayMode() const {
|
||||
return displayMode;
|
||||
}
|
||||
|
||||
void Stopwatch::stopInternal() {
|
||||
elapsedTime = Clock::getUptime() - startTime;
|
||||
}
|
71
timemanager/Stopwatch.h
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file Stopwatch.h
|
||||
*
|
||||
* @date 08.04.2020
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_TIMEMANAGER_STOPWATCH_H_
|
||||
#define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_
|
||||
#include <framework/timemanager/Clock.h>
|
||||
|
||||
enum class StopwatchDisplayMode {
|
||||
MILLIS,
|
||||
SECONDS
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Simple Stopwatch implementation to measure elapsed time
|
||||
* @details
|
||||
* This class can be used to measure elapsed times. It also displays elapsed
|
||||
* times automatically on destruction if not explicitely deactivated in the
|
||||
* constructor. The default time format is the elapsed time in miliseconds
|
||||
* as a float.
|
||||
*/
|
||||
class Stopwatch {
|
||||
public:
|
||||
/**
|
||||
* Default constructor. Call "Stopwatch stopwatch" without brackets if
|
||||
* no parameters are required!
|
||||
* @param displayOnDestruction If set to true, displays measured time on
|
||||
* object destruction
|
||||
* @param displayMode Display format is either MS rounded or MS as double
|
||||
* format
|
||||
* @param outputPrecision If using double format, specify precision here.
|
||||
gaisser
commented
The last part of the comment is outdated The last part of the comment is outdated
|
||||
*/
|
||||
Stopwatch(bool displayOnDestruction = true, StopwatchDisplayMode displayMode
|
||||
= StopwatchDisplayMode::MILLIS);
|
||||
virtual~ Stopwatch();
|
||||
|
||||
/**
|
||||
* Caches the start time
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Calculates the elapsed time since start and returns it
|
||||
* @return elapsed time in milliseconds (rounded)
|
||||
*/
|
||||
millis_t stop();
|
||||
seconds_t stopSeconds();
|
||||
|
||||
/**
|
||||
* Displays the elapsed times on the osstream, depending on internal display
|
||||
* mode.
|
||||
*/
|
||||
void display();
|
||||
|
||||
StopwatchDisplayMode getDisplayMode() const;
|
||||
void setDisplayMode(StopwatchDisplayMode displayMode);
|
||||
private:
|
||||
timeval startTime {0, 0};
|
||||
timeval elapsedTime {0, 0};
|
||||
|
||||
StopwatchDisplayMode displayMode = StopwatchDisplayMode::MILLIS;
|
||||
bool displayOnDestruction = true;
|
||||
void stopInternal();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ */
|
Where does this header comm from?
I don't know. TickType_t is defined in partmacro.h (includes by FreeRTOS.h, just portmacro.h did not work I think) and xGetTickCount is part of task.h .
I now know where it comes from: The configTICK_RATE_HZ is used and is located
inside the FreeRTOSConfig.h file. This file needs to be in the include path in any case, but compiler/indexer warnings are always annoying, so I included it explicitely.