Merge pull request 'C++ ostream made optional' (#342) from mueller/fsfw-printers into development
Reviewed-on: fsfw/fsfw#342
This commit is contained in:
commit
5639273d9b
12
CHANGELOG
12
CHANGELOG
@ -70,3 +70,15 @@ now
|
||||
### Commanding Service Base
|
||||
|
||||
- CSB uses the new fsfwconfig::FSFW_CSB_FIFO_DEPTH variable to determine the FIFO depth for each CSB instance. This variable has to be set in the FSFWConfig.h file
|
||||
|
||||
### Service Interface
|
||||
|
||||
- Proper printf support contained in ServiceInterfacePrinter.h
|
||||
- CPP ostream support now optional (can reduce executable size by 150 - 250 kB)
|
||||
- Amalagated header which determines automatically which service interface to use depending on FSFWConfig.h configuration.
|
||||
Users can just use #include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
- If CPP streams are excluded, sif:: calls won't work anymore and need to be replaced by their printf counterparts.
|
||||
For the fsfw, this can be done by checking the processor define FSFW_CPP_OSTREAM_ENABLED from FSFWConfig.h.
|
||||
For mission code, developers need to replace sif:: calls by the printf counterparts, but only if the CPP stream are excluded.
|
||||
If this is not the case, everything should work as usual.
|
||||
-
|
@ -47,9 +47,11 @@ ReturnValue_t SharedRingBuffer::initialize() {
|
||||
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
|
||||
if(receiveSizesFIFO == nullptr) {
|
||||
// Configuration error.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
|
||||
<< " was not configured to have sizes FIFO, returning nullptr!"
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
return receiveSizesFIFO;
|
||||
}
|
||||
|
@ -107,7 +107,9 @@ MessageQueueId_t ExtendedControllerBase::getCommandQueue() const {
|
||||
}
|
||||
|
||||
LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ExtendedControllerBase::getDataSetHandle: No child "
|
||||
<< " implementation provided, returning nullptr!" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -55,7 +55,9 @@ void Clcw::setBitLock(bool bitLock) {
|
||||
}
|
||||
|
||||
void Clcw::print() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "Clcw::print: Clcw is: " << std::hex << getAsWhole() << std::dec << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Clcw::setWhole(uint32_t rawClcw) {
|
||||
|
@ -98,8 +98,10 @@ ReturnValue_t DataLinkLayer::processFrame(uint16_t length) {
|
||||
receivedDataLength = length;
|
||||
ReturnValue_t status = allFramesReception();
|
||||
if (status != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DataLinkLayer::processFrame: frame reception failed. "
|
||||
"Error code: " << std::hex << status << std::dec << std::endl;
|
||||
#endif
|
||||
// currentFrame.print();
|
||||
return status;
|
||||
} else {
|
||||
@ -124,7 +126,9 @@ ReturnValue_t DataLinkLayer::initialize() {
|
||||
if ( virtualChannels.begin() != virtualChannels.end() ) {
|
||||
clcw->setVirtualChannel( virtualChannels.begin()->second->getChannelId() );
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DataLinkLayer::initialize: No VC assigned to this DLL instance! " << std::endl;
|
||||
#endif
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,11 @@ ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
|
||||
bufferPosition = &packetBuffer[packetLength];
|
||||
status = RETURN_OK;
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error
|
||||
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
|
||||
<< packetLength << std::endl;
|
||||
#endif
|
||||
clearBuffers();
|
||||
status = CONTENT_TOO_LARGE;
|
||||
}
|
||||
@ -51,24 +53,30 @@ ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {
|
||||
}
|
||||
status = RETURN_OK;
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error
|
||||
<< "MapPacketExtraction::extractPackets. Packet too large! Size: "
|
||||
<< packetLength << std::endl;
|
||||
#endif
|
||||
clearBuffers();
|
||||
status = CONTENT_TOO_LARGE;
|
||||
}
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error
|
||||
<< "MapPacketExtraction::extractPackets. Illegal segment! Last flag: "
|
||||
<< (int) lastSegmentationFlag << std::endl;
|
||||
#endif
|
||||
clearBuffers();
|
||||
status = ILLEGAL_SEGMENTATION_FLAG;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error
|
||||
<< "MapPacketExtraction::extractPackets. Illegal segmentationFlag: "
|
||||
<< (int) segmentationFlag << std::endl;
|
||||
#endif
|
||||
clearBuffers();
|
||||
status = DATA_CORRUPTED;
|
||||
break;
|
||||
@ -135,10 +143,14 @@ ReturnValue_t MapPacketExtraction::initialize() {
|
||||
}
|
||||
|
||||
void MapPacketExtraction::printPacketBuffer(void) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "DLL: packet_buffer contains: " << std::endl;
|
||||
#endif
|
||||
for (uint32_t i = 0; i < this->packetLength; ++i) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "packet_buffer[" << std::dec << i << "]: 0x" << std::hex
|
||||
<< (uint16_t) this->packetBuffer[i] << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,16 +87,25 @@ uint8_t* TcTransferFrame::getFullDataField() {
|
||||
}
|
||||
|
||||
void TcTransferFrame::print() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "Raw Frame: " << std::hex << std::endl;
|
||||
for (uint16_t count = 0; count < this->getFullSize(); count++ ) {
|
||||
sif::debug << (uint16_t)this->getFullFrame()[count] << " ";
|
||||
}
|
||||
sif::debug << std::dec << std::endl;
|
||||
// debug << "Frame Header:" << std::endl;
|
||||
// debug << "Version Number: " << std::hex << (uint16_t)this->current_frame.getVersionNumber() << std::endl;
|
||||
// debug << "Bypass Flag set?| Ctrl Cmd Flag set?: " << (uint16_t)this->current_frame.bypassFlagSet() << " | " << (uint16_t)this->current_frame.controlCommandFlagSet() << std::endl;
|
||||
// debug << "SCID : " << this->current_frame.getSpacecraftId() << std::endl;
|
||||
// debug << "VCID : " << (uint16_t)this->current_frame.getVirtualChannelId() << std::endl;
|
||||
// debug << "Frame length: " << std::dec << this->current_frame.getFrameLength() << std::endl;
|
||||
// debug << "Sequence Number: " << (uint16_t)this->current_frame.getSequenceNumber() << std::endl;
|
||||
|
||||
sif::debug << "Frame Header:" << std::endl;
|
||||
sif::debug << "Version Number: " << std::hex
|
||||
<< (uint16_t)this->getVersionNumber() << std::endl;
|
||||
sif::debug << "Bypass Flag set?| Ctrl Cmd Flag set?: "
|
||||
<< (uint16_t)this->bypassFlagSet() << " | "
|
||||
<< (uint16_t)this->controlCommandFlagSet() << std::endl;
|
||||
sif::debug << "SCID : " << this->getSpacecraftId() << std::endl;
|
||||
sif::debug << "VCID : " << (uint16_t)this->getVirtualChannelId()
|
||||
<< std::endl;
|
||||
sif::debug << "Frame length: " << std::dec << this->getFrameLength()
|
||||
<< std::endl;
|
||||
sif::debug << "Sequence Number: " << (uint16_t)this->getSequenceNumber()
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
|
@ -37,7 +37,9 @@ TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uin
|
||||
this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8;
|
||||
this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF);
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "TcTransferFrameLocal: dataSize too large: " << dataSize << std::endl;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
//No data in frame
|
||||
|
@ -102,8 +102,10 @@ uint8_t VirtualChannelReception::getChannelId() const {
|
||||
ReturnValue_t VirtualChannelReception::initialize() {
|
||||
ReturnValue_t returnValue = RETURN_FAILED;
|
||||
if ((slidingWindowWidth > 254) || (slidingWindowWidth % 2 != 0)) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "VirtualChannelReception::initialize: Illegal sliding window width: "
|
||||
<< (int) slidingWindowWidth << std::endl;
|
||||
#endif
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
for (mapChannelIterator iterator = mapChannels.begin(); iterator != mapChannels.end();
|
||||
|
@ -9,21 +9,28 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||
|
||||
PoolDataSetBase::~PoolDataSetBase() {}
|
||||
|
||||
|
||||
ReturnValue_t PoolDataSetBase::registerVariable(
|
||||
PoolVariableIF *variable) {
|
||||
if (state != States::DATA_SET_UNINITIALISED) {
|
||||
if (state != States::STATE_SET_UNINITIALISED) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DataSet::registerVariable: "
|
||||
"Call made in wrong position." << std::endl;
|
||||
#endif
|
||||
return DataSetIF::DATA_SET_UNINITIALISED;
|
||||
}
|
||||
if (variable == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DataSet::registerVariable: "
|
||||
"Pool variable is nullptr." << std::endl;
|
||||
#endif
|
||||
return DataSetIF::POOL_VAR_NULL;
|
||||
}
|
||||
if (fillCount >= maxFillCount) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DataSet::registerVariable: "
|
||||
"DataSet is full." << std::endl;
|
||||
#endif
|
||||
return DataSetIF::DATA_SET_FULL;
|
||||
}
|
||||
registeredVariables[fillCount] = variable;
|
||||
@ -33,23 +40,30 @@ ReturnValue_t PoolDataSetBase::registerVariable(
|
||||
|
||||
ReturnValue_t PoolDataSetBase::read(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
if (state == States::DATA_SET_UNINITIALISED) {
|
||||
ReturnValue_t error = result;
|
||||
if (state == States::STATE_SET_UNINITIALISED) {
|
||||
lockDataPool(lockTimeout);
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
result = readVariable(count);
|
||||
if(result != RETURN_OK) {
|
||||
break;
|
||||
error = result;
|
||||
}
|
||||
}
|
||||
state = States::DATA_SET_WAS_READ;
|
||||
state = States::STATE_SET_WAS_READ;
|
||||
unlockDataPool();
|
||||
}
|
||||
else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DataSet::read(): "
|
||||
"Call made in wrong position. Don't forget to commit"
|
||||
" member datasets!" << std::endl;
|
||||
#endif
|
||||
result = SET_WAS_ALREADY_READ;
|
||||
}
|
||||
|
||||
if(error != HasReturnvaluesIF::RETURN_OK) {
|
||||
result = error;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -71,7 +85,13 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
||||
registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER)
|
||||
{
|
||||
result = registeredVariables[count]->readWithoutLock();
|
||||
if(protectEveryReadCommitCall) {
|
||||
result = registeredVariables[count]->read(mutexTimeout);
|
||||
}
|
||||
else {
|
||||
result = registeredVariables[count]->readWithoutLock();
|
||||
}
|
||||
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
result = INVALID_PARAMETER_DEFINITION;
|
||||
}
|
||||
@ -80,7 +100,7 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
||||
}
|
||||
|
||||
ReturnValue_t PoolDataSetBase::commit(uint32_t lockTimeout) {
|
||||
if (state == States::DATA_SET_WAS_READ) {
|
||||
if (state == States::STATE_SET_WAS_READ) {
|
||||
handleAlreadyReadDatasetCommit(lockTimeout);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
@ -96,10 +116,15 @@ void PoolDataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) {
|
||||
!= PoolVariableIF::VAR_READ
|
||||
&& registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
registeredVariables[count]->commitWithoutLock();
|
||||
if(protectEveryReadCommitCall) {
|
||||
registeredVariables[count]->commit(mutexTimeout);
|
||||
}
|
||||
else {
|
||||
registeredVariables[count]->commitWithoutLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
state = States::DATA_SET_UNINITIALISED;
|
||||
state = States::STATE_SET_UNINITIALISED;
|
||||
unlockDataPool();
|
||||
}
|
||||
|
||||
@ -111,17 +136,25 @@ ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) {
|
||||
== PoolVariableIF::VAR_WRITE
|
||||
&& registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
registeredVariables[count]->commitWithoutLock();
|
||||
if(protectEveryReadCommitCall) {
|
||||
result = registeredVariables[count]->commit(mutexTimeout);
|
||||
}
|
||||
else {
|
||||
result = registeredVariables[count]->commitWithoutLock();
|
||||
}
|
||||
|
||||
} else if (registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
if (result != COMMITING_WITHOUT_READING) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DataSet::commit(): commit-without-read call made "
|
||||
"with non write-only variable." << std::endl;
|
||||
#endif
|
||||
result = COMMITING_WITHOUT_READING;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = States::DATA_SET_UNINITIALISED;
|
||||
state = States::STATE_SET_UNINITIALISED;
|
||||
unlockDataPool();
|
||||
return result;
|
||||
}
|
||||
@ -172,3 +205,9 @@ size_t PoolDataSetBase::getSerializedSize() const {
|
||||
void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
|
||||
this->registeredVariables = variablesContainer;
|
||||
}
|
||||
|
||||
void PoolDataSetBase::setReadCommitProtectionBehaviour(
|
||||
bool protectEveryReadCommit, uint32_t mutexTimeout) {
|
||||
this->protectEveryReadCommitCall = protectEveryReadCommit;
|
||||
this->mutexTimeout = mutexTimeout;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief The read call initializes reading out all registered variables.
|
||||
* It is mandatory to call commit after every read call!
|
||||
* @details
|
||||
* It iterates through the list of registered variables and calls all read()
|
||||
* functions of the registered pool variables (which read out their values
|
||||
@ -52,13 +53,14 @@ public:
|
||||
* the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned.
|
||||
*
|
||||
* The data pool is locked during the whole read operation and
|
||||
* freed afterwards.The state changes to "was written" after this operation.
|
||||
* freed afterwards. It is mandatory to call commit after a read call,
|
||||
* even if the read operation is not successful!
|
||||
* @return
|
||||
* - @c RETURN_OK if all variables were read successfully.
|
||||
* - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the
|
||||
* requested variable is invalid.
|
||||
* - @c INVALID_PARAMETER_DEFINITION if a pool entry does not exist or there
|
||||
* is a type conflict.
|
||||
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
||||
* commit() in between
|
||||
* commit() in between
|
||||
*/
|
||||
virtual ReturnValue_t read(uint32_t lockTimeout =
|
||||
MutexIF::BLOCKING) override;
|
||||
@ -75,7 +77,7 @@ public:
|
||||
* If the set does contain at least one variable which is not write-only
|
||||
* commit() can only be called after read(). If the set only contains
|
||||
* variables which are write only, commit() can be called without a
|
||||
* preceding read() call.
|
||||
* preceding read() call. Every read call must be followed by a commit call!
|
||||
* @return - @c RETURN_OK if all variables were read successfully.
|
||||
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
||||
* contains non write-only variables
|
||||
@ -89,6 +91,7 @@ public:
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override;
|
||||
|
||||
/**
|
||||
* Provides the means to lock the underlying data structure to ensure
|
||||
* thread-safety. Default implementation is empty
|
||||
@ -114,6 +117,15 @@ public:
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Can be used to individually protect every read and commit call.
|
||||
* @param protectEveryReadCommit
|
||||
* @param mutexTimeout
|
||||
*/
|
||||
void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
|
||||
uint32_t mutexTimeout = 20);
|
||||
|
||||
/**
|
||||
* @brief The fill_count attribute ensures that the variables
|
||||
* register in the correct array position and that the maximum
|
||||
@ -124,14 +136,14 @@ protected:
|
||||
* States of the seet.
|
||||
*/
|
||||
enum class States {
|
||||
DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
|
||||
DATA_SET_WAS_READ //!< DATA_SET_WAS_READ
|
||||
STATE_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
|
||||
STATE_SET_WAS_READ //!< DATA_SET_WAS_READ
|
||||
};
|
||||
/**
|
||||
* @brief state manages the internal state of the data set,
|
||||
* which is important e.g. for the behavior on destruction.
|
||||
*/
|
||||
States state = States::DATA_SET_UNINITIALISED;
|
||||
States state = States::STATE_SET_UNINITIALISED;
|
||||
|
||||
/**
|
||||
* @brief This array represents all pool variables registered in this set.
|
||||
@ -144,6 +156,9 @@ protected:
|
||||
void setContainer(PoolVariableIF** variablesContainer);
|
||||
|
||||
private:
|
||||
bool protectEveryReadCommitCall = false;
|
||||
uint32_t mutexTimeout = 20;
|
||||
|
||||
ReturnValue_t readVariable(uint16_t count);
|
||||
void handleAlreadyReadDatasetCommit(uint32_t lockTimeout);
|
||||
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);
|
||||
|
@ -1,19 +1,17 @@
|
||||
#ifndef FSFW_DATAPOOL_POOLDATASETIF_H_
|
||||
#define FSFW_DATAPOOL_POOLDATASETIF_H_
|
||||
|
||||
#include "ReadCommitIF.h"
|
||||
#include "DataSetIF.h"
|
||||
|
||||
/**
|
||||
* @brief Extendes the DataSetIF by adding abstract functions to lock
|
||||
* and unlock a data pool and read/commit semantics.
|
||||
*/
|
||||
class PoolDataSetIF: public DataSetIF {
|
||||
class PoolDataSetIF: public DataSetIF, public ReadCommitIF {
|
||||
public:
|
||||
virtual~ PoolDataSetIF() {};
|
||||
|
||||
virtual ReturnValue_t read(dur_millis_t lockTimeout) = 0;
|
||||
virtual ReturnValue_t commit(dur_millis_t lockTimeout) = 0;
|
||||
|
||||
/**
|
||||
* @brief Most underlying data structures will have a pool like structure
|
||||
* and will require a lock and unlock mechanism to ensure
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../globalfunctions/arrayprinter.h"
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
template <typename T>
|
||||
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength,
|
||||
@ -12,9 +13,11 @@ PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength,
|
||||
std::memset(this->address, 0, this->getByteSize());
|
||||
}
|
||||
else if (initValue.size() != setLength){
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "PoolEntry: setLength is not equal to initializer list"
|
||||
"length! Performing zero initialization with given setLength"
|
||||
<< std::endl;
|
||||
#endif
|
||||
std::memset(this->address, 0, this->getByteSize());
|
||||
}
|
||||
else {
|
||||
@ -67,10 +70,14 @@ bool PoolEntry<T>::getValid() {
|
||||
|
||||
template <typename T>
|
||||
void PoolEntry<T>::print() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "Pool Entry Validity: " <<
|
||||
(this->valid? " (valid) " : " (invalid) ") << std::endl;
|
||||
#endif
|
||||
arrayprinter::print(reinterpret_cast<uint8_t*>(address), length);
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << std::dec << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "ReadCommitIF.h"
|
||||
|
||||
/**
|
||||
* @brief This interface is used to control data pool
|
||||
@ -17,9 +18,9 @@
|
||||
* @author Bastian Baetz
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
class PoolVariableIF : public SerializeIF {
|
||||
class PoolVariableIF : public SerializeIF,
|
||||
public ReadCommitIF {
|
||||
friend class PoolDataSetBase;
|
||||
friend class GlobDataSet;
|
||||
friend class LocalPoolDataSetBase;
|
||||
public:
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF;
|
||||
@ -57,41 +58,6 @@ public:
|
||||
*/
|
||||
virtual void setValid(bool validity) = 0;
|
||||
|
||||
/**
|
||||
* @brief The commit call shall write back a newly calculated local
|
||||
* value to the data pool.
|
||||
* @details
|
||||
* It is assumed that these calls are implemented in a thread-safe manner!
|
||||
*/
|
||||
virtual ReturnValue_t commit(uint32_t lockTimeout) = 0;
|
||||
/**
|
||||
* @brief The read call shall read the value of this parameter from
|
||||
* the data pool and store the content locally.
|
||||
* @details
|
||||
* It is assumbed that these calls are implemented in a thread-safe manner!
|
||||
*/
|
||||
virtual ReturnValue_t read(uint32_t lockTimeout) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief Same as commit with the difference that comitting will be
|
||||
* performed without a lock
|
||||
* @return
|
||||
* This can be used if the lock protection is handled externally
|
||||
* to avoid the overhead of locking and unlocking consecutively.
|
||||
* Declared protected to avoid free public usage.
|
||||
*/
|
||||
virtual ReturnValue_t readWithoutLock() = 0;
|
||||
/**
|
||||
* @brief Same as commit with the difference that comitting will be
|
||||
* performed without a lock
|
||||
* @return
|
||||
* This can be used if the lock protection is handled externally
|
||||
* to avoid the overhead of locking and unlocking consecutively.
|
||||
* Declared protected to avoid free public usage.
|
||||
*/
|
||||
virtual ReturnValue_t commitWithoutLock() = 0;
|
||||
};
|
||||
|
||||
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
||||
|
31
datapool/ReadCommitIF.h
Normal file
31
datapool/ReadCommitIF.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef FSFW_DATAPOOL_READCOMMITIF_H_
|
||||
#define FSFW_DATAPOOL_READCOMMITIF_H_
|
||||
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
/**
|
||||
* @brief Common interface for all software objects which employ read-commit
|
||||
* semantics.
|
||||
*/
|
||||
class ReadCommitIF {
|
||||
public:
|
||||
virtual ~ReadCommitIF() {}
|
||||
virtual ReturnValue_t read(uint32_t mutexTimeout) = 0;
|
||||
virtual ReturnValue_t commit(uint32_t mutexTimeout) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
//! Optional and protected because this is interesting for classes grouping
|
||||
//! members with commit and read semantics where the lock is only necessary
|
||||
//! once.
|
||||
virtual ReturnValue_t readWithoutLock() {
|
||||
return read(20);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t commitWithoutLock() {
|
||||
return commit(20);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* FSFW_DATAPOOL_READCOMMITIF_H_ */
|
@ -44,6 +44,9 @@ public:
|
||||
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
|
||||
|
||||
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
|
||||
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
||||
|
||||
virtual object_id_t getObjectId() const = 0;
|
||||
@ -86,8 +89,10 @@ public:
|
||||
* @return
|
||||
*/
|
||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "HasLocalDataPoolIF::getPoolObjectHandle: Not overriden"
|
||||
<< ". Returning nullptr!" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -21,15 +21,19 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
|
||||
MessageQueueIF* queueToUse, bool appendValidityBuffer):
|
||||
appendValidityBuffer(appendValidityBuffer) {
|
||||
if(owner == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||
<< "Invalid supplied owner!" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
this->owner = owner;
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
if(mutex == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||
<< "Could not create mutex." << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
hkQueue = queueToUse;
|
||||
@ -39,17 +43,21 @@ LocalDataPoolManager::~LocalDataPoolManager() {}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||
if(queueToUse == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalDataPoolManager::initialize: "
|
||||
<< std::hex << "0x" << owner->getObjectId() << ". Supplied "
|
||||
<< "queue invalid!" << std::dec << std::endl;
|
||||
#endif
|
||||
}
|
||||
hkQueue = queueToUse;
|
||||
|
||||
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if(ipcStore == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalDataPoolManager::initialize: "
|
||||
<< std::hex << "0x" << owner->getObjectId() << ": Could not "
|
||||
<< "set IPC store." <<std::dec << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
@ -61,8 +69,10 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||
}
|
||||
else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||
<< "Default HK destination object is invalid!" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
@ -85,8 +95,10 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "HousekeepingManager: The map should only be initialized "
|
||||
<< "once!" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -339,8 +351,10 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
|
||||
AcceptsHkPacketsIF* hkReceiverObject =
|
||||
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
if(hkReceiverObject == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:"
|
||||
<< " Invalid receiver!"<< std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -369,8 +383,10 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePackets(sid_t sid,
|
||||
AcceptsHkPacketsIF* hkReceiverObject =
|
||||
objectManager->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
if(hkReceiverObject == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalDataPoolManager::subscribeForPeriodicPacket:"
|
||||
<< " Invalid receiver!"<< std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -575,9 +591,11 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry(
|
||||
lp_id_t localPoolId) {
|
||||
auto poolIter = localPoolMap.find(localPoolId);
|
||||
if (poolIter == localPoolMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "HousekeepingManager::fechPoolEntry:"
|
||||
<< " Pool entry not found." << std::endl;
|
||||
return POOL_ENTRY_NOT_FOUND;
|
||||
#endif
|
||||
return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND;
|
||||
}
|
||||
poolIter->second->print();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
@ -596,8 +614,10 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
||||
MessageQueueId_t destination) {
|
||||
if(dataSet == nullptr) {
|
||||
// Configuration error.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
||||
<< " Set ID not found or dataset not assigned!" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
@ -678,10 +698,12 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
||||
sid, dataSet, true);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
// configuration error
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "LocalDataPoolManager::performHkOperation:"
|
||||
<< "0x" << std::hex << std::setfill('0') << std::setw(8)
|
||||
<< owner->getObjectId() << " Error generating "
|
||||
<< "HK packet" << std::setfill(' ') << std::dec << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,8 +748,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
||||
// Get and check dataset first.
|
||||
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
|
||||
if(dataSet == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
||||
<< " Set ID not found" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
@ -752,8 +776,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
|
||||
expectedSize,&storePtr);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
|
||||
<< "Could not get free element from IPC store." << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -762,8 +788,10 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
|
||||
result = setPacket.serialize(&storePtr, &size, expectedSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if(expectedSize != size) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "HousekeepingManager::generateSetStructurePacket: "
|
||||
<< "Expected size is not equal to serialized size" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send structure reporting reply.
|
||||
|
@ -55,14 +55,11 @@ class LocalDataPoolManager {
|
||||
public:
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
|
||||
|
||||
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x00);
|
||||
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x01);
|
||||
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x0);
|
||||
|
||||
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x02);
|
||||
|
||||
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x03);
|
||||
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x04);
|
||||
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x05);
|
||||
static constexpr ReturnValue_t WRONG_HK_PACKET_TYPE = MAKE_RETURN_CODE(0x01);
|
||||
static constexpr ReturnValue_t REPORTING_STATUS_UNCHANGED = MAKE_RETURN_CODE(0x02);
|
||||
static constexpr ReturnValue_t PERIODIC_HELPER_INVALID = MAKE_RETURN_CODE(0x03);
|
||||
|
||||
/**
|
||||
* This constructor is used by a class which wants to implement
|
||||
@ -378,16 +375,20 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
||||
PoolEntry<T> **poolEntry) {
|
||||
auto poolIter = localPoolMap.find(localPoolId);
|
||||
if (poolIter == localPoolMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry "
|
||||
"not found." << std::endl;
|
||||
return POOL_ENTRY_NOT_FOUND;
|
||||
#endif
|
||||
return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
|
||||
if(*poolEntry == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "HousekeepingManager::fetchPoolEntry:"
|
||||
" Pool entry not found." << std::endl;
|
||||
return POOL_ENTRY_TYPE_CONFLICT;
|
||||
#endif
|
||||
return HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -8,12 +8,14 @@
|
||||
|
||||
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
||||
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
||||
const size_t maxNumberOfVariables, bool noPeriodicHandling):
|
||||
const size_t maxNumberOfVariables, bool periodicHandling):
|
||||
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
||||
if(hkOwner == nullptr) {
|
||||
// Configuration error.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
||||
<< "invalid!" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
hkManager = hkOwner->getHkManagerHandle();
|
||||
@ -23,7 +25,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
|
||||
// Data creators get a periodic helper for periodic HK data generation.
|
||||
if(not noPeriodicHandling) {
|
||||
if(periodicHandling) {
|
||||
periodicHelper = new PeriodicHousekeepingHelper(this);
|
||||
}
|
||||
}
|
||||
@ -34,13 +36,9 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid,
|
||||
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
|
||||
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
|
||||
sid.objectId);
|
||||
if(hkOwner == nullptr) {
|
||||
// Configuration error.
|
||||
sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner "
|
||||
<< "invalid!" << std::endl;
|
||||
return;
|
||||
if(hkOwner != nullptr) {
|
||||
hkManager = hkOwner->getHkManagerHandle();
|
||||
}
|
||||
hkManager = hkOwner->getHkManagerHandle();
|
||||
this->sid = sid;
|
||||
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
@ -50,8 +48,11 @@ LocalPoolDataSetBase::~LocalPoolDataSetBase() {
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolDataSetBase::lockDataPool(uint32_t timeoutMs) {
|
||||
MutexIF* mutex = hkManager->getMutexHandle();
|
||||
return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs);
|
||||
if(hkManager != nullptr) {
|
||||
MutexIF* mutex = hkManager->getMutexHandle();
|
||||
return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer,
|
||||
@ -127,8 +128,11 @@ ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer(
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolDataSetBase::unlockDataPool() {
|
||||
MutexIF* mutex = hkManager->getMutexHandle();
|
||||
return mutex->unlockMutex();
|
||||
if(hkManager != nullptr) {
|
||||
MutexIF* mutex = hkManager->getMutexHandle();
|
||||
return mutex->unlockMutex();
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
||||
@ -145,8 +149,10 @@ ReturnValue_t LocalPoolDataSetBase::serializeLocalPoolIds(uint8_t** buffer,
|
||||
auto result = SerializeAdapter::serialize(¤tPoolId, buffer,
|
||||
size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization"
|
||||
" error!" << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -204,8 +210,10 @@ ReturnValue_t LocalPoolDataSetBase::serialize(uint8_t **buffer, size_t *size,
|
||||
|
||||
void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const {
|
||||
if(position > 7) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "Pool Raw Access: Bit setting invalid position"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||
@ -254,8 +262,10 @@ sid_t LocalPoolDataSetBase::getSid() const {
|
||||
bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte,
|
||||
uint8_t position) const {
|
||||
if(position > 7) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "Pool Raw Access: Bit setting invalid position"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||
@ -276,3 +286,9 @@ void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
|
||||
}
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
void LocalPoolDataSetBase::setReadCommitProtectionBehaviour(
|
||||
bool protectEveryReadCommit, uint32_t mutexTimeout) {
|
||||
PoolDataSetBase::setReadCommitProtectionBehaviour(protectEveryReadCommit,
|
||||
mutexTimeout);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
*/
|
||||
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
|
||||
uint32_t setId, PoolVariableIF** registeredVariablesArray,
|
||||
const size_t maxNumberOfVariables, bool noPeriodicHandling = false);
|
||||
const size_t maxNumberOfVariables, bool periodicHandling = true);
|
||||
|
||||
/**
|
||||
* @brief Constructor for users of local pool data.
|
||||
@ -77,6 +77,16 @@ public:
|
||||
*/
|
||||
~LocalPoolDataSetBase();
|
||||
|
||||
/**
|
||||
* If the data is pulled from different local data pools, every read and
|
||||
* commit call should be mutex protected for thread safety.
|
||||
* This can be specified with the second parameter.
|
||||
* @param dataCreator
|
||||
* @param protectEveryReadCommit
|
||||
*/
|
||||
void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
|
||||
uint32_t mutexTimeout = 20);
|
||||
|
||||
void setValidityBufferGeneration(bool withValidityBuffer);
|
||||
|
||||
sid_t getSid() const;
|
||||
@ -128,6 +138,7 @@ public:
|
||||
|
||||
protected:
|
||||
sid_t sid;
|
||||
uint32_t mutexTimeout = 20;
|
||||
MutexIF* mutex = nullptr;
|
||||
|
||||
bool diagnostic = false;
|
||||
@ -181,7 +192,7 @@ protected:
|
||||
*/
|
||||
ReturnValue_t unlockDataPool() override;
|
||||
|
||||
LocalDataPoolManager* hkManager;
|
||||
LocalDataPoolManager* hkManager = nullptr;
|
||||
|
||||
/**
|
||||
* Set n-th bit of a byte, with n being the position from 0
|
||||
|
@ -5,12 +5,16 @@ LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId,
|
||||
pool_rwm_t setReadWriteMode): localPoolId(poolId),
|
||||
readWriteMode(setReadWriteMode) {
|
||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
||||
<< "which is the NO_PARAMETER value!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
if(hkOwner == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalPoolVar<T>::LocalPoolVar: The supplied pool "
|
||||
<< "owner is a invalid!" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
hkManager = hkOwner->getHkManagerHandle();
|
||||
@ -23,15 +27,19 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
||||
DataSetIF *dataSet, pool_rwm_t setReadWriteMode): localPoolId(poolId),
|
||||
readWriteMode(setReadWriteMode) {
|
||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LocalPoolVar<T>::LocalPoolVar: 0 passed as pool ID, "
|
||||
<< "which is the NO_PARAMETER value!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
HasLocalDataPoolIF* hkOwner =
|
||||
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
||||
if(hkOwner == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalPoolVariable: The supplied pool owner did not "
|
||||
<< "implement the correct interface"
|
||||
<< " HasLocalDataPoolIF!" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
hkManager = hkOwner->getHkManagerHandle();
|
||||
|
@ -157,10 +157,12 @@ protected:
|
||||
*/
|
||||
ReturnValue_t commitWithoutLock() override;
|
||||
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
// std::ostream is the type for object std::cout
|
||||
template <typename U>
|
||||
friend std::ostream& operator<< (std::ostream &out,
|
||||
const LocalPoolVariable<U> &var);
|
||||
#endif
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -11,14 +11,14 @@ inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner,
|
||||
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
||||
|
||||
template<typename T>
|
||||
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
|
||||
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||
inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner,
|
||||
lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF *dataSet,
|
||||
pool_rwm_t setReadWriteMode):
|
||||
inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId,
|
||||
DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
|
||||
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
|
||||
dataSet, setReadWriteMode){}
|
||||
|
||||
@ -33,18 +33,22 @@ inline ReturnValue_t LocalPoolVariable<T>::read(dur_millis_t lockTimeout) {
|
||||
template<typename T>
|
||||
inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
|
||||
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "LocalPoolVar: Invalid read write "
|
||||
"mode for read() call." << std::endl;
|
||||
#endif
|
||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||
}
|
||||
|
||||
PoolEntry<T>* poolEntry = nullptr;
|
||||
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
||||
if(result != RETURN_OK and poolEntry != nullptr) {
|
||||
if(result != RETURN_OK or poolEntry == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PoolVector: Read of local pool variable of object "
|
||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
||||
hkManager->getOwner() << " and lp ID 0x" << localPoolId <<
|
||||
std::dec << " failed.\n" << std::flush;
|
||||
<< std::hex << std::setw(8) << std::setfill('0')
|
||||
<< hkManager->getOwner() << " and lp ID " << localPoolId
|
||||
<< std::dec << " failed." << std::setfill(' ') << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
this->value = *(poolEntry->address);
|
||||
@ -62,17 +66,21 @@ inline ReturnValue_t LocalPoolVariable<T>::commit(dur_millis_t lockTimeout) {
|
||||
template<typename T>
|
||||
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
|
||||
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
||||
sif::debug << "LocalPoolVar: Invalid read write "
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "LocalPoolVariable: Invalid read write "
|
||||
"mode for commit() call." << std::endl;
|
||||
#endif
|
||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||
}
|
||||
PoolEntry<T>* poolEntry = nullptr;
|
||||
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
||||
if(result != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PoolVector: Read of local pool variable of object "
|
||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
||||
hkManager->getOwner() << " and lp ID 0x" << localPoolId <<
|
||||
std::dec << " failed.\n" << std::flush;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
*(poolEntry->address) = this->value;
|
||||
@ -98,12 +106,14 @@ inline ReturnValue_t LocalPoolVariable<T>::deSerialize(const uint8_t** buffer,
|
||||
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
template<typename T>
|
||||
inline std::ostream& operator<< (std::ostream &out,
|
||||
const LocalPoolVariable<T> &var) {
|
||||
out << var.value;
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline LocalPoolVariable<T>::operator T() const {
|
||||
|
@ -32,8 +32,10 @@ inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(uint32_t lockTimeout)
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
||||
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "LocalPoolVar: Invalid read write "
|
||||
"mode for read() call." << std::endl;
|
||||
#endif
|
||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||
}
|
||||
|
||||
@ -42,10 +44,12 @@ inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
|
||||
memset(this->value, 0, vectorSize * sizeof(T));
|
||||
|
||||
if(result != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PoolVector: Read of local pool variable of object "
|
||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
||||
hkManager->getOwner() << "and lp ID 0x" << localPoolId <<
|
||||
std::dec << " failed." << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
std::memcpy(this->value, poolEntry->address, poolEntry->getByteSize());
|
||||
@ -64,17 +68,21 @@ inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commitWithoutLock() {
|
||||
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "LocalPoolVar: Invalid read write "
|
||||
"mode for commit() call." << std::endl;
|
||||
#endif
|
||||
return PoolVariableIF::INVALID_READ_WRITE_MODE;
|
||||
}
|
||||
PoolEntry<T>* poolEntry = nullptr;
|
||||
ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry);
|
||||
if(result != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PoolVector: Read of local pool variable of object "
|
||||
"0x" << std::hex << std::setw(8) << std::setfill('0') <<
|
||||
hkManager->getOwner() << " and lp ID 0x" << localPoolId <<
|
||||
std::dec << " failed.\n" << std::flush;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
std::memcpy(poolEntry->address, this->value, poolEntry->getByteSize());
|
||||
@ -89,8 +97,10 @@ inline T& LocalPoolVector<T, vectorSize>::operator [](int i) {
|
||||
}
|
||||
// If this happens, I have to set some value. I consider this
|
||||
// a configuration error, but I wont exit here.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalPoolVector: Invalid index. Setting or returning"
|
||||
" last value!" << std::endl;
|
||||
#endif
|
||||
return value[i];
|
||||
}
|
||||
|
||||
@ -101,8 +111,10 @@ inline const T& LocalPoolVector<T, vectorSize>::operator [](int i) const {
|
||||
}
|
||||
// If this happens, I have to set some value. I consider this
|
||||
// a configuration error, but I wont exit here.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalPoolVector: Invalid index. Setting or returning"
|
||||
" last value!" << std::endl;
|
||||
#endif
|
||||
return value[i];
|
||||
}
|
||||
|
||||
|
43
datapoollocal/PoolReadHelper.h
Normal file
43
datapoollocal/PoolReadHelper.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef FSFW_DATAPOOLLOCAL_POOLREADHELPER_H_
|
||||
#define FSFW_DATAPOOLLOCAL_POOLREADHELPER_H_
|
||||
|
||||
#include <fsfw/datapoollocal/LocalPoolDataSetBase.h>
|
||||
#include <FSFWConfig.h>
|
||||
|
||||
/**
|
||||