fsfw container taken over

This commit is contained in:
Robin Müller 2020-11-02 15:53:08 +01:00
parent 41bf5622f3
commit cd71a9cc12
4 changed files with 51 additions and 62 deletions

View File

@ -1,34 +1,27 @@
#ifndef FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ #ifndef FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
#define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ #define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
#include "../container/ArrayList.h" #include "ArrayList.h"
#include "../globalfunctions/CRC.h" #include "../globalfunctions/CRC.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../serialize/SerialArrayListAdapter.h" #include "../serialize/SerialArrayListAdapter.h"
#include <cmath> #include <cmath>
/**
* Index is the Type used for the list of indices.
*
* @tparam T Type which destribes the index. Needs to be a child of SerializeIF
* to be able to make it persistent
*/
template<typename T> template<typename T>
class Index: public SerializeIF{ class Index: public SerializeIF{
/** /**
* * Index is the Type used for the list of indices. The template parameter is the type which describes the index, it needs to be a child of SerializeIF to be able to make it persistent
*/ */
static_assert(std::is_base_of<SerializeIF,T>::value, static_assert(std::is_base_of<SerializeIF,T>::value,"Wrong Type for Index, Type must implement SerializeIF");
"Wrong Type for Index, Type must implement SerializeIF");
public: public:
Index():blockStartAddress(0),size(0),storedPackets(0){} Index():blockStartAddress(0),size(0),storedPackets(0){}
Index(uint32_t startAddress):blockStartAddress(startAddress), Index(uint32_t startAddress):blockStartAddress(startAddress),size(0),storedPackets(0){
size(0),storedPackets(0) {
} }
void setBlockStartAddress(uint32_t newAddress) { void setBlockStartAddress(uint32_t newAddress){
this->blockStartAddress = newAddress; this->blockStartAddress = newAddress;
} }
@ -40,7 +33,7 @@ public:
return &indexType; return &indexType;
} }
T* modifyIndexType() { T* modifyIndexType(){
return &indexType; return &indexType;
} }
/** /**
@ -135,35 +128,26 @@ private:
}; };
/**
* @brief Indexed Ring Memory Array is a class for a ring memory with indices.
* @details
* It assumes that the newest data comes in last
* It uses the currentWriteBlock as pointer to the current writing position
* The currentReadBlock must be set manually
* @tparam T
*/
template<typename T> template<typename T>
class IndexedRingMemoryArray: public SerializeIF, public ArrayList<Index<T>, uint32_t>{ class IndexedRingMemoryArray: public SerializeIF, public ArrayList<Index<T>, uint32_t>{
/** /**
* * Indexed Ring Memory Array is a class for a ring memory with indices. It assumes that the newest data comes in last
* It uses the currentWriteBlock as pointer to the current writing position
* The currentReadBlock must be set manually
*/ */
public: public:
IndexedRingMemoryArray(uint32_t startAddress, uint32_t size, uint32_t bytesPerBlock, IndexedRingMemoryArray(uint32_t startAddress, uint32_t size, uint32_t bytesPerBlock, SerializeIF* additionalInfo,
SerializeIF* additionalInfo, bool overwriteOld): bool overwriteOld) :ArrayList<Index<T>,uint32_t>(NULL,(uint32_t)10,(uint32_t)0),totalSize(size),indexAddress(startAddress),currentReadSize(0),currentReadBlockSizeCached(0),lastBlockToReadSize(0), additionalInfo(additionalInfo),overwriteOld(overwriteOld){
ArrayList<Index<T>,uint32_t>(NULL,(uint32_t)10,(uint32_t)0),totalSize(size),
indexAddress(startAddress),currentReadSize(0),currentReadBlockSizeCached(0),
lastBlockToReadSize(0), additionalInfo(additionalInfo),overwriteOld(overwriteOld)
{
//Calculate the maximum number of indices needed for this blocksize //Calculate the maximum number of indices needed for this blocksize
uint32_t maxNrOfIndices = floor(static_cast<double>(size)/static_cast<double>(bytesPerBlock)); uint32_t maxNrOfIndices = floor(static_cast<double>(size)/static_cast<double>(bytesPerBlock));
//Calculate the Size needeed for the index itself //Calculate the Size needeed for the index itself
size_t serializedSize = 0; uint32_t serializedSize = 0;
if(additionalInfo!=NULL) { if(additionalInfo!=NULL){
serializedSize += additionalInfo->getSerializedSize(); serializedSize += additionalInfo->getSerializedSize();
} }
//Size of current iterator type //Size of current iterator type
Index<T> tempIndex; Index<T> tempIndex;
serializedSize += tempIndex.getSerializedSize(); serializedSize += tempIndex.getSerializedSize();
@ -178,7 +162,6 @@ public:
error << "IndexedRingMemory: Store is too small for index" << std::endl; error << "IndexedRingMemory: Store is too small for index" << std::endl;
} }
uint32_t useableSize = totalSize - serializedSize; uint32_t useableSize = totalSize - serializedSize;
//Update the totalSize for calculations //Update the totalSize for calculations
totalSize = useableSize; totalSize = useableSize;
@ -195,10 +178,12 @@ public:
this->allocated = true; this->allocated = true;
//Check trueNumberOfBlocks //Check trueNumberOfBlocks
if(trueNumberOfBlocks<1) { if(trueNumberOfBlocks<1){
error << "IndexedRingMemory: Invalid Number of Blocks: " << trueNumberOfBlocks; error << "IndexedRingMemory: Invalid Number of Blocks: " << trueNumberOfBlocks;
} }
//Fill address into index //Fill address into index
uint32_t address = trueStartAddress; uint32_t address = trueStartAddress;
for (typename IndexedRingMemoryArray<T>::Iterator it = this->begin();it!=this->end();++it) { for (typename IndexedRingMemoryArray<T>::Iterator it = this->begin();it!=this->end();++it) {
@ -208,6 +193,7 @@ public:
address += bytesPerBlock; address += bytesPerBlock;
} }
//Initialize iterators //Initialize iterators
currentWriteBlock = this->begin(); currentWriteBlock = this->begin();
currentReadBlock = this->begin(); currentReadBlock = this->begin();
@ -246,10 +232,10 @@ public:
(*typeResetFnc)(it->modifyIndexType()); (*typeResetFnc)(it->modifyIndexType());
} }
/** /*
* Reading * Reading
* @param it
*/ */
void setCurrentReadBlock(typename IndexedRingMemoryArray<T>::Iterator it){ void setCurrentReadBlock(typename IndexedRingMemoryArray<T>::Iterator it){
currentReadBlock = it; currentReadBlock = it;
currentReadBlockSizeCached = it->getSize(); currentReadBlockSizeCached = it->getSize();
@ -262,7 +248,6 @@ public:
lastBlockToRead = currentWriteBlock; lastBlockToRead = currentWriteBlock;
lastBlockToReadSize = currentWriteBlock->getSize(); lastBlockToReadSize = currentWriteBlock->getSize();
} }
/** /**
* Sets the last block to read to this iterator. * Sets the last block to read to this iterator.
* Can be used to dump until block x * Can be used to dump until block x
@ -307,39 +292,33 @@ public:
uint32_t getCurrentReadAddress() const { uint32_t getCurrentReadAddress() const {
return getAddressOfCurrentReadBlock() + currentReadSize; return getAddressOfCurrentReadBlock() + currentReadSize;
} }
/** /**
* Adds readSize to the current size and checks if the read has no more data * Adds readSize to the current size and checks if the read has no more data left and advances the read block
* left and advances the read block.
* @param readSize The size that was read * @param readSize The size that was read
* @return Returns true if the read can go on * @return Returns true if the read can go on
*/ */
bool addReadSize(uint32_t readSize) { bool addReadSize(uint32_t readSize) {
if(currentReadBlock == lastBlockToRead) { if(currentReadBlock == lastBlockToRead){
//The current read block is the last to read //The current read block is the last to read
if((currentReadSize+readSize)<lastBlockToReadSize) { if((currentReadSize+readSize)<lastBlockToReadSize){
//the block has more data -> return true //the block has more data -> return true
currentReadSize += readSize; currentReadSize += readSize;
return true; return true;
} }else{
else {
//Reached end of read -> return false //Reached end of read -> return false
currentReadSize = lastBlockToReadSize; currentReadSize = lastBlockToReadSize;
return false; return false;
} }
} }else{
else {
//We are not in the last Block //We are not in the last Block
if((currentReadSize + readSize)<currentReadBlockSizeCached) { if((currentReadSize + readSize)<currentReadBlockSizeCached){
//The current Block has more data //The current Block has more data
currentReadSize += readSize; currentReadSize += readSize;
return true; return true;
} }else{
// TODO: Maybe some logic blocks should be extracted
else {
//The current block is written completely //The current block is written completely
readNext(); readNext();
if(currentReadBlockSizeCached==0) { if(currentReadBlockSizeCached==0){
//Next block is empty //Next block is empty
typename IndexedRingMemoryArray<T>::Iterator it(currentReadBlock); typename IndexedRingMemoryArray<T>::Iterator it(currentReadBlock);
//Search if any block between this and the last block is not empty //Search if any block between this and the last block is not empty
@ -442,13 +421,13 @@ public:
T* modifyCurrentWriteBlockIndexType(){ T* modifyCurrentWriteBlockIndexType(){
return currentWriteBlock->modifyIndexType(); return currentWriteBlock->modifyIndexType();
} }
void updatePreviousWriteSize(uint32_t size, uint32_t storedPackets){ void updatePreviousWriteSize(uint32_t size, uint32_t storedPackets){
typename IndexedRingMemoryArray<T>::Iterator it = getPreviousBlock(currentWriteBlock); typename IndexedRingMemoryArray<T>::Iterator it = getPreviousBlock(currentWriteBlock);
it->addSize(size); it->addSize(size);
it->addStoredPackets(storedPackets); it->addStoredPackets(storedPackets);
} }
/** /**
* Checks if the block has enough space for sizeToWrite * Checks if the block has enough space for sizeToWrite
* @param sizeToWrite The data to be written in the Block * @param sizeToWrite The data to be written in the Block
@ -457,10 +436,7 @@ public:
bool hasCurrentWriteBlockEnoughSpace(uint32_t sizeToWrite){ bool hasCurrentWriteBlockEnoughSpace(uint32_t sizeToWrite){
typename IndexedRingMemoryArray<T>::Iterator next = getNextWrite(); typename IndexedRingMemoryArray<T>::Iterator next = getNextWrite();
uint32_t addressOfNextBlock = next->getBlockStartAddress(); uint32_t addressOfNextBlock = next->getBlockStartAddress();
uint32_t availableSize = uint32_t availableSize = ((addressOfNextBlock+totalSize) - (getAddressOfCurrentWriteBlock()+getSizeOfCurrentWriteBlock()))%totalSize;
( ( addressOfNextBlock + totalSize ) -
(getAddressOfCurrentWriteBlock() + getSizeOfCurrentWriteBlock()))
% totalSize;
return (sizeToWrite < availableSize); return (sizeToWrite < availableSize);
} }
@ -550,7 +526,7 @@ public:
*/ */
size_t getSerializedSize() const { size_t getSerializedSize() const {
size_t size = 0; uint32_t size = 0;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL){
size += additionalInfo->getSerializedSize(); size += additionalInfo->getSerializedSize();
} }
@ -718,4 +694,7 @@ private:
}; };
#endif /* FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ */ #endif /* FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ */

View File

@ -18,7 +18,7 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
} }
void SharedRingBuffer::setToUseReceiveSizeFIFO(uint32_t fifoDepth) { void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
this->fifoDepth = fifoDepth; this->fifoDepth = fifoDepth;
} }

View File

@ -27,7 +27,15 @@ public:
SharedRingBuffer(object_id_t objectId, const size_t size, SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, size_t maxExcessBytes); bool overwriteOld, size_t maxExcessBytes);
void setToUseReceiveSizeFIFO(uint32_t fifoDepth); /**
* @brief This function can be used to add an optional FIFO to the class
* @details
* This FIFO will be allocated in the initialize function (and will
* have a fixed maximum size after that). It can be used to store
* values like packet sizes, for example for a shared ring buffer
* used by producer/consumer tasks.
*/
void setToUseReceiveSizeFIFO(size_t fifoDepth);
/** /**
* This constructor takes an external buffer with the specified size. * This constructor takes an external buffer with the specified size.

View File

@ -4,9 +4,11 @@
/** /**
* @defgroup container Container * @defgroup container Container
* *
* General Purpose Containers to store various elements. * General Purpose Container to store various elements.
* As opposed to the STL library implementation, these implementations *
* don't allocate memory dynamically. * Also contains Adapter classes to print elements to a
* bytestream and to read them from a bytestream, as well
* as an Adapter to swap the endianness.
*/ */