From dd74ebecbaebf5a22e4d6f48e8863353009e103d Mon Sep 17 00:00:00 2001 From: petriVM18 Date: Wed, 16 Sep 2020 14:54:52 +0200 Subject: [PATCH] Added SharedRingBuffer and Updated version of SimpleRingBuffer for new serialpolling task --- container/SharedRingBuffer.cpp | 28 +++++++ container/SharedRingBuffer.h | 68 +++++++++++++++ container/SimpleRingBuffer.cpp | 148 ++++++++++++++++----------------- container/SimpleRingBuffer.h | 136 +++++++++++++++--------------- tmtcservices/TmTcBridge.cpp | 3 + 5 files changed, 241 insertions(+), 142 deletions(-) create mode 100755 container/SharedRingBuffer.cpp create mode 100755 container/SharedRingBuffer.h mode change 100644 => 100755 container/SimpleRingBuffer.cpp mode change 100644 => 100755 container/SimpleRingBuffer.h diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp new file mode 100755 index 00000000..4923aca7 --- /dev/null +++ b/container/SharedRingBuffer.cpp @@ -0,0 +1,28 @@ +#include "SharedRingBuffer.h" +#include "../ipc/MutexFactory.h" +#include "../ipc/MutexHelper.h" + +SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size, + bool overwriteOld, size_t maxExcessBytes): + SystemObject(objectId), SimpleRingBuffer(size, overwriteOld) { + mutex = MutexFactory::instance()->createMutex(); +} + +SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, + const size_t size, bool overwriteOld, size_t maxExcessBytes): + SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld) { + mutex = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t SharedRingBuffer::lockRingBufferMutex( + MutexIF::TimeoutType timeoutType, dur_millis_t timeout) { + return mutex->lockMutex(timeoutType, timeout); +} + +ReturnValue_t SharedRingBuffer::unlockRingBufferMutex() { + return mutex->unlockMutex(); +} + +MutexIF* SharedRingBuffer::getMutexHandle() const { + return mutex; +} diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h new file mode 100755 index 00000000..80c068b3 --- /dev/null +++ b/container/SharedRingBuffer.h @@ -0,0 +1,68 @@ +#ifndef FSFW_CONTAINER_SHAREDRINGBUFFER_H_ +#define FSFW_CONTAINER_SHAREDRINGBUFFER_H_ + +#include "SimpleRingBuffer.h" +#include "../ipc/MutexIF.h" +#include "../objectmanager/SystemObject.h" +#include "../timemanager/Clock.h" + +/** + * @brief Ring buffer which can be shared among multiple objects + * @details + * This class offers a mutex to perform thread-safe operation on the ring + * buffer. It is still up to the developer to actually perform the lock + * and unlock operations. + */ +class SharedRingBuffer: public SystemObject, + public SimpleRingBuffer { +public: + /** + * This constructor allocates a new internal buffer with the supplied size. + * @param size + * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. + */ + SharedRingBuffer(object_id_t objectId, const size_t size, + bool overwriteOld, size_t maxExcessBytes); + + /** + * This constructor takes an external buffer with the specified size. + * @param buffer + * @param size + * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. + */ + SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, + bool overwriteOld, size_t maxExcessBytes); + + /** + * Unless a read-only constant value is read, all operations on the + * shared ring buffer should be protected by calling this function. + * @param timeoutType + * @param timeout + * @return + */ + virtual ReturnValue_t lockRingBufferMutex(MutexIF::TimeoutType timeoutType, + dur_millis_t timeout); + /** + * Any locked mutex also has to be unlocked, otherwise, access to the + * shared ring buffer will be blocked. + * @return + */ + virtual ReturnValue_t unlockRingBufferMutex(); + + /** + * The mutex handle can be accessed directly, for example to perform + * the lock with the #MutexHelper for a RAII compliant lock operation. + * @return + */ + MutexIF* getMutexHandle() const; +private: + MutexIF* mutex = nullptr; +}; + + + +#endif /* FSFW_CONTAINER_SHAREDRINGBUFFER_H_ */ diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp old mode 100644 new mode 100755 index 30e70514..a6384a39 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -1,74 +1,74 @@ -#include "SimpleRingBuffer.h" -#include - -SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld) : - RingBufferBase<>(0, size, overwriteOld) { - buffer = new uint8_t[size]; -} - -SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, - bool overwriteOld): - RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {} - - -SimpleRingBuffer::~SimpleRingBuffer() { - delete[] buffer; -} - -ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, - uint32_t amount) { - if (availableWriteSpace() >= amount or overwriteOld) { - uint32_t amountTillWrap = writeTillWrap(); - if (amountTillWrap >= amount) { - memcpy(&buffer[write], data, amount); - } else { - memcpy(&buffer[write], data, amountTillWrap); - memcpy(buffer, data + amountTillWrap, amount - amountTillWrap); - } - incrementWrite(amount); - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } -} - -ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount, - bool readRemaining, uint32_t* trueAmount) { - uint32_t availableData = availableReadData(READ_PTR); - uint32_t amountTillWrap = readTillWrap(READ_PTR); - if (availableData < amount) { - if (readRemaining) { - amount = availableData; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } - } - if (trueAmount != nullptr) { - *trueAmount = amount; - } - if (amountTillWrap >= amount) { - memcpy(data, &buffer[read[READ_PTR]], amount); - } else { - memcpy(data, &buffer[read[READ_PTR]], amountTillWrap); - memcpy(data + amountTillWrap, buffer, amount - amountTillWrap); - } - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount, - bool deleteRemaining, uint32_t* trueAmount) { - uint32_t availableData = availableReadData(READ_PTR); - if (availableData < amount) { - if (deleteRemaining) { - amount = availableData; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } - } - if (trueAmount != nullptr) { - *trueAmount = amount; - } - incrementRead(amount, READ_PTR); - return HasReturnvaluesIF::RETURN_OK; -} - +#include "SimpleRingBuffer.h" +#include + +SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld) : + RingBufferBase<>(0, size, overwriteOld) { + buffer = new uint8_t[size]; +} + +SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, + bool overwriteOld): + RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {} + + +SimpleRingBuffer::~SimpleRingBuffer() { + delete[] buffer; +} + +ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, + uint32_t amount) { + if (availableWriteSpace() >= amount or overwriteOld) { + uint32_t amountTillWrap = writeTillWrap(); + if (amountTillWrap >= amount) { + memcpy(&buffer[write], data, amount); + } else { + memcpy(&buffer[write], data, amountTillWrap); + memcpy(buffer, data + amountTillWrap, amount - amountTillWrap); + } + incrementWrite(amount); + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount, + bool readRemaining, uint32_t* trueAmount) { + uint32_t availableData = availableReadData(READ_PTR); + uint32_t amountTillWrap = readTillWrap(READ_PTR); + if (availableData < amount) { + if (readRemaining) { + amount = availableData; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } + if (trueAmount != nullptr) { + *trueAmount = amount; + } + if (amountTillWrap >= amount) { + memcpy(data, &buffer[read[READ_PTR]], amount); + } else { + memcpy(data, &buffer[read[READ_PTR]], amountTillWrap); + memcpy(data + amountTillWrap, buffer, amount - amountTillWrap); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount, + bool deleteRemaining, uint32_t* trueAmount) { + uint32_t availableData = availableReadData(READ_PTR); + if (availableData < amount) { + if (deleteRemaining) { + amount = availableData; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } + if (trueAmount != nullptr) { + *trueAmount = amount; + } + incrementRead(amount, READ_PTR); + return HasReturnvaluesIF::RETURN_OK; +} + diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h old mode 100644 new mode 100755 index c6a29902..c7d3ccc1 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -1,68 +1,68 @@ -#ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ -#define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ - -#include "RingBufferBase.h" -#include - -/** - * @brief Circular buffer implementation, useful for buffering - * into data streams. - * @details - * Note that the deleteData() has to be called to increment the read pointer. - * This class allocated dynamically, so - * @ingroup containers - */ -class SimpleRingBuffer: public RingBufferBase<> { -public: - /** - * This constructor allocates a new internal buffer with the supplied size. - * @param size - * @param overwriteOld - */ - SimpleRingBuffer(const size_t size, bool overwriteOld); - /** - * This constructor takes an external buffer with the specified size. - * @param buffer - * @param size - * @param overwriteOld - */ - SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); - - virtual ~SimpleRingBuffer(); - - /** - * Write to circular buffer and increment write pointer by amount - * @param data - * @param amount - * @return - */ - ReturnValue_t writeData(const uint8_t* data, uint32_t amount); - - /** - * Read from circular buffer at read pointer - * @param data - * @param amount - * @param readRemaining - * @param trueAmount - * @return - */ - ReturnValue_t readData(uint8_t* data, uint32_t amount, - bool readRemaining = false, uint32_t* trueAmount = nullptr); - - /** - * Delete data starting by incrementing read pointer - * @param amount - * @param deleteRemaining - * @param trueAmount - * @return - */ - ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, - uint32_t* trueAmount = nullptr); -private: -// static const uint8_t TEMP_READ_PTR = 1; - static const uint8_t READ_PTR = 0; - uint8_t* buffer = nullptr; -}; - -#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */ - +#ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ +#define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ + +#include "RingBufferBase.h" +#include + +/** + * @brief Circular buffer implementation, useful for buffering + * into data streams. + * @details + * Note that the deleteData() has to be called to increment the read pointer. + * This class allocated dynamically, so + * @ingroup containers + */ +class SimpleRingBuffer: public RingBufferBase<> { +public: + /** + * This constructor allocates a new internal buffer with the supplied size. + * @param size + * @param overwriteOld + */ + SimpleRingBuffer(const size_t size, bool overwriteOld); + /** + * This constructor takes an external buffer with the specified size. + * @param buffer + * @param size + * @param overwriteOld + */ + SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); + + virtual ~SimpleRingBuffer(); + + /** + * Write to circular buffer and increment write pointer by amount + * @param data + * @param amount + * @return + */ + ReturnValue_t writeData(const uint8_t* data, uint32_t amount); + + /** + * Read from circular buffer at read pointer + * @param data + * @param amount + * @param readRemaining + * @param trueAmount + * @return + */ + ReturnValue_t readData(uint8_t* data, uint32_t amount, + bool readRemaining = false, uint32_t* trueAmount = nullptr); + + /** + * Delete data starting by incrementing read pointer + * @param amount + * @param deleteRemaining + * @param trueAmount + * @return + */ + ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, + uint32_t* trueAmount = nullptr); +private: +// static const uint8_t TEMP_READ_PTR = 1; + static const uint8_t READ_PTR = 0; + uint8_t* buffer = nullptr; +}; + +#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */ + diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 8c2f15e5..ee6ec82f 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -130,12 +130,14 @@ ReturnValue_t TmTcBridge::handleTmQueue() { } result = tmStore->getData(message.getStorageId(), &data, &size); +// sif::info << "TmTcBridge::handleTmQueue: result getData: "<