From 30ed08005fd07cd894a49dee5123e028d1fbeed6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Apr 2020 22:16:43 +0200 Subject: [PATCH 1/7] reverted some naming changes --- datapool/DataPool.h | 3 +- serialize/SerialBufferAdapter.cpp | 56 +++++++++++++++---------------- serialize/SerialBufferAdapter.h | 6 ++-- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/datapool/DataPool.h b/datapool/DataPool.h index a9af8af0..857bc3b2 100644 --- a/datapool/DataPool.h +++ b/datapool/DataPool.h @@ -42,7 +42,8 @@ private: /** * \brief This is the actual data pool itself. * \details It is represented by a map - * with the data pool id as index and a pointer to a single PoolEntry as value. + * with the data pool id as index and a pointer to a single + * PoolEntry as value. */ std::map data_pool; public: diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index 618e8a15..f97d0d58 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -5,19 +5,19 @@ template SerialBufferAdapter::SerialBufferAdapter(const void* buffer, count_t bufferLength, bool serializeLength) : - m_serialize_length(serializeLength), - m_const_buffer(static_cast(buffer)), m_buffer(nullptr), - m_buffer_length(bufferLength) { + serializeLength(serializeLength), + constBuffer(static_cast(buffer)), m_buffer(nullptr), + bufferLength(bufferLength) { } template SerialBufferAdapter::SerialBufferAdapter(void* buffer, count_t bufferLength, bool serializeLength) : - m_serialize_length(serializeLength), m_buffer_length(bufferLength) { + serializeLength(serializeLength), bufferLength(bufferLength) { uint8_t * member_buffer = static_cast(buffer); m_buffer = member_buffer; - m_const_buffer = member_buffer; + constBuffer = member_buffer; } @@ -28,37 +28,37 @@ SerialBufferAdapter::~SerialBufferAdapter() { template ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, size_t* size, const size_t max_size, bool bigEndian) const { - uint32_t serializedLength = m_buffer_length; - if (m_serialize_length) { + uint32_t serializedLength = bufferLength; + if (serializeLength) { serializedLength += AutoSerializeAdapter::getSerializedSize( - &m_buffer_length); + &bufferLength); } if (*size + serializedLength > max_size) { return BUFFER_TOO_SHORT; } else { - if (m_serialize_length) { - AutoSerializeAdapter::serialize(&m_buffer_length, buffer, size, + if (serializeLength) { + AutoSerializeAdapter::serialize(&bufferLength, buffer, size, max_size, bigEndian); } - if (m_const_buffer != nullptr) { - memcpy(*buffer, m_const_buffer, m_buffer_length); + if (constBuffer != nullptr) { + memcpy(*buffer, constBuffer, bufferLength); } else if (m_buffer != nullptr) { - memcpy(*buffer, m_buffer, m_buffer_length); + memcpy(*buffer, m_buffer, bufferLength); } else { return HasReturnvaluesIF::RETURN_FAILED; } - *size += m_buffer_length; - (*buffer) += m_buffer_length; + *size += bufferLength; + (*buffer) += bufferLength; return HasReturnvaluesIF::RETURN_OK; } } template size_t SerialBufferAdapter::getSerializedSize() const { - if (m_serialize_length) { - return m_buffer_length + AutoSerializeAdapter::getSerializedSize(&m_buffer_length); + if (serializeLength) { + return bufferLength + AutoSerializeAdapter::getSerializedSize(&bufferLength); } else { - return m_buffer_length; + return bufferLength; } } template @@ -66,15 +66,15 @@ ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, ssize_t* size, bool bigEndian) { //TODO Ignores Endian flag! if (buffer != NULL) { - if(m_serialize_length){ + if(serializeLength){ // Suggestion (would require removing rest of the block inside this if clause !): //ReturnValue_t result = AutoSerializeAdapter::deSerialize(&bufferLength,buffer,size,bigEndian); //if (result != HasReturnvaluesIF::RETURN_OK) { // return result; //} count_t serializedSize = AutoSerializeAdapter::getSerializedSize( - &m_buffer_length); - if((*size - m_buffer_length - serializedSize) >= 0){ + &bufferLength); + if((*size - bufferLength - serializedSize) >= 0){ *buffer += serializedSize; *size -= serializedSize; }else{ @@ -82,10 +82,10 @@ ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, } } //No Else If, go on with buffer - if (*size - m_buffer_length >= 0) { - *size -= m_buffer_length; - memcpy(m_buffer, *buffer, m_buffer_length); - (*buffer) += m_buffer_length; + if (*size - bufferLength >= 0) { + *size -= bufferLength; + memcpy(m_buffer, *buffer, bufferLength); + (*buffer) += bufferLength; return HasReturnvaluesIF::RETURN_OK; } else { return STREAM_TOO_SHORT; @@ -106,17 +106,17 @@ uint8_t * SerialBufferAdapter::getBuffer() { template const uint8_t * SerialBufferAdapter::getConstBuffer() { - if(m_const_buffer == nullptr) { + if(constBuffer == nullptr) { error << "Wrong access function for stored type ! Use getBuffer()" << std::endl; return nullptr; } - return m_const_buffer; + return constBuffer; } template void SerialBufferAdapter::setBuffer(void * buffer, count_t buffer_length) { m_buffer = static_cast(buffer); - m_buffer_length = buffer_length; + bufferLength = buffer_length; } diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index ff2083de..cf3ae07e 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -52,10 +52,10 @@ public: const uint8_t * getConstBuffer(); void setBuffer(void* buffer_, count_t bufferLength_); private: - bool m_serialize_length = false; - const uint8_t *m_const_buffer = nullptr; + bool serializeLength = false; + const uint8_t *constBuffer = nullptr; uint8_t *m_buffer = nullptr; - count_t m_buffer_length = 0; + count_t bufferLength = 0; }; From e0e1e64a092b9a06570149c2c694102230af182c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Apr 2020 18:08:14 +0200 Subject: [PATCH 2/7] various changes, stopwatch Semaphore: Some bugfixes, some constructors added Stopwatch: First implementation, can measure in ms(double) and ms(normal) --- datalinklayer/Clcw.cpp | 3 +- datapool/PoolEntry.cpp | 3 +- health/HealthHelper.cpp | 5 +- osal/FreeRTOS/BinarySemaphore.cpp | 68 ++++++++++++++++++----- osal/FreeRTOS/BinarySemaphore.h | 51 +++++++++++++---- osal/FreeRTOS/Clock.cpp | 4 +- osal/FreeRTOS/Timekeeper.cpp | 26 +++++---- osal/FreeRTOS/Timekeeper.h | 9 ++- serviceinterface/ServiceInterfaceStream.h | 3 +- timemanager/CCSDSTime.cpp | 3 +- timemanager/Clock.h | 3 +- timemanager/Stopwatch.cpp | 62 +++++++++++++++++++++ timemanager/Stopwatch.h | 52 +++++++++++++++++ 13 files changed, 247 insertions(+), 45 deletions(-) create mode 100644 timemanager/Stopwatch.cpp create mode 100644 timemanager/Stopwatch.h diff --git a/datalinklayer/Clcw.cpp b/datalinklayer/Clcw.cpp index 448d4d7b..0ffa7abf 100644 --- a/datalinklayer/Clcw.cpp +++ b/datalinklayer/Clcw.cpp @@ -55,7 +55,8 @@ void Clcw::setBitLock(bool bitLock) { } void Clcw::print() { - debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl; + debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() + << std::dec << std::endl; } void Clcw::setWhole(uint32_t rawClcw) { diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index e5d4ffde..655b467a 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -60,7 +60,8 @@ uint8_t PoolEntry::getValid() { template void PoolEntry::print() { for (uint8_t size = 0; size < this->length; size++ ) { - debug << "| " << std::hex << (double)this->address[size] << (this->valid? " (valid) " : " (invalid) "); + debug << "| " << std::hex << (double)this->address[size] + << (this->valid? " (valid) " : " (invalid) "); } debug << std::dec << std::endl; } diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index 8fc413ed..931645d1 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -89,8 +89,7 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* message) { } if (MessageQueueSenderIF::sendMessage(message->getSender(), &reply, owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { - debug - << "HealthHelper::handleHealthCommand: sending health reply failed." - << std::endl; + debug << "HealthHelper::handleHealthCommand: sending health " + "reply failed." << std::endl; } } diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 546c5a46..05c97ae2 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -21,26 +21,68 @@ BinarySemaphore::~BinarySemaphore() { vSemaphoreDelete(handle); } +// This copy ctor is important as it prevents the assignment to a ressource +// (other.handle) variable which is later deleted! +BinarySemaphore::BinarySemaphore(const BinarySemaphore& other) { + xSemaphoreCreateBinary(handle); + if(handle == nullptr) { + error << "Binary semaphore creation failure" << std::endl; + } +} + +BinarySemaphore& BinarySemaphore::operator =(const BinarySemaphore& s) { + if(this != &s) { + xSemaphoreCreateBinary(handle); + if(handle == nullptr) { + error << "Binary semaphore creation failure" << std::endl; + } + } + return *this; +} + +BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) { + xSemaphoreCreateBinary(handle); + if(handle == nullptr) { + error << "Binary semaphore creation failure" << std::endl; + } +} + +BinarySemaphore& BinarySemaphore::operator =( + BinarySemaphore&& s) { + if(&s != this) { + xSemaphoreCreateBinary(handle); + if(handle == nullptr) { + error << "Binary semaphore creation failure" << std::endl; + } + } + return *this; +} + ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) { if(handle == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return SEMAPHORE_NULLPOINTER; } - TickType_t timeout = portMAX_DELAY; - if(timeoutMs != 0) { - timeout = pdMS_TO_TICKS(timeoutMs); + TickType_t timeout = BinarySemaphore::NO_BLOCK_TICKS; + if(timeoutMs == BinarySemaphore::BLOCK_TIMEOUT) { + timeout = BinarySemaphore::BLOCK_TIMEOUT_TICKS; + } + else if(timeoutMs > BinarySemaphore::NO_BLOCK_TIMEOUT){ + timeout = pdMS_TO_TICKS(timeoutMs); } BaseType_t returncode = xSemaphoreTake(handle, timeout); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_NOT_FOUND; + } + else { + return SEMAPHORE_TIMEOUT; } } -ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks) { +ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout( + TickType_t timeoutTicks) { if(handle == nullptr) { - return SEMAPHORE_NOT_FOUND; + return SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreTake(handle, timeoutTicks); @@ -53,7 +95,7 @@ ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout(TickType_t timeout ReturnValue_t BinarySemaphore::giveBinarySemaphore() { if (handle == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreGive(handle); if (returncode == pdPASS) { @@ -69,7 +111,7 @@ SemaphoreHandle_t BinarySemaphore::getSemaphore() { ReturnValue_t BinarySemaphore::giveBinarySemaphore(SemaphoreHandle_t semaphore) { if (semaphore == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreGive(semaphore); if (returncode == pdPASS) { @@ -86,11 +128,12 @@ void BinarySemaphore::resetSemaphore() { } } + // Be careful with the stack size here. This is called from an ISR! ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR(SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken) { if (semaphore == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreGiveFromISR(semaphore, higherPriorityTaskWoken); if (returncode == pdPASS) { @@ -99,11 +142,10 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR(SemaphoreHandle_t sema // TODO: I don't know if this will ever happen but if it does, // I want to to know in case this causes issues. If it doesn't // we should remove this. - TRACE_INFO("Binary Semaphore: Higher priority task unblocked!"); TaskManagement::requestContextSwitch(CallContext::isr); } return HasReturnvaluesIF::RETURN_OK; } else { - return HasReturnvaluesIF::RETURN_FAILED; + return SEMAPHORE_NOT_OWNED; } } diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index a809f0bb..54126692 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -20,22 +20,51 @@ class BinarySemaphore: public HasReturnvaluesIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; - /** Semaphore object not found */ - static const ReturnValue_t SEMAPHORE_NOT_FOUND = MAKE_RETURN_CODE(1); - /** Semaphore timeout */ - static const ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(2); + //! No block time, poll the semaphore. Can also be used as tick type. + //! Can be passed as tick type and ms value. + static constexpr uint32_t NO_BLOCK_TIMEOUT = 0; + static constexpr TickType_t NO_BLOCK_TICKS = 0; + //! No block time, poll the semaphore. + //! Can be passed as tick type and ms value. + static constexpr TickType_t BLOCK_TIMEOUT_TICKS = portMAX_DELAY; + static constexpr uint32_t BLOCK_TIMEOUT = portMAX_DELAY; + + //! Semaphore timeout + static constexpr ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(1); /** The current semaphore can not be given, because it is not owned */ - static const ReturnValue_t SEMAPHORE_NOT_OWNED = MAKE_RETURN_CODE(3); + static constexpr ReturnValue_t SEMAPHORE_NOT_OWNED = MAKE_RETURN_CODE(2); + static constexpr ReturnValue_t SEMAPHORE_NULLPOINTER = MAKE_RETURN_CODE(3); /** * Create a binary semaphore */ BinarySemaphore(); + /** + * Copy ctor + * @param + */ + BinarySemaphore(const BinarySemaphore&); + + /** + * Copy assignment + */ + BinarySemaphore& operator=(const BinarySemaphore&); + + /** + * Move constructor + */ + BinarySemaphore (BinarySemaphore &&); + + /** + * Move assignment + */ + BinarySemaphore & operator=(BinarySemaphore &&); + /** * Delete the binary semaphore to prevent a memory leak */ - ~BinarySemaphore(); + virtual ~BinarySemaphore(); /** * Take the binary semaphore. @@ -46,7 +75,8 @@ public: * @return -@c RETURN_OK on success * -@c RETURN_FAILED on failure */ - ReturnValue_t takeBinarySemaphore(uint32_t timeoutMs); + ReturnValue_t takeBinarySemaphore(uint32_t timeoutMs = + BinarySemaphore::NO_BLOCK_TIMEOUT); /** * Same as lockBinarySemaphore() with timeout in FreeRTOS ticks. @@ -54,7 +84,8 @@ public: * @return -@c RETURN_OK on success * -@c RETURN_FAILED on failure */ - ReturnValue_t takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks); + ReturnValue_t takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks = + BinarySemaphore::NO_BLOCK_TICKS); /** * Give back the binary semaphore @@ -96,8 +127,4 @@ private: SemaphoreHandle_t handle; }; - - - - #endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */ diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index cffc2125..5e597f25 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -3,8 +3,11 @@ #include #include "Timekeeper.h" +extern "C" { #include #include +} + //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); } diff --git a/osal/FreeRTOS/Timekeeper.cpp b/osal/FreeRTOS/Timekeeper.cpp index 81f7f997..949e1df3 100644 --- a/osal/FreeRTOS/Timekeeper.cpp +++ b/osal/FreeRTOS/Timekeeper.cpp @@ -1,20 +1,24 @@ -#include "Timekeeper.h" -#include +/** + * @file Timekeeper.cpp + * @date + */ -Timekeeper::Timekeeper() : - offset( { 0, 0 }) { - // TODO Auto-generated constructor stub +#include +extern "C" { +#include } -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(); +} diff --git a/osal/FreeRTOS/Timekeeper.h b/osal/FreeRTOS/Timekeeper.h index 2ba3e4a9..05f0f701 100644 --- a/osal/FreeRTOS/Timekeeper.h +++ b/osal/FreeRTOS/Timekeeper.h @@ -2,8 +2,10 @@ #define FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ #include - +extern "C" { #include +} + /** * 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); diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index 32bc263e..44cf1168 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -7,7 +7,8 @@ #include #include -//Unfortunately, there must be a forward declaration of log_fe (MUST be defined in main), to let the system know where to write to. +//Unfortunately, there must be a forward declaration of log_fe +// (MUST be defined in main), to let the system know where to write to. extern std::ostream debug; extern std::ostream info; extern std::ostream warning; diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 29aafb68..47cab911 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -196,7 +196,8 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* to->usecond = (second - floor(second)) * 1000000; return RETURN_OK; } -// Warning: Compiler/Linker fails ambiguously if library does not implement C99 I/O +// Warning: Compiler/Linker fails ambiguously if library does not implement +// C99 I/O #else uint16_t year; uint8_t month; diff --git a/timemanager/Clock.h b/timemanager/Clock.h index af657247..afa9963c 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -7,7 +7,8 @@ #include #include - +typedef uint32_t ms_normal_t; +typedef double ms_double_t; class Clock { public: diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp new file mode 100644 index 00000000..37133def --- /dev/null +++ b/timemanager/Stopwatch.cpp @@ -0,0 +1,62 @@ +/** + * @file Stopwatch.cpp + * + * @date 08.04.2020 + */ + +#include +#include + +Stopwatch::Stopwatch(bool displayOnDestruction, DisplayMode displayMode): + displayOnDestruction(displayOnDestruction) { + Clock::getUptime(&startTime); + stopwatchState = StopwatchState::STARTED; +} + +void Stopwatch::start() { + startTime = Clock::getUptime(); +} + +ms_normal_t Stopwatch::stop() { + elapsedTime = Clock::getUptime() - startTime; + int32_t elapsedTimeMs = elapsedTime.tv_sec * 1000 + + elapsedTime.tv_usec/1000; + if(elapsedTimeMs < 0) { + error << "Stopwatch: Measured time negative!"; + return INVALID_TIME; + } + else { + return static_cast(elapsedTimeMs); + } +} + +ms_double_t Stopwatch::stopPrecise() { + elapsedTime = Clock::getUptime() - startTime; + return timevalOperations::toDouble(elapsedTime) * 1000.0; +} + + +void Stopwatch::display() { + if(displayMode == DisplayMode::MS_FLOAT) { + info << "Stopwatch: Operation took " << + elapsedTimeMs << " milliseconds" << std::endl; + } + else { + timeval elapsedTime = stopTime - startTime; + info << "Stopwatch: Operation took " << elapsedTime.tv_sec * 1000 + + elapsedTime.tv_usec * 1000 << " milliseconds"; + } +} + + +Stopwatch::~Stopwatch() { + if(displayOnDestruction) { + stopInternal(); + display(); + } +} + +void Stopwatch::stopInternal() { + elapsedTime = Clock::getUptime() - startTime; + elapsedTimeMs = timevalOperations::toDouble(elapsedTime) * 1000.0; +} diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h new file mode 100644 index 00000000..6f58553f --- /dev/null +++ b/timemanager/Stopwatch.h @@ -0,0 +1,52 @@ +/** + * @file Stopwatch.h + * + * @date 08.04.2020 + */ + +#ifndef FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ +#define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ +#include + +class Stopwatch { + enum class DisplayMode { + MS_FLOAT, + MS + }; + + Stopwatch(bool displayOnDestruction = true, DisplayMode displayMode = + DisplayMode::MS_FLOAT); + virtual~ Stopwatch(); + + void start(); + + ms_normal_t stop(); + ms_double_t stopPrecise(); + + void display(); +private: + static const ms_normal_t INVALID_TIME = 0xFFFFFFFF; + + timeval startTime {0, 0}; + timeval stopTime {0, 0}; + timeval elapsedTime {0, 0}; + double elapsedTimeMs = 0; + //ms_normal_t elapsedTimeMs {0}; + + bool displayOnDestruction = true; + + enum class StopwatchState { + IDLE, + STARTED, + }; + + StopwatchState stopwatchState = StopwatchState::IDLE; + DisplayMode displayMode = DisplayMode::MS_FLOAT; + + void stopInternal(); +}; + + + + +#endif /* FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ */ From 3af241b9c48f1c0f5685435f198d27e4333caa99 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Apr 2020 18:27:18 +0200 Subject: [PATCH 3/7] stopwatch more lightweight now --- timemanager/Stopwatch.cpp | 25 ++++++++----------------- timemanager/Stopwatch.h | 27 +++++++++++++-------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 37133def..fde77540 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -10,7 +10,6 @@ Stopwatch::Stopwatch(bool displayOnDestruction, DisplayMode displayMode): displayOnDestruction(displayOnDestruction) { Clock::getUptime(&startTime); - stopwatchState = StopwatchState::STARTED; } void Stopwatch::start() { @@ -18,31 +17,22 @@ void Stopwatch::start() { } ms_normal_t Stopwatch::stop() { - elapsedTime = Clock::getUptime() - startTime; - int32_t elapsedTimeMs = elapsedTime.tv_sec * 1000 + - elapsedTime.tv_usec/1000; - if(elapsedTimeMs < 0) { - error << "Stopwatch: Measured time negative!"; - return INVALID_TIME; - } - else { - return static_cast(elapsedTimeMs); - } + stopInternal(); + return elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000; } ms_double_t Stopwatch::stopPrecise() { - elapsedTime = Clock::getUptime() - startTime; - return timevalOperations::toDouble(elapsedTime) * 1000.0; + stopInternal(); + return elapsedTimeMsDouble; } void Stopwatch::display() { - if(displayMode == DisplayMode::MS_FLOAT) { + if(displayMode == DisplayMode::MS_DOUBLE) { info << "Stopwatch: Operation took " << - elapsedTimeMs << " milliseconds" << std::endl; + elapsedTimeMsDouble << " milliseconds" << std::endl; } else { - timeval elapsedTime = stopTime - startTime; info << "Stopwatch: Operation took " << elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec * 1000 << " milliseconds"; } @@ -56,7 +46,8 @@ Stopwatch::~Stopwatch() { } } + void Stopwatch::stopInternal() { elapsedTime = Clock::getUptime() - startTime; - elapsedTimeMs = timevalOperations::toDouble(elapsedTime) * 1000.0; + elapsedTimeMsDouble = timevalOperations::toDouble(elapsedTime) * 1000.0; } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 6f58553f..7760fda9 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -8,14 +8,23 @@ #define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ #include +/** + * @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. + * This class caches the value + */ class Stopwatch { enum class DisplayMode { - MS_FLOAT, + MS_DOUBLE, MS }; Stopwatch(bool displayOnDestruction = true, DisplayMode displayMode = - DisplayMode::MS_FLOAT); + DisplayMode::MS_DOUBLE); virtual~ Stopwatch(); void start(); @@ -25,23 +34,13 @@ class Stopwatch { void display(); private: - static const ms_normal_t INVALID_TIME = 0xFFFFFFFF; timeval startTime {0, 0}; - timeval stopTime {0, 0}; timeval elapsedTime {0, 0}; - double elapsedTimeMs = 0; - //ms_normal_t elapsedTimeMs {0}; + double elapsedTimeMsDouble = 0; bool displayOnDestruction = true; - - enum class StopwatchState { - IDLE, - STARTED, - }; - - StopwatchState stopwatchState = StopwatchState::IDLE; - DisplayMode displayMode = DisplayMode::MS_FLOAT; + DisplayMode displayMode = DisplayMode::MS_DOUBLE; void stopInternal(); }; From 3dbf35338561897c356a1f949ed2a74ec7e9f311 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Apr 2020 18:33:38 +0200 Subject: [PATCH 4/7] some more refactoring for stopwatch --- timemanager/Stopwatch.cpp | 13 +++++++++++-- timemanager/Stopwatch.h | 35 +++++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index fde77540..7b08c120 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -7,8 +7,10 @@ #include #include -Stopwatch::Stopwatch(bool displayOnDestruction, DisplayMode displayMode): +Stopwatch::Stopwatch(bool displayOnDestruction, + StopwatchDisplayMode displayMode): displayOnDestruction(displayOnDestruction) { + // Measures start time on initialization. Clock::getUptime(&startTime); } @@ -28,7 +30,7 @@ ms_double_t Stopwatch::stopPrecise() { void Stopwatch::display() { - if(displayMode == DisplayMode::MS_DOUBLE) { + if(displayMode == StopwatchDisplayMode::MS_DOUBLE) { info << "Stopwatch: Operation took " << elapsedTimeMsDouble << " milliseconds" << std::endl; } @@ -46,6 +48,13 @@ Stopwatch::~Stopwatch() { } } +void Stopwatch::setDisplayMode(StopwatchDisplayMode displayMode) { + this->displayMode = displayMode; +} + +StopwatchDisplayMode Stopwatch::getDisplayMode() const { + return displayMode; +} void Stopwatch::stopInternal() { elapsedTime = Clock::getUptime() - startTime; diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 7760fda9..b136019f 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -8,6 +8,11 @@ #define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ #include +enum class StopwatchDisplayMode { + MS_DOUBLE, + MS +}; + /** * @brief Simple Stopwatch implementation to measure elapsed time * @details @@ -15,24 +20,38 @@ * times automatically on destruction if not explicitely deactivated in the * constructor. The default time format is the elapsed time in miliseconds * as a float. - * This class caches the value */ class Stopwatch { - enum class DisplayMode { - MS_DOUBLE, - MS - }; - Stopwatch(bool displayOnDestruction = true, DisplayMode displayMode = - DisplayMode::MS_DOUBLE); + Stopwatch(bool displayOnDestruction = true, + StopwatchDisplayMode displayMode = StopwatchDisplayMode::MS_DOUBLE); virtual~ Stopwatch(); + /** + * Caches the start time + */ void start(); + /** + * Calculates the elapsed time since start and returns it + * @return elapsed time in milliseconds (rounded) + */ ms_normal_t stop(); + + /** + * Calculates the elapsed time since start and returns it + * @return elapsed time in milliseconds (doulbe precision) + */ ms_double_t stopPrecise(); + /** + * 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}; @@ -40,7 +59,7 @@ private: double elapsedTimeMsDouble = 0; bool displayOnDestruction = true; - DisplayMode displayMode = DisplayMode::MS_DOUBLE; + StopwatchDisplayMode displayMode = StopwatchDisplayMode::MS_DOUBLE; void stopInternal(); }; From da9bb97b23f2519137674a8b352e7b93592f4ef4 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Apr 2020 19:05:21 +0200 Subject: [PATCH 5/7] added precision for double output --- timemanager/Stopwatch.cpp | 12 ++++++++---- timemanager/Stopwatch.h | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 7b08c120..1ccebc57 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -6,10 +6,11 @@ #include #include +#include Stopwatch::Stopwatch(bool displayOnDestruction, - StopwatchDisplayMode displayMode): - displayOnDestruction(displayOnDestruction) { + StopwatchDisplayMode displayMode, uint8_t precision): + displayOnDestruction(displayOnDestruction), outputPrecision(precision) { // Measures start time on initialization. Clock::getUptime(&startTime); } @@ -31,8 +32,9 @@ ms_double_t Stopwatch::stopPrecise() { void Stopwatch::display() { if(displayMode == StopwatchDisplayMode::MS_DOUBLE) { - info << "Stopwatch: Operation took " << - elapsedTimeMsDouble << " milliseconds" << std::endl; + info << "Stopwatch: Operation took " + << std::setprecision(outputPrecision) << elapsedTimeMsDouble + << " milliseconds" << std::endl; } else { info << "Stopwatch: Operation took " << elapsedTime.tv_sec * 1000 + @@ -56,6 +58,8 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; } + + void Stopwatch::stopInternal() { elapsedTime = Clock::getUptime() - startTime; elapsedTimeMsDouble = timevalOperations::toDouble(elapsedTime) * 1000.0; diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index b136019f..1e438272 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -22,9 +22,19 @@ enum class StopwatchDisplayMode { * 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. + */ Stopwatch(bool displayOnDestruction = true, - StopwatchDisplayMode displayMode = StopwatchDisplayMode::MS_DOUBLE); + StopwatchDisplayMode displayMode = StopwatchDisplayMode::MS_DOUBLE, + uint8_t outputPrecision = 4); virtual~ Stopwatch(); /** @@ -53,12 +63,12 @@ class Stopwatch { StopwatchDisplayMode getDisplayMode() const; void setDisplayMode(StopwatchDisplayMode displayMode); private: - timeval startTime {0, 0}; timeval elapsedTime {0, 0}; - double elapsedTimeMsDouble = 0; + double elapsedTimeMsDouble {0.0}; bool displayOnDestruction = true; + uint8_t outputPrecision = 4; StopwatchDisplayMode displayMode = StopwatchDisplayMode::MS_DOUBLE; void stopInternal(); From 5b0f80509f7f8dec258d333c26766dfdf8336ccc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Apr 2020 19:24:24 +0200 Subject: [PATCH 6/7] usec replaced by seconds --- timemanager/Clock.h | 4 ++-- timemanager/Stopwatch.cpp | 27 +++++++++++---------------- timemanager/Stopwatch.h | 22 +++++++--------------- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/timemanager/Clock.h b/timemanager/Clock.h index afa9963c..5f18de3e 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -7,8 +7,8 @@ #include #include -typedef uint32_t ms_normal_t; -typedef double ms_double_t; +typedef uint32_t millis_t; +typedef float seconds_t; class Clock { public: diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 1ccebc57..40b711d9 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -9,8 +9,8 @@ #include Stopwatch::Stopwatch(bool displayOnDestruction, - StopwatchDisplayMode displayMode, uint8_t precision): - displayOnDestruction(displayOnDestruction), outputPrecision(precision) { + StopwatchDisplayMode displayMode): + displayOnDestruction(displayOnDestruction) { // Measures start time on initialization. Clock::getUptime(&startTime); } @@ -19,30 +19,28 @@ void Stopwatch::start() { startTime = Clock::getUptime(); } -ms_normal_t Stopwatch::stop() { +millis_t Stopwatch::stop() { stopInternal(); return elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000; } -ms_double_t Stopwatch::stopPrecise() { +seconds_t Stopwatch::stopSeconds() { stopInternal(); - return elapsedTimeMsDouble; + return timevalOperations::toDouble(elapsedTime); } - void Stopwatch::display() { - if(displayMode == StopwatchDisplayMode::MS_DOUBLE) { - info << "Stopwatch: Operation took " - << std::setprecision(outputPrecision) << elapsedTimeMsDouble - << " milliseconds" << std::endl; - } - else { + if(displayMode == StopwatchDisplayMode::MILLIS) { info << "Stopwatch: Operation took " << elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec * 1000 << " milliseconds"; } + else if(displayMode == StopwatchDisplayMode::SECONDS) { + info <<"Stopwatch: Operation took " << std::setprecision(4) + << std::fixed << timevalOperations::toDouble(elapsedTime) + << " seconds"; + } } - Stopwatch::~Stopwatch() { if(displayOnDestruction) { stopInternal(); @@ -58,9 +56,6 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; } - - void Stopwatch::stopInternal() { elapsedTime = Clock::getUptime() - startTime; - elapsedTimeMsDouble = timevalOperations::toDouble(elapsedTime) * 1000.0; } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 1e438272..aeb61265 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -9,8 +9,8 @@ #include enum class StopwatchDisplayMode { - MS_DOUBLE, - MS + MILLIS, + SECONDS }; /** @@ -32,9 +32,8 @@ public: * format * @param outputPrecision If using double format, specify precision here. */ - Stopwatch(bool displayOnDestruction = true, - StopwatchDisplayMode displayMode = StopwatchDisplayMode::MS_DOUBLE, - uint8_t outputPrecision = 4); + Stopwatch(bool displayOnDestruction = true, StopwatchDisplayMode displayMode + = StopwatchDisplayMode::MILLIS); virtual~ Stopwatch(); /** @@ -46,13 +45,8 @@ public: * Calculates the elapsed time since start and returns it * @return elapsed time in milliseconds (rounded) */ - ms_normal_t stop(); - - /** - * Calculates the elapsed time since start and returns it - * @return elapsed time in milliseconds (doulbe precision) - */ - ms_double_t stopPrecise(); + millis_t stop(); + seconds_t stopSeconds(); /** * Displays the elapsed times on the osstream, depending on internal display @@ -65,11 +59,9 @@ public: private: timeval startTime {0, 0}; timeval elapsedTime {0, 0}; - double elapsedTimeMsDouble {0.0}; bool displayOnDestruction = true; - uint8_t outputPrecision = 4; - StopwatchDisplayMode displayMode = StopwatchDisplayMode::MS_DOUBLE; + StopwatchDisplayMode displayMode = StopwatchDisplayMode::MILLIS; void stopInternal(); }; From 640cc1ddec6fa6e53c8dca212b06b61604e5a6da Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Apr 2020 19:30:39 +0200 Subject: [PATCH 7/7] some more bugfixes --- timemanager/Stopwatch.cpp | 8 ++++---- timemanager/Stopwatch.h | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 40b711d9..6c50f0de 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -9,7 +9,7 @@ #include Stopwatch::Stopwatch(bool displayOnDestruction, - StopwatchDisplayMode displayMode): + StopwatchDisplayMode displayMode): displayMode(displayMode), displayOnDestruction(displayOnDestruction) { // Measures start time on initialization. Clock::getUptime(&startTime); @@ -32,12 +32,12 @@ seconds_t Stopwatch::stopSeconds() { void Stopwatch::display() { if(displayMode == StopwatchDisplayMode::MILLIS) { info << "Stopwatch: Operation took " << elapsedTime.tv_sec * 1000 + - elapsedTime.tv_usec * 1000 << " milliseconds"; + elapsedTime.tv_usec * 1000 << " milliseconds" << std::endl; } else if(displayMode == StopwatchDisplayMode::SECONDS) { - info <<"Stopwatch: Operation took " << std::setprecision(4) + info <<"Stopwatch: Operation took " << std::setprecision(3) << std::fixed << timevalOperations::toDouble(elapsedTime) - << " seconds"; + << " seconds" << std::endl; } } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index aeb61265..786a9d57 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -60,9 +60,8 @@ private: timeval startTime {0, 0}; timeval elapsedTime {0, 0}; - bool displayOnDestruction = true; StopwatchDisplayMode displayMode = StopwatchDisplayMode::MILLIS; - + bool displayOnDestruction = true; void stopInternal(); };