From 6f50356964da86b311b9e96b08d33de6c2b76233 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 14:26:15 +0200 Subject: [PATCH] new shared ring buffer --- container/RingBufferBase.h | 73 ++++++++++++++++------------ container/SharedRingBuffer.cpp | 32 ++++++++++++ container/SharedRingBuffer.h | 42 ++++++++++++++++ container/SimpleRingBuffer.cpp | 27 ++++++---- container/SimpleRingBuffer.h | 44 ++++++++++++----- devicehandlers/ChildHandlerBase.cpp | 16 +++--- devicehandlers/ChildHandlerBase.h | 4 +- devicehandlers/DeviceHandlerBase.cpp | 38 ++++++++++----- devicehandlers/DeviceHandlerBase.h | 19 ++++---- globalfunctions/DleEncoder.cpp | 3 +- timemanager/Clock.h | 4 +- 11 files changed, 216 insertions(+), 86 deletions(-) create mode 100644 container/SharedRingBuffer.cpp create mode 100644 container/SharedRingBuffer.h diff --git a/container/RingBufferBase.h b/container/RingBufferBase.h index 1beb51c2..86896b9e 100644 --- a/container/RingBufferBase.h +++ b/container/RingBufferBase.h @@ -7,29 +7,23 @@ template class RingBufferBase { public: - RingBufferBase(uint32_t startAddress, const size_t size, bool overwriteOld) : + RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) : start(startAddress), write(startAddress), size(size), overwriteOld(overwriteOld) { for (uint8_t count = 0; count < N_READ_PTRS; count++) { read[count] = startAddress; } } - ReturnValue_t readData(uint32_t amount, uint8_t n = 0) { - if (availableReadData(n) >= amount) { - incrementRead(amount, n); - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } + + virtual ~RingBufferBase() {} + + bool isFull(uint8_t n = 0) { + return (availableWriteSpace(n) == 0); } - ReturnValue_t writeData(uint32_t amount) { - if (availableWriteSpace() >= amount || overwriteOld) { - incrementWrite(amount); - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } + bool isEmpty(uint8_t n = 0) { + return (availableReadData(n) == 0); } + uint32_t availableReadData(uint8_t n = 0) const { return ((write + size) - read[n]) % size; } @@ -37,54 +31,55 @@ public: //One less to avoid ambiguous full/empty problem. return (((read[n] + size) - write - 1) % size); } - bool isFull(uint8_t n = 0) { - return (availableWriteSpace(n) == 0); - } - bool isEmpty(uint8_t n = 0) { - return (availableReadData(n) == 0); - } - virtual ~RingBufferBase() { - } uint32_t getRead(uint8_t n = 0) const { return read[n]; } + void setRead(uint32_t read, uint8_t n = 0) { if (read >= start && read < (start+size)) { this->read[n] = read; } } + uint32_t getWrite() const { return write; } + void setWrite(uint32_t write) { this->write = write; } + void clear() { write = start; for (uint8_t count = 0; count < N_READ_PTRS; count++) { read[count] = start; } } - uint32_t writeTillWrap() { + + size_t writeTillWrap() { return (start + size) - write; } - uint32_t readTillWrap(uint8_t n = 0) { + + size_t readTillWrap(uint8_t n = 0) { return (start + size) - read[n]; } - uint32_t getStart() const { + + size_t getStart() const { return start; } + bool overwritesOld() const { return overwriteOld; } - uint32_t maxSize() const { + + size_t maxSize() const { return size - 1; } protected: - const uint32_t start; - uint32_t write; - uint32_t read[N_READ_PTRS]; + const size_t start; + size_t write; + size_t read[N_READ_PTRS]; const size_t size; const bool overwriteOld; void incrementWrite(uint32_t amount) { @@ -93,6 +88,24 @@ protected: void incrementRead(uint32_t amount, uint8_t n = 0) { read[n] = ((read[n] + amount - start) % size) + start; } + + ReturnValue_t readData(uint32_t amount, uint8_t n = 0) { + if (availableReadData(n) >= amount) { + incrementRead(amount, n); + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } + + ReturnValue_t writeData(uint32_t amount) { + if (availableWriteSpace() >= amount or overwriteOld) { + incrementWrite(amount); + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } }; #endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */ diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp new file mode 100644 index 00000000..36315753 --- /dev/null +++ b/container/SharedRingBuffer.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +SharedRingBuffer::SharedRingBuffer(const size_t size, bool overwriteOld): + SimpleRingBuffer(size, overwriteOld) { + mutex = MutexFactory::instance()->createMutex(); +} + +SharedRingBuffer::SharedRingBuffer(uint8_t *buffer, const size_t size, + bool overwriteOld): SimpleRingBuffer(buffer, size, overwriteOld) { + mutex = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data, + size_t amount, dur_millis_t timeout) { + MutexHelper(mutex, timeout); + return writeData(data,amount); +} + +ReturnValue_t SharedRingBuffer::readDataProtected(uint8_t *data, size_t amount, + dur_millis_t timeout, bool incrementReadPtr, bool readRemaining, + size_t *trueAmount) { + MutexHelper(mutex, timeout); + return readData(data,amount, incrementReadPtr, readRemaining, trueAmount); +} + +ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount, + bool deleteRemaining, size_t *trueAmount, dur_millis_t timeout) { + MutexHelper(mutex, timeout); + return deleteData(amount, deleteRemaining, trueAmount); +} diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h new file mode 100644 index 00000000..41186619 --- /dev/null +++ b/container/SharedRingBuffer.h @@ -0,0 +1,42 @@ +#ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ +#define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ +#include +#include +#include + +class SharedRingBuffer: 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(const size_t size, bool overwriteOld); + + /** + * 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(uint8_t* buffer, const size_t size, bool overwriteOld); + + ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount, + dur_millis_t timeout = 10); + ReturnValue_t readDataProtected(uint8_t *data, size_t amount, + dur_millis_t timeout = 10, bool incrementReadPtr = false, + bool readRemaining = false, size_t *trueAmount = nullptr); + ReturnValue_t deleteDataProtected(size_t amount, + bool deleteRemaining = false, size_t* trueAmount = nullptr, + dur_millis_t timeout = 10); +private: + MutexIF* mutex = nullptr; +}; + + + +#endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */ diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index 731c9dc9..69d94143 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -16,12 +16,14 @@ SimpleRingBuffer::~SimpleRingBuffer() { } ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, - uint32_t amount) { + size_t amount) { if (availableWriteSpace() >= amount or overwriteOld) { - uint32_t amountTillWrap = writeTillWrap(); + size_t amountTillWrap = writeTillWrap(); if (amountTillWrap >= amount) { + // remaining size in buffer is sufficient to fit full amount. memcpy(&buffer[write], data, amount); - } else { + } + else { memcpy(&buffer[write], data, amountTillWrap); memcpy(buffer, data + amountTillWrap, amount - amountTillWrap); } @@ -32,12 +34,13 @@ ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, } } -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); +ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount, + bool incrementReadPtr, bool readRemaining, size_t* trueAmount) { + size_t availableData = availableReadData(READ_PTR); + size_t amountTillWrap = readTillWrap(READ_PTR); if (availableData < amount) { if (readRemaining) { + // more data available than amount specified. amount = availableData; } else { return HasReturnvaluesIF::RETURN_FAILED; @@ -52,12 +55,16 @@ ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount, memcpy(data, &buffer[read[READ_PTR]], amountTillWrap); memcpy(data + amountTillWrap, buffer, amount - amountTillWrap); } + + if(incrementReadPtr) { + deleteData(amount, readRemaining); + } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount, - bool deleteRemaining, uint32_t* trueAmount) { - uint32_t availableData = availableReadData(READ_PTR); +ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, + bool deleteRemaining, size_t* trueAmount) { + size_t availableData = availableReadData(READ_PTR); if (availableData < amount) { if (deleteRemaining) { amount = availableData; diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 30dd184c..cf78814f 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -18,6 +18,8 @@ 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. */ SimpleRingBuffer(const size_t size, bool overwriteOld); /** @@ -25,41 +27,59 @@ public: * @param buffer * @param size * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. */ SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); virtual ~SimpleRingBuffer(); /** - * Write to circular buffer and increment write pointer by amount + * Write to circular buffer and increment write pointer by amount. * @param data * @param amount - * @return + * @return -@c RETURN_OK if write operation was successfull + * -@c RETURN_FAILED if */ - ReturnValue_t writeData(const uint8_t* data, uint32_t amount); + ReturnValue_t writeData(const uint8_t* data, size_t amount); /** - * Read from circular buffer at read pointer + * Read from circular buffer at read pointer. * @param data * @param amount + * @param incrementReadPtr + * If this is set to true, the read pointer will be incremented. + * If readRemaining is set to true, the read pointer will be incremented + * accordingly. * @param readRemaining - * @param trueAmount + * If this is set to true, the data will be read even if the amount + * specified exceeds the read data available. + * @param trueAmount [out] + * If readRemaining was set to true, the true amount read will be assigned + * to the passed value. * @return + * - @c RETURN_OK if data was read successfully + * - @c RETURN_FAILED if not enough data was available and readRemaining + * was set to false. */ - ReturnValue_t readData(uint8_t* data, uint32_t amount, - bool readRemaining = false, uint32_t* trueAmount = nullptr); + ReturnValue_t readData(uint8_t* data, size_t amount, + bool incrementReadPtr = false, bool readRemaining = false, + size_t* trueAmount = nullptr); /** - * Delete data starting by incrementing read pointer + * Delete data by incrementing read pointer. * @param amount * @param deleteRemaining - * @param trueAmount + * If the amount specified is larger than the remaing size to read and this + * is set to true, the remaining amount will be deleted as well + * @param trueAmount [out] + * If deleteRemaining was set to true, the amount deleted will be assigned + * to the passed value. * @return */ - ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, - uint32_t* trueAmount = nullptr); + ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false, + size_t* trueAmount = nullptr); private: -// static const uint8_t TEMP_READ_PTR = 1; static const uint8_t READ_PTR = 0; uint8_t* buffer = nullptr; }; diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index 3e5bcc60..9e5019b4 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -4,15 +4,19 @@ ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * cookie, - uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, - object_id_t hkDestination, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, uint32_t parent, + uint8_t setDeviceSwitch, object_id_t hkDestination, + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, + object_id_t parent, FailureIsolationBase* customFdir, size_t cmdQueueSize) : DeviceHandlerBase(setObjectId, deviceCommunication, cookie, - hkDestination, setDeviceSwitch, thermalStatePoolId, - thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), + (customFdir == nullptr? &childHandlerFdir : customFdir), cmdQueueSize), parentId(parent), childHandlerFdir(setObjectId) { + this->setDeviceSwitch(setDeviceSwitch); + this->setHkDestination(hkDestination); + this->setThermalStateRequestPoolIds(thermalStatePoolId, + thermalRequestPoolId); + } ChildHandlerBase::~ChildHandlerBase() { @@ -26,7 +30,7 @@ ReturnValue_t ChildHandlerBase::initialize() { MessageQueueId_t parentQueue = 0; - if (parentId != 0) { + if (parentId != objects::NO_OBJECT) { SubsystemBase *parent = objectManager->get(parentId); if (parent == NULL) { return RETURN_FAILED; diff --git a/devicehandlers/ChildHandlerBase.h b/devicehandlers/ChildHandlerBase.h index 10021631..5c216e86 100644 --- a/devicehandlers/ChildHandlerBase.h +++ b/devicehandlers/ChildHandlerBase.h @@ -7,9 +7,9 @@ class ChildHandlerBase: public DeviceHandlerBase { public: ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, - CookieIF * cookie, uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, + CookieIF * cookie, uint8_t setDeviceSwitch, object_id_t hkDestination, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, uint32_t parent, + uint32_t thermalRequestPoolId, object_id_t parent = objects::NO_OBJECT, FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20); virtual ~ChildHandlerBase(); diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index fcb61ace..08d92130 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -18,43 +18,55 @@ object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; -object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; +object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * comCookie, - uint8_t setDeviceSwitch, object_id_t hkDestination, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, - FailureIsolationBase* fdirInstance, size_t cmdQueueSize) : + FailureIsolationBase* fdirInstance, + size_t cmdQueueSize) : SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), deviceCommunicationId(deviceCommunication), comCookie(comCookie), healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), actionHelper(this, nullptr), hkManager(this, nullptr), - deviceThermalStatePoolId(thermalStatePoolId), - deviceThermalRequestPoolId(thermalRequestPoolId), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), switchOffWasReported(false), hkDestination(hkDestination), childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), - transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { + transitionSourceSubMode(SUBMODE_NONE) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); insertInCommandMap(RAW_COMMAND_ID); cookieInfo.state = COOKIE_UNUSED; cookieInfo.pendingCommand = deviceCommandMap.end(); if (comCookie == nullptr) { - sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex << - std::setw(8) << std::setfill('0') << this->getObjectId() << - std::dec << ": Do not pass nullptr as a cookie, consider " - << std::setfill(' ') << "passing a dummy cookie instead!" << - std::endl; + sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex + << std::setw(8) << std::setfill('0') << this->getObjectId() + << std::dec << ": Do not pass nullptr as a cookie, consider " + << std::setfill(' ') << "passing a dummy cookie instead!" + << std::endl; } if (this->fdirInstance == nullptr) { this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, - defaultFDIRParentId); + defaultFdirParentId); } } +void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) { + this->hkDestination = hkDestination; +} + +void DeviceHandlerBase::setThermalStateRequestPoolIds( + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) { + this->deviceThermalRequestPoolId = thermalStatePoolId; + this->deviceThermalRequestPoolId = thermalRequestPoolId; +} + + +void DeviceHandlerBase::setDeviceSwitch(uint8_t deviceSwitch) { + this->deviceSwitch = deviceSwitch; +} + DeviceHandlerBase::~DeviceHandlerBase() { delete comCookie; if (defaultFDIRUsed) { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 3fdab9ed..2adaa80e 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -106,13 +106,14 @@ public: * @param cmdQueueSize */ DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, - CookieIF * comCookie, uint8_t setDeviceSwitch, - object_id_t hkDestination = objects::NO_OBJECT, - uint32_t thermalStatePoolId = PoolVariableIF::NO_PARAMETER, - uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER, - FailureIsolationBase* fdirInstance = nullptr, + CookieIF * comCookie, FailureIsolationBase* fdirInstance = nullptr, size_t cmdQueueSize = 20); + void setDeviceSwitch(uint8_t deviceSwitch); + void setHkDestination(object_id_t hkDestination); + void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId); + /** * @brief This function is the device handler base core component and is * called periodically. @@ -691,14 +692,14 @@ protected: * * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking */ - uint32_t deviceThermalStatePoolId; + uint32_t deviceThermalStatePoolId = PoolVariableIF::NO_PARAMETER; /** * this is the datapool variable with the thermal request of the device * * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking */ - uint32_t deviceThermalRequestPoolId; + uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER; /** * Optional Error code @@ -724,7 +725,7 @@ protected: static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default. - static object_id_t defaultFDIRParentId; //!< Object which may be the root cause of an identified fault. + static object_id_t defaultFdirParentId; //!< Object which may be the root cause of an identified fault. /** * Helper function to report a missed reply * @@ -1082,7 +1083,7 @@ private: * * for devices using two switches override getSwitches() */ - const uint8_t deviceSwitch; + uint8_t deviceSwitch; /** * read the command queue diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index c8f78872..f4bd765d 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -81,8 +81,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) && (sourceStream[encodedIndex] != ETX) - && (sourceStream[encodedIndex] != STX)) - { + && (sourceStream[encodedIndex] != STX)) { if (sourceStream[encodedIndex] == DLE) { nextByte = sourceStream[encodedIndex + 1]; // The next byte is a DLE character that was escaped by another diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 121c63df..65e152bf 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -9,8 +9,8 @@ #include //! 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; +using dur_millis_t = uint32_t; +using dur_seconds_t = double; class Clock { public: