From fe246b9bca27038708bd2d0380d198966b951b9a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Apr 2020 11:43:37 +0200 Subject: [PATCH 01/45] fixed map improvements --- container/FixedMap.h | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/container/FixedMap.h b/container/FixedMap.h index 0b84bf4e..7f3d28f7 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -6,7 +6,11 @@ #include /** - * \ingroup container + * @brief Map implementation for maps with a pre-defined size. + * @details Can be initialized with desired maximum size. + * Iterator is used to access pair and + * iterate through map entries. Complexity O(n). + * @ingroup container */ template class FixedMap: public SerializeIF { @@ -52,12 +56,24 @@ public: return ArrayList, uint32_t>::Iterator::value->second; } + // -> operator overloaded, can be used to access value T *operator->() { return &ArrayList, uint32_t>::Iterator::value->second; } + // Can be used to access the key of the iterator + key_t first() { + return ArrayList, uint32_t>::Iterator::value->first; + } + + // Alternative to access value, similar to std::map implementation + T second() { + return ArrayList, uint32_t>::Iterator::value->second; + } }; + + Iterator begin() const { return Iterator(&theMap[0]); } @@ -72,10 +88,10 @@ public: ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) { if (exists(key) == HasReturnvaluesIF::RETURN_OK) { - return KEY_ALREADY_EXISTS; + return FixedMap::KEY_ALREADY_EXISTS; } if (_size == theMap.maxSize()) { - return MAP_FULL; + return FixedMap::MAP_FULL; } theMap[_size].first = key; theMap[_size].second = value; @@ -87,7 +103,7 @@ public: } ReturnValue_t insert(std::pair pair) { - return insert(pair.fist, pair.second); + return insert(pair.first, pair.second); } ReturnValue_t exists(key_t key) const { @@ -148,8 +164,17 @@ public: return theMap.maxSize(); } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + bool full() { + if(_size == theMap.maxSize()) { + return true; + } + else { + return false; + } + } + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const { ReturnValue_t result = SerializeAdapter::serialize(&this->_size, buffer, size, max_size, bigEndian); uint32_t i = 0; @@ -163,7 +188,7 @@ public: return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { uint32_t printSize = sizeof(_size); uint32_t i = 0; @@ -176,7 +201,7 @@ public: return printSize; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, + virtual ReturnValue_t deSerialize(const uint8_t** buffer, ssize_t* size, bool bigEndian) { ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, buffer, size, bigEndian); From 826e2bdb2dfbfad69919ccb856a7835219bc1075 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Apr 2020 15:10:23 +0200 Subject: [PATCH 02/45] Revert "fixed map improvements" This reverts commit fe246b9bca27038708bd2d0380d198966b951b9a. --- container/FixedMap.h | 41 ++++++++--------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/container/FixedMap.h b/container/FixedMap.h index 7f3d28f7..0b84bf4e 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -6,11 +6,7 @@ #include /** - * @brief Map implementation for maps with a pre-defined size. - * @details Can be initialized with desired maximum size. - * Iterator is used to access pair and - * iterate through map entries. Complexity O(n). - * @ingroup container + * \ingroup container */ template class FixedMap: public SerializeIF { @@ -56,24 +52,12 @@ public: return ArrayList, uint32_t>::Iterator::value->second; } - // -> operator overloaded, can be used to access value T *operator->() { return &ArrayList, uint32_t>::Iterator::value->second; } - // Can be used to access the key of the iterator - key_t first() { - return ArrayList, uint32_t>::Iterator::value->first; - } - - // Alternative to access value, similar to std::map implementation - T second() { - return ArrayList, uint32_t>::Iterator::value->second; - } }; - - Iterator begin() const { return Iterator(&theMap[0]); } @@ -88,10 +72,10 @@ public: ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) { if (exists(key) == HasReturnvaluesIF::RETURN_OK) { - return FixedMap::KEY_ALREADY_EXISTS; + return KEY_ALREADY_EXISTS; } if (_size == theMap.maxSize()) { - return FixedMap::MAP_FULL; + return MAP_FULL; } theMap[_size].first = key; theMap[_size].second = value; @@ -103,7 +87,7 @@ public: } ReturnValue_t insert(std::pair pair) { - return insert(pair.first, pair.second); + return insert(pair.fist, pair.second); } ReturnValue_t exists(key_t key) const { @@ -164,17 +148,8 @@ public: return theMap.maxSize(); } - bool full() { - if(_size == theMap.maxSize()) { - return true; - } - else { - return false; - } - } - - virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, + const uint32_t max_size, bool bigEndian) const { ReturnValue_t result = SerializeAdapter::serialize(&this->_size, buffer, size, max_size, bigEndian); uint32_t i = 0; @@ -188,7 +163,7 @@ public: return result; } - virtual size_t getSerializedSize() const { + virtual uint32_t getSerializedSize() const { uint32_t printSize = sizeof(_size); uint32_t i = 0; @@ -201,7 +176,7 @@ public: return printSize; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, ssize_t* size, + virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, buffer, size, bigEndian); From 2a72e94d6f4fde6653c3ead47d0d9d26b90e6712 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Apr 2020 19:33:01 +0200 Subject: [PATCH 03/45] new stopwatch :-) --- osal/FreeRTOS/Clock.cpp | 4 +- osal/FreeRTOS/Timekeeper.cpp | 26 ++++++++----- osal/FreeRTOS/Timekeeper.h | 9 ++++- timemanager/Clock.h | 3 +- timemanager/Stopwatch.cpp | 61 +++++++++++++++++++++++++++++++ timemanager/Stopwatch.h | 71 ++++++++++++++++++++++++++++++++++++ 6 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 timemanager/Stopwatch.cpp create mode 100644 timemanager/Stopwatch.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/timemanager/Clock.h b/timemanager/Clock.h index af657247..5f18de3e 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -7,7 +7,8 @@ #include #include - +typedef uint32_t millis_t; +typedef float seconds_t; class Clock { public: diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp new file mode 100644 index 00000000..6c50f0de --- /dev/null +++ b/timemanager/Stopwatch.cpp @@ -0,0 +1,61 @@ +/** + * @file Stopwatch.cpp + * + * @date 08.04.2020 + */ + +#include +#include +#include + +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() { + 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; +} diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h new file mode 100644 index 00000000..786a9d57 --- /dev/null +++ b/timemanager/Stopwatch.h @@ -0,0 +1,71 @@ +/** + * @file Stopwatch.h + * + * @date 08.04.2020 + */ + +#ifndef FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ +#define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ +#include + +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. + */ + 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_ */ From 2b740a3c0f9f2b28173afb1b3eb1e4efa161551f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Apr 2020 18:02:42 +0200 Subject: [PATCH 04/45] bugfix --- timemanager/Stopwatch.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 6c50f0de..3f0755fd 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -12,7 +12,7 @@ Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode): displayMode(displayMode), displayOnDestruction(displayOnDestruction) { // Measures start time on initialization. - Clock::getUptime(&startTime); + startTime = Clock::getUptime(); } void Stopwatch::start() { @@ -31,8 +31,8 @@ seconds_t Stopwatch::stopSeconds() { void Stopwatch::display() { if(displayMode == StopwatchDisplayMode::MILLIS) { - info << "Stopwatch: Operation took " << elapsedTime.tv_sec * 1000 + - elapsedTime.tv_usec * 1000 << " milliseconds" << std::endl; + 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) From 2173d43d92b38ca5d2e64017ca3738e353d2d494 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 26 Dec 2019 19:47:46 +0100 Subject: [PATCH 05/45] Generic TMTC Bridge added --- tmtcservices/TmTcBridge.cpp | 173 ++++++++++++++++++++++++++++++++++++ tmtcservices/TmTcBridge.h | 121 +++++++++++++++++++++++++ 2 files changed, 294 insertions(+) create mode 100644 tmtcservices/TmTcBridge.cpp create mode 100644 tmtcservices/TmTcBridge.h diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp new file mode 100644 index 00000000..e7928317 --- /dev/null +++ b/tmtcservices/TmTcBridge.cpp @@ -0,0 +1,173 @@ +/** + * @file TmTcBridge.cpp + * + * @date 26.12.2019 + */ + +#include + +#include +#include +#include + +TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): + SystemObject(objectId_),tcStore(NULL), tmStore(NULL), + ccsdsPacketDistributor(ccsdsPacketDistributor_), communicationLinkUp(false), + tmStored(false) { + TmTcReceptionQueue = QueueFactory::instance()-> + createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); + +} + +TmTcBridge::~TmTcBridge() { +} + +ReturnValue_t TmTcBridge::initialize() { + tcStore = objectManager->get(objects::TC_STORE); + if (tcStore == NULL) { + return RETURN_FAILED; + } + tmStore = objectManager->get(objects::TM_STORE); + if (tmStore == NULL) { + return RETURN_FAILED; + } + AcceptsTelecommandsIF* tcDistributor = + objectManager->get(ccsdsPacketDistributor); + if (tcDistributor == NULL) { + return RETURN_FAILED; + } + TmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue()); + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { + ReturnValue_t result; + result = handleTc(); + if(result != RETURN_OK) { + error << "TMTC Bridge: Error handling TCs" << std::endl; + } + result = handleTm(); + if (result != RETURN_OK) { + error << "TMTC Bridge: Error handling TMs" << std::endl; + } + return result; +} + +ReturnValue_t TmTcBridge::handleTc() { + ReturnValue_t result = receiveTc(); + return result; +} + +ReturnValue_t TmTcBridge::handleTm() { + ReturnValue_t result = readTmQueue(); + if(result != RETURN_OK) { + error << "TMTC Bridge: Reading TM Queue failed" << std::endl; + return RETURN_FAILED; + } + + if(tmStored && communicationLinkUp) { + result = sendStoredTm(); + } + return result; + +} + +ReturnValue_t TmTcBridge::readTmQueue() { + TmTcMessage message; + const uint8_t* data = NULL; + uint32_t size = 0; + for (ReturnValue_t result = TmTcReceptionQueue->receiveMessage(&message); + result == RETURN_OK; result = TmTcReceptionQueue->receiveMessage(&message)) + { + if(not communicationLinkUp) { + result = storeDownlinkData(&message); + return result; + } + + result = tmStore->getData(message.getStorageId(), &data, &size); + if (result != HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = sendTm(data, size); + if (result != RETURN_OK) { + error << "UDP Server: Could not send TM packet"<< std::endl; + tmStore->deleteData(message.getStorageId()); + return result; + + } + tmStore->deleteData(message.getStorageId()); + } + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { + info << "UDP Server: Client address not bound yet. Packet can not be sent. " + "Saving packet to be sent later " << std::endl; + store_address_t storeId; + + if(fifo.full()) { + info << "UDP Server: TM downlink store is full. Overwriting old data" << std::endl; + fifo.retrieve(&storeId); + } + storeId = message->getStorageId(); + fifo.insert(storeId); + //storageIdBufferCounter ++; + tmStored = true; + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::sendStoredTm() { + uint8_t counter = 0; + ReturnValue_t result = RETURN_OK; + while(!fifo.empty() && counter < MAX_STORED_DATA_SENT_PER_CYCLE) { + info << "UDP Server: Sending stored TM data. There are " + << (int) fifo.size() << " left to send" << std::endl; + store_address_t storeId; + const uint8_t* data = NULL; + uint32_t size = 0; + fifo.retrieve(&storeId); + result = tmStore->getData(storeId, &data, &size); + sendTm(data,size); + if(result != RETURN_OK) { + error << "UDP Server: Could not send stored downlink data" << std::endl; + result = RETURN_FAILED; + } + counter ++; + + if(fifo.empty()) { + tmStored = false; + } + tmStore->deleteData(storeId); + } + return result; +} + +void TmTcBridge::registerCommConnect() { + info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; + if(not communicationLinkUp) { + communicationLinkUp = true; + } +} + +void TmTcBridge::registerCommDisconnect() { + info << "TMTC Bridge: Registered Comm Link Disconnect" << std::endl; + if(communicationLinkUp) { + communicationLinkUp = false; + } +} + +MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { + return TmTcReceptionQueue->getId(); +} + +void TmTcBridge::printData(uint8_t * data, uint32_t dataLen) { + info << "TMTC Bridge: Printing data: ["; + for(uint32_t i=0;i +#include +#include +#include +#include + +#include +#include + +class TmTcBridge : public AcceptsTelemetryIF, + public ExecutableObjectIF, + public HasReturnvaluesIF, + public SystemObject { +public: + TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_); + virtual ~TmTcBridge(); + + /** + * Initializes basic FSFW components for TMTC Bridge + * @return + */ + virtual ReturnValue_t initialize(); + + /** + * @brief The performOperation method is executed in a task. + * @details There are no restrictions for calls within this method, so any + * other member of the class can be used. + * @return Currently, the return value is ignored. + */ + virtual ReturnValue_t performOperation(uint8_t operationCode = 0); + + /** + * Return TMTC Reception Queue + * @param virtualChannel + * @return + */ + virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0); + +protected: + MessageQueueIF* TmTcReceptionQueue; //!< Used to send and receive TMTC messages. TmTcMessage is used to transport messages between tasks. + StorageManagerIF* tcStore; + StorageManagerIF* tmStore; + object_id_t ccsdsPacketDistributor; + bool communicationLinkUp; //!< Used to specify whether communication link is up + bool tmStored; + + /** + * Handle TC reception. Default implementation provided + * @return + */ + virtual ReturnValue_t handleTc(); + + /** + * Implemented by child class. Perform receiving of Telecommand + * @return + */ + virtual ReturnValue_t receiveTc() = 0; + + /** + * Handle Telemetry. Default implementation provided. + * Calls sendTm() + * @return + */ + virtual ReturnValue_t handleTm(); + + /** + * Read the TM Queue and send TM if necessary. Default implementation provided + * @return + */ + virtual ReturnValue_t readTmQueue(); + + /** + * Implemented by child class. Perform sending of Telemetry + * @param data + * @param dataLen + * @return + */ + virtual ReturnValue_t sendTm(const uint8_t * data, uint32_t dataLen) = 0; + + /** + * Store data to be sent later if communication link is not up. + * @param message + * @return + */ + ReturnValue_t storeDownlinkData(TmTcMessage * message); + + /** + * Send stored data if communication link is active + * @return + */ + ReturnValue_t sendStoredTm(); + + /** + * Print data as hexidecimal array + * @param data + * @param dataLen + */ + void printData(uint8_t * data, uint32_t dataLen); + + void registerCommConnect(); + void registerCommDisconnect(); + +private: + static const uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; + static const uint8_t MAX_STORED_DATA_SENT_PER_CYCLE = 10; + static const uint8_t MAX_DOWNLINK_PACKETS_STORED = 20; + + FIFO fifo; +}; + + +#endif /* FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ */ From ceb688daf4ed1c35fc9b6f637cca07cb850d43de Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:14:11 +0200 Subject: [PATCH 06/45] tmtc bridge bugfix --- tmtcservices/TmTcBridge.cpp | 5 +++-- tmtcservices/TmTcBridge.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index e7928317..9e863ffd 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -2,6 +2,7 @@ * @file TmTcBridge.cpp * * @date 26.12.2019 + * @author R. Mueller */ #include @@ -144,8 +145,8 @@ ReturnValue_t TmTcBridge::sendStoredTm() { } void TmTcBridge::registerCommConnect() { - info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; - if(not communicationLinkUp) { + if(!communicationLinkUp) { + info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; communicationLinkUp = true; } } diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index ad09bf7c..0f045e47 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -25,7 +25,7 @@ public: virtual ~TmTcBridge(); /** - * Initializes basic FSFW components for TMTC Bridge + * Initializes basic FSFW components for the TMTC Bridge * @return */ virtual ReturnValue_t initialize(); From c867b8354176a05a048db02a843af62bec8d3636 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:17:04 +0200 Subject: [PATCH 07/45] doc extended, instructions for sendTm and recvTc --- tmtcservices/TmTcBridge.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 0f045e47..216dae8b 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -60,7 +60,8 @@ protected: virtual ReturnValue_t handleTc(); /** - * Implemented by child class. Perform receiving of Telecommand + * Implemented by child class. Perform receiving of Telecommand, for example by implementing + * specific drivers or wrappers, e.g. UART Communication or lwIP stack * @return */ virtual ReturnValue_t receiveTc() = 0; @@ -79,7 +80,8 @@ protected: virtual ReturnValue_t readTmQueue(); /** - * Implemented by child class. Perform sending of Telemetry + * Implemented by child class. Perform sending of Telemetry by implementing + * communication drivers or wrappers, e.g. UART communication or lwIP stack. * @param data * @param dataLen * @return From f3af2987e661b5515a5119fd2b0f201720410c8d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:17:32 +0200 Subject: [PATCH 08/45] receiveTc function adapted --- tmtcservices/TmTcBridge.cpp | 4 ++-- tmtcservices/TmTcBridge.h | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 9e863ffd..58f17a86 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -14,7 +14,7 @@ TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_),tcStore(NULL), tmStore(NULL), ccsdsPacketDistributor(ccsdsPacketDistributor_), communicationLinkUp(false), - tmStored(false) { + tmStored(false), size(0) { TmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); @@ -55,7 +55,7 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { } ReturnValue_t TmTcBridge::handleTc() { - ReturnValue_t result = receiveTc(); + ReturnValue_t result = receiveTc(&recvBuffer, &size); return result; } diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 216dae8b..8edf3f37 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -62,9 +62,11 @@ protected: /** * Implemented by child class. Perform receiving of Telecommand, for example by implementing * specific drivers or wrappers, e.g. UART Communication or lwIP stack + * @param recvBuffer [out] Received data + * @param size [out] Size of received data * @return */ - virtual ReturnValue_t receiveTc() = 0; + virtual ReturnValue_t receiveTc(uint8_t ** recvBuffer, uint32_t * size) = 0; /** * Handle Telemetry. Default implementation provided. @@ -117,6 +119,8 @@ private: static const uint8_t MAX_DOWNLINK_PACKETS_STORED = 20; FIFO fifo; + uint8_t * recvBuffer; + uint32_t size; }; From b422ff601a523ee4001d36a151e0ecd8972e82c3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:17:59 +0200 Subject: [PATCH 09/45] connect and disconnect functions public --- tmtcservices/TmTcBridge.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 8edf3f37..7870e79b 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -45,6 +45,8 @@ public: */ virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0); + void registerCommConnect(); + void registerCommDisconnect(); protected: MessageQueueIF* TmTcReceptionQueue; //!< Used to send and receive TMTC messages. TmTcMessage is used to transport messages between tasks. StorageManagerIF* tcStore; @@ -110,9 +112,6 @@ protected: */ void printData(uint8_t * data, uint32_t dataLen); - void registerCommConnect(); - void registerCommDisconnect(); - private: static const uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; static const uint8_t MAX_STORED_DATA_SENT_PER_CYCLE = 10; From 4a218470cffda54b9ed2611e615d0070dfb1f990 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:18:16 +0200 Subject: [PATCH 10/45] max number of stored packets lowered --- tmtcservices/TmTcBridge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 7870e79b..8e4124e0 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -115,7 +115,7 @@ protected: private: static const uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; static const uint8_t MAX_STORED_DATA_SENT_PER_CYCLE = 10; - static const uint8_t MAX_DOWNLINK_PACKETS_STORED = 20; + static const uint8_t MAX_DOWNLINK_PACKETS_STORED = 15; FIFO fifo; uint8_t * recvBuffer; From 8cb4a9897e963ea1d0ca0238303ae81428dfa60a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:20:10 +0200 Subject: [PATCH 11/45] tmtc bridge debug output corrected --- tmtcservices/TmTcBridge.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 58f17a86..12771bbf 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -103,12 +103,13 @@ ReturnValue_t TmTcBridge::readTmQueue() { } ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { - info << "UDP Server: Client address not bound yet. Packet can not be sent. " - "Saving packet to be sent later " << std::endl; + info << "TMTC Bridge: Comm Link down. " + "Saving packet ID to be sent later " << std::endl; store_address_t storeId; if(fifo.full()) { - info << "UDP Server: TM downlink store is full. Overwriting old data" << std::endl; + info << "TMTC Bridge: TM downlink max. number of stored packet IDs reached." + " Overwriting old data" << std::endl; fifo.retrieve(&storeId); } storeId = message->getStorageId(); From 20c67c4aa3d1de8b3dbf9b11ee1ca8dae8ef10b9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:20:47 +0200 Subject: [PATCH 12/45] tmtc bridge bugfix: tm data deleted when overwriting old data --- tmtcservices/TmTcBridge.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 12771bbf..ddeacd16 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -111,6 +111,7 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { info << "TMTC Bridge: TM downlink max. number of stored packet IDs reached." " Overwriting old data" << std::endl; fifo.retrieve(&storeId); + tmStore->deleteData(storeId); } storeId = message->getStorageId(); fifo.insert(storeId); From 8a6a2bf840c47480a1c7182101d4bb381fde05bf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 26 Dec 2019 22:15:19 +0100 Subject: [PATCH 13/45] comment deleted --- tmtcservices/TmTcBridge.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index ddeacd16..ddd63d47 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -115,7 +115,6 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { } storeId = message->getStorageId(); fifo.insert(storeId); - //storageIdBufferCounter ++; tmStored = true; return RETURN_OK; } From 2e95906f278948c591fc0d59605013059040a054 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 1 Jan 2020 17:31:17 +0100 Subject: [PATCH 14/45] recvBuffer and recvSize initialized --- tmtcservices/TmTcBridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index ddd63d47..7cc97d0d 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -14,7 +14,7 @@ TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_),tcStore(NULL), tmStore(NULL), ccsdsPacketDistributor(ccsdsPacketDistributor_), communicationLinkUp(false), - tmStored(false), size(0) { + tmStored(false),recvBuffer(NULL), size(0) { TmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); From 914dec3691b1bdb1737afc1a4fcfcc9ae117a683 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 2 Jan 2020 21:12:21 +0100 Subject: [PATCH 15/45] debug output change --- tmtcservices/TmTcBridge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 7cc97d0d..e402d79e 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -80,7 +80,7 @@ ReturnValue_t TmTcBridge::readTmQueue() { for (ReturnValue_t result = TmTcReceptionQueue->receiveMessage(&message); result == RETURN_OK; result = TmTcReceptionQueue->receiveMessage(&message)) { - if(not communicationLinkUp) { + if(communicationLinkUp == false) { result = storeDownlinkData(&message); return result; } @@ -92,7 +92,7 @@ ReturnValue_t TmTcBridge::readTmQueue() { result = sendTm(data, size); if (result != RETURN_OK) { - error << "UDP Server: Could not send TM packet"<< std::endl; + error << "TMTC Bridge: Could not send TM packet"<< std::endl; tmStore->deleteData(message.getStorageId()); return result; From ad01a36c0275996a266435cd968fc5b841f0caae Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 17 Apr 2020 23:25:08 +0200 Subject: [PATCH 16/45] std::flush instead of std::endl --- tmtcservices/TmTcBridge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index e402d79e..af4d0d61 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -104,7 +104,7 @@ ReturnValue_t TmTcBridge::readTmQueue() { ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { info << "TMTC Bridge: Comm Link down. " - "Saving packet ID to be sent later " << std::endl; + "Saving packet ID to be sent later\r\n" << std::flush; store_address_t storeId; if(fifo.full()) { @@ -124,7 +124,7 @@ ReturnValue_t TmTcBridge::sendStoredTm() { ReturnValue_t result = RETURN_OK; while(!fifo.empty() && counter < MAX_STORED_DATA_SENT_PER_CYCLE) { info << "UDP Server: Sending stored TM data. There are " - << (int) fifo.size() << " left to send" << std::endl; + << (int) fifo.size() << " left to send\r\n" << std::flush; store_address_t storeId; const uint8_t* data = NULL; uint32_t size = 0; From 98c0b2c9ac252e63d5962713de3176703d89b050 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Apr 2020 13:16:00 +0200 Subject: [PATCH 17/45] null replaced by nullptr. storeID initialization added, all nullptr/0 initializations in header --- tmtcservices/TmTcBridge.cpp | 18 ++++++++---------- tmtcservices/TmTcBridge.h | 25 ++++++++++++++----------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index af4d0d61..6442f245 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -11,17 +11,15 @@ #include #include -TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): - SystemObject(objectId_),tcStore(NULL), tmStore(NULL), - ccsdsPacketDistributor(ccsdsPacketDistributor_), communicationLinkUp(false), - tmStored(false),recvBuffer(NULL), size(0) { - TmTcReceptionQueue = QueueFactory::instance()-> +TmTcBridge::TmTcBridge(object_id_t objectId_, + object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), + ccsdsPacketDistributor(ccsdsPacketDistributor_) +{ + TmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); - } -TmTcBridge::~TmTcBridge() { -} +TmTcBridge::~TmTcBridge() {} ReturnValue_t TmTcBridge::initialize() { tcStore = objectManager->get(objects::TC_STORE); @@ -75,7 +73,7 @@ ReturnValue_t TmTcBridge::handleTm() { ReturnValue_t TmTcBridge::readTmQueue() { TmTcMessage message; - const uint8_t* data = NULL; + const uint8_t* data = nullptr; uint32_t size = 0; for (ReturnValue_t result = TmTcReceptionQueue->receiveMessage(&message); result == RETURN_OK; result = TmTcReceptionQueue->receiveMessage(&message)) @@ -105,7 +103,7 @@ ReturnValue_t TmTcBridge::readTmQueue() { ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { info << "TMTC Bridge: Comm Link down. " "Saving packet ID to be sent later\r\n" << std::flush; - store_address_t storeId; + store_address_t storeId = 0; if(fifo.full()) { info << "TMTC Bridge: TM downlink max. number of stored packet IDs reached." diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 8e4124e0..e0634098 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -48,12 +48,15 @@ public: void registerCommConnect(); void registerCommDisconnect(); protected: - MessageQueueIF* TmTcReceptionQueue; //!< Used to send and receive TMTC messages. TmTcMessage is used to transport messages between tasks. - StorageManagerIF* tcStore; - StorageManagerIF* tmStore; - object_id_t ccsdsPacketDistributor; - bool communicationLinkUp; //!< Used to specify whether communication link is up - bool tmStored; + //! Used to send and receive TMTC messages. + //! TmTcMessage is used to transport messages between tasks. + MessageQueueIF* TmTcReceptionQueue = nullptr; + StorageManagerIF* tcStore = nullptr; + StorageManagerIF* tmStore = nullptr; + object_id_t ccsdsPacketDistributor = 0; + //! Used to specify whether communication link is up + bool communicationLinkUp = false; + bool tmStored = false; /** * Handle TC reception. Default implementation provided @@ -113,13 +116,13 @@ protected: void printData(uint8_t * data, uint32_t dataLen); private: - static const uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; - static const uint8_t MAX_STORED_DATA_SENT_PER_CYCLE = 10; - static const uint8_t MAX_DOWNLINK_PACKETS_STORED = 15; + static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; + static constexpr uint8_t MAX_STORED_DATA_SENT_PER_CYCLE = 10; + static constexpr uint8_t MAX_DOWNLINK_PACKETS_STORED = 15; FIFO fifo; - uint8_t * recvBuffer; - uint32_t size; + uint8_t * recvBuffer = nullptr; + uint32_t size = 0; }; From 502651702845452441fd107d75820593bb51ecf2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Apr 2020 13:35:41 +0200 Subject: [PATCH 18/45] info output correction --- tmtcservices/TmTcBridge.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 6442f245..3ba00ba2 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -121,8 +121,8 @@ ReturnValue_t TmTcBridge::sendStoredTm() { uint8_t counter = 0; ReturnValue_t result = RETURN_OK; while(!fifo.empty() && counter < MAX_STORED_DATA_SENT_PER_CYCLE) { - info << "UDP Server: Sending stored TM data. There are " - << (int) fifo.size() << " left to send\r\n" << std::flush; + info << "TMTC Bridge: Sending stored TM data. There are " + << (int) fifo.size() << " left to send\r\n" << std::flush; store_address_t storeId; const uint8_t* data = NULL; uint32_t size = 0; @@ -130,7 +130,8 @@ ReturnValue_t TmTcBridge::sendStoredTm() { result = tmStore->getData(storeId, &data, &size); sendTm(data,size); if(result != RETURN_OK) { - error << "UDP Server: Could not send stored downlink data" << std::endl; + error << "TMTC Bridge: Could not send stored downlink data" + << std::endl; result = RETURN_FAILED; } counter ++; From b252299bdb9627b4319b94b186be31f6165278f2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 21 Apr 2020 14:51:26 +0200 Subject: [PATCH 19/45] U. Mohr suggestions worked in Furthermore, some enhancements added: delay between sent tm and max number of sent tm per cycle can be specified --- tmtcservices/TmTcBridge.cpp | 58 ++++++++++++++++++++++++--------- tmtcservices/TmTcBridge.h | 65 +++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 46 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 3ba00ba2..d63d4405 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -1,19 +1,16 @@ -/** - * @file TmTcBridge.cpp - * - * @date 26.12.2019 - * @author R. Mueller - */ - #include #include +#include +#include #include #include +#include TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), - ccsdsPacketDistributor(ccsdsPacketDistributor_) + ccsdsPacketDistributor(ccsdsPacketDistributor_), + sentPacketsPerCycle(5), delayBetweenSentPacketsMs(0) { TmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); @@ -21,6 +18,21 @@ TmTcBridge::TmTcBridge(object_id_t objectId_, TmTcBridge::~TmTcBridge() {} +void TmTcBridge::setDelayBetweenSentPackets(uint32_t delayBetweenSentPackets) { + this->delayBetweenSentPacketsMs = delayBetweenSentPackets; +} + +ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( + uint8_t sentPacketsPerCycle) { + if(sentPacketsPerCycle <= MAX_STORED_DATA_SENT_PER_CYCLE) { + this->sentPacketsPerCycle = sentPacketsPerCycle; + return RETURN_OK; + } + else { + return RETURN_FAILED; + } +} + ReturnValue_t TmTcBridge::initialize() { tcStore = objectManager->get(objects::TC_STORE); if (tcStore == NULL) { @@ -53,7 +65,21 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { } ReturnValue_t TmTcBridge::handleTc() { - ReturnValue_t result = receiveTc(&recvBuffer, &size); + uint8_t * recvBuffer = nullptr; + size_t recvLen = 0; + ReturnValue_t result = receiveTc(&recvBuffer, &recvLen); + if(result == RETURN_OK and recvLen > 0 and recvBuffer != nullptr) { + store_address_t storeId = 0; + ReturnValue_t result = tcStore->addData(&storeId, + recvBuffer, (uint32_t)recvLen); + if(result != RETURN_OK) { + return result; + } + TmTcMessage message(storeId); + if (TmTcReceptionQueue->sendToDefault(&message) != RETURN_OK) { + tcStore->deleteData(storeId); + } + } return result; } @@ -106,8 +132,8 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { store_address_t storeId = 0; if(fifo.full()) { - info << "TMTC Bridge: TM downlink max. number of stored packet IDs reached." - " Overwriting old data" << std::endl; + error << "TMTC Bridge: TM downlink max. number of stored packet IDs " + "reached! Overwriting old data" << std::endl; fifo.retrieve(&storeId); tmStore->deleteData(storeId); } @@ -120,14 +146,16 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { ReturnValue_t TmTcBridge::sendStoredTm() { uint8_t counter = 0; ReturnValue_t result = RETURN_OK; - while(!fifo.empty() && counter < MAX_STORED_DATA_SENT_PER_CYCLE) { - info << "TMTC Bridge: Sending stored TM data. There are " - << (int) fifo.size() << " left to send\r\n" << std::flush; + while(!fifo.empty() && counter < sentPacketsPerCycle) { + //info << "TMTC Bridge: Sending stored TM data. There are " + // << (int) fifo.size() << " left to send\r\n" << std::flush; store_address_t storeId; const uint8_t* data = NULL; uint32_t size = 0; fifo.retrieve(&storeId); result = tmStore->getData(storeId, &data, &size); + // This does not work yet: is not static function + //PeriodicTaskIF::sleepFor(delayBetweenSentPacketsMs); sendTm(data,size); if(result != RETURN_OK) { error << "TMTC Bridge: Could not send stored downlink data" @@ -162,7 +190,7 @@ MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { return TmTcReceptionQueue->getId(); } -void TmTcBridge::printData(uint8_t * data, uint32_t dataLen) { +void TmTcBridge::printData(uint8_t * data, size_t dataLen) { info << "TMTC Bridge: Printing data: ["; for(uint32_t i=0;i fifo; - uint8_t * recvBuffer = nullptr; - uint32_t size = 0; + uint8_t sentPacketsPerCycle = 10; + uint32_t delayBetweenSentPacketsMs = 0; }; From fdbc5d5c570ee4017dd482c18b2309515db12067 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 21 Apr 2020 14:54:04 +0200 Subject: [PATCH 20/45] com downlink message now debug and commented out --- tmtcservices/TmTcBridge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index d63d4405..0040b163 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -127,8 +127,8 @@ ReturnValue_t TmTcBridge::readTmQueue() { } ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { - info << "TMTC Bridge: Comm Link down. " - "Saving packet ID to be sent later\r\n" << std::flush; + //debug << "TMTC Bridge: Comm Link down. " + // "Saving packet ID to be sent later\r\n" << std::flush; store_address_t storeId = 0; if(fifo.full()) { From 7a79fab52aef5e0fad3c54c991977a96d436bec6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 21 Apr 2020 21:48:47 +0200 Subject: [PATCH 21/45] receiveTc (almost) empty now --- tmtcservices/TmTcBridge.cpp | 12 ------------ tmtcservices/TmTcBridge.h | 7 ++++++- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 0040b163..471fe828 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -68,18 +68,6 @@ ReturnValue_t TmTcBridge::handleTc() { uint8_t * recvBuffer = nullptr; size_t recvLen = 0; ReturnValue_t result = receiveTc(&recvBuffer, &recvLen); - if(result == RETURN_OK and recvLen > 0 and recvBuffer != nullptr) { - store_address_t storeId = 0; - ReturnValue_t result = tcStore->addData(&storeId, - recvBuffer, (uint32_t)recvLen); - if(result != RETURN_OK) { - return result; - } - TmTcMessage message(storeId); - if (TmTcReceptionQueue->sendToDefault(&message) != RETURN_OK) { - tcStore->deleteData(storeId); - } - } return result; } diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 865cd001..ef160257 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -65,7 +65,12 @@ protected: bool tmStored = false; /** - * Handle TC reception. Default implementation provided + * @brief Handle TC reception + * @details + * Default implementation provided, but is empty. + * Child handler should override this in most cases orsend TC to the + * TC distributor directly with the address of the reception queue by + * calling getReportRecptionQueue() * @return */ virtual ReturnValue_t handleTc(); From 57c225d4fcf9978796b58cf76c5e42f434ca8640 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 22 Apr 2020 18:15:45 +0200 Subject: [PATCH 22/45] faulty includes removed --- tmtcservices/TmTcBridge.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 471fe828..827e855e 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -2,10 +2,8 @@ #include #include -#include #include #include -#include TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), From 04835587a7d31487d0707ebfdfdbbd076ebf7175 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 22 Apr 2020 18:20:04 +0200 Subject: [PATCH 23/45] delay variable removed --- tmtcservices/TmTcBridge.cpp | 7 +------ tmtcservices/TmTcBridge.h | 3 +-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 827e855e..f24b2561 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -8,18 +8,13 @@ TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), ccsdsPacketDistributor(ccsdsPacketDistributor_), - sentPacketsPerCycle(5), delayBetweenSentPacketsMs(0) -{ + sentPacketsPerCycle(5) { TmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); } TmTcBridge::~TmTcBridge() {} -void TmTcBridge::setDelayBetweenSentPackets(uint32_t delayBetweenSentPackets) { - this->delayBetweenSentPacketsMs = delayBetweenSentPackets; -} - ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( uint8_t sentPacketsPerCycle) { if(sentPacketsPerCycle <= MAX_STORED_DATA_SENT_PER_CYCLE) { diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index ef160257..b3a58329 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -112,7 +112,7 @@ protected: * @param message * @return */ - ReturnValue_t storeDownlinkData(TmTcMessage * message); + virtual ReturnValue_t storeDownlinkData(TmTcMessage * message); /** * Send stored data if communication link is active @@ -130,7 +130,6 @@ protected: private: FIFO fifo; uint8_t sentPacketsPerCycle = 10; - uint32_t delayBetweenSentPacketsMs = 0; }; From d0ce075e0d70332a1cee51d777338b3808a689cc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 22 Apr 2020 18:21:50 +0200 Subject: [PATCH 24/45] added old comment --- tmtcservices/TmTcBridge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index f24b2561..9408df2f 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -135,9 +135,9 @@ ReturnValue_t TmTcBridge::sendStoredTm() { uint32_t size = 0; fifo.retrieve(&storeId); result = tmStore->getData(storeId, &data, &size); - // This does not work yet: is not static function - //PeriodicTaskIF::sleepFor(delayBetweenSentPacketsMs); + sendTm(data,size); + if(result != RETURN_OK) { error << "TMTC Bridge: Could not send stored downlink data" << std::endl; From d7278c449327c435f3cbf84da22a1a847cbfff4f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 23 Apr 2020 10:20:19 +0200 Subject: [PATCH 25/45] adapting tmtc bridge --- tmtcservices/TmTcBridge.cpp | 31 ++++++++++++++++++++++++------- tmtcservices/TmTcBridge.h | 32 +++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 9408df2f..06c5bf66 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -7,25 +7,40 @@ TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), - ccsdsPacketDistributor(ccsdsPacketDistributor_), - sentPacketsPerCycle(5) { - TmTcReceptionQueue = QueueFactory::instance()-> - createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); + ccsdsPacketDistributor(ccsdsPacketDistributor_) +{ + TmTcReceptionQueue = QueueFactory::instance()-> + createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); } TmTcBridge::~TmTcBridge() {} ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( uint8_t sentPacketsPerCycle) { - if(sentPacketsPerCycle <= MAX_STORED_DATA_SENT_PER_CYCLE) { + if(sentPacketsPerCycle <= LIMIT_STORED_DATA_SENT_PER_CYCLE) { this->sentPacketsPerCycle = sentPacketsPerCycle; return RETURN_OK; } else { + warning << "TmTcBridge: Number of packets sent per cycle " + "exceeds limits" << std::endl; return RETURN_FAILED; } } +ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored( + uint8_t maxNumberOfPacketsStored) { + if(maxNumberOfPacketsStored <= LIMIT_DOWNLINK_PACKETS_STORED) { + this->maxNumberOfPacketsStored = maxNumberOfPacketsStored; + return RETURN_OK; + } + else { + warning << "TmTcBridge: Number of packets stored " + "exceeds limits" << std::endl; + return RETURN_FAILED; + } +} + ReturnValue_t TmTcBridge::initialize() { tcStore = objectManager->get(objects::TC_STORE); if (tcStore == NULL) { @@ -72,7 +87,7 @@ ReturnValue_t TmTcBridge::handleTm() { } if(tmStored && communicationLinkUp) { - result = sendStoredTm(); + result = handleStoredTm(); } return result; @@ -124,7 +139,7 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { return RETURN_OK; } -ReturnValue_t TmTcBridge::sendStoredTm() { +ReturnValue_t TmTcBridge::handleStoredTm() { uint8_t counter = 0; ReturnValue_t result = RETURN_OK; while(!fifo.empty() && counter < sentPacketsPerCycle) { @@ -171,6 +186,8 @@ MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { return TmTcReceptionQueue->getId(); } + + void TmTcBridge::printData(uint8_t * data, size_t dataLen) { info << "TMTC Bridge: Printing data: ["; for(uint32_t i=0;i fifo; - uint8_t sentPacketsPerCycle = 10; + FIFO fifo; + uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; + uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; From e3a4eca3f90fc573c917aca0b0be3a6ea7809ca2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 23 Apr 2020 10:22:25 +0200 Subject: [PATCH 26/45] info output commented out --- tmtcservices/TmTcBridge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 06c5bf66..aa0a0539 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -170,13 +170,13 @@ ReturnValue_t TmTcBridge::handleStoredTm() { void TmTcBridge::registerCommConnect() { if(!communicationLinkUp) { - info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; + //info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; communicationLinkUp = true; } } void TmTcBridge::registerCommDisconnect() { - info << "TMTC Bridge: Registered Comm Link Disconnect" << std::endl; + //info << "TMTC Bridge: Registered Comm Link Disconnect" << std::endl; if(communicationLinkUp) { communicationLinkUp = false; } From ab2794e2d8b12634b32463e7a4a2d05eb0967cbf Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 23 Apr 2020 10:24:34 +0200 Subject: [PATCH 27/45] minor form changes --- tmtcservices/TmTcBridge.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index aa0a0539..6a7bbcad 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -23,7 +23,7 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( } else { warning << "TmTcBridge: Number of packets sent per cycle " - "exceeds limits" << std::endl; + "exceeds limits. Keeping default value." << std::endl; return RETURN_FAILED; } } @@ -36,7 +36,7 @@ ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored( } else { warning << "TmTcBridge: Number of packets stored " - "exceeds limits" << std::endl; + "exceeds limits. Keeping default value." << std::endl; return RETURN_FAILED; } } @@ -142,7 +142,7 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { ReturnValue_t TmTcBridge::handleStoredTm() { uint8_t counter = 0; ReturnValue_t result = RETURN_OK; - while(!fifo.empty() && counter < sentPacketsPerCycle) { + while(not fifo.empty() && counter < sentPacketsPerCycle) { //info << "TMTC Bridge: Sending stored TM data. There are " // << (int) fifo.size() << " left to send\r\n" << std::flush; store_address_t storeId; @@ -169,7 +169,7 @@ ReturnValue_t TmTcBridge::handleStoredTm() { } void TmTcBridge::registerCommConnect() { - if(!communicationLinkUp) { + if(not communicationLinkUp) { //info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; communicationLinkUp = true; } @@ -190,7 +190,7 @@ MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { void TmTcBridge::printData(uint8_t * data, size_t dataLen) { info << "TMTC Bridge: Printing data: ["; - for(uint32_t i=0;i Date: Thu, 23 Apr 2020 10:32:05 +0200 Subject: [PATCH 28/45] better names --- tmtcservices/TmTcBridge.cpp | 4 ++-- tmtcservices/TmTcBridge.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 6a7bbcad..b4732a85 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -80,7 +80,7 @@ ReturnValue_t TmTcBridge::handleTc() { } ReturnValue_t TmTcBridge::handleTm() { - ReturnValue_t result = readTmQueue(); + ReturnValue_t result = handleTmQueue(); if(result != RETURN_OK) { error << "TMTC Bridge: Reading TM Queue failed" << std::endl; return RETURN_FAILED; @@ -93,7 +93,7 @@ ReturnValue_t TmTcBridge::handleTm() { } -ReturnValue_t TmTcBridge::readTmQueue() { +ReturnValue_t TmTcBridge::handleTmQueue() { TmTcMessage message; const uint8_t* data = nullptr; uint32_t size = 0; diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 815d6a87..c6c79d6c 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -108,7 +108,7 @@ protected: * Read the TM Queue and send TM if necessary. Default implementation provided * @return */ - virtual ReturnValue_t readTmQueue(); + virtual ReturnValue_t handleTmQueue(); /** * Send stored data if communication link is active From 07247dbf403b625dcc1b5c54241243ad19219288 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 23 Apr 2020 11:50:13 +0200 Subject: [PATCH 29/45] added virtual keyword for init and performOp() --- tmtcservices/TmTcBridge.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index c6c79d6c..9fb00ef1 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -52,12 +52,12 @@ public: * Initializes necessary FSFW components for the TMTC Bridge * @return */ - ReturnValue_t initialize() override; + virtual ReturnValue_t initialize() override; /** * @brief Handles TMTC reception */ - ReturnValue_t performOperation(uint8_t operationCode = 0) override; + virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; /** * Return TMTC Reception Queue From 6be607e4220141111c67a2a611fc1e62517e269c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 4 May 2020 17:33:56 +0200 Subject: [PATCH 30/45] FIFO protected --- tmtcservices/TmTcBridge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 9fb00ef1..15fd42c1 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -75,6 +75,7 @@ protected: //! Used to specify whether communication link is up bool communicationLinkUp = false; bool tmStored = false; + FIFO fifo; /** * @brief Handle TC reception @@ -141,7 +142,6 @@ protected: void printData(uint8_t * data, size_t dataLen); private: - FIFO fifo; uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; From 684dd67f638040143c425df537d16ab13230b38d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 5 May 2020 19:14:51 +0200 Subject: [PATCH 31/45] seconds_t double now --- timemanager/Clock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 5f18de3e..2883878f 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -8,7 +8,7 @@ #include typedef uint32_t millis_t; -typedef float seconds_t; +typedef double seconds_t; class Clock { public: From 25ff8784cf0554e85ed50ff0d073dbff56bf2d51 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 7 May 2020 20:00:42 +0200 Subject: [PATCH 32/45] corrected documentation --- timemanager/Stopwatch.cpp | 6 ------ timemanager/Stopwatch.h | 13 +++---------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 3f0755fd..771b63dc 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -1,9 +1,3 @@ -/** - * @file Stopwatch.cpp - * - * @date 08.04.2020 - */ - #include #include #include diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 786a9d57..19e1f92b 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -1,9 +1,3 @@ -/** - * @file Stopwatch.h - * - * @date 08.04.2020 - */ - #ifndef FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ #define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ #include @@ -18,8 +12,7 @@ enum class StopwatchDisplayMode { * @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. + * constructor. The default time format is the elapsed time in miliseconds. */ class Stopwatch { public: @@ -28,8 +21,8 @@ public: * 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 displayMode Display format is either MS rounded or seconds as + * double format * @param outputPrecision If using double format, specify precision here. */ Stopwatch(bool displayOnDestruction = true, StopwatchDisplayMode displayMode From fadebe2eb4255aa6ff870ed3fa07e70905487138 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 8 May 2020 14:38:10 +0200 Subject: [PATCH 33/45] new initializer list ctor --- datapool/PoolEntry.cpp | 18 ++++++++-- datapool/PoolEntry.h | 79 ++++++++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index de024c81..97c60131 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -2,9 +2,22 @@ #include template -PoolEntry::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : length(set_length), valid(set_valid) { +PoolEntry::PoolEntry(std::initializer_list initValue, uint8_t set_length, + uint8_t set_valid ) : length(set_length), valid(set_valid) { this->address = new T[this->length]; - if (initValue != NULL) { + if(initValue.size() == 0) { + memset(this->address, 0, this->getByteSize()); + } + else { + memcpy(this->address, initValue.begin(), this->getByteSize()); + } +} + +template +PoolEntry::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : + length(set_length), valid(set_valid) { + this->address = new T[this->length]; + if (initValue != nullptr) { memcpy(this->address, initValue, this->getByteSize() ); } else { memset(this->address, 0, this->getByteSize() ); @@ -57,6 +70,7 @@ Type PoolEntry::getType() { return PodTypeConversion::type; } +template class PoolEntry; template class PoolEntry; template class PoolEntry; template class PoolEntry; diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h index ce41a991..5edc0198 100644 --- a/datapool/PoolEntry.h +++ b/datapool/PoolEntry.h @@ -1,81 +1,94 @@ #ifndef POOLENTRY_H_ #define POOLENTRY_H_ - #include #include #include +#include + /** - * \brief This is a small helper class that defines a single data pool entry. + * @brief This is a small helper class that defines a single data pool entry. + * @details + * The helper is used to store all information together with the data as a + * single data pool entry.The content's type is defined by the template argument. + * It is prepared for use with plain old data types, but may be extended to + * complex types if necessary. It can be initialized with a certain value, + * size and validity flag. It holds a pointer to the real data and offers + * methods to access this data and to acquire additional information + * (such as validity and array/byte size). It is NOT intended to be used + * outside the DataPool class. * - * \details The helper is used to store all information together with the data as a single data pool entry. - * The content's type is defined by the template argument. - * It is prepared for use with plain old data types, - * but may be extended to complex types if necessary. - * It can be initialized with a certain value, size and validity flag. - * It holds a pointer to the real data and offers methods to access this data and to acquire - * additional information (such as validity and array/byte size). - * It is NOT intended to be used outside the DataPool class. - * - * \ingroup data_pool + * @ingroup data_pool * */ template class PoolEntry : public PoolEntryIF { public: /** - * \brief In the classe's constructor, space is allocated on the heap and + * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. - * \param initValue A pointer to the single value or array that holds the init value. - * With the default value (NULL), the entry is initalized with all 0. - * \param set_length Defines the array length of this entry. - * \param set_valid Sets the initialization flag. It is invalid (0) by default. + * @param initValue Initializer list with values to initialize with + * @param set_length Defines the array length of this entry. + * @param set_valid Sets the initialization flag. + * It is invalid (0) by default. */ - PoolEntry( T* initValue = NULL, uint8_t set_length = 1, uint8_t set_valid = 0 ); + PoolEntry(std::initializer_list initValue = {}, uint8_t set_length = 1, + uint8_t set_valid = 0); /** - * \brief The allocated memory for the variable is freed in the destructor. - * \details As the data pool is global, this dtor is only called on program exit. - * PoolEntries shall never be copied, as a copy might delete the variable on the heap. + * @brief In the classe's constructor, space is allocated on the heap and + * potential init values are copied to that space. + * @param initValue A pointer to the single value or array that holds + * the init value. With the default value (nullptr), the entry is + * initalized with all 0. + * @param set_length Defines the array length of this entry. + * @param set_valid Sets the initialization flag. It is invalid (0) by default. + */ + PoolEntry(T* initValue = nullptr, uint8_t set_length = 1, uint8_t set_valid = 0); + + /** + * @brief The allocated memory for the variable is freed in the destructor. + * @details As the data pool is global, this dtor is only called on program exit. + * PoolEntries shall never be copied, as a copy might delete the variable on the heap. */ ~PoolEntry(); /** - * \brief This is the address pointing to the allocated memory. + * @brief This is the address pointing to the allocated memory. */ T* address; /** - * \brief This attribute stores the length information. + * @brief This attribute stores the length information. */ uint8_t length; /** - * \brief Here, the validity information for a variable is stored. + * @brief Here, the validity information for a variable is stored. * Every entry (single variable or vector) has one valid flag. */ uint8_t valid; /** - * \brief getSize returns the array size of the entry. - * \details A single parameter has size 1. + * @brief getSize returns the array size of the entry. + * @details A single parameter has size 1. */ uint8_t getSize(); /** - * \brief This operation returns the size in bytes. - * \details The size is calculated by sizeof(type) * array_size. + * @brief This operation returns the size in bytes. + * @details The size is calculated by sizeof(type) * array_size. */ uint16_t getByteSize(); /** - * \brief This operation returns a the address pointer casted to void*. + * @brief This operation returns a the address pointer casted to void*. */ void* getRawData(); /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information of the pool entry. */ void setValid( uint8_t isValid ); /** - * \brief This method allows to get the valid information of the pool entry. + * @brief This method allows to get the valid information of the pool entry. */ uint8_t getValid(); /** - * \brief This is a debug method that prints all values and the valid information to the screen. - * It prints all array entries in a row. + * @brief This is a debug method that prints all values and the valid + * information to the screen. It prints all array entries in a row. */ void print(); From a159e60a9055e51b6c38a739b1f489e378a30857 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 11 May 2020 16:53:16 +0200 Subject: [PATCH 34/45] removed bool specialization --- datapool/PoolEntry.cpp | 1 - datapool/PoolEntry.h | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index 97c60131..1d8d2486 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -70,7 +70,6 @@ Type PoolEntry::getType() { return PodTypeConversion::type; } -template class PoolEntry; template class PoolEntry; template class PoolEntry; template class PoolEntry; diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h index 5edc0198..4487db72 100644 --- a/datapool/PoolEntry.h +++ b/datapool/PoolEntry.h @@ -2,10 +2,10 @@ #define POOLENTRY_H_ #include -#include +#include #include #include - +#include /** * @brief This is a small helper class that defines a single data pool entry. * @details @@ -24,6 +24,9 @@ template class PoolEntry : public PoolEntryIF { public: + static_assert(not std::is_same::value, + "Do not use boolean for the PoolEntry type, use uint8_t instead!" + "Warum? Darum :-)"); /** * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. From 7eb250a90ab432b8a5e5d10f78ec7598f13cdd45 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 25 May 2020 15:06:54 +0200 Subject: [PATCH 35/45] include testing --- osal/FreeRTOS/Clock.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index 5e597f25..a672076a 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -4,8 +4,7 @@ #include "Timekeeper.h" extern "C" { -#include -#include +#include } From 35b9346c2bface422ad7943d66689a8c7da21ed0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 25 May 2020 15:25:17 +0200 Subject: [PATCH 36/45] include improvements for clock, sif fixes --- osal/FreeRTOS/Clock.cpp | 1 + timemanager/Stopwatch.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index a672076a..82c9e170 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -5,6 +5,7 @@ extern "C" { #include +#include } diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 771b63dc..2c85376d 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -25,11 +25,11 @@ seconds_t Stopwatch::stopSeconds() { void Stopwatch::display() { if(displayMode == StopwatchDisplayMode::MILLIS) { - info << "Stopwatch: Operation took " << (elapsedTime.tv_sec * 1000 + + sif::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) + sif::info <<"Stopwatch: Operation took " << std::setprecision(3) << std::fixed << timevalOperations::toDouble(elapsedTime) << " seconds" << std::endl; } From 1cf5991101f9dc0e677911e1d7cfeffaa250285b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:43:06 +0200 Subject: [PATCH 37/45] getClock_timval used now --- timemanager/Stopwatch.cpp | 12 +++++++----- timemanager/Stopwatch.h | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 2c85376d..bc8b4149 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -3,14 +3,14 @@ #include Stopwatch::Stopwatch(bool displayOnDestruction, - StopwatchDisplayMode displayMode): displayMode(displayMode), - displayOnDestruction(displayOnDestruction) { + StopwatchDisplayMode displayMode): displayOnDestruction( + displayOnDestruction), displayMode(displayMode) { // Measures start time on initialization. - startTime = Clock::getUptime(); + Clock::getClock_timeval(&startTime); } void Stopwatch::start() { - startTime = Clock::getUptime(); + Clock::getClock_timeval(&startTime); } millis_t Stopwatch::stop() { @@ -51,5 +51,7 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { } void Stopwatch::stopInternal() { - elapsedTime = Clock::getUptime() - startTime; + timeval endTime; + Clock::getClock_timeval(&endTime); + elapsedTime = endTime - startTime; } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 19e1f92b..71580778 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -8,11 +8,13 @@ enum class StopwatchDisplayMode { }; /** - * @brief Simple Stopwatch implementation to measure elapsed time + * @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. + * constructor. The default time format is the elapsed time in miliseconds + * in seconds as a double. + * @author R. Mueller */ class Stopwatch { public: @@ -21,8 +23,8 @@ public: * 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 seconds as - * double format + * @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 @@ -39,6 +41,10 @@ public: * @return elapsed time in milliseconds (rounded) */ millis_t stop(); + /** + * Calculates the elapsed time since start and returns it + * @return elapsed time in seconds (double precision) + */ seconds_t stopSeconds(); /** @@ -49,12 +55,13 @@ public: StopwatchDisplayMode getDisplayMode() const; void setDisplayMode(StopwatchDisplayMode displayMode); + bool displayOnDestruction = true; private: timeval startTime {0, 0}; timeval elapsedTime {0, 0}; StopwatchDisplayMode displayMode = StopwatchDisplayMode::MILLIS; - bool displayOnDestruction = true; + void stopInternal(); }; From 0be418a553a95971a56fc61a0f9e57276a345165 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:45:08 +0200 Subject: [PATCH 38/45] clock.h form improvements --- timemanager/Clock.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 2883878f..19991b81 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -2,11 +2,12 @@ #define FRAMEWORK_TIMEMANAGER_CLOCK_H_ #include -#include -#include #include #include +#include +#include + typedef uint32_t millis_t; typedef double seconds_t; @@ -22,7 +23,7 @@ public: uint32_t usecond; //!< Microseconds, 0 .. 999999 } TimeOfDay_t; - /**static Clock* TimeOfDay_t(); + /** * This method returns the number of clock ticks per second. * In RTEMS, this is typically 1000. * @return The number of ticks. @@ -34,22 +35,23 @@ public: * This system call sets the system time. * To set the time, it uses a TimeOfDay_t struct. * @param time The struct with the time settings to set. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return -@c RETURN_OK on success. Otherwise, the OS failure code + * is returned. */ static ReturnValue_t setClock(const TimeOfDay_t* time); /** * This system call sets the system time. * To set the time, it uses a timeval struct. * @param time The struct with the time settings to set. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return -@c RETURN_OK on success. Otherwise, the OS failure code is returned. */ static ReturnValue_t setClock(const 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 + * The timval format has the fields @c tv_sec with seconds and @c tv_usec with * microseconds since an OS-defined epoch. * @param time A pointer to a timeval struct where the current time is stored. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return @c RETURN_OK on success. Otherwise, the OS failure code is returned. */ static ReturnValue_t getClock_timeval(timeval* time); @@ -57,7 +59,7 @@ public: * Get the time since boot in a timeval struct * * @param[out] time A pointer to a timeval struct where the uptime is stored. - * @return\c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return @c RETURN_OK on success. Otherwise, the OS failure code is returned. * * @deprecated, I do not think this should be able to fail, use timeval getUptime() */ From f15424be4fef0a280385fc4d3a5eae85beba9ec5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:47:55 +0200 Subject: [PATCH 39/45] implemented missing static function --- osal/linux/Clock.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/osal/linux/Clock.cpp b/osal/linux/Clock.cpp index e24a4fe4..630b2cf4 100644 --- a/osal/linux/Clock.cpp +++ b/osal/linux/Clock.cpp @@ -1,10 +1,10 @@ -#include -#include +#include #include - +#include #include #include +#include #include //#include @@ -65,6 +65,15 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) { return HasReturnvaluesIF::RETURN_OK; } +timeval Clock::getUptime() { + timeval uptime; + auto result = getUptime(&uptime); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Clock::getUptime: Error getting uptime" << std::endl; + } + return uptime; +} + ReturnValue_t Clock::getUptime(timeval* uptime) { //TODO This is not posix compatible and delivers only seconds precision struct sysinfo sysInfo; From c5bb18a7884a1b1f383581a854772ca0771cf04b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:49:39 +0200 Subject: [PATCH 40/45] include improvements, nullptr used --- osal/FreeRTOS/Clock.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index 82c9e170..dce20265 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -1,19 +1,18 @@ #include #include -#include -#include "Timekeeper.h" +#include -extern "C" { #include #include -} +#include +#include //TODO sanitize input? //TODO much of this code can be reused for tick-only systems uint16_t Clock::leapSeconds = 0; -MutexIF* Clock::timeMutex = NULL; +MutexIF* Clock::timeMutex = nullptr; uint32_t Clock::getTicksPerSecond(void) { return 1000; @@ -130,7 +129,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { //SHOULDDO: works not for dates in the past (might have less leap seconds) - if (timeMutex == NULL) { + if (timeMutex == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } From a9a23d76231564d2d5bc15836455686b618a546a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:51:15 +0200 Subject: [PATCH 41/45] include improvements --- osal/FreeRTOS/Timekeeper.cpp | 15 ++++----------- osal/FreeRTOS/Timekeeper.h | 6 +++--- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/osal/FreeRTOS/Timekeeper.cpp b/osal/FreeRTOS/Timekeeper.cpp index 949e1df3..643b2747 100644 --- a/osal/FreeRTOS/Timekeeper.cpp +++ b/osal/FreeRTOS/Timekeeper.cpp @@ -1,17 +1,12 @@ -/** - * @file Timekeeper.cpp - * @date - */ - #include -extern "C" { -#include -} +#include "FreeRTOSConfig.h" Timekeeper * Timekeeper::myinstance = nullptr; -Timekeeper::Timekeeper() : offset( { 0, 0 }) {} +Timekeeper::Timekeeper() : offset( { 0, 0 } ) {} + +Timekeeper::~Timekeeper() {} const timeval& Timekeeper::getOffset() const { return offset; @@ -28,8 +23,6 @@ void Timekeeper::setOffset(const timeval& offset) { this->offset = offset; } -Timekeeper::~Timekeeper() {} - timeval Timekeeper::ticksToTimeval(TickType_t ticks) { timeval uptime; uptime.tv_sec = ticks / configTICK_RATE_HZ; diff --git a/osal/FreeRTOS/Timekeeper.h b/osal/FreeRTOS/Timekeeper.h index 05f0f701..7d3ca22b 100644 --- a/osal/FreeRTOS/Timekeeper.h +++ b/osal/FreeRTOS/Timekeeper.h @@ -2,9 +2,9 @@ #define FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ #include -extern "C" { -#include -} + +#include +#include /** From ef1324940579d307b8ba62c1270c7db3fbaa9472 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 13:01:59 +0200 Subject: [PATCH 42/45] typedef renamed --- timemanager/Clock.h | 5 +++-- timemanager/Stopwatch.cpp | 4 ++-- timemanager/Stopwatch.h | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 19991b81..121c63df 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -8,8 +8,9 @@ #include #include -typedef uint32_t millis_t; -typedef double seconds_t; +//! Don't use these for time points, type is not large enough for UNIX epoch. +typedef uint32_t dur_millis_t; +typedef double dur_seconds_t; class Clock { public: diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index bc8b4149..52118d58 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -13,12 +13,12 @@ void Stopwatch::start() { Clock::getClock_timeval(&startTime); } -millis_t Stopwatch::stop() { +dur_millis_t Stopwatch::stop() { stopInternal(); return elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000; } -seconds_t Stopwatch::stopSeconds() { +dur_seconds_t Stopwatch::stopSeconds() { stopInternal(); return timevalOperations::toDouble(elapsedTime); } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 71580778..630202cc 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -40,12 +40,12 @@ public: * Calculates the elapsed time since start and returns it * @return elapsed time in milliseconds (rounded) */ - millis_t stop(); + dur_millis_t stop(); /** * Calculates the elapsed time since start and returns it * @return elapsed time in seconds (double precision) */ - seconds_t stopSeconds(); + dur_seconds_t stopSeconds(); /** * Displays the elapsed times on the osstream, depending on internal display From cef5fda3796754ae28b3982a8de2bdca6c92a86e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 13:43:06 +0200 Subject: [PATCH 43/45] refactored initializer list --- datapool/PoolEntry.cpp | 35 ++++++++------ datapool/PoolEntry.h | 95 +++++++++++++++++++++++++------------- datapool/PoolEntryIF.h | 57 +++++++++++------------ datapool/PoolRawAccess.cpp | 2 + 4 files changed, 111 insertions(+), 78 deletions(-) diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index 1d8d2486..a87a6c4e 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -1,26 +1,34 @@ #include #include +#include +#include template -PoolEntry::PoolEntry(std::initializer_list initValue, uint8_t set_length, - uint8_t set_valid ) : length(set_length), valid(set_valid) { +PoolEntry::PoolEntry(std::initializer_list initValue, uint8_t setLength, + bool setValid ) : length(setLength), valid(setValid) { this->address = new T[this->length]; if(initValue.size() == 0) { - memset(this->address, 0, this->getByteSize()); + std::memset(this->address, 0, this->getByteSize()); + } + else if (initValue.size() != setLength){ + sif::warning << "PoolEntry: setLength is not equal to initializer list" + "length! Performing zero initialization with given setLength" + << std::endl; + std::memset(this->address, 0, this->getByteSize()); } else { - memcpy(this->address, initValue.begin(), this->getByteSize()); + std::copy(initValue.begin(), initValue.end(), this->address); } } template -PoolEntry::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : - length(set_length), valid(set_valid) { +PoolEntry::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) : + length(setLength), valid(setValid) { this->address = new T[this->length]; if (initValue != nullptr) { - memcpy(this->address, initValue, this->getByteSize() ); + std::memcpy(this->address, initValue, this->getByteSize() ); } else { - memset(this->address, 0, this->getByteSize() ); + std::memset(this->address, 0, this->getByteSize() ); } } @@ -47,21 +55,20 @@ void* PoolEntry::getRawData() { } template -void PoolEntry::setValid( uint8_t isValid ) { +void PoolEntry::setValid(bool isValid) { this->valid = isValid; } template -uint8_t PoolEntry::getValid() { +bool PoolEntry::getValid() { return valid; } template void PoolEntry::print() { - for (uint8_t size = 0; size < this->length; size++ ) { - sif::debug << "| " << std::hex << (double)this->address[size] - << (this->valid? " (valid) " : " (invalid) "); - } + sif::debug << "Pool Entry Validity: " << + (this->valid? " (valid) " : " (invalid) ") << std::endl; + printer::print(reinterpret_cast(address), length); sif::debug << std::dec << std::endl; } diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h index 4487db72..1a22bb63 100644 --- a/datapool/PoolEntry.h +++ b/datapool/PoolEntry.h @@ -1,59 +1,86 @@ -#ifndef POOLENTRY_H_ -#define POOLENTRY_H_ +#ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_ +#define FRAMEWORK_DATAPOOL_POOLENTRY_H_ #include -#include -#include + #include #include +#include + /** * @brief This is a small helper class that defines a single data pool entry. * @details * The helper is used to store all information together with the data as a - * single data pool entry.The content's type is defined by the template argument. - * It is prepared for use with plain old data types, but may be extended to - * complex types if necessary. It can be initialized with a certain value, - * size and validity flag. It holds a pointer to the real data and offers - * methods to access this data and to acquire additional information - * (such as validity and array/byte size). It is NOT intended to be used - * outside the DataPool class. + * single data pool entry. The content's type is defined by the template + * argument. + * + * It is prepared for use with plain old data types, but may be + * extended to complex types if necessary. It can be initialized with a + * certain value, size and validity flag. + * + * It holds a pointer to the real data and offers methods to access this data + * and to acquire additional information (such as validity and array/byte size). + * It is NOT intended to be used outside DataPool implementations as it performs + * dynamic memory allocation. * * @ingroup data_pool - * */ template class PoolEntry : public PoolEntryIF { public: static_assert(not std::is_same::value, - "Do not use boolean for the PoolEntry type, use uint8_t instead!" - "Warum? Darum :-)"); + "Do not use boolean for the PoolEntry type, use uint8_t " + "instead! The ECSS standard defines a boolean as a one bit " + "field. Therefore it is preferred to store a boolean as an " + "uint8_t"); /** * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. - * @param initValue Initializer list with values to initialize with - * @param set_length Defines the array length of this entry. - * @param set_valid Sets the initialization flag. - * It is invalid (0) by default. + * @details + * Not passing any arguments will initialize an non-array pool entry + * (setLength = 1) with an initial invalid state. + * Please note that if an initializer list is passed, the correct + * corresponding length should be passed too, otherwise a zero + * initialization will be performed with the given setLength. + * @param initValue + * Initializer list with values to initialize with, for example {0,0} to + * initialize the two entries to zero. + * @param setLength + * Defines the array length of this entry. Should be equal to the + * intializer list length. + * @param setValid + * Sets the initialization flag. It is invalid by default. */ - PoolEntry(std::initializer_list initValue = {}, uint8_t set_length = 1, - uint8_t set_valid = 0); + PoolEntry(std::initializer_list initValue = {}, uint8_t setLength = 1, + bool setValid = false); /** * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. - * @param initValue A pointer to the single value or array that holds - * the init value. With the default value (nullptr), the entry is - * initalized with all 0. - * @param set_length Defines the array length of this entry. - * @param set_valid Sets the initialization flag. It is invalid (0) by default. + * @param initValue + * A pointer to the single value or array that holds the init value. + * With the default value (nullptr), the entry is initalized with all 0. + * @param setLength + * Defines the array length of this entry. + * @param setValid + * Sets the initialization flag. It is invalid by default. */ - PoolEntry(T* initValue = nullptr, uint8_t set_length = 1, uint8_t set_valid = 0); + PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false); + + //! Explicitely deleted copy ctor, copying is not allowed! + PoolEntry(const PoolEntry&) = delete; + //! Explicitely deleted copy assignment, copying is not allowed! + PoolEntry& operator=(const PoolEntry&) = delete; /** - * @brief The allocated memory for the variable is freed in the destructor. - * @details As the data pool is global, this dtor is only called on program exit. - * PoolEntries shall never be copied, as a copy might delete the variable on the heap. + * @brief The allocated memory for the variable is freed + * in the destructor. + * @details + * As the data pool is global, this dtor is only called on program exit. + * PoolEntries shall never be copied, as a copy might delete the variable + * on the heap. */ ~PoolEntry(); + /** * @brief This is the address pointing to the allocated memory. */ @@ -82,13 +109,15 @@ public: */ void* getRawData(); /** - * @brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information + * of the pool entry. */ - void setValid( uint8_t isValid ); + void setValid( bool isValid ); /** - * @brief This method allows to get the valid information of the pool entry. + * @brief This method allows to get the valid information + * of the pool entry. */ - uint8_t getValid(); + bool getValid(); /** * @brief This is a debug method that prints all values and the valid * information to the screen. It prints all array entries in a row. diff --git a/datapool/PoolEntryIF.h b/datapool/PoolEntryIF.h index 514e67ef..a075436e 100644 --- a/datapool/PoolEntryIF.h +++ b/datapool/PoolEntryIF.h @@ -1,62 +1,57 @@ -/** - * \file PoolEntryIF.h - * - * \brief This file holds the class that defines the Interface for Pool Entry elements. - * - * \date 10/18/2012 - * - * \author Bastian Baetz - */ - -#ifndef POOLENTRYIF_H_ -#define POOLENTRYIF_H_ +#ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ +#define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ #include -#include - - +#include /** - * \brief This interface defines the access possibilities to a single data pool entry. + * @brief This interface defines the access possibilities to a + * single data pool entry. + * @details + * The interface provides methods to determine the size and the validity + * information of a value. It also defines a method to receive a pointer to the + * raw data content. It is mainly used by DataPool itself, but also as a + * return pointer. * - * \details The interface provides methods to determine the size and the validity information of a value. - * It also defines a method to receive a pointer to the raw data content. - * It is mainly used by DataPool itself, but also as a return pointer. - * - * \ingroup data_pool + * @author Bastian Baetz + * @ingroup data_pool * */ class PoolEntryIF { public: /** - * \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. + * @brief This is an empty virtual destructor, + * as it is required for C++ interfaces. */ virtual ~PoolEntryIF() { } /** - * \brief getSize returns the array size of the entry. A single variable parameter has size 1. + * @brief getSize returns the array size of the entry. + * A single variable parameter has size 1. */ virtual uint8_t getSize() = 0; /** - * \brief This operation returns the size in bytes, which is calculated by + * @brief This operation returns the size in bytes, which is calculated by * sizeof(type) * array_size. */ virtual uint16_t getByteSize() = 0; /** - * \brief This operation returns a the address pointer casted to void*. + * @brief This operation returns a the address pointer casted to void*. */ virtual void* getRawData() = 0; /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information of the pool entry. */ - virtual void setValid(uint8_t isValid) = 0; + virtual void setValid(bool isValid) = 0; /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information of the pool entry. */ - virtual uint8_t getValid() = 0; + virtual bool getValid() = 0; /** - * \brief This is a debug method that prints all values and the valid information to the screen. - * It prints all array entries in a row. + * @brief This is a debug method that prints all values and the valid + * information to the screen. It prints all array entries in a row. + * @details + * Also displays whether the pool entry is valid or invalid. */ virtual void print() = 0; /** diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index ba68bcd2..fd81b894 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -4,6 +4,8 @@ #include #include +#include + PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, DataSetIF* data_set, ReadWriteMode_t setReadWriteMode) : dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(Type::UNKNOWN_TYPE), typeSize( From e935b8bd04ee349e45c4bdcd60a2fa306cc73d74 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 10:45:47 +0200 Subject: [PATCH 44/45] some minor improvements --- tmtcservices/TmTcBridge.cpp | 50 ++++++++++++++++--------------------- tmtcservices/TmTcBridge.h | 20 ++++++++------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index b4732a85..f9a7d3bc 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -1,9 +1,9 @@ #include #include -#include #include #include +#include TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), @@ -22,7 +22,7 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( return RETURN_OK; } else { - warning << "TmTcBridge: Number of packets sent per cycle " + sif::warning << "TmTcBridge: Number of packets sent per cycle " "exceeds limits. Keeping default value." << std::endl; return RETURN_FAILED; } @@ -35,7 +35,7 @@ ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored( return RETURN_OK; } else { - warning << "TmTcBridge: Number of packets stored " + sif::warning << "TmTcBridge: Number of packets stored " "exceeds limits. Keeping default value." << std::endl; return RETURN_FAILED; } @@ -63,11 +63,11 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { ReturnValue_t result; result = handleTc(); if(result != RETURN_OK) { - error << "TMTC Bridge: Error handling TCs" << std::endl; + sif::error << "TMTC Bridge: Error handling TCs" << std::endl; } result = handleTm(); if (result != RETURN_OK) { - error << "TMTC Bridge: Error handling TMs" << std::endl; + sif::error << "TMTC Bridge: Error handling TMs" << std::endl; } return result; } @@ -82,11 +82,11 @@ ReturnValue_t TmTcBridge::handleTc() { ReturnValue_t TmTcBridge::handleTm() { ReturnValue_t result = handleTmQueue(); if(result != RETURN_OK) { - error << "TMTC Bridge: Reading TM Queue failed" << std::endl; + sif::error << "TMTC Bridge: Reading TM Queue failed" << std::endl; return RETURN_FAILED; } - if(tmStored && communicationLinkUp) { + if(tmStored and communicationLinkUp) { result = handleStoredTm(); } return result; @@ -95,8 +95,8 @@ ReturnValue_t TmTcBridge::handleTm() { ReturnValue_t TmTcBridge::handleTmQueue() { TmTcMessage message; - const uint8_t* data = nullptr; - uint32_t size = 0; + const uint8_t* data = nullptr; + size_t size = 0; for (ReturnValue_t result = TmTcReceptionQueue->receiveMessage(&message); result == RETURN_OK; result = TmTcReceptionQueue->receiveMessage(&message)) { @@ -112,7 +112,7 @@ ReturnValue_t TmTcBridge::handleTmQueue() { result = sendTm(data, size); if (result != RETURN_OK) { - error << "TMTC Bridge: Could not send TM packet"<< std::endl; + sif::error << "TMTC Bridge: Could not send TM packet"<< std::endl; tmStore->deleteData(message.getStorageId()); return result; @@ -127,14 +127,14 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { // "Saving packet ID to be sent later\r\n" << std::flush; store_address_t storeId = 0; - if(fifo.full()) { - error << "TMTC Bridge: TM downlink max. number of stored packet IDs " + if(tmFifo.full()) { + sif::error << "TMTC Bridge: TM downlink max. number of stored packet IDs " "reached! Overwriting old data" << std::endl; - fifo.retrieve(&storeId); + tmFifo.retrieve(&storeId); tmStore->deleteData(storeId); } storeId = message->getStorageId(); - fifo.insert(storeId); + tmFifo.insert(storeId); tmStored = true; return RETURN_OK; } @@ -142,25 +142,25 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { ReturnValue_t TmTcBridge::handleStoredTm() { uint8_t counter = 0; ReturnValue_t result = RETURN_OK; - while(not fifo.empty() && counter < sentPacketsPerCycle) { + while(not tmFifo.empty() and counter < sentPacketsPerCycle) { //info << "TMTC Bridge: Sending stored TM data. There are " // << (int) fifo.size() << " left to send\r\n" << std::flush; store_address_t storeId; - const uint8_t* data = NULL; - uint32_t size = 0; - fifo.retrieve(&storeId); + const uint8_t* data = nullptr; + size_t size = 0; + tmFifo.retrieve(&storeId); result = tmStore->getData(storeId, &data, &size); sendTm(data,size); if(result != RETURN_OK) { - error << "TMTC Bridge: Could not send stored downlink data" + sif::error << "TMTC Bridge: Could not send stored downlink data" << std::endl; result = RETURN_FAILED; } counter ++; - if(fifo.empty()) { + if(tmFifo.empty()) { tmStored = false; } tmStore->deleteData(storeId); @@ -187,14 +187,6 @@ MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { } - void TmTcBridge::printData(uint8_t * data, size_t dataLen) { - info << "TMTC Bridge: Printing data: ["; - for(uint32_t i = 0; i < dataLen; i++) { - info << std::hex << (int)data[i]; - if(i < dataLen-1){ - info << " , "; - } - } - info << " ] " << std::endl; + arrayprinter::print(data, dataLen); } diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 15fd42c1..3e0432d8 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -25,8 +25,6 @@ public: TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_); virtual ~TmTcBridge(); - void setDelayBetweenSentPackets(uint32_t delayBetweenSentPackets); - /** * Set number of packets sent per performOperation().Please note that this * value must be smaller than MAX_STORED_DATA_SENT_PER_CYCLE @@ -45,8 +43,8 @@ public: */ ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored); - void registerCommConnect(); - void registerCommDisconnect(); + virtual void registerCommConnect(); + virtual void registerCommDisconnect(); /** * Initializes necessary FSFW components for the TMTC Bridge @@ -64,7 +62,8 @@ public: * @param virtualChannel * @return */ - MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override; + MessageQueueId_t getReportReceptionQueue( + uint8_t virtualChannel = 0) override; protected: //! Used to send and receive TMTC messages. //! TmTcMessage is used to transport messages between tasks. @@ -75,7 +74,6 @@ protected: //! Used to specify whether communication link is up bool communicationLinkUp = false; bool tmStored = false; - FIFO fifo; /** * @brief Handle TC reception @@ -141,9 +139,13 @@ protected: */ void printData(uint8_t * data, size_t dataLen); -private: - uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; - uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; + /** + * This fifo can be used to store downlink data + * which can not be sent at the moment. + */ + FIFO tmFifo; + uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; + uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; From 986bb154be701a7ce989ac4edd6a8a4f4a6965de Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 13:24:04 +0200 Subject: [PATCH 45/45] hotfix: arrayprinter was renamed --- datapool/PoolEntry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index a87a6c4e..d535a72b 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include template @@ -68,7 +68,7 @@ template void PoolEntry::print() { sif::debug << "Pool Entry Validity: " << (this->valid? " (valid) " : " (invalid) ") << std::endl; - printer::print(reinterpret_cast(address), length); + arrayprinter::print(reinterpret_cast(address), length); sif::debug << std::dec << std::endl; }