From cbfa21d45a51bbe97d6d35a6b54ab8f409a8f2d1 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 01:17:11 +0200 Subject: [PATCH 01/14] merging renaming into main branch --- datapool/ControllerSet.h | 4 +- datapool/DataPool.cpp | 132 ------ datapool/DataPool.h | 136 ------ datapool/DataSet.cpp | 150 ------ datapool/DataSet.h | 168 ------- datapool/DataSetIF.h | 39 +- datapool/HkSwitchHelper.cpp | 1 - datapool/PIDReader.h | 8 +- datapool/PoolEntry.cpp | 1 - datapool/PoolEntry.h | 46 +- datapool/PoolEntryIF.h | 61 ++- datapool/PoolRawAccess.cpp | 126 ++--- datapool/PoolRawAccess.h | 172 +++---- datapool/PoolRawAccessHelper.cpp | 6 +- datapool/PoolRawAccessHelper.h | 2 +- datapool/PoolVarList.h | 6 +- datapool/PoolVariableIF.h | 63 ++- {datapool => datapoolglob}/DataPoolAdmin.cpp | 18 +- {datapool => datapoolglob}/DataPoolAdmin.h | 15 +- .../DataPoolParameterWrapper.cpp | 14 +- .../DataPoolParameterWrapper.h | 0 datapoolglob/GlobalDataPool.cpp | 132 ++++++ datapoolglob/GlobalDataPool.h | 146 ++++++ datapoolglob/GlobalDataSet.cpp | 166 +++++++ datapoolglob/GlobalDataSet.h | 185 ++++++++ datapoolglob/GlobalPoolVariable.h | 189 ++++++++ datapoolglob/GlobalPoolVariable.tpp | 84 ++++ datapoolglob/GlobalPoolVector.h | 223 +++++++++ datapoollocal/LocalDataSet.cpp | 66 +++ datapoollocal/LocalDataSet.h | 187 ++++++++ datapoollocal/LocalPoolVariable.h | 103 ++++ datapoollocal/LocalPoolVariable.tpp | 109 +++++ devicehandlers/DeviceHandlerBase.cpp | 189 ++++---- devicehandlers/DeviceHandlerBase.h | 439 +++++++++--------- housekeeping/HasHkPoolParametersIF.h | 32 ++ housekeeping/HousekeepingManager.cpp | 50 ++ housekeeping/HousekeepingManager.h | 95 ++++ housekeeping/HousekeepingMessage.cpp | 10 + housekeeping/HousekeepingMessage.h | 87 ++++ internalError/InternalErrorReporter.cpp | 10 +- monitoring/MonitorBase.h | 4 +- power/Fuse.cpp | 2 +- power/Fuse.h | 6 +- power/PowerSensor.h | 6 +- thermal/CoreComponent.cpp | 12 +- thermal/CoreComponent.h | 12 +- thermal/ThermalModule.h | 6 +- 47 files changed, 2465 insertions(+), 1253 deletions(-) delete mode 100644 datapool/DataPool.cpp delete mode 100644 datapool/DataPool.h delete mode 100644 datapool/DataSet.cpp delete mode 100644 datapool/DataSet.h rename {datapool => datapoolglob}/DataPoolAdmin.cpp (96%) rename {datapool => datapoolglob}/DataPoolAdmin.h (90%) rename {datapool => datapoolglob}/DataPoolParameterWrapper.cpp (96%) rename {datapool => datapoolglob}/DataPoolParameterWrapper.h (100%) create mode 100644 datapoolglob/GlobalDataPool.cpp create mode 100644 datapoolglob/GlobalDataPool.h create mode 100644 datapoolglob/GlobalDataSet.cpp create mode 100644 datapoolglob/GlobalDataSet.h create mode 100644 datapoolglob/GlobalPoolVariable.h create mode 100644 datapoolglob/GlobalPoolVariable.tpp create mode 100644 datapoolglob/GlobalPoolVector.h create mode 100644 datapoollocal/LocalDataSet.cpp create mode 100644 datapoollocal/LocalDataSet.h create mode 100644 datapoollocal/LocalPoolVariable.h create mode 100644 datapoollocal/LocalPoolVariable.tpp create mode 100644 housekeeping/HasHkPoolParametersIF.h create mode 100644 housekeeping/HousekeepingManager.cpp create mode 100644 housekeeping/HousekeepingManager.h create mode 100644 housekeeping/HousekeepingMessage.cpp create mode 100644 housekeeping/HousekeepingMessage.h diff --git a/datapool/ControllerSet.h b/datapool/ControllerSet.h index de06bf91..7625c3d1 100644 --- a/datapool/ControllerSet.h +++ b/datapool/ControllerSet.h @@ -1,9 +1,9 @@ #ifndef CONTROLLERSET_H_ #define CONTROLLERSET_H_ -#include +#include -class ControllerSet :public DataSet { +class ControllerSet :public GlobDataSet { public: ControllerSet(); virtual ~ControllerSet(); diff --git a/datapool/DataPool.cpp b/datapool/DataPool.cpp deleted file mode 100644 index c6a1a74e..00000000 --- a/datapool/DataPool.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include - -DataPool::DataPool( void ( *initFunction )( std::map* pool_map ) ) { - mutex = MutexFactory::instance()->createMutex(); - if (initFunction != NULL ) { - initFunction( &this->data_pool ); - } -} - -DataPool::~DataPool() { - MutexFactory::instance()->deleteMutex(mutex); - for ( std::map::iterator it = this->data_pool.begin(); it != this->data_pool.end(); ++it ) { - delete it->second; - } -} - -//The function checks PID, type and array length before returning a copy of the PoolEntry. In failure case, it returns a temp-Entry with size 0 and NULL-ptr. -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t sizeOrPosition ) { - std::map::iterator it = this->data_pool.find( data_pool_id ); - if ( it != this->data_pool.end() ) { - PoolEntry* entry = dynamic_cast< PoolEntry* >( it->second ); - if (entry != NULL ) { - if ( sizeOrPosition <= entry->length ) { - return entry; - } - } - } - return NULL; -} - -PoolEntryIF* DataPool::getRawData( uint32_t data_pool_id ) { - std::map::iterator it = this->data_pool.find( data_pool_id ); - if ( it != this->data_pool.end() ) { - return it->second; - } else { - return NULL; - } -} - -//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t max_size ) { -// std::map::iterator it = this->data_pool.find( data_pool_id ); -// if ( it != this->data_pool.end() ) { -// if ( it->second->getByteSize() <= max_size ) { -// *size = it->second->getByteSize(); -// memcpy( address, it->second->getRawData(), *size ); -// return DP_SUCCESSFUL; -// } -// } -// *size = 0; -// return DP_FAILURE; -//} - -ReturnValue_t DataPool::freeDataPoolLock() { - ReturnValue_t status = mutex->unlockMutex(); - if ( status != RETURN_OK ) { - sif::error << "DataPool::DataPool: unlock of mutex failed with error code: " << status << std::endl; - } - return status; -} - -ReturnValue_t DataPool::lockDataPool() { - ReturnValue_t status = mutex->lockMutex(MutexIF::NO_TIMEOUT); - if ( status != RETURN_OK ) { - sif::error << "DataPool::DataPool: lock of mutex failed with error code: " << status << std::endl; - } - return status; -} - -void DataPool::print() { - sif::debug << "DataPool contains: " << std::endl; - std::map::iterator dataPoolIt; - dataPoolIt = this->data_pool.begin(); - while( dataPoolIt != this->data_pool.end() ) { - sif::debug << std::hex << dataPoolIt->first << std::dec << " |"; - dataPoolIt->second->print(); - dataPoolIt++; - } -} - -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData(uint32_t data_pool_id, - uint8_t size); -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData( uint32_t data_pool_id, uint8_t size ); -template PoolEntry* DataPool::getData(uint32_t data_pool_id, - uint8_t size); - - -uint32_t DataPool::PIDToDataPoolId(uint32_t parameter_id) { - return (parameter_id >> 8) & 0x00FFFFFF; -} - -uint8_t DataPool::PIDToArrayIndex(uint32_t parameter_id) { - return (parameter_id & 0x000000FF); -} - -uint32_t DataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) { - return (poolId << 8) + index; -} - - -//SHOULDDO: Do we need a mutex lock here... I don't think so, as we only check static const values of elements in a list that do not change. -//there is no guarantee in the standard, but it seems to me that the implementation is safe -UM -ReturnValue_t DataPool::getType(uint32_t parameter_id, Type* type) { - std::map::iterator it = this->data_pool.find( PIDToDataPoolId(parameter_id)); - if ( it != this->data_pool.end() ) { - *type = it->second->getType(); - return RETURN_OK; - } else { - *type = Type::UNKNOWN_TYPE; - return RETURN_FAILED; - } -} - -bool DataPool::exists(uint32_t parameterId) { - uint32_t poolId = PIDToDataPoolId(parameterId); - uint32_t index = PIDToArrayIndex(parameterId); - std::map::iterator it = this->data_pool.find( poolId ); - if (it != data_pool.end()) { - if (it->second->getSize() >= index) { - return true; - } - } - return false; -} diff --git a/datapool/DataPool.h b/datapool/DataPool.h deleted file mode 100644 index 857bc3b2..00000000 --- a/datapool/DataPool.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * \file DataPool.h - * - * \date 10/17/2012 - * \author Bastian Baetz - * - * \brief This file contains the definition of the DataPool class and (temporarily) - * the "extern" definition of the global dataPool instance. - */ - -#ifndef DATAPOOL_H_ -#define DATAPOOL_H_ - -#include -#include -#include -#include - -/** - * \defgroup data_pool Data Pool - * This is the group, where all classes associated with Data Pool Handling belong to. - * This includes classes to access Data Pool variables. - */ - -#define DP_SUCCESSFUL 0 -#define DP_FAILURE 1 - -/** - * \brief This class represents the OBSW global data-pool. - * - * \details All variables are registered and space is allocated in an initialization - * function, which is passed to the constructor. - * Space for the variables is allocated on the heap (with a new call). - * The data is found by a data pool id, which uniquely represents a variable. - * Data pool variables should be used with a blackboard logic in mind, - * which means read data is valid (if flagged so), but not necessarily up-to-date. - * Variables are either single values or arrays. - * \ingroup data_pool - */ -class DataPool : public HasReturnvaluesIF { -private: - /** - * \brief This is the actual data pool itself. - * \details It is represented by a map - * with the data pool id as index and a pointer to a single - * PoolEntry as value. - */ - std::map data_pool; -public: - /** - * \brief The mutex is created in the constructor and makes access mutual exclusive. - * \details Locking and unlocking the pool is only done by the DataSet class. - */ - MutexIF* mutex; - /** - * \brief In the classes constructor, the passed initialization function is called. - * \details To enable filling the pool, - * a pointer to the map is passed, allowing direct access to the pool's content. - * On runtime, adding or removing variables is forbidden. - */ - DataPool( void ( *initFunction )( std::map* pool_map ) ); - /** - * \brief The destructor iterates through the data_pool map and calls all Entries destructors to clean up the heap. - */ - ~DataPool(); - /** - * \brief This is the default call to access the pool. - * \details A pointer to the PoolEntry object is returned. - * The call checks data pool id, type and array size. Returns NULL in case of failure. - * \param data_pool_id The data pool id to search. - * \param sizeOrPosition The array size (not byte size!) of the pool entry, or the position the user wants to read. - * If smaller than the entry size, everything's ok. - */ - template PoolEntry* getData( uint32_t data_pool_id, uint8_t sizeOrPosition ); - /** - * \brief An alternative call to get a data pool entry in case the type is not implicitly known - * (i.e. in Housekeeping Telemetry). - * \details It returns a basic interface and does NOT perform - * a size check. The caller has to assure he does not copy too much data. - * Returns NULL in case the entry is not found. - * \param data_pool_id The data pool id to search. - */ - PoolEntryIF* getRawData( uint32_t data_pool_id ); - /** - * \brief This is a small helper function to facilitate locking the global data pool. - * \details It fetches the pool's mutex id and tries to acquire the mutex. - */ - ReturnValue_t lockDataPool(); - /** - * \brief This is a small helper function to facilitate unlocking the global data pool. - * \details It fetches the pool's mutex id and tries to free the mutex. - */ - ReturnValue_t freeDataPoolLock(); - /** - * \brief The print call is a simple debug method. - * \details It prints the current content of the data pool. - * It iterates through the data_pool map and calls each entry's print() method. - */ - void print(); - /** - * Extracts the data pool id from a SCOS 2000 PID. - * @param parameter_id The passed Parameter ID. - * @return The data pool id as used within the OBSW. - */ - static uint32_t PIDToDataPoolId( uint32_t parameter_id ); - /** - * Extracts an array index out of a SCOS 2000 PID. - * @param parameter_id The passed Parameter ID. - * @return The index of the corresponding data pool entry. - */ - static uint8_t PIDToArrayIndex( uint32_t parameter_id ); - /** - * Retransforms a data pool id and an array index to a SCOS 2000 PID. - */ - static uint32_t poolIdAndPositionToPid( uint32_t poolId, uint8_t index ); - - /** - * Method to return the type of a pool variable. - * @param parameter_id A parameterID (not pool id) of a DP member. - * @param type Returns the type or TYPE::UNKNOWN_TYPE - * @return RETURN_OK if parameter exists, RETURN_FAILED else. - */ - ReturnValue_t getType( uint32_t parameter_id, Type* type ); - - /** - * Method to check if a PID exists. - * Does not lock, as there's no possibility to alter the list that is checked during run-time. - * @param parameterId The PID (not pool id!) of a parameter. - * @return true if exists, false else. - */ - bool exists(uint32_t parameterId); -}; - -//We assume someone globally instantiates a DataPool. -extern DataPool dataPool; -#endif /* DATAPOOL_H_ */ diff --git a/datapool/DataSet.cpp b/datapool/DataSet.cpp deleted file mode 100644 index 30362118..00000000 --- a/datapool/DataSet.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include - -DataSet::DataSet() : - fill_count(0), state(DATA_SET_UNINITIALISED) { - for (unsigned count = 0; count < DATA_SET_MAX_SIZE; count++) { - registeredVariables[count] = NULL; - } -} - -DataSet::~DataSet() { - //Don't do anything with your variables, they are dead already! (Destructor is already called) -} - -ReturnValue_t DataSet::read() { - ReturnValue_t result = RETURN_OK; - if (state == DATA_SET_UNINITIALISED) { - lockDataPool(); - for (uint16_t count = 0; count < fill_count; count++) { - if (registeredVariables[count]->getReadWriteMode() - != PoolVariableIF::VAR_WRITE - && registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - ReturnValue_t status = registeredVariables[count]->read(); - if (status != RETURN_OK) { - result = INVALID_PARAMETER_DEFINITION; - break; - } - } - } - state = DATA_SET_WAS_READ; - freeDataPoolLock(); - } else { - sif::error << "DataSet::read(): Call made in wrong position." << std::endl; - result = SET_WAS_ALREADY_READ; - } - return result; -} - -ReturnValue_t DataSet::commit(uint8_t valid) { - setValid(valid); - return commit(); -} - -ReturnValue_t DataSet::commit() { - if (state == DATA_SET_WAS_READ) { - lockDataPool(); - for (uint16_t count = 0; count < fill_count; count++) { - if (registeredVariables[count]->getReadWriteMode() - != PoolVariableIF::VAR_READ - && registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commit(); - } - } - state = DATA_SET_UNINITIALISED; - freeDataPoolLock(); - return RETURN_OK; - } else { - ReturnValue_t result = RETURN_OK; - lockDataPool(); - for (uint16_t count = 0; count < fill_count; count++) { - if (registeredVariables[count]->getReadWriteMode() - == PoolVariableIF::VAR_WRITE - && registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commit(); - } else if (registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - if (result != COMMITING_WITHOUT_READING) { - sif::error << - "DataSet::commit(): commit-without-read " - "call made with non write-only variable." << std::endl; - result = COMMITING_WITHOUT_READING; - } - } - } - state = DATA_SET_UNINITIALISED; - freeDataPoolLock(); - return result; - } - -} - -void DataSet::registerVariable(PoolVariableIF* variable) { - if (state == DATA_SET_UNINITIALISED) { - if (variable != NULL) { - if (fill_count < DATA_SET_MAX_SIZE) { - registeredVariables[fill_count] = variable; - fill_count++; - return; - } - } - } - sif::error - << "DataSet::registerVariable: failed. Either NULL, or set is full, or call made in wrong position." - << std::endl; - return; -} - -uint8_t DataSet::freeDataPoolLock() { - return ::dataPool.freeDataPoolLock(); -} - -uint8_t DataSet::lockDataPool() { - return ::dataPool.lockDataPool(); -} - -ReturnValue_t DataSet::serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - ReturnValue_t result = RETURN_FAILED; - for (uint16_t count = 0; count < fill_count; count++) { - result = registeredVariables[count]->serialize(buffer, size, max_size, - bigEndian); - if (result != RETURN_OK) { - return result; - } - } - return result; -} - -size_t DataSet::getSerializedSize() const { - size_t size = 0; - for (uint16_t count = 0; count < fill_count; count++) { - size += registeredVariables[count]->getSerializedSize(); - } - return size; -} - -void DataSet::setValid(uint8_t valid) { - for (uint16_t count = 0; count < fill_count; count++) { - if (registeredVariables[count]->getReadWriteMode() - != PoolVariableIF::VAR_READ) { - registeredVariables[count]->setValid(valid); - } - } -} - -ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) { - ReturnValue_t result = RETURN_FAILED; - for (uint16_t count = 0; count < fill_count; count++) { - result = registeredVariables[count]->deSerialize(buffer, size, - bigEndian); - if (result != RETURN_OK) { - return result; - } - } - return result; -} diff --git a/datapool/DataSet.h b/datapool/DataSet.h deleted file mode 100644 index 1e34e07c..00000000 --- a/datapool/DataSet.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * \file DataSet.h - * - * \brief This file contains the DataSet class and a small structure called DataSetContent. - * - * \date 10/17/2012 - * - * \author Bastian Baetz - * - */ - -#ifndef DATASET_H_ -#define DATASET_H_ - -#include -#include -#include -#include -#include -#include -#include -/** - * \brief The DataSet class manages a set of locally checked out variables. - * - * \details This class manages a list, where a set of local variables (or pool variables) are - * registered. They are checked-out (i.e. their values are looked up and copied) - * with the read call. After the user finishes working with the pool variables, - * he can write back all variable values to the pool with the commit call. - * The data set manages locking and freeing the data pool, to ensure that all values - * are read and written back at once. - * An internal state manages usage of this class. Variables may only be registered before - * the read call is made, and the commit call only after the read call. - * If pool variables are writable and not committed until destruction of the set, the - * DataSet class automatically sets the valid flag in the data pool to invalid (without) - * changing the variable's value. - * - * \ingroup data_pool - */ -class DataSet: public DataSetIF, public HasReturnvaluesIF, public SerializeIF { - -public: - //SHOULDDO we could use a linked list of datapool variables - static const uint8_t DATA_SET_MAX_SIZE = 63; //!< This definition sets the maximum number of variables to register in one DataSet. - - static const uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS; - static const ReturnValue_t INVALID_PARAMETER_DEFINITION = - MAKE_RETURN_CODE( 0x01 ); - static const ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 ); - static const ReturnValue_t COMMITING_WITHOUT_READING = - MAKE_RETURN_CODE(0x03); - - /** - * \brief The constructor simply sets the fill_count to zero and sets the state to "uninitialized". - */ - DataSet(); - /** - * \brief The destructor automatically manages writing the valid information of variables. - * \details In case the data set was read out, but not committed (indicated by state), - * the destructor parses all variables that are still registered to the set. - * For each, the valid flag in the data pool is set to "invalid". - */ - ~DataSet(); - /** - * \brief The read call initializes reading out all registered variables. - * \details It iterates through the list of registered variables and calls all read() - * functions of the registered pool variables (which read out their values from the - * data pool) which are not write-only. In case of an error (e.g. a wrong data type, - * or an invalid data pool id), 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. - * \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 SET_WAS_ALREADY_READ if read() is called twice without calling - * commit() in between - */ - ReturnValue_t read(); - /** - * \brief The commit call initializes writing back the registered variables. - * \details It iterates through the list of registered variables and calls - * the commit() method of the remaining registered variables (which write back - * their values to the pool). - * The data pool is locked during the whole commit operation and freed afterwards. - * The state changes to "was committed" after this operation. - * 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. - * \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 - */ - ReturnValue_t commit(void); - /** - * Variant of method above which sets validity of all elements of the set. - * @param valid Validity information from PoolVariableIF. - * \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 - */ - ReturnValue_t commit(uint8_t valid); - /** - * \brief This operation is used to register the local variables in the set. - * \details It copies all required information to the currently - * free space in the registeredVariables list. - */ - void registerVariable(PoolVariableIF* variable); - - /** - * Set the valid information of all variables contained in the set which are not readonly - * - * @param valid Validity information from PoolVariableIF. - */ - void setValid(uint8_t valid); - - /** - * Serialize all registered pool variables into the provided buffer - * @param buffer - * @param size Is incremented by serialized size - * @param max_size - * @param bigEndian - * @return - */ - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const; - - virtual size_t getSerializedSize() const; - - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian); - -private: - /** - * \brief This array represents all pool variables registered in this set. - * \details It has a maximum size of DATA_SET_MAX_SIZE. - */ - PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE]; - /** - * \brief The fill_count attribute ensures that the variables register in the correct array - * position and that the maximum number of variables is not exceeded. - */ - uint16_t fill_count; - /** - * States of the seet. - */ - enum States { - DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED - DATA_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; - /** - * \brief This is a small helper function to facilitate locking the global data pool. - * \details It makes use of the lockDataPool method offered by the DataPool class. - */ - uint8_t lockDataPool(); - /** - * \brief This is a small helper function to facilitate unlocking the global data pool. - * \details It makes use of the freeDataPoolLock method offered by the DataPool class. - */ - uint8_t freeDataPoolLock(); - -}; - -#endif /* DATASET_H_ */ diff --git a/datapool/DataSetIF.h b/datapool/DataSetIF.h index 7741477d..4e351416 100644 --- a/datapool/DataSetIF.h +++ b/datapool/DataSetIF.h @@ -1,39 +1,36 @@ -/** - * \file DataSetIF.h - * - * \brief This file contains the small interface to access the DataSet class. - * - * \date 10/23/2012 - * - * \author Bastian Baetz - * - */ - #ifndef DATASETIF_H_ #define DATASETIF_H_ +#include class PoolVariableIF; /** - * \brief This class defines a small interface to register on a DataSet. + * @brief This class defines a small interface to register on a DataSet. * - * \details Currently, the only purpose of this interface is to provide a method for locally - * checked-out variables to register on a data set. Still, it may become useful for - * other purposes as well. - * - * \ingroup data_pool + * @details + * Currently, the only purpose of this interface is to provide a + * method for locally checked-out variables to register on a data set. + * Still, it may become useful for other purposes as well. + * @author Bastian Baetz + * @ingroup data_pool */ class DataSetIF { public: /** - * \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. + * @brief This is an empty virtual destructor, + * as it is proposed for C++ interfaces. */ virtual ~DataSetIF() {} + /** - * \brief This operation provides a method to register local data pool variables - * to register in a data set by passing itself to this DataSet operation. + * @brief This operation provides a method to register local data pool + * variables to register in a data set by passing itself + * to this DataSet operation. */ - virtual void registerVariable( PoolVariableIF* variable ) = 0; + virtual ReturnValue_t registerVariable( PoolVariableIF* variable ) = 0; + + virtual ReturnValue_t lockDataPool() = 0; + virtual ReturnValue_t unlockDataPool() = 0; }; #endif /* DATASETIF_H_ */ diff --git a/datapool/HkSwitchHelper.cpp b/datapool/HkSwitchHelper.cpp index caae2146..844fcd90 100644 --- a/datapool/HkSwitchHelper.cpp +++ b/datapool/HkSwitchHelper.cpp @@ -1,5 +1,4 @@ #include -//#include #include HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) : diff --git a/datapool/PIDReader.h b/datapool/PIDReader.h index 5eb86026..3a815cee 100644 --- a/datapool/PIDReader.h +++ b/datapool/PIDReader.h @@ -1,9 +1,9 @@ #ifndef PIDREADER_H_ #define PIDREADER_H_ -#include #include #include #include +#include #include #include @@ -16,9 +16,9 @@ protected: uint32_t parameterId; uint8_t valid; ReturnValue_t read() { - uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId); + uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId); PoolEntry* read_out = ::dataPool.getData( - DataPool::PIDToDataPoolId(parameterId), arrayIndex); + GlobalDataPool::PIDToDataPoolId(parameterId), arrayIndex); if (read_out != NULL) { valid = read_out->valid; value = read_out->address[arrayIndex]; @@ -88,7 +88,7 @@ public: * \brief This operation returns the data pool id of the variable. */ uint32_t getDataPoolId() const { - return DataPool::PIDToDataPoolId(parameterId); + return GlobalDataPool::PIDToDataPoolId(parameterId); } uint32_t getParameterId() const { return parameterId; diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index e38af775..d07c516d 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -71,7 +71,6 @@ Type PoolEntry::getType() { return PodTypeConversion::type; } -template class PoolEntry; template class PoolEntry; template class PoolEntry; template class PoolEntry; diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h index a02c6c60..4971ee45 100644 --- a/datapool/PoolEntry.h +++ b/datapool/PoolEntry.h @@ -6,34 +6,46 @@ #include #include #include +#include /** - * \brief This is a small helper class that defines a single data pool entry. - * - * \details The helper is used to store all information together with the data as a single data pool entry. - * The content's type is defined by the template argument. - * It is prepared for use with plain old data types, - * but may be extended to complex types if necessary. - * It can be initialized with a certain value, size and validity flag. - * It holds a pointer to the real data and offers methods to access this data and to acquire - * additional information (such as validity and array/byte size). - * It is NOT intended to be used outside the DataPool class. - * - * \ingroup data_pool + * @brief This is a small helper class that defines a single data pool entry. + * @details + * The helper is used to store all information together with the data as a + * single data pool entry.The content's type is defined by the template argument. + * It is prepared for use with plain old data types, but may be extended to + * complex types if necessary. It can be initialized with a certain value, + * size and validity flag. It holds a pointer to the real data and offers + * methods to access this data and to acquire additional information + * (such as validity and array/byte size). It is NOT intended to be used + * outside the DataPool class. + * @author Bastian Baetz + * @ingroup data_pool * */ template class PoolEntry : public PoolEntryIF { public: + static_assert(not std::is_same::value, + "Do not use boolean for the PoolEntry type, use uint8_t instead!" + "Warum? Darum :-)"); /** - * \brief In the classe's constructor, space is allocated on the heap and + * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. - * \param initValue A pointer to the single value or array that holds the init value. - * With the default value (NULL), the entry is initalized with all 0. - * \param set_length Defines the array length of this entry. - * \param set_valid Sets the initialization flag. It is invalid (0) by default. + * @param initValue Initializer list with values to initialize with + * @param set_length Defines the array length of this entry. + * @param set_valid Sets the initialization flag. It is invalid (0) by default. */ PoolEntry( std::initializer_list initValue = {}, uint8_t set_length = 1, uint8_t set_valid = 0 ); + /** + * @brief In the classe's constructor, space is allocated on the heap and + * potential init values are copied to that space. + * @param initValue A pointer to the single value or array that holds the init value. + * With the default value (NULL), the entry is initalized with all 0. + * @param set_length Defines the array length of this entry. + * @param set_valid Sets the initialization flag. It is invalid (0) by default. + */ PoolEntry( T* initValue = NULL, uint8_t set_length = 1, uint8_t set_valid = 0 ); + /** * \brief The allocated memory for the variable is freed in the destructor. * \details As the data pool is global, this dtor is only called on program exit. diff --git a/datapool/PoolEntryIF.h b/datapool/PoolEntryIF.h index 514e67ef..d24d553a 100644 --- a/datapool/PoolEntryIF.h +++ b/datapool/PoolEntryIF.h @@ -1,66 +1,63 @@ -/** - * \file PoolEntryIF.h - * - * \brief This file holds the class that defines the Interface for Pool Entry elements. - * - * \date 10/18/2012 - * - * \author Bastian Baetz - */ - #ifndef POOLENTRYIF_H_ #define POOLENTRYIF_H_ #include -#include - - +#include /** - * \brief This interface defines the access possibilities to a single data pool entry. - * - * \details The interface provides methods to determine the size and the validity information of a value. - * It also defines a method to receive a pointer to the raw data content. - * It is mainly used by DataPool itself, but also as a return pointer. - * - * \ingroup data_pool - * + * @brief This interface defines the access possibilities to a + * single data pool entry. + * @details + * The interface provides methods to determine the size and the validity + * information of a value. It also defines a method to receive a pointer to + * the raw data content. It is mainly used by DataPool itself, but also as a + * return pointer. + * @author Bastian Baetz + * @ingroup data_pool */ class PoolEntryIF { public: /** - * \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. + * @brief This is an empty virtual destructor, + * as it is proposed for C++ interfaces. */ - virtual ~PoolEntryIF() { - } + virtual ~PoolEntryIF() {} + /** - * \brief getSize returns the array size of the entry. A single variable parameter has size 1. + * @brief getSize returns the array size of the entry. + * A single variable parameter has size 1. */ virtual uint8_t getSize() = 0; + /** - * \brief This operation returns the size in bytes, which is calculated by + * @brief This operation returns the size in bytes, which is calculated by * sizeof(type) * array_size. */ virtual uint16_t getByteSize() = 0; + /** - * \brief This operation returns a the address pointer casted to void*. + * @brief This operation returns a the address pointer casted to void*. */ virtual void* getRawData() = 0; + /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information of the pool entry. */ virtual void setValid(uint8_t isValid) = 0; + /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information of the pool entry. */ virtual uint8_t getValid() = 0; + /** - * \brief This is a debug method that prints all values and the valid information to the screen. - * It prints all array entries in a row. + * @brief This is a debug method that prints all values and the valid + * information to the screen. It prints all array entries in a row. */ virtual void print() = 0; + /** - * Returns the type of the entry. + * @brief Returns the type of the entry. */ virtual Type getType() = 0; }; diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index 592f663f..97bdc2b3 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -1,6 +1,6 @@ -#include #include #include +#include #include #include @@ -14,63 +14,41 @@ PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, } } -PoolRawAccess::~PoolRawAccess() {} +PoolRawAccess::~PoolRawAccess() { + +} ReturnValue_t PoolRawAccess::read() { - ReturnValue_t result = RETURN_FAILED; PoolEntryIF* read_out = ::dataPool.getRawData(dataPoolId); if (read_out != NULL) { - result = handleReadOut(read_out); - if(result == RETURN_OK) { - return result; - } - } else { - result = READ_ENTRY_NON_EXISTENT; - } - handleReadError(result); - return result; -} - -ReturnValue_t PoolRawAccess::handleReadOut(PoolEntryIF* read_out) { - ReturnValue_t result = RETURN_FAILED; - valid = read_out->getValid(); - if (read_out->getSize() > arrayEntry) { - arraySize = read_out->getSize(); - typeSize = read_out->getByteSize() / read_out->getSize(); - type = read_out->getType(); - if (typeSize <= sizeof(value)) { - uint16_t arrayPosition = arrayEntry * typeSize; - sizeTillEnd = read_out->getByteSize() - arrayPosition; - uint8_t* ptr = &((uint8_t*) read_out->getRawData())[arrayPosition]; - memcpy(value, ptr, typeSize); - return RETURN_OK; + valid = read_out->getValid(); + if (read_out->getSize() > arrayEntry) { + arraySize = read_out->getSize(); + typeSize = read_out->getByteSize() / read_out->getSize(); + type = read_out->getType(); + if (typeSize <= sizeof(value)) { + uint16_t arrayPosition = arrayEntry * typeSize; + sizeTillEnd = read_out->getByteSize() - arrayPosition; + uint8_t* ptr = + &((uint8_t*) read_out->getRawData())[arrayPosition]; + memcpy(value, ptr, typeSize); + return HasReturnvaluesIF::RETURN_OK; + } else { + //Error value type too large. + } } else { - result = READ_TYPE_TOO_LARGE; + //Error index requested too large } } else { - //debug << "PoolRawAccess: Size: " << (int)read_out->getSize() << std::endl; - result = READ_INDEX_TOO_LARGE; + //Error entry does not exist. } - return result; -} - -void PoolRawAccess::handleReadError(ReturnValue_t result) { sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId - << std::dec << " failed, "; - if(result == READ_TYPE_TOO_LARGE) { - sif::error << "type too large." << std::endl; - } - else if(result == READ_INDEX_TOO_LARGE) { - sif::error << "index too large." << std::endl; - } - else if(result == READ_ENTRY_NON_EXISTENT) { - sif::error << "entry does not exist." << std::endl; - } - + << std::dec << " failed." << std::endl; valid = INVALID; typeSize = 0; sizeTillEnd = 0; memset(value, 0, sizeof(value)); + return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t PoolRawAccess::commit() { @@ -111,32 +89,6 @@ ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, return HasReturnvaluesIF::RETURN_OK; } - -ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - if (typeSize + *size <= max_size) { - if (bigEndian) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - (*buffer)[count] = value[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(*buffer, value, typeSize); -#endif - } else { - memcpy(*buffer, value, typeSize); - } - *size += typeSize; - (*buffer) += typeSize; - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::BUFFER_TOO_SHORT; - } -} - - Type PoolRawAccess::getType() { return type; } @@ -193,6 +145,29 @@ uint16_t PoolRawAccess::getSizeTillEnd() const { return sizeTillEnd; } +ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const { + if (typeSize + *size <= max_size) { + if (bigEndian) { +#ifndef BYTE_ORDER_SYSTEM +#error BYTE_ORDER_SYSTEM not defined +#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + for (uint8_t count = 0; count < typeSize; count++) { + (*buffer)[count] = value[typeSize - count - 1]; + } +#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + memcpy(*buffer, value, typeSize); +#endif + } else { + memcpy(*buffer, value, typeSize); + } + *size += typeSize; + (*buffer) += typeSize; + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::BUFFER_TOO_SHORT; + } +} size_t PoolRawAccess::getSerializedSize() const { return typeSize; @@ -200,9 +175,8 @@ size_t PoolRawAccess::getSerializedSize() const { ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) { - // TODO: Needs to be tested!!! if (*size >= typeSize) { - *size -= typeSize; + if (bigEndian) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined @@ -213,14 +187,12 @@ ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, size_t* size, #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN memcpy(value, *buffer, typeSize); #endif - } - else { + } else { memcpy(value, *buffer, typeSize); } *buffer += typeSize; return HasReturnvaluesIF::RETURN_OK; - } - else { + } else { return SerializeIF::STREAM_TOO_SHORT; } } diff --git a/datapool/PoolRawAccess.h b/datapool/PoolRawAccess.h index b491d949..f32aac51 100644 --- a/datapool/PoolRawAccess.h +++ b/datapool/PoolRawAccess.h @@ -6,54 +6,83 @@ #include /** - * @brief This class allows accessing Data Pool variables as raw bytes. - * @details + * This class allows accessing Data Pool variables as raw bytes. * This is necessary to have an access method for HK data, as the PID's alone do not - * provide a type information. Please note that the the raw pool access read() and commit() - * calls are not thread-safe. - * Please supply a data set and use the data set read(), commit() calls for thread-safe - * data pool access. - * @ingroup data_pool + * provide a type information. + * \ingroup data_pool */ -class PoolRawAccess: public PoolVariableIF, HasReturnvaluesIF { +class PoolRawAccess: public PoolVariableIF { +private: + /** + * \brief To access the correct data pool entry on read and commit calls, the data pool id + * is stored. + */ + uint32_t dataPoolId; + /** + * \brief The array entry that is fetched from the data pool. + */ + uint8_t arrayEntry; + /** + * \brief The valid information as it was stored in the data pool is copied to this attribute. + */ + uint8_t valid; + /** + * \brief This value contains the type of the data pool entry. + */ + Type type; + /** + * \brief This value contains the size of the data pool entry in bytes. + */ + uint8_t typeSize; + /** + * The size of the DP array (single values return 1) + */ + uint8_t arraySize; + /** + * The size (in bytes) from the selected entry till the end of this DataPool variable. + */ + uint16_t sizeTillEnd; + /** + * \brief The information whether the class is read-write or read-only is stored here. + */ + ReadWriteMode_t readWriteMode; + static const uint8_t RAW_MAX_SIZE = sizeof(double); +protected: + /** + * \brief This is a call to read the value from the global data pool. + * \details When executed, this operation tries to fetch the pool entry with matching + * data pool id from the global data pool and copies the value and the valid + * information to its local attributes. In case of a failure (wrong type or + * pool id not found), the variable is set to zero and invalid. + * The operation does NOT provide any mutual exclusive protection by itself. + */ + ReturnValue_t read(); + /** + * \brief The commit call writes back the variable's value to the data pool. + * \details It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the valid flag is automatically set to "valid". + * The operation does NOT provide any mutual exclusive protection by itself. + * + */ + ReturnValue_t commit(); public: static const uint8_t INTERFACE_ID = CLASS_ID::POOL_RAW_ACCESS_CLASS; static const ReturnValue_t INCORRECT_SIZE = MAKE_RETURN_CODE(0x01); static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02); - static const ReturnValue_t READ_TYPE_TOO_LARGE = MAKE_RETURN_CODE(0x03); - static const ReturnValue_t READ_INDEX_TOO_LARGE = MAKE_RETURN_CODE(0x04); - static const ReturnValue_t READ_ENTRY_NON_EXISTENT = MAKE_RETURN_CODE(0x05); - static const uint8_t RAW_MAX_SIZE = sizeof(double); uint8_t value[RAW_MAX_SIZE]; - - /** - * This constructor is used to access a data pool entry with a - * given ID if the target type is not known. A DataSet object is supplied - * and the data pool entry with the given ID is registered to that data set. - * Please note that a pool raw access buffer only has a buffer - * with a size of double. As such, for vector entries which have - * @param data_pool_id Target data pool entry ID - * @param arrayEntry - * @param data_set Dataset to register data pool entry to - * @param setReadWriteMode - * @param registerVectors If set to true, the constructor checks if - * there are multiple vector entries to registers - * and registers all of them recursively into the data_set - * - */ PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry, DataSetIF* data_set, ReadWriteMode_t setReadWriteMode = - PoolVariableIF::VAR_READ); + PoolVariableIF::VAR_READ); /** * \brief The classes destructor is empty. If commit() was not called, the local value is * discarded and not written back to the data pool. */ ~PoolRawAccess(); - /** * \brief This operation returns a pointer to the entry fetched. - * \details Return pointer to the buffer containing the raw data - * Size and number of data can be retrieved by other means. + * \details This means, it does not return a pointer to byte "index", but to the start byte of + * array entry "index". Example: If the original data pool array consists of an double + * array of size four, getEntry(1) returns &(this->value[8]). */ uint8_t* getEntry(); /** @@ -71,19 +100,6 @@ public: */ ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size, uint32_t max_size); - - /** - * @brief Serialize raw pool entry into provided buffer directly - * @param buffer Provided buffer. Raw pool data will be copied here - * @param size [out] Increment provided size value by serialized size - * @param max_size Maximum allowed serialization size - * @param bigEndian Specify endianess - * @return - @c RETURN_OK if serialization was successfull - * - @c SerializeIF::BUFFER_TOO_SHORT if range check failed - */ - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const; - /** * With this method, the content can be set from a big endian buffer safely. * @param buffer Pointer to the data to set @@ -125,73 +141,13 @@ public: */ uint16_t getSizeTillEnd() const; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const; + size_t getSerializedSize() const; ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian); - -protected: - /** - * \brief This is a call to read the value from the global data pool. - * \details When executed, this operation tries to fetch the pool entry with matching - * data pool id from the global data pool and copies the value and the valid - * information to its local attributes. In case of a failure (wrong type or - * pool id not found), the variable is set to zero and invalid. - * The operation does NOT provide any mutual exclusive protection by itself ! - * If reading from the data pool without information about the type is desired, - * initialize the raw pool access by supplying a data set and using the data set - * read function, which calls this read function. - * @return -@c RETURN_OK Read successfull - * -@c READ_TYPE_TOO_LARGE - * -@c READ_INDEX_TOO_LARGE - * -@c READ_ENTRY_NON_EXISTENT - */ - ReturnValue_t read(); - /** - * \brief The commit call writes back the variable's value to the data pool. - * \details It checks type and size, as well as if the variable is writable. If so, - * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. - * - */ - ReturnValue_t commit(); - - ReturnValue_t handleReadOut(PoolEntryIF* read_out); - void handleReadError(ReturnValue_t result); -private: - /** - * \brief To access the correct data pool entry on read and commit calls, the data pool id - * is stored. - */ - uint32_t dataPoolId; - /** - * \brief The array entry that is fetched from the data pool. - */ - uint8_t arrayEntry; - /** - * \brief The valid information as it was stored in the data pool is copied to this attribute. - */ - uint8_t valid; - /** - * \brief This value contains the type of the data pool entry. - */ - Type type; - /** - * \brief This value contains the size of the data pool entry type in bytes. - */ - uint8_t typeSize; - /** - * The size of the DP array (single values return 1) - */ - uint8_t arraySize; - /** - * The size (in bytes) from the selected entry till the end of this DataPool variable. - */ - uint16_t sizeTillEnd; - /** - * \brief The information whether the class is read-write or read-only is stored here. - */ - ReadWriteMode_t readWriteMode; }; #endif /* POOLRAWACCESS_H_ */ diff --git a/datapool/PoolRawAccessHelper.cpp b/datapool/PoolRawAccessHelper.cpp index 91d6309f..cf02b20a 100644 --- a/datapool/PoolRawAccessHelper.cpp +++ b/datapool/PoolRawAccessHelper.cpp @@ -9,7 +9,7 @@ #include -#include +#include PoolRawAccessHelper::PoolRawAccessHelper(uint32_t * poolIdBuffer_, uint8_t numberOfParameters_): @@ -97,7 +97,7 @@ ReturnValue_t PoolRawAccessHelper::handlePoolEntrySerialization( // << std::hex << currentPoolId << std::endl; while(not poolEntrySerialized) { - if(counter > DataSet::DATA_SET_MAX_SIZE) { + if(counter > GlobDataSet::DATA_SET_MAX_SIZE) { sif::error << "PoolRawAccessHelper: Config error, " "max. number of possible data set variables exceeded" << std::endl; @@ -105,7 +105,7 @@ ReturnValue_t PoolRawAccessHelper::handlePoolEntrySerialization( } counter ++; - DataSet currentDataSet = DataSet(); + GlobDataSet currentDataSet; //debug << "Current array position: " << (int)arrayPosition << std::endl; PoolRawAccess currentPoolRawAccess(currentPoolId,arrayPosition, ¤tDataSet,PoolVariableIF::VAR_READ); diff --git a/datapool/PoolRawAccessHelper.h b/datapool/PoolRawAccessHelper.h index 61d79731..ab881a5f 100644 --- a/datapool/PoolRawAccessHelper.h +++ b/datapool/PoolRawAccessHelper.h @@ -8,7 +8,7 @@ #define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ #include -#include +#include /** * @brief This helper function simplifies accessing data pool entries diff --git a/datapool/PoolVarList.h b/datapool/PoolVarList.h index 90c9f178..9d6bc461 100644 --- a/datapool/PoolVarList.h +++ b/datapool/PoolVarList.h @@ -1,12 +1,12 @@ #ifndef POOLVARLIST_H_ #define POOLVARLIST_H_ -#include #include +#include template class PoolVarList { private: - PoolVariable variables[n_var]; + GlobPoolVar variables[n_var]; public: PoolVarList( const uint32_t set_id[n_var], DataSetIF* dataSet, PoolVariableIF::ReadWriteMode_t setReadWriteMode ) { //I really should have a look at the new init list c++ syntax. @@ -20,7 +20,7 @@ public: } } - PoolVariable &operator [](int i) { return variables[i]; } + GlobPoolVar &operator [](int i) { return variables[i]; } }; diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 7626c9c1..9935ef75 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -1,71 +1,70 @@ -/* - * \file PoolVariableIF.h - * - * \brief This file contains the interface definition for pool variables. - * - * \date 10/17/2012 - * - * \author Bastian Baetz - */ - #ifndef POOLVARIABLEIF_H_ #define POOLVARIABLEIF_H_ #include #include + /** - * \brief This interface is used to control local data pool variable representations. - * - * \details To securely handle data pool variables, all pool entries are locally managed by - * data pool variable access classes, which are called pool variables. To ensure a - * common state of a set of variables needed in a function, these local pool variables - * again are managed by other classes, e.g. the DataSet. This interface provides unified - * access to local pool variables for such manager classes. - * \ingroup data_pool + * @brief This interface is used to control data pool variable representations. + * @details + * To securely handle data pool variables, all pool entries are locally + * managed by data pool variable access classes, which are called pool + * variables. To ensure a common state of a set of variables needed in a + * function, these local pool variables again are managed by other classes, + * like the DataSet classes. This interface provides unified access to + * local pool variables for such manager classes. + * @author Bastian Baetz + * @ingroup data_pool */ class PoolVariableIF : public SerializeIF { - friend class DataSet; + friend class GlobDataSet; + friend class LocalDataSet; protected: /** - * \brief The commit call shall write back a newly calculated local value to the data pool. + * @brief The commit call shall write back a newly calculated local + * value to the data pool. */ virtual ReturnValue_t commit() = 0; /** - * \brief The read call shall read the value of this parameter from the data pool and store - * the content locally. + * @brief The read call shall read the value of this parameter from + * the data pool and store the content locally. */ virtual ReturnValue_t read() = 0; public: - static const uint8_t VALID = 1; - static const uint8_t INVALID = 0; - static const uint32_t NO_PARAMETER = 0; + static constexpr bool VALID = 1; + static constexpr bool INVALID = 0; + static constexpr uint32_t NO_PARAMETER = 0; + enum ReadWriteMode_t { VAR_READ, VAR_WRITE, VAR_READ_WRITE }; /** - * \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. + * @brief This is an empty virtual destructor, + * as it is proposed for C++ interfaces. */ - virtual ~PoolVariableIF() { - } + virtual ~PoolVariableIF() {} /** - * \brief This method returns if the variable is write-only, read-write or read-only. + * @brief This method returns if the variable is write-only, read-write or read-only. */ virtual ReadWriteMode_t getReadWriteMode() const = 0; /** - * \brief This operation shall return the data pool id of the variable. + * @brief This operation shall return the data pool id of the variable. */ virtual uint32_t getDataPoolId() const = 0; /** - * \brief With this call, the valid information of the variable is returned. + * @brief With this call, the valid information of the variable is returned. */ virtual bool isValid() const = 0; /** - * \brief With this call, the valid information of the variable is set. + * @brief With this call, the valid information of the variable is set. */ + // why not just use a boolean here? virtual void setValid(uint8_t validity) = 0; }; +using pool_rwm_t = PoolVariableIF::ReadWriteMode_t; + #endif /* POOLVARIABLEIF_H_ */ diff --git a/datapool/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp similarity index 96% rename from datapool/DataPoolAdmin.cpp rename to datapoolglob/DataPoolAdmin.cpp index 25013726..59bd9f30 100644 --- a/datapool/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -1,7 +1,5 @@ -#include -#include -#include -#include +#include +#include #include #include #include @@ -26,7 +24,7 @@ MessageQueueId_t DataPoolAdmin::getCommandQueue() const { } ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { if (actionId != SET_VALIDITY) { return INVALID_ACTION_ID; } @@ -42,7 +40,7 @@ ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, uint32_t poolId = ::dataPool.PIDToDataPoolId(address); - DataSet mySet; + GlobDataSet mySet; PoolRawAccess variable(poolId, 0, &mySet, PoolVariableIF::VAR_READ_WRITE); ReturnValue_t status = mySet.read(); if (status != RETURN_OK) { @@ -94,7 +92,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, const uint8_t* data, uint32_t size, uint8_t** dataPointer) { uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); - DataSet testSet; + GlobDataSet testSet; PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet, PoolVariableIF::VAR_READ); ReturnValue_t status = testSet.read(); @@ -113,7 +111,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, const uint8_t* readPosition = data; for (; size > 0; size -= typeSize) { - DataSet rawSet; + GlobDataSet rawSet; PoolRawAccess variable(poolId, arrayIndex, &rawSet, PoolVariableIF::VAR_READ_WRITE); status = rawSet.read(); @@ -133,7 +131,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, uint8_t** dataPointer, uint8_t* copyHere) { uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); - DataSet testSet; + GlobDataSet testSet; PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet, PoolVariableIF::VAR_READ); ReturnValue_t status = testSet.read(); @@ -146,7 +144,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, } uint8_t* ptrToCopy = copyHere; for (; size > 0; size -= typeSize) { - DataSet rawSet; + GlobDataSet rawSet; PoolRawAccess variable(poolId, arrayIndex, &rawSet, PoolVariableIF::VAR_READ); status = rawSet.read(); diff --git a/datapool/DataPoolAdmin.h b/datapoolglob/DataPoolAdmin.h similarity index 90% rename from datapool/DataPoolAdmin.h rename to datapoolglob/DataPoolAdmin.h index dffcd462..5f995893 100644 --- a/datapool/DataPoolAdmin.h +++ b/datapoolglob/DataPoolAdmin.h @@ -1,15 +1,16 @@ #ifndef DATAPOOLADMIN_H_ #define DATAPOOLADMIN_H_ -#include -#include -#include #include #include #include -#include -#include +#include #include +#include + +#include +#include +#include class DataPoolAdmin: public HasActionsIF, public ExecutableObjectIF, @@ -33,8 +34,8 @@ public: ReturnValue_t handleMemoryDump(uint32_t address, uint32_t size, uint8_t** dataPointer, uint8_t* copyHere); - virtual ReturnValue_t executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size); + ReturnValue_t executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size); //not implemented as ParameterHelper is no used ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, diff --git a/datapool/DataPoolParameterWrapper.cpp b/datapoolglob/DataPoolParameterWrapper.cpp similarity index 96% rename from datapool/DataPoolParameterWrapper.cpp rename to datapoolglob/DataPoolParameterWrapper.cpp index 11399fb6..d93cd88e 100644 --- a/datapool/DataPoolParameterWrapper.cpp +++ b/datapoolglob/DataPoolParameterWrapper.cpp @@ -1,10 +1,8 @@ -#include "DataPoolParameterWrapper.h" - -//for returncodes +#include +#include +#include #include -#include -#include DataPoolParameterWrapper::DataPoolParameterWrapper() : type(Type::UNKNOWN_TYPE), rows(0), columns(0), poolId( @@ -20,7 +18,7 @@ ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId, uint16_t parameterId) { poolId = (domainId << 16) + parameterId; - DataSet mySet; + GlobDataSet mySet; PoolRawAccess raw(poolId, 0, &mySet, PoolVariableIF::VAR_READ); ReturnValue_t status = mySet.read(); if (status != HasReturnvaluesIF::RETURN_OK) { @@ -57,7 +55,7 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, } for (uint8_t index = 0; index < rows; index++){ - DataSet mySet; + GlobDataSet mySet; PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ); mySet.read(); result = raw.serialize(buffer,size,max_size,bigEndian); @@ -94,7 +92,7 @@ ReturnValue_t DataPoolParameterWrapper::deSerializeData(uint8_t startingRow, for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { - DataSet mySet; + GlobDataSet mySet; PoolRawAccess raw(poolId, startingRow + fromRow, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); diff --git a/datapool/DataPoolParameterWrapper.h b/datapoolglob/DataPoolParameterWrapper.h similarity index 100% rename from datapool/DataPoolParameterWrapper.h rename to datapoolglob/DataPoolParameterWrapper.h diff --git a/datapoolglob/GlobalDataPool.cpp b/datapoolglob/GlobalDataPool.cpp new file mode 100644 index 00000000..e13765ba --- /dev/null +++ b/datapoolglob/GlobalDataPool.cpp @@ -0,0 +1,132 @@ +#include +#include +#include + +GlobalDataPool::GlobalDataPool( + void(*initFunction)(GlobPoolMap* pool_map)) { + mutex = MutexFactory::instance()->createMutex(); + if (initFunction != NULL ) { + initFunction( &this->globDataPool ); + } +} + +GlobalDataPool::~GlobalDataPool() { + MutexFactory::instance()->deleteMutex(mutex); + for(GlobPoolMapIter it = this->globDataPool.begin(); + it != this->globDataPool.end(); ++it ) + { + delete it->second; + } +} + +// The function checks PID, type and array length before returning a copy of +// the PoolEntry. In failure case, it returns a temp-Entry with size 0 and NULL-ptr. +template PoolEntry* GlobalDataPool::getData( uint32_t data_pool_id, + uint8_t sizeOrPosition ) { + GlobPoolMapIter it = this->globDataPool.find( data_pool_id ); + if ( it != this->globDataPool.end() ) { + PoolEntry* entry = dynamic_cast< PoolEntry* >( it->second ); + if (entry != nullptr ) { + if ( sizeOrPosition <= entry->length ) { + return entry; + } + } + } + return nullptr; +} + +PoolEntryIF* GlobalDataPool::getRawData( uint32_t data_pool_id ) { + GlobPoolMapIter it = this->globDataPool.find( data_pool_id ); + if ( it != this->globDataPool.end() ) { + return it->second; + } else { + return nullptr; + } +} + +ReturnValue_t GlobalDataPool::freeDataPoolLock() { + ReturnValue_t status = mutex->unlockMutex(); + if ( status != RETURN_OK ) { + sif::error << "DataPool::DataPool: unlock of mutex failed with" + " error code: " << status << std::endl; + } + return status; +} + +ReturnValue_t GlobalDataPool::lockDataPool() { + ReturnValue_t status = mutex->lockMutex(MutexIF::NO_TIMEOUT); + if ( status != RETURN_OK ) { + sif::error << "DataPool::DataPool: lock of mutex failed " + "with error code: " << status << std::endl; + } + return status; +} + +void GlobalDataPool::print() { + sif::debug << "DataPool contains: " << std::endl; + std::map::iterator dataPoolIt; + dataPoolIt = this->globDataPool.begin(); + while( dataPoolIt != this->globDataPool.end() ) { + sif::debug << std::hex << dataPoolIt->first << std::dec << " |"; + dataPoolIt->second->print(); + dataPoolIt++; + } +} + +uint32_t GlobalDataPool::PIDToDataPoolId(uint32_t parameter_id) { + return (parameter_id >> 8) & 0x00FFFFFF; +} + +uint8_t GlobalDataPool::PIDToArrayIndex(uint32_t parameter_id) { + return (parameter_id & 0x000000FF); +} + +uint32_t GlobalDataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) { + return (poolId << 8) + index; +} + + +//SHOULDDO: Do we need a mutex lock here... I don't think so, +//as we only check static const values of elements in a list that do not change. +//there is no guarantee in the standard, but it seems to me that the implementation is safe -UM +ReturnValue_t GlobalDataPool::getType(uint32_t parameter_id, Type* type) { + GlobPoolMapIter it = this->globDataPool.find( PIDToDataPoolId(parameter_id)); + if ( it != this->globDataPool.end() ) { + *type = it->second->getType(); + return RETURN_OK; + } else { + *type = Type::UNKNOWN_TYPE; + return RETURN_FAILED; + } +} + +bool GlobalDataPool::exists(uint32_t parameterId) { + uint32_t poolId = PIDToDataPoolId(parameterId); + uint32_t index = PIDToArrayIndex(parameterId); + GlobPoolMapIter it = this->globDataPool.find( poolId ); + if (it != globDataPool.end()) { + if (it->second->getSize() >= index) { + return true; + } + } + return false; +} + +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size ); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size ); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size ); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size ); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size ); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size ); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size ); +template PoolEntry* GlobalDataPool::getData( + uint32_t data_pool_id, uint8_t size); diff --git a/datapoolglob/GlobalDataPool.h b/datapoolglob/GlobalDataPool.h new file mode 100644 index 00000000..e0c086ad --- /dev/null +++ b/datapoolglob/GlobalDataPool.h @@ -0,0 +1,146 @@ +#ifndef GLOBALDATAPOOL_H_ +#define GLOBALDATAPOOL_H_ + +#include +#include +#include +#include + +/** + * @defgroup data_pool Global data pool + * This is the group, where all classes associated with global + * data pool handling belong to. + * This includes classes to access Data Pool variables. + */ + +/** + * Typedefs for the global pool representations + */ +using GlobPoolMap = std::map; +using GlobPoolMapIter = GlobPoolMap::iterator; + +/** + * @brief This class represents the OBSW global data-pool. + * + * @details + * All variables are registered and space is allocated in an initialization + * function, which is passed do the constructor. Space for the variables is + * allocated on the heap (with a new call). + * + * The data is found by a data pool id, which uniquely represents a variable. + * Data pool variables should be used with a blackboard logic in mind, + * which means read data is valid (if flagged so), + * but not necessarily up-to-date. + * + * Variables are either single values or arrays. + * @author Bastian Baetz + * @ingroup data_pool + */ +class GlobalDataPool : public HasReturnvaluesIF { +private: + /** + * @brief This is the actual data pool itself. + * @details It is represented by a map with the data pool id as index + * and a pointer to a single PoolEntry as value. + */ + GlobPoolMap globDataPool; + + /** + * @brief The mutex is created in the constructor and makes + * access mutual exclusive. + * @details Locking and unlocking the pool is only done by the DataSet class. + */ + MutexIF* mutex; +public: + /** + * @brief In the classes constructor, + * the passed initialization function is called. + * @details + * To enable filling the pool, a pointer to the map is passed, + * allowing direct access to the pool's content. + * On runtime, adding or removing variables is forbidden. + */ + GlobalDataPool( void ( *initFunction )( GlobPoolMap* pool_map ) ); + + /** + * @brief The destructor iterates through the data_pool map and + * calls all entries destructors to clean up the heap. + */ + ~GlobalDataPool(); + + /** + * @brief This is the default call to access the pool. + * @details + * A pointer to the PoolEntry object is returned. + * The call checks data pool id, type and array size. + * Returns NULL in case of failure. + * @param data_pool_id The data pool id to search. + * @param sizeOrPosition The array size (not byte size!) of the pool entry, + * or the position the user wants to read. + * If smaller than the entry size, everything's ok. + */ + template PoolEntry* getData( uint32_t data_pool_id, + uint8_t sizeOrPosition ); + + /** + * @brief An alternative call to get a data pool entry in case the type is not implicitly known + * (i.e. in Housekeeping Telemetry). + * @details It returns a basic interface and does NOT perform + * a size check. The caller has to assure he does not copy too much data. + * Returns NULL in case the entry is not found. + * @param data_pool_id The data pool id to search. + */ + PoolEntryIF* getRawData( uint32_t data_pool_id ); + /** + * @brief This is a small helper function to facilitate locking the global data pool. + * @details It fetches the pool's mutex id and tries to acquire the mutex. + */ + ReturnValue_t lockDataPool(); + /** + * @brief This is a small helper function to facilitate unlocking the global data pool. + * @details It fetches the pool's mutex id and tries to free the mutex. + */ + ReturnValue_t freeDataPoolLock(); + /** + * @brief The print call is a simple debug method. + * @details It prints the current content of the data pool. + * It iterates through the data_pool map and calls each entry's print() method. + */ + void print(); + /** + * Extracts the data pool id from a SCOS 2000 PID. + * @param parameter_id The passed Parameter ID. + * @return The data pool id as used within the OBSW. + */ + static uint32_t PIDToDataPoolId( uint32_t parameter_id ); + /** + * Extracts an array index out of a SCOS 2000 PID. + * @param parameter_id The passed Parameter ID. + * @return The index of the corresponding data pool entry. + */ + static uint8_t PIDToArrayIndex( uint32_t parameter_id ); + /** + * Retransforms a data pool id and an array index to a SCOS 2000 PID. + */ + static uint32_t poolIdAndPositionToPid( uint32_t poolId, uint8_t index ); + + /** + * Method to return the type of a pool variable. + * @param parameter_id A parameterID (not pool id) of a DP member. + * @param type Returns the type or TYPE::UNKNOWN_TYPE + * @return RETURN_OK if parameter exists, RETURN_FAILED else. + */ + ReturnValue_t getType( uint32_t parameter_id, Type* type ); + + /** + * Method to check if a PID exists. Does not lock, as there's no + * possibility to alter the list that is checked during run-time. + * @param parameterId The PID (not pool id!) of a parameter. + * @return true if exists, false else. + */ + bool exists(uint32_t parameterId); +}; + +//We assume someone globally instantiates a DataPool. +extern GlobalDataPool dataPool; +#endif /* DATAPOOL_H_ */ diff --git a/datapoolglob/GlobalDataSet.cpp b/datapoolglob/GlobalDataSet.cpp new file mode 100644 index 00000000..7409dbbd --- /dev/null +++ b/datapoolglob/GlobalDataSet.cpp @@ -0,0 +1,166 @@ +#include +#include +#include + +GlobDataSet::GlobDataSet() : + fill_count(0), state(DATA_SET_UNINITIALISED) { + for (unsigned count = 0; count < DATA_SET_MAX_SIZE; count++) { + registeredVariables[count] = nullptr; + } +} + +GlobDataSet::~GlobDataSet() { + //Don't do anything with your variables, they are dead already! + // (Destructor is already called) +} + +ReturnValue_t GlobDataSet::registerVariable(PoolVariableIF* variable) { + if (state != DATA_SET_UNINITIALISED) { + sif::error << "DataSet::registerVariable: Call made in wrong position." << std::endl; + return DATA_SET_UNINITIALISED; + } + if (variable == nullptr) { + sif::error << "DataSet::registerVariable: Pool variable is nullptr." << std::endl; + return POOL_VAR_NULL; + } + if (fill_count >= DATA_SET_MAX_SIZE) { + sif::error << "DataSet::registerVariable: DataSet is full." << std::endl; + return DATA_SET_FULL; + } + registeredVariables[fill_count] = variable; + fill_count++; + return RETURN_OK; +} + +ReturnValue_t GlobDataSet::read() { + ReturnValue_t result = RETURN_OK; + if (state == DATA_SET_UNINITIALISED) { + lockDataPool(); + for (uint16_t count = 0; count < fill_count; count++) { + if (registeredVariables[count]->getReadWriteMode() + != PoolVariableIF::VAR_WRITE + && registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + ReturnValue_t status = registeredVariables[count]->read(); + if (status != RETURN_OK) { + result = INVALID_PARAMETER_DEFINITION; + break; + } + } + } + state = DATA_SET_WAS_READ; + unlockDataPool(); + } else { + sif::error << "DataSet::read(): Call made in wrong position." << std::endl; + result = SET_WAS_ALREADY_READ; + } + return result; +} + +ReturnValue_t GlobDataSet::commit(bool valid) { + setEntriesValid(valid); + setSetValid(valid); + return commit(); +} + +ReturnValue_t GlobDataSet::commit() { + if (state == DATA_SET_WAS_READ) { + handleAlreadyReadDatasetCommit(); + return RETURN_OK; + } + else { + return handleUnreadDatasetCommit(); + } +} + +void GlobDataSet::handleAlreadyReadDatasetCommit() { + lockDataPool(); + for (uint16_t count = 0; count < fill_count; count++) { + if (registeredVariables[count]->getReadWriteMode() + != PoolVariableIF::VAR_READ + && registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + registeredVariables[count]->commit(); + } + } + state = DATA_SET_UNINITIALISED; + unlockDataPool(); +} + +ReturnValue_t GlobDataSet::handleUnreadDatasetCommit() { + ReturnValue_t result = RETURN_OK; + lockDataPool(); + for (uint16_t count = 0; count < fill_count; count++) { + if (registeredVariables[count]->getReadWriteMode() + == PoolVariableIF::VAR_WRITE + && registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + registeredVariables[count]->commit(); + } else if (registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + if (result != COMMITING_WITHOUT_READING) { + sif::error << "DataSet::commit(): commit-without-read call made " + "with non write-only variable." << std::endl; + result = COMMITING_WITHOUT_READING; + } + } + } + state = DATA_SET_UNINITIALISED; + unlockDataPool(); + return result; +} + +ReturnValue_t GlobDataSet::unlockDataPool() { + return ::dataPool.freeDataPoolLock(); +} + +ReturnValue_t GlobDataSet::lockDataPool() { + return ::dataPool.lockDataPool(); +} + +ReturnValue_t GlobDataSet::serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const { + ReturnValue_t result = RETURN_FAILED; + for (uint16_t count = 0; count < fill_count; count++) { + result = registeredVariables[count]->serialize(buffer, size, max_size, + bigEndian); + if (result != RETURN_OK) { + return result; + } + } + return result; +} + +size_t GlobDataSet::getSerializedSize() const { + uint32_t size = 0; + for (uint16_t count = 0; count < fill_count; count++) { + size += registeredVariables[count]->getSerializedSize(); + } + return size; +} + +void GlobDataSet::setEntriesValid(bool valid) { + for (uint16_t count = 0; count < fill_count; count++) { + if (registeredVariables[count]->getReadWriteMode() + != PoolVariableIF::VAR_READ) { + registeredVariables[count]->setValid(valid); + } + } +} + +void GlobDataSet::setSetValid(bool valid) { + this->valid = valid; +} + +ReturnValue_t GlobDataSet::deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) { + ReturnValue_t result = RETURN_FAILED; + for (uint16_t count = 0; count < fill_count; count++) { + result = registeredVariables[count]->deSerialize(buffer, size, + bigEndian); + if (result != RETURN_OK) { + return result; + } + } + return result; +} diff --git a/datapoolglob/GlobalDataSet.h b/datapoolglob/GlobalDataSet.h new file mode 100644 index 00000000..365de380 --- /dev/null +++ b/datapoolglob/GlobalDataSet.h @@ -0,0 +1,185 @@ +#ifndef DATASET_H_ +#define DATASET_H_ + +#include +#include +#include + +#include +/** + * @brief The DataSet class manages a set of locally checked out variables + * for the global data pool. + * + * @details + * This class manages a list, where a set of local variables (or pool variables) + * are registered. They are checked-out (i.e. their values are looked + * up and copied) with the read call. After the user finishes working with the + * pool variables, he can write back all variable values to the pool with + * the commit call. The data set manages locking and freeing the data pool, + * to ensure that all values are read and written back at once. + * + * An internal state manages usage of this class. Variables may only be + * registered before the read call is made, and the commit call only + * after the read call. + * + * If pool variables are writable and not committed until destruction + * of the set, the DataSet class automatically sets the valid flag in the + * data pool to invalid (without) changing the variable's value. + * @author Bastian Baetz + * @ingroup data_pool + */ +class GlobDataSet: public DataSetIF, public HasReturnvaluesIF, public SerializeIF { +public: + //SHOULDDO we could use a linked list of datapool variables + //!< This definition sets the maximum number of variables to + //! register in one DataSet. + static const uint8_t DATA_SET_MAX_SIZE = 63; + + + static constexpr uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS; + static constexpr ReturnValue_t INVALID_PARAMETER_DEFINITION = + MAKE_RETURN_CODE( 0x01 ); + static constexpr ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 ); + static constexpr ReturnValue_t COMMITING_WITHOUT_READING = + MAKE_RETURN_CODE(0x03); + + static constexpr ReturnValue_t DATA_SET_UNINITIALIZED = MAKE_RETURN_CODE( 0x04 ); + static constexpr ReturnValue_t DATA_SET_FULL = MAKE_RETURN_CODE( 0x05 ); + static constexpr ReturnValue_t POOL_VAR_NULL = MAKE_RETURN_CODE( 0x06 ); + /** + * @brief The constructor simply sets the fill_count to zero and sets + * the state to "uninitialized". + */ + GlobDataSet(); + + /** + * @brief This operation is used to register the local variables in the set. + * @details It stores the pool variable pointer in a variable list. + */ + ReturnValue_t registerVariable(PoolVariableIF* variable) override; + + /** + * @brief The destructor automatically manages writing the valid + * information of variables. + * @details + * In case the data set was read out, but not committed(indicated by state), + * the destructor parses all variables that are still registered to the set. + * For each, the valid flag in the data pool is set to "invalid". + */ + ~GlobDataSet(); + /** + * @brief The read call initializes reading out all registered variables. + * @details + * It iterates through the list of registered variables and calls all read() + * functions of the registered pool variables (which read out their values + * from the data pool) which are not write-only. + * In case of an error (e.g. a wrong data type, or an invalid data pool id), + * 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. + * @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 SET_WAS_ALREADY_READ if read() is called twice without calling + * commit() in between + */ + ReturnValue_t read(); + /** + * @brief The commit call initializes writing back the registered variables. + * @details + * It iterates through the list of registered variables and calls the + * commit() method of the remaining registered variables (which write back + * their values to the pool). + * + * The data pool is locked during the whole commit operation and + * freed afterwards. The state changes to "was committed" after this operation. + * + * 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. + * @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 + */ + ReturnValue_t commit(void); + /** + * Variant of method above which sets validity of all elements of the set. + * @param valid Validity information from PoolVariableIF. + * @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 + */ + ReturnValue_t commit(bool valid); + + /** + * Set all entries + * @param valid + */ + void setSetValid(bool valid); + + /** + * Set the valid information of all variables contained in the set which + * are not read-only + * + * @param valid Validity information from PoolVariableIF. + */ + void setEntriesValid(bool valid); + + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const override; + + size_t getSerializedSize() const override; + + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) override; +private: + + /** + * @brief This array represents all pool variables registered in this set. + */ + PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE]; + /** + * \brief The fill_count attribute ensures that the variables register in the correct array + * position and that the maximum number of variables is not exceeded. + */ + uint16_t fill_count; + /** + * States of the seet. + */ + enum States { + DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED + DATA_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; + + /** + * If the valid state of a dataset is always relevant to the whole + * data set we can use this flag. + */ + bool valid = false; + /** + * @brief This is a small helper function to facilitate locking + * the underlying data data pool structure + * @details + * It makes use of the lockDataPool method offered by the DataPool class. + */ + ReturnValue_t lockDataPool() override; + + /** + * @brief This is a small helper function to facilitate + * unlocking the underlying data data pool structure + * @details + * It makes use of the freeDataPoolLock method offered by the DataPool class. + */ + ReturnValue_t unlockDataPool() override; + + void handleAlreadyReadDatasetCommit(); + ReturnValue_t handleUnreadDatasetCommit(); +}; + +#endif /* DATASET_H_ */ diff --git a/datapoolglob/GlobalPoolVariable.h b/datapoolglob/GlobalPoolVariable.h new file mode 100644 index 00000000..9f80492b --- /dev/null +++ b/datapoolglob/GlobalPoolVariable.h @@ -0,0 +1,189 @@ +#ifndef POOLVARIABLE_H_ +#define POOLVARIABLE_H_ + +#include +#include +#include +#include +#include +#include + +template class PoolVarList; + + +/** + * @brief This is the access class for non-array data pool entries. + * + * @details + * To ensure safe usage of the data pool, operation is not done directly + * on the data pool entries, but on local copies. This class provides simple + * type-safe access to single data pool entries (i.e. entries with length = 1). + * The class can be instantiated as read-write and read only. + * It provides a commit-and-roll-back semantic, which means that the + * variable's value in the data pool is not changed until the + * commit call is executed. + * @tparam T The template parameter sets the type of the variable. + * Currently, all plain data types are supported, but in principle + * any type is possible. + * @ingroup data_pool + */ +template +class GlobPoolVar: public PoolVariableIF { + template friend class PoolVarList; + static_assert(not std::is_same::value, + "Do not use boolean for the PoolEntry type, use uint8_t instead!" + "Warum? Darum :-)"); +public: + /** + * @brief In the constructor, the variable can register itself in a + * DataSet (if nullptr is not passed). + * @details + * It DOES NOT fetch the current value from the data pool, but + * sets the value attribute to default (0). + * The value is fetched within the read() operation. + * @param set_id This is the id in the global data pool + * this instance of the access class corresponds to. + * @param dataSet The data set in which the variable shall register + * itself. If NULL, the variable is not registered. + * @param setWritable If this flag is set to true, changes in the value + * attribute can be written back to the data pool, otherwise not. + */ + GlobPoolVar(uint32_t set_id, DataSetIF* dataSet, + ReadWriteMode_t setReadWriteMode); + + /** + * @brief This is the local copy of the data pool entry. + * @details The user can work on this attribute + * just like he would on a simple local variable. + */ + T value = 0; + + /** + * @brief Copy ctor to copy classes containing Pool Variables. + * (Robin): This only copies member variables, which is done + * by the default copy ctor. maybe we can ommit this ctor? + */ + GlobPoolVar(const GlobPoolVar& rhs); + + /** + * @brief The classes destructor is empty. + * @details If commit() was not called, the local value is + * discarded and not written back to the data pool. + */ + ~GlobPoolVar() {} + +protected: + /** + * @brief To access the correct data pool entry on read and commit calls, + * the data pool is stored. + */ + uint32_t dataPoolId; + + /** + * @brief The valid information as it was stored in the data pool is + * copied to this attribute. + */ + uint8_t valid; + + /** + * @brief The information whether the class is read-write or read-only + * is stored here. + */ + pool_rwm_t readWriteMode; + + /** + * @brief This is a call to read the value from the global data pool. + * @details + * When executed, this operation tries to fetch the pool entry with matching + * data pool id from the global data pool and copies the value and the valid + * information to its local attributes. In case of a failure (wrong type or + * pool id not found), the variable is set to zero and invalid. + * The operation does NOT provide any mutual exclusive protection by itself. + */ + ReturnValue_t read() override; + + /** + * @brief The commit call writes back the variable's value to the data pool. + * @details It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the valid flag is automatically set to "valid". + * The operation does NOT provide any mutual exclusive protection by itself. + * + */ + ReturnValue_t commit() override; + + /** + * Empty ctor for List initialization + */ + GlobPoolVar(); +public: + /** + * \brief This operation returns the data pool id of the variable. + */ + uint32_t getDataPoolId() const override; + + /** + * This method returns if the variable is write-only, read-write or read-only. + */ + ReadWriteMode_t getReadWriteMode() const override; + /** + * This operation sets the data pool id of the variable. + * The method is necessary to set id's of data pool member variables with bad initialization. + */ + void setDataPoolId(uint32_t poolId); + + /** + * \brief With this call, the valid information of the variable is returned. + */ + bool isValid() const override; + + uint8_t getValid(); + + void setValid(uint8_t valid); + + operator T() { + return value; + } + + operator T() const { + return value; + } + + GlobPoolVar &operator=(T newValue) { + value = newValue; + return *this; + } + + GlobPoolVar &operator=(GlobPoolVar newPoolVariable) { + value = newPoolVariable.value; + return *this; + } + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const override { + return SerializeAdapter::serialize(&value, buffer, size, max_size, + bigEndian); + } + + virtual size_t getSerializedSize() const { + return SerializeAdapter::getSerializedSize(&value); + } + + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) { + return SerializeAdapter::deSerialize(&value, buffer, size, bigEndian); + } +}; + +#include + +typedef GlobPoolVar gp_bool_t; +typedef GlobPoolVar gp_uint8_t; +typedef GlobPoolVar gp_uint16_t; +typedef GlobPoolVar gp_uint32_t; +typedef GlobPoolVar gp_int8_t; +typedef GlobPoolVar gp_int16_t; +typedef GlobPoolVar gp_int32_t; +typedef GlobPoolVar gp_float_t; +typedef GlobPoolVar gp_double_t; + +#endif /* POOLVARIABLE_H_ */ diff --git a/datapoolglob/GlobalPoolVariable.tpp b/datapoolglob/GlobalPoolVariable.tpp new file mode 100644 index 00000000..287f06dd --- /dev/null +++ b/datapoolglob/GlobalPoolVariable.tpp @@ -0,0 +1,84 @@ +#pragma once + +template +inline GlobPoolVar::GlobPoolVar(uint32_t set_id, + DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode): + dataPoolId(set_id), valid(PoolVariableIF::INVALID), + readWriteMode(setReadWriteMode) +{ + if (dataSet != nullptr) { + dataSet->registerVariable(this); + } +} + +template +inline ReturnValue_t GlobPoolVar::read() { + PoolEntry* read_out = ::dataPool.getData(dataPoolId, 1); + if (read_out != NULL) { + valid = read_out->valid; + value = *(read_out->address); + return HasReturnvaluesIF::RETURN_OK; + } else { + value = 0; + valid = false; + sif::error << "PoolVariable: read of DP Variable 0x" << std::hex + << dataPoolId << std::dec << " failed." << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +template +inline ReturnValue_t GlobPoolVar::commit() { + PoolEntry* write_back = ::dataPool.getData(dataPoolId, 1); + if ((write_back != NULL) && (readWriteMode != VAR_READ)) { + write_back->valid = valid; + *(write_back->address) = value; + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +template +inline GlobPoolVar::GlobPoolVar(): + dataPoolId(PoolVariableIF::NO_PARAMETER), + valid(PoolVariableIF::INVALID), + readWriteMode(VAR_READ), value(0) {} + +template +inline GlobPoolVar::GlobPoolVar(const GlobPoolVar& rhs) : + dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode( + rhs.readWriteMode), value(rhs.value) {} + +template +inline pool_rwm_t GlobPoolVar::getReadWriteMode() const { + return readWriteMode; +} + +template +inline uint32_t GlobPoolVar::getDataPoolId() const { + return dataPoolId; +} + +template +inline void GlobPoolVar::setDataPoolId(uint32_t poolId) { + dataPoolId = poolId; +} + +template +inline bool GlobPoolVar::isValid() const { + if (valid) + return true; + else + return false; +} + +template +inline uint8_t GlobPoolVar::getValid() { + return valid; +} + +template +inline void GlobPoolVar::setValid(uint8_t valid) { + this->valid = valid; +} diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h new file mode 100644 index 00000000..47381aec --- /dev/null +++ b/datapoolglob/GlobalPoolVector.h @@ -0,0 +1,223 @@ +#ifndef POOLVECTOR_H_ +#define POOLVECTOR_H_ + +#include +#include +#include +#include +#include + +/** + * \brief This is the access class for array-type data pool entries. + * + * \details To ensure safe usage of the data pool, operation is not done directly on the data pool + * entries, but on local copies. This class provides simple type- and length-safe access + * to vector-style data pool entries (i.e. entries with length > 1). + * The class can be instantiated as read-write and read only. + * It provides a commit-and-roll-back semantic, which means that no array entry in + * the data pool is changed until the commit call is executed. + * There are two template parameters: + * \tparam T This template parameter specifies the data type of an array entry. Currently, all + * plain data types are supported, but in principle any type is possible. + * \tparam vector_size This template parameter specifies the vector size of this entry. + * Using a template parameter for this is not perfect, but avoids dynamic memory allocation. + * \ingroup data_pool + */ +template +class GlobPoolVector: public PoolVariableIF { +private: + /** + * \brief To access the correct data pool entry on read and commit calls, the data pool id + * is stored. + */ + uint32_t dataPoolId; + /** + * \brief The valid information as it was stored in the data pool is copied to this attribute. + */ + uint8_t valid; + /** + * \brief The information whether the class is read-write or read-only is stored here. + */ + ReadWriteMode_t readWriteMode; + +protected: + /** + * \brief This is a call to read the array's values from the global data pool. + * \details When executed, this operation tries to fetch the pool entry with matching + * data pool id from the global data pool and copies all array values and the valid + * information to its local attributes. In case of a failure (wrong type, size or + * pool id not found), the variable is set to zero and invalid. + * The operation does NOT provide any mutual exclusive protection by itself. + */ + ReturnValue_t read() { + PoolEntry* read_out = ::dataPool.getData(this->dataPoolId, + vector_size); + if (read_out != NULL) { + this->valid = read_out->valid; + memcpy(this->value, read_out->address, read_out->getByteSize()); + + return HasReturnvaluesIF::RETURN_OK; + + } else { + memset(this->value, 0, vector_size * sizeof(T)); + sif::error << "PoolVector: read of DP Variable 0x" << std::hex + << dataPoolId << std::dec << " failed." << std::endl; + this->valid = INVALID; + return HasReturnvaluesIF::RETURN_FAILED; + } + } + /** + * \brief The commit call copies the array values back to the data pool. + * \details It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the valid flag is automatically set to "valid". + * The operation does NOT provide any mutual exclusive protection by itself. + * + */ + ReturnValue_t commit() { + PoolEntry* write_back = ::dataPool.getData(this->dataPoolId, + vector_size); + if ((write_back != NULL) && (this->readWriteMode != VAR_READ)) { + write_back->valid = valid; + memcpy(write_back->address, this->value, write_back->getByteSize()); + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } +public: + /** + * \brief This is the local copy of the data pool entry. + * \detials The user can work on this attribute + * just like he would on a local array of this type. + */ + T value[vector_size]; + /** + * \brief In the constructor, the variable can register itself in a DataSet (if not NULL is + * passed). + * \details It DOES NOT fetch the current value from the data pool, but sets the value + * attribute to default (0). The value is fetched within the read() operation. + * \param set_id This is the id in the global data pool this instance of the access class + * corresponds to. + * \param dataSet The data set in which the variable shall register itself. If NULL, + * the variable is not registered. + * \param setWritable If this flag is set to true, changes in the value attribute can be + * written back to the data pool, otherwise not. + */ + GlobPoolVector(uint32_t set_id, DataSetIF* set, + ReadWriteMode_t setReadWriteMode) : + dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) { + memset(this->value, 0, vector_size * sizeof(T)); + if (set != NULL) { + set->registerVariable(this); + } + } + /** + * Copy ctor to copy classes containing Pool Variables. + */ +// PoolVector(const PoolVector& rhs) { +// PoolVector temp(rhs.dataPoolId, rhs.) +// memcpy(value, rhs.value, sizeof(T)*vector_size); +// } + /** + * \brief The classes destructor is empty. + * \details If commit() was not called, the local value is + * discarded and not written back to the data pool. + */ + ~GlobPoolVector() { + } + ; + /** + * \brief The operation returns the number of array entries in this variable. + */ + uint8_t getSize() { + return vector_size; + } + /** + * \brief This operation returns the data pool id of the variable. + */ + uint32_t getDataPoolId() const { + return dataPoolId; + } + /** + * This operation sets the data pool id of the variable. + * The method is necessary to set id's of data pool member variables with bad initialization. + */ + void setDataPoolId(uint32_t poolId) { + dataPoolId = poolId; + } + /** + * This method returns if the variable is write-only, read-write or read-only. + */ + ReadWriteMode_t getReadWriteMode() const { + return readWriteMode; + } + ; + /** + * \brief With this call, the valid information of the variable is returned. + */ + bool isValid() const { + if (valid != INVALID) + return true; + else + return false; + } + + void setValid(uint8_t valid) { + this->valid = valid; + } + + uint8_t getValid() { + return valid; + } + + T &operator [](int i) { + return value[i]; + } + + const T &operator [](int i) const { + return value[i]; + } + + GlobPoolVector &operator=( + GlobPoolVector newPoolVector) { + + for (uint16_t i = 0; i < vector_size; i++) { + this->value[i] = newPoolVector.value[i]; + } + return *this; + } + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const override { + uint16_t i; + ReturnValue_t result; + for (i = 0; i < vector_size; i++) { + result = SerializeAdapter::serialize(&(value[i]), buffer, size, + max_size, bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; + } + + virtual size_t getSerializedSize() const override { + return vector_size * SerializeAdapter::getSerializedSize(value); + } + + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) override { + uint16_t i; + ReturnValue_t result; + for (i = 0; i < vector_size; i++) { + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, + bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; + } +}; + +#endif /* POOLVECTOR_H_ */ diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp new file mode 100644 index 00000000..07f86e18 --- /dev/null +++ b/datapoollocal/LocalDataSet.cpp @@ -0,0 +1,66 @@ +#include + +LocalDataSet::LocalDataSet(): + fill_count(0), state(DATA_SET_UNINITIALISED) +{ + for (unsigned count = 0; count < DATA_SET_MAX_SIZE; count++) { + registeredVariables[count] = nullptr; + } +} + +// who has the responsibility to lock the mutex? the local pool variable +// has access to the HK manager and could call its mutex lock function. +ReturnValue_t LocalDataSet::registerVariable( + PoolVariableIF *variable) { + return RETURN_OK; +} + +LocalDataSet::~LocalDataSet() { +} + +ReturnValue_t LocalDataSet::read() { + return RETURN_OK; +} + +ReturnValue_t LocalDataSet::commit(void) { + return RETURN_OK; +} + +ReturnValue_t LocalDataSet::commit(bool valid) { + return RETURN_OK; +} + +void LocalDataSet::setSetValid(bool valid) { +} + +void LocalDataSet::setEntriesValid(bool valid) { +} + +ReturnValue_t LocalDataSet::serialize(uint8_t **buffer, + size_t *size, const size_t max_size, bool bigEndian) const { + return RETURN_OK; +} + +size_t LocalDataSet::getSerializedSize() const { + return 0; +} + +ReturnValue_t LocalDataSet::deSerialize(const uint8_t **buffer, + size_t *size, bool bigEndian) { + return RETURN_OK; +} + +ReturnValue_t LocalDataSet::lockDataPool() { + return RETURN_OK; +} + +ReturnValue_t LocalDataSet::unlockDataPool() { + return RETURN_OK; +} + +void LocalDataSet::handleAlreadyReadDatasetCommit() { +} + +ReturnValue_t LocalDataSet::handleUnreadDatasetCommit() { + return RETURN_OK; +} diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h new file mode 100644 index 00000000..6110175c --- /dev/null +++ b/datapoollocal/LocalDataSet.h @@ -0,0 +1,187 @@ +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ +#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ +#include +#include + +/** + * @brief The LocalDataSet class manages a set of locally checked out variables + * for local data pools + * @details + * This class manages a list, where a set of local variables (or pool variables) + * are registered. They are checked-out (i.e. their values are looked + * up and copied) with the read call. After the user finishes working with the + * pool variables, he can write back all variable values to the pool with + * the commit call. The data set manages locking and freeing the local data pools, + * to ensure thread-safety. + * + * An internal state manages usage of this class. Variables may only be + * registered before the read call is made, and the commit call only + * after the read call. + * + * If pool variables are writable and not committed until destruction + * of the set, the DataSet class automatically sets the valid flag in the + * data pool to invalid (without) changing the variable's value. + * + * @ingroup data_pool + */ +class LocalDataSet: + public DataSetIF, + public HasReturnvaluesIF, + public SerializeIF { +public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS; + static constexpr ReturnValue_t INVALID_PARAMETER_DEFINITION = + MAKE_RETURN_CODE( 0x01 ); + static constexpr ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 ); + static constexpr ReturnValue_t COMMITING_WITHOUT_READING = + MAKE_RETURN_CODE(0x03); + + static constexpr ReturnValue_t DATA_SET_UNINITIALIZED = MAKE_RETURN_CODE( 0x04 ); + static constexpr ReturnValue_t DATA_SET_FULL = MAKE_RETURN_CODE( 0x05 ); + static constexpr ReturnValue_t POOL_VAR_NULL = MAKE_RETURN_CODE( 0x06 ); + /** + * @brief The constructor simply sets the fill_count to zero and sets + * the state to "uninitialized". + */ + LocalDataSet(); + + /** + * @brief This operation is used to register the local variables in the set. + * @details It stores the pool variable pointer in a variable list. + */ + ReturnValue_t registerVariable(PoolVariableIF* variable) override; + + /** + * @brief The destructor automatically manages writing the valid + * information of variables. + * @details + * In case the data set was read out, but not committed(indicated by state), + * the destructor parses all variables that are still registered to the set. + * For each, the valid flag in the data pool is set to "invalid". + */ + ~LocalDataSet(); + + /** + * @brief The read call initializes reading out all registered variables. + * @details + * It iterates through the list of registered variables and calls all read() + * functions of the registered pool variables (which read out their values + * from the data pool) which are not write-only. + * In case of an error (e.g. a wrong data type, or an invalid data pool id), + * 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. + * @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 SET_WAS_ALREADY_READ if read() is called twice without + * calling commit() in between + */ + ReturnValue_t read(); + + /** + * @brief The commit call initializes writing back the registered variables. + * @details + * It iterates through the list of registered variables and calls the + * commit() method of the remaining registered variables (which write back + * their values to the pool). + * + * The data pool is locked during the whole commit operation and + * freed afterwards. The state changes to "was committed" after this operation. + * + * 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. + * @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 + */ + ReturnValue_t commit(void); + + /** + * Variant of method above which sets validity of all elements of the set. + * @param valid Validity information from PoolVariableIF. + * @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 + */ + ReturnValue_t commit(bool valid); + + /** + * Set all entries + * @param valid + */ + void setSetValid(bool valid); + + /** + * Set the valid information of all variables contained in the set which + * are not read-only + * + * @param valid Validity information from PoolVariableIF. + */ + void setEntriesValid(bool valid); + + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const override; + + size_t getSerializedSize() const override; + + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) override; +private: + // SHOULDDO we could use a linked list of datapool variables + //! This definition sets the maximum number of variables + //! to register in one DataSet. + static const uint8_t DATA_SET_MAX_SIZE = 63; + /** + * @brief This array represents all pool variables registered in this set. + */ + PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE]; + /** + * @brief The fill_count attribute ensures that the variables register in + * the correct array position and that the maximum number of + * variables is not exceeded. + */ + uint16_t fill_count; + + /** + * States of the seet. + */ + enum States { + DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED + DATA_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; + + /** + * If the valid state of a dataset is always relevant to the whole + * data set we can use this flag. + */ + bool valid = false; + /** + * @brief This is a small helper function to facilitate locking + * the underlying data data pool structure + * @details + * It makes use of the lockDataPool method offered by the DataPool class. + */ + ReturnValue_t lockDataPool() override; + + /** + * @brief This is a small helper function to facilitate + * unlocking the underlying data data pool structure + * @details + * It makes use of the freeDataPoolLock method offered by the DataPool class. + */ + ReturnValue_t unlockDataPool() override; + + void handleAlreadyReadDatasetCommit(); + ReturnValue_t handleUnreadDatasetCommit(); +}; + +#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h new file mode 100644 index 00000000..44c16a7c --- /dev/null +++ b/datapoollocal/LocalPoolVariable.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include + +#include + +#include +/** + * @brief This is the access class for non-array local data pool entries. + * + * @details + * + * @tparam T The template parameter sets the type of the variable. + * Currently, all plain data types are supported, but in principle + * any type is possible. + * @ingroup data_pool + */ + +/** + * @brief Local Pool Variable class which is used to access the local pools. + * @details This class is not stored in the map. Instead, it is used to access + * the pool entries by using a pointer to the map storing the pool + * entries. It can also be used to organize these pool entries + * into data sets. + * @tparam T + */ +template +class LocalPoolVar: public PoolVariableIF, HasReturnvaluesIF { +public: + static constexpr lp_id_t INVALID_POOL_ID = 0xFFFFFFFF; + + /** + * This constructor is used by the data creators to have pool variable + * instances which can also be stored in datasets. + * @param set_id + * @param setReadWriteMode + * @param localPoolMap + * @param dataSet + */ + LocalPoolVar(lp_id_t poolId, HasHkPoolParametersIF* hkOwner, + pool_rwm_t setReadWriteMode, DataSetIF* dataSet = nullptr); + + /** + * This constructor is used by data users like controllers to have + * access to the local pool variables of data creators by supplying + * the respective creator object ID. + * @param poolId + * @param poolOwner + * @param setReadWriteMode + * @param dataSet + */ + LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, + pool_rwm_t setReadWriteMode, DataSetIF* dataSet = nullptr); + + virtual~ LocalPoolVar() {}; + + /** + * @brief This is the local copy of the data pool entry. + * @details The user can work on this attribute + * just like he would on a simple local variable. + */ + T value = 0; + + ReturnValue_t commit() override; + ReturnValue_t read() override; + pool_rwm_t getReadWriteMode() const override; + uint32_t getDataPoolId() const override; + bool isValid() const override; + void setValid(uint8_t validity) override; + + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const override; + virtual size_t getSerializedSize() const override; + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) override; +private: + lp_id_t localPoolId = INVALID_POOL_ID; + pool_rwm_t readWriteMode = pool_rwm_t::VAR_READ_WRITE; + bool valid = false; + + bool objectValid = true; + //! Pointer to the class which manages the HK pool. + HousekeepingManager* hkManager; +}; + +#include +template +using lp_variable = LocalPoolVar; + +using lp_bool_t = LocalPoolVar; +using lp_uint8_t = LocalPoolVar; +using lp_uint16_t = LocalPoolVar; +using lp_uint32_t = LocalPoolVar; +using lp_uint64_t = LocalPoolVar; +using lp_int8_t = LocalPoolVar; +using lp_int16_t = LocalPoolVar; +using lp_int32_t = LocalPoolVar; +using lp_int64_t = LocalPoolVar; +using lp_float_t = LocalPoolVar; +using lp_double_t = LocalPoolVar; + + diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp new file mode 100644 index 00000000..fdd18bcd --- /dev/null +++ b/datapoollocal/LocalPoolVariable.tpp @@ -0,0 +1,109 @@ +#pragma once + +#include +#include + +#include + +template +inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, + HasHkPoolParametersIF* hkOwner, pool_rwm_t setReadWriteMode, + DataSetIF* dataSet): + localPoolId(poolId),readWriteMode(setReadWriteMode) { + hkManager = hkOwner->getHkManagerHandle(); + if(dataSet != nullptr) { + dataSet->registerVariable(this); + } +} + +template +inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, + pool_rwm_t setReadWriteMode, DataSetIF *dataSet): + readWriteMode(readWriteMode) { + HasHkPoolParametersIF* hkOwner = + objectManager->get(poolOwner); + if(hkOwner == nullptr) { + sif::error << "LocalPoolVariable: The supplied pool owner did not implement" + "the correct interface HasHkPoolParametersIF!" << std::endl; + objectValid = false; + return; + } + hkManager = hkOwner->getHkManagerHandle(); + if(dataSet != nullptr) { + dataSet->registerVariable(this); + } +} + +template +inline ReturnValue_t LocalPoolVar::read() { + if(readWriteMode == pool_rwm_t::VAR_WRITE) { + sif::debug << "LocalPoolVar: Invalid read write " + "mode for read() call." << std::endl; + // TODO: special return value + return HasReturnvaluesIF::RETURN_FAILED; + } + MutexHelper(hkManager->getMutexHandle(), MutexIF::NO_TIMEOUT); + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, poolEntry); + if(result != RETURN_OK) { + return result; + } + this->value = *(poolEntry->address); + return RETURN_OK; +} + +template +inline ReturnValue_t LocalPoolVar::commit() { + if(readWriteMode == pool_rwm_t::VAR_READ) { + sif::debug << "LocalPoolVar: Invalid read write " + "mode for commit() call." << std::endl; + // TODO: special return value + return HasReturnvaluesIF::RETURN_FAILED; + } + MutexHelper(hkManager->getMutexHandle(), MutexIF::NO_TIMEOUT); + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, poolEntry); + if(result != RETURN_OK) { + return result; + } + *(poolEntry->address) = this->value; + return RETURN_OK; +} + +template +inline pool_rwm_t LocalPoolVar::getReadWriteMode() const { + return readWriteMode; +} + +template +inline lp_id_t LocalPoolVar::getDataPoolId() const { + return localPoolId; +} + +template +inline bool LocalPoolVar::isValid() const { + return valid; +} + +template +inline void LocalPoolVar::setValid(uint8_t validity) { + this->valid = validity; +} + +template +inline ReturnValue_t LocalPoolVar::serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const { + return AutoSerializeAdapter::serialize(&value, + buffer, size ,max_size, bigEndian); +} + +template +inline size_t LocalPoolVar::getSerializedSize() const { + return AutoSerializeAdapter::getSerializedSize(&value); +} + +template +inline ReturnValue_t LocalPoolVar::deSerialize(const uint8_t** buffer, + size_t* size, bool bigEndian) { + return AutoSerializeAdapter::deSerialize(&value, buffer, size, bigEndian); +} diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 710e97d7..0549bd45 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1,14 +1,14 @@ -#include -#include -#include -#include #include -#include -#include #include #include -#include #include +#include + +#include +#include +#include +#include +#include #include #include @@ -17,34 +17,33 @@ object_id_t DeviceHandlerBase::rawDataReceiverId = 0; object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, - object_id_t deviceCommunication, CookieIF * comCookie_, + object_id_t deviceCommunication, CookieIF * comCookie, uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance, size_t cmdQueueSize) : SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), - deviceCommunicationId(deviceCommunication), comCookie(comCookie_), - deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId(thermalRequestPoolId), - healthHelper(this, setObjectId), modeHelper(this), parameterHelper(this), - fdirInstance(fdirInstance), hkSwitcher(this), - defaultFDIRUsed(fdirInstance == nullptr), switchOffWasReported(false), - executingTask(nullptr), actionHelper(this, nullptr), cookieInfo(), - childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), - transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(setDeviceSwitch) -{ - commandQueue = QueueFactory::instance()-> - createMessageQueue(cmdQueueSize, CommandMessage::MAX_MESSAGE_SIZE); + deviceCommunicationId(deviceCommunication), deviceThermalStatePoolId( + thermalStatePoolId),deviceThermalRequestPoolId(thermalRequestPoolId), + healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), + childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), + hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), + switchOffWasReported(false), actionHelper(this, nullptr), cookieInfo(), + childTransitionDelay(5000), + transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( + SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { + commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, + CommandMessage::MAX_MESSAGE_SIZE); cookieInfo.state = COOKIE_UNUSED; insertInCommandMap(RAW_COMMAND_ID); if (this->fdirInstance == nullptr) { - this->fdirInstance = - new DeviceHandlerFailureIsolation(setObjectId, - defaultFDIRParentId); + this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, + defaultFDIRParentId); } } DeviceHandlerBase::~DeviceHandlerBase() { - delete comCookie; + //communicationInterface->close(cookie); if (defaultFDIRUsed) { delete fdirInstance; } @@ -53,7 +52,8 @@ DeviceHandlerBase::~DeviceHandlerBase() { ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { this->pstStep = counter; - if (counter == 0) { + + if (getComAction() == SEND_WRITE) { cookieInfo.state = COOKIE_UNUSED; readCommandQueue(); doStateMachine(); @@ -66,7 +66,6 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { if (mode == MODE_OFF) { return RETURN_OK; } - switch (getComAction()) { case SEND_WRITE: if ((cookieInfo.state == COOKIE_UNUSED)) { @@ -87,7 +86,6 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { default: break; } - return RETURN_OK; } @@ -116,7 +114,7 @@ ReturnValue_t DeviceHandlerBase::initialize() { AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< AcceptsDeviceResponsesIF>(rawDataReceiverId); - if (rawReceiver == nullptr) { + if (rawReceiver == NULL) { return RETURN_FAILED; } @@ -158,14 +156,15 @@ ReturnValue_t DeviceHandlerBase::initialize() { fillCommandAndReplyMap(); //Set temperature target state to NON_OP. - DataSet mySet; - PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, + GlobDataSet mySet; + gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_WRITE); mySet.read(); thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; mySet.commit(PoolVariableIF::VALID); return RETURN_OK; + } void DeviceHandlerBase::decrementDeviceReplyMap() { @@ -366,8 +365,11 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm info.expectedReplies = 0; info.isExecuting = false; info.sendReplyTo = NO_COMMANDER; - std::pair result = deviceCommandMap.emplace(deviceCommand,info); - if (result.second) { + std::pair::iterator, bool> returnValue; + returnValue = deviceCommandMap.insert( + std::pair(deviceCommand, + info)); + if (returnValue.second) { return RETURN_OK; } else { return RETURN_FAILED; @@ -426,8 +428,8 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) { Clock::getUptime(&timeoutStart); if (mode == MODE_OFF) { - DataSet mySet; - PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, + GlobDataSet mySet; + gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -487,7 +489,7 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter, return; } //Check if more replies are expected. If so, do nothing. - DeviceCommandInfo * info = &(iter->second.command->second); + DeviceCommandInfo* info = &(iter->second.command->second); if (--info->expectedReplies == 0) { //Check if it was transition or internal command. Don't send any replies in that case. if (info->sendReplyTo != NO_COMMANDER) { @@ -526,6 +528,7 @@ void DeviceHandlerBase::doGetWrite() { if (wiretappingMode == RAW) { replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true); } + //We need to distinguish here, because a raw command never expects a reply. //(Could be done in eRIRM, but then child implementations need to be careful. result = enableReplyInReplyMap(cookieInfo.pendingCommand); @@ -541,25 +544,22 @@ void DeviceHandlerBase::doGetWrite() { } void DeviceHandlerBase::doSendRead() { - ReturnValue_t result = RETURN_FAILED; + ReturnValue_t result; + size_t requestLen = 0; - // If the device handler can only request replies after a command - // has been sent, there should be only one reply enabled and the - // correct reply length will be mapped. - for(DeviceReplyIter iter = deviceReplyMap.begin(); - iter != deviceReplyMap.end();iter++) - { - if(iter->second.delayCycles != 0) { - requestLen = iter->second.replyLen; - break; - } + DeviceReplyIter iter = deviceReplyMap.find(cookieInfo.pendingCommand->first); + if(iter != deviceReplyMap.end()) { + requestLen = iter->second.replyLen; + } + else { + requestLen = 0; } result = communicationInterface->requestReceiveMessage(comCookie, requestLen); + if (result == RETURN_OK) { cookieInfo.state = COOKIE_READ_SENT; - } - else { + } else { triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result); //We can't inform anyone, because we don't know which command was sent last. //So, we need to wait for a timeout. @@ -583,8 +583,8 @@ void DeviceHandlerBase::doGetRead() { cookieInfo.state = COOKIE_UNUSED; - result = communicationInterface->readReceivedMessage(comCookie, &receivedData, - &receivedDataLen); + result = communicationInterface->readReceivedMessage(comCookie, + &receivedData, &receivedDataLen); if (result != RETURN_OK) { triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result); @@ -644,7 +644,7 @@ void DeviceHandlerBase::doGetRead() { } ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, - uint8_t ** data, size_t * len) { + uint8_t * *data, uint32_t * len) { size_t lenTmp; if (IPCStore == NULL) { @@ -663,10 +663,8 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, *len = 0; return result; } - } - void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand) { if (IPCStore == NULL || len == 0) { @@ -681,6 +679,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, } CommandMessage message; + DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&message, getObjectId(), address, isCommand); @@ -690,14 +689,12 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, if (result != RETURN_OK) { IPCStore->deleteData(address); - // Silently discard data, this indicates heavy TM traffic which should - // not be increased by additional events. + //Silently discard data, this indicates heavy TM traffic which should not be increased by additional events. } } //Default child implementations - -DeviceHandlerBase::CommunicationAction_t DeviceHandlerBase::getComAction() { +DeviceHandlerIF::CommunicationAction_t DeviceHandlerBase::getComAction() { switch (pstStep) { case 0: return SEND_WRITE; @@ -762,8 +759,8 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, // DeviceCommunicationIF>(newChannelId); // // if (newCommunication != NULL) { -// ReturnValue_t result = newCommunication->reOpen(cookie, logicalAddress, -// maxDeviceReplyLen, comParameter1, comParameter2); +// ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress, +// maxDeviceReplyLen); // if (result != RETURN_OK) { // return result; // } @@ -780,8 +777,8 @@ void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) { replyReturnvalueToCommand(result, RAW_COMMAND_ID); storedRawData.raw = StorageManagerIF::INVALID_ADDRESS; } else { - cookieInfo.pendingCommand = deviceCommandMap. - find((DeviceCommandId_t) RAW_COMMAND_ID); + cookieInfo.pendingCommand = deviceCommandMap.find( + (DeviceCommandId_t) RAW_COMMAND_ID); cookieInfo.pendingCommand->second.isExecuting = true; cookieInfo.state = COOKIE_WRITE_READY; } @@ -820,7 +817,7 @@ ReturnValue_t DeviceHandlerBase::enableReplyInReplyMap( iter = deviceReplyMap.find(command->first); } if (iter != deviceReplyMap.end()) { - DeviceReplyInfo * info = &(iter->second); + DeviceReplyInfo *info = &(iter->second); info->delayCycles = info->maxDelayCycles; info->command = command; command->second.expectedReplies = expectedReplies; @@ -846,9 +843,8 @@ ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) { ReturnValue_t result = getSwitches(&switches, &numberOfSwitches); if ((result == RETURN_OK) && (numberOfSwitches != 0)) { while (numberOfSwitches > 0) { - if (powerSwitcher-> getSwitchState(switches[numberOfSwitches - 1]) - == PowerSwitchIF::SWITCH_OFF) - { + if (powerSwitcher->getSwitchState(switches[numberOfSwitches - 1]) + == PowerSwitchIF::SWITCH_OFF) { return PowerSwitchIF::SWITCH_OFF; } numberOfSwitches--; @@ -890,10 +886,10 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, if ((commandedMode == MODE_ON) && (mode == MODE_OFF) && (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) { - DataSet mySet; - PoolVariable thermalState(deviceThermalStatePoolId, &mySet, + GlobDataSet mySet; + gp_uint8_t thermalState(deviceThermalStatePoolId, &mySet, PoolVariableIF::VAR_READ); - PoolVariable thermalRequest(deviceThermalRequestPoolId, &mySet, + gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -920,8 +916,8 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, MODE_ON); triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); - DataSet mySet; - PoolVariable thermalRequest(deviceThermalRequestPoolId, + GlobDataSet mySet; + gp_int8_t thermalRequest(deviceThermalRequestPoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { @@ -1032,7 +1028,6 @@ void DeviceHandlerBase::replyRawReplyIfnotWiretapped(const uint8_t* data, ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( CommandMessage * message) { - ReturnValue_t result; switch (message->getCommand()) { case DeviceHandlerMessage::CMD_WIRETAPPING: switch (DeviceHandlerMessage::getWiretappingMode(message)) { @@ -1054,21 +1049,19 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( } replyReturnvalueToCommand(RETURN_OK); return RETURN_OK; - case DeviceHandlerMessage::CMD_SWITCH_ADDRESS: - if (mode != MODE_OFF) { - replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND); - } else { - // rework in progress - result = RETURN_OK; - //result = switchCookieChannel( - // DeviceHandlerMessage::getIoBoardObjectId(message)); - if (result == RETURN_OK) { - replyReturnvalueToCommand(RETURN_OK); - } else { - replyReturnvalueToCommand(CANT_SWITCH_ADDRESS); - } - } - return RETURN_OK; +// case DeviceHandlerMessage::CMD_SWITCH_IOBOARD: +// if (mode != MODE_OFF) { +// replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND); +// } else { +//// result = switchCookieChannel( +//// DeviceHandlerMessage::getIoBoardObjectId(message)); +// if (result == RETURN_OK) { +// replyReturnvalueToCommand(RETURN_OK); +// } else { +// replyReturnvalueToCommand(CANT_SWITCH_IO_ADDRESS); +// } +// } +// return RETURN_OK; case DeviceHandlerMessage::CMD_RAW: if ((mode != MODE_RAW)) { DeviceHandlerMessage::clear(message); @@ -1124,7 +1117,8 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, // hiding of sender needed so the service will handle it as unexpected Data, no matter what state //(progress or completed) it is in - actionHelper.reportData(defaultRawReceiver, replyId, &wrapper, true); + actionHelper.reportData(defaultRawReceiver, replyId, &wrapper, + true); } } else { //unrequested/aperiodic replies @@ -1137,9 +1131,9 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, true); } } -//Try to cast to DataSet and commit data. +//Try to cast to GlobDataSet and commit data. if (!neverInDataPool) { - DataSet* dataSet = dynamic_cast(data); + GlobDataSet* dataSet = dynamic_cast(data); if (dataSet != NULL) { dataSet->commit(PoolVariableIF::VALID); } @@ -1147,12 +1141,11 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, } ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { ReturnValue_t result = acceptExternalDeviceCommands(); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - DeviceCommandMap::iterator iter = deviceCommandMap.find(actionId); if (iter == deviceCommandMap.end()) { result = COMMAND_NOT_SUPPORTED; @@ -1171,7 +1164,7 @@ ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, } void DeviceHandlerBase::buildInternalCommand(void) { - // Neither Raw nor Direct could build a command +//Neither Raw nor Direct could build a command ReturnValue_t result = NOTHING_TO_SEND; DeviceCommandId_t deviceCommandId = NO_COMMAND_ID; if (mode == MODE_NORMAL) { @@ -1189,13 +1182,12 @@ void DeviceHandlerBase::buildInternalCommand(void) { } else { return; } - if (result == NOTHING_TO_SEND) { return; } if (result == RETURN_OK) { - DeviceCommandMap::iterator iter = - deviceCommandMap.find(deviceCommandId); + DeviceCommandMap::iterator iter = deviceCommandMap.find( + deviceCommandId); if (iter == deviceCommandMap.end()) { result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { @@ -1210,7 +1202,6 @@ void DeviceHandlerBase::buildInternalCommand(void) { cookieInfo.state = COOKIE_WRITE_READY; } } - if (result != RETURN_OK) { triggerEvent(DEVICE_BUILDING_COMMAND_FAILED, result, deviceCommandId); } @@ -1285,8 +1276,8 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ executingTask = task_; } -void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId, uint32_t parameter) { -} +// Default implementations empty. +void DeviceHandlerBase::debugInterface(uint8_t positionTracker, + object_id_t objectId, uint32_t parameter) {} -void DeviceHandlerBase::performOperationHook() { -} +void DeviceHandlerBase::performOperationHook() {} diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 25ec75b9..379992b1 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1,26 +1,23 @@ #ifndef DEVICEHANDLERBASE_H_ #define DEVICEHANDLERBASE_H_ -#include +#include +#include +#include +#include #include -#include #include #include -#include -#include #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include + +#include +#include +#include +#include +#include + #include namespace Factory{ @@ -92,21 +89,22 @@ public: * The constructor passes the objectId to the SystemObject(). * * @param setObjectId the ObjectId to pass to the SystemObject() Constructor - * @param maxDeviceReplyLen the largest allowed reply size + * @param maxDeviceReplyLen the length the RMAP getRead call will be sent with * @param setDeviceSwitch the switch the device is connected to, - * for devices using two switches, overwrite getSwitches() - * @param deviceCommuncation Communcation Interface object which is - * used to implement communication functions + * for devices using two switches, overwrite getSwitches() + * @param deviceCommuncation Communcation Interface object which is used + * to implement communication functions * @param thermalStatePoolId * @param thermalRequestPoolId * @param fdirInstance * @param cmdQueueSize */ DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, - CookieIF * comCookie_, uint8_t setDeviceSwitch, + CookieIF * comCookie, uint8_t setDeviceSwitch, uint32_t thermalStatePoolId = PoolVariableIF::NO_PARAMETER, uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER, - FailureIsolationBase* fdirInstance = nullptr, size_t cmdQueueSize = 20); + FailureIsolationBase* fdirInstance = nullptr, + size_t cmdQueueSize = 20); /** * @brief This function is the device handler base core component and is @@ -213,12 +211,13 @@ protected: /** * Build the device command to send for normal mode. * - * This is only called in @c MODE_NORMAL. If multiple submodes for @c MODE_NORMAL are supported, - * different commands can built returned depending on the submode. + * This is only called in @c MODE_NORMAL. If multiple submodes for + * @c MODE_NORMAL are supported, different commands can built, + * depending on the submode. * - * #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. - * If variable command frequence is required, a counter can be used and - * the frequency in the reply map has to be set manually + * #rawPacket and #rawPacketLen must be set by this method to the + * packet to be sent. If variable command frequence is required, a counter + * can be used and the frequency in the reply map has to be set manually * by calling updateReplyMap(). * * @param[out] id the device command id that has been built @@ -233,10 +232,13 @@ protected: * Build the device command to send for a transitional mode. * * This is only called in @c _MODE_TO_NORMAL, @c _MODE_TO_ON, @c _MODE_TO_RAW, - * @c _MODE_START_UP and @c _MODE_TO_POWER_DOWN. So it is used by doStartUp() and doShutDown() as well as doTransition() + * @c _MODE_START_UP and @c _MODE_TO_POWER_DOWN. So it is used by doStartUp() + * and doShutDown() as well as doTransition() * - * A good idea is to implement a flag indicating a command has to be built and a variable containing the command number to be built - * and filling them in doStartUp(), doShutDown() and doTransition() so no modes have to be checked here. + * A good idea is to implement a flag indicating a command has to be built + * and a variable containing the command number to be built + * and filling them in doStartUp(), doShutDown() and doTransition() so no + * modes have to be checked here. * * #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. * @@ -266,6 +268,63 @@ protected: virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t * commandData, size_t commandDataLen) = 0; + /** + * @brief Scans a buffer for a valid reply. + * @details + * This is used by the base class to check the data received for valid packets. + * It only checks if a valid packet starts at @c start. + * It also only checks the structural validy of the packet, + * e.g. checksums lengths and protocol data. No information check is done, + * e.g. range checks etc. + * + * Errors should be reported directly, the base class does NOT report any + * errors based on the return value of this function. + * + * @param start start of remaining buffer to be scanned + * @param len length of remaining buffer to be scanned + * @param[out] foundId the id of the data found in the buffer. + * @param[out] foundLen length of the data found. Is to be set in function, + * buffer is scanned at previous position + foundLen. + * @return + * - @c RETURN_OK a valid packet was found at @c start, @c foundLen is valid + * - @c RETURN_FAILED no reply could be found starting at @c start, + * implies @c foundLen is not valid, base class will call scanForReply() + * again with ++start + * - @c DeviceHandlerIF::INVALID_DATA a packet was found but it is invalid, + * e.g. checksum error, implies @c foundLen is valid, can be used to + * skip some bytes + * - @c DeviceHandlerIF::LENGTH_MISSMATCH @c len is invalid + * - @c DeviceHandlerIF::IGNORE_REPLY_DATA Ignore this specific part of + * the packet + * - @c DeviceHandlerIF::IGNORE_FULL_PACKET Ignore the packet + * - @c APERIODIC_REPLY if a valid reply is received that has not been + * requested by a command, but should be handled anyway + * (@see also fillCommandAndCookieMap() ) + */ + virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len, + DeviceCommandId_t *foundId, size_t *foundLen) = 0; + + /** + * @brief Interpret a reply from the device. + * @details + * This is called after scanForReply() found a valid packet, it can be + * assumed that the length and structure is valid. + * This routine extracts the data from the packet into a DataSet and then + * calls handleDeviceTM(), which either sends a TM packet or stores the + * data in the DataPool depending on whether it was an external command. + * No packet length is given, as it should be defined implicitly by the id. + * + * @param id the id found by scanForReply() + * @param packet + * @return + * - @c RETURN_OK when the reply was interpreted. + * - @c RETURN_FAILED when the reply could not be interpreted, + * e.g. logical errors or range violations occurred + */ + + virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) = 0; + /** * @brief fill the #deviceCommandMap * called by the initialize() of the base class @@ -312,85 +371,83 @@ protected: virtual void fillCommandAndReplyMap() = 0; /** - * @brief Scans a buffer for a valid reply. - * @details - * This is used by the base class to check the data received for valid packets. - * It only checks if a valid packet starts at @c start. - * It also only checks the structural validy of the packet, - * e.g. checksums lengths and protocol data. - * No information check is done, e.g. range checks etc. - * - * Errors should be reported directly, the base class does NOT report - * any errors based on the returnvalue of this function. - * - * @param start start of remaining buffer to be scanned - * @param len length of remaining buffer to be scanned - * @param[out] foundId the id of the data found in the buffer. - * @param[out] foundLen length of the data found. Is to be set in function, - * buffer is scanned at previous position + foundLen. - * @return - * - @c RETURN_OK a valid packet was found at @c start, @c foundLen is valid - * - @c RETURN_FAILED no reply could be found starting at @c start, - * implies @c foundLen is not valid, - * base class will call scanForReply() again with ++start - * - @c DeviceHandlerIF::INVALID_DATA a packet was found but it is invalid, - * e.g. checksum error, implies @c foundLen is valid, can be used to skip some bytes - * - @c DeviceHandlerIF::LENGTH_MISSMATCH @c len is invalid - * - @c DeviceHandlerIF::IGNORE_REPLY_DATA Ignore this specific part of the packet - * - @c DeviceHandlerIF::IGNORE_FULL_PACKET Ignore the packet - * - @c APERIODIC_REPLY if a valid reply is received that has not been - * requested by a command, but should be handled anyway - * (@see also fillCommandAndCookieMap() ) + * This is a helper method to facilitate inserting entries in the command map. + * @param deviceCommand Identifier of the command to add. + * @param maxDelayCycles The maximum number of delay cycles the command + * waits until it times out. + * @param periodic Indicates if the command is periodic (i.e. it is sent + * by the device repeatedly without request) or not. Default is aperiodic (0) + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. */ - virtual ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, - DeviceCommandId_t *foundId, size_t *foundLen) = 0; + ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, + uint16_t maxDelayCycles, size_t replyLen = 0, uint8_t periodic = 0, + bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); /** - * @brief Interpret a reply from the device. - * @details - * This is called after scanForReply() found a valid packet, it can be assumed that the length and structure is valid. - * This routine extracts the data from the packet into a DataSet and then calls handleDeviceTM(), which either sends - * a TM packet or stores the data in the DataPool depending on whether the it was an external command. - * No packet length is given, as it should be defined implicitly by the id. - * - * @param id the id found by scanForReply() - * @param packet - * @return - * - @c RETURN_OK when the reply was interpreted. - * - @c RETURN_FAILED when the reply could not be interpreted, eg. logical errors or range violations occurred + * @brief This is a helper method to insert replies in the reply map. + * @param deviceCommand Identifier of the reply to add. + * @param maxDelayCycles The maximum number of delay cycles the reply waits + * until it times out. + * @param periodic Indicates if the command is periodic (i.e. it is sent + * by the device repeatedly without request) or not. Default is aperiodic (0) + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. */ - virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) = 0; + ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, + uint16_t maxDelayCycles, size_t replyLen = 0, uint8_t periodic = 0); /** - * set all datapool variables that are update periodically in normal mode invalid - * - * Child classes should provide an implementation which sets all those variables invalid - * which are set periodically during any normal mode. + * @brief A simple command to add a command to the commandList. + * @param deviceCommand The command to add + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. */ - virtual void setNormalDatapoolEntriesInvalid() = 0; + ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); + /** + * @brief This is a helper method to facilitate updating entries + * in the reply map. + * @param deviceCommand Identifier of the reply to update. + * @param delayCycles The current number of delay cycles to wait. + * As stated in #fillCommandAndCookieMap, to disable periodic commands, + * this is set to zero. + * @param maxDelayCycles The maximum number of delay cycles the reply waits + * until it times out. By passing 0 the entry remains untouched. + * @param periodic Indicates if the command is periodic (i.e. it is sent + * by the device repeatedly without request) or not.Default is aperiodic (0). + * Warning: The setting always overrides the value that was entered in the map. + * @return - @c RETURN_OK when the command was successfully inserted, + * - @c RETURN_FAILED else. + */ + ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, + uint16_t delayCycles, uint16_t maxDelayCycles, + uint8_t periodic = 0); /** * @brief Can be implemented by child handler to * perform debugging * @details Example: Calling this in performOperation * to track values like mode. - * @param positionTracker Provide the child handler a way to know where the debugInterface was called - * @param objectId Provide the child handler object Id to specify actions for spefic devices - * @param parameter Supply a parameter of interest + * @param positionTracker Provide the child handler a way to know + * where the debugInterface was called + * @param objectId Provide the child handler object Id to + * specify actions for spefic devices + * @param parameter Supply a parameter of interest * Please delete all debugInterface calls in DHB after debugging is finished ! */ - virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0, uint32_t parameter = 0); + virtual void debugInterface(uint8_t positionTracker = 0, + object_id_t objectId = 0, uint32_t parameter = 0); /** * Get the time needed to transit from modeFrom to modeTo. * * Used for the following transitions: * modeFrom -> modeTo: - * - MODE_ON -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] - * - MODE_NORMAL -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] - * - MODE_RAW -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] - * - _MODE_START_UP -> MODE_ON (do not include time to set the switches, the base class got you covered) + * MODE_ON -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] + * MODE_NORMAL -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] + * MODE_RAW -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] + * _MODE_START_UP -> MODE_ON (do not include time to set the switches, + * the base class got you covered) * * The default implementation returns 0 ! * @param modeFrom @@ -408,40 +465,24 @@ protected: * @param[out] numberOfSwitches length of returned array * @return * - @c RETURN_OK if the parameters were set - * - @c NO_SWITCH or any other returnvalue if no switches exist + * - @c RETURN_FAILED if no switches exist */ virtual ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches); /** - * Can be used to perform device specific periodic operations. - * This is called on the SEND_READ step of the performOperation() call + * @brief Hook function for child handlers which is called once per + * performOperation(). Default implementation is empty. */ virtual void performOperationHook(); - - /** - * The Returnvalues id of this class, required by HasReturnvaluesIF - */ - static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE; - public: /** * @param parentQueueId */ virtual void setParentQueue(MessageQueueId_t parentQueueId); - /** - * This function call handles the execution of external commands as required - * by the HasActionIF. - * @param actionId - * @param commandedBy - * @param data - * @param size - * @return - */ ReturnValue_t executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, size_t size); - + MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size); Mode_t getTransitionSourceMode() const; Submode_t getTransitionSourceSubMode() const; virtual void getMode(Mode_t *mode, Submode_t *submode); @@ -460,6 +501,28 @@ public: virtual MessageQueueId_t getCommandQueue(void) const; protected: + /** + * The Returnvalues id of this class, required by HasReturnvaluesIF + */ + static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE; + + /** + * These returnvalues can be returned from abstract functions + * to alter the behaviour of DHB.For error values, refer to + * DeviceHandlerIF.h returnvalues. + */ + static const ReturnValue_t INVALID_CHANNEL = MAKE_RETURN_CODE(4); + // Returnvalues for scanForReply() + static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(5); //!< This is used to specify for replies from a device which are not replies to requests + static const ReturnValue_t IGNORE_REPLY_DATA = MAKE_RETURN_CODE(6); //!< Ignore parts of the received packet + static const ReturnValue_t IGNORE_FULL_PACKET = MAKE_RETURN_CODE(7); //!< Ignore full received packet + +// static const ReturnValue_t ONE_SWITCH = MAKE_RETURN_CODE(8); +// static const ReturnValue_t TWO_SWITCHES = MAKE_RETURN_CODE(9); + static const ReturnValue_t NO_SWITCH = MAKE_RETURN_CODE(10); + static const ReturnValue_t COMMAND_MAP_ERROR = MAKE_RETURN_CODE(11); + static const ReturnValue_t NOTHING_TO_SEND = MAKE_RETURN_CODE(12); + //Mode handling error Codes static const ReturnValue_t CHILD_TIMEOUT = MAKE_RETURN_CODE(0xE1); static const ReturnValue_t SWITCH_FAILED = MAKE_RETURN_CODE(0xE2); @@ -475,7 +538,7 @@ protected: /** * Size of the #rawPacket. */ - size_t rawPacketLen = 0; + uint32_t rawPacketLen = 0; /** * The mode the device handler is currently in. @@ -502,7 +565,7 @@ protected: * indicates either that all raw messages to and from the device should be sent to #theOneWhoWantsToReadRawTraffic * or that all device TM should be downlinked to #theOneWhoWantsToReadRawTraffic */ - enum WiretappingMode: uint8_t { + enum WiretappingMode { OFF = 0, RAW = 1, TM = 2 } wiretappingMode; @@ -546,18 +609,16 @@ protected: DeviceCommunicationIF *communicationInterface = nullptr; /** - * Cookie used for communication. This is passed to the communication - * interface. + * Cookie used for communication */ - CookieIF *comCookie; + CookieIF * comCookie = nullptr; struct DeviceCommandInfo { bool isExecuting; //!< Indicates if the command is already executing. uint8_t expectedReplies; //!< Dynamic value to indicate how many replies are expected. Inititated with 0. MessageQueueId_t sendReplyTo; //!< if this is != NO_COMMANDER, DHB was commanded externally and shall report everything to commander. }; - typedef std::map DeviceCommandMap; - typedef DeviceCommandMap::iterator DeviceCommandIter; + using DeviceCommandMap = std::map ; /** * @brief Information about expected replies @@ -568,15 +629,12 @@ protected: uint16_t maxDelayCycles; //!< The maximum number of cycles the handler should wait for a reply to this command. uint16_t delayCycles; //!< The currently remaining cycles the handler should wait for a reply, 0 means there is no reply expected size_t replyLen = 0; //!< Expected size of the reply. - //(Robin): This is a flag, isnt it? could we declare it bool? uint8_t always - // gives away the impression that this variable is more than a simple flag - // and true/false are also more explicit. uint8_t periodic; //!< if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles DeviceCommandMap::iterator command; //!< The command that expects this reply. }; - typedef std::map DeviceReplyMap; - typedef DeviceReplyMap::iterator DeviceReplyIter; + using DeviceReplyMap = std::map ; + using DeviceReplyIter = DeviceReplyMap::iterator; /** * The MessageQueue used to receive device handler commands and to send replies. @@ -610,7 +668,7 @@ protected: * Optional Error code * Can be set in doStartUp(), doShutDown() and doTransition() to signal cause for Transition failure. */ - ReturnValue_t childTransitionFailure = RETURN_OK; + ReturnValue_t childTransitionFailure; uint32_t ignoreMissedRepliesCount = 0; //!< Counts if communication channel lost a reply, so some missed replys can be ignored. @@ -622,35 +680,13 @@ protected: bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown. - PeriodicTaskIF* executingTask;//!< Pointer to the task which executes this component, is invalid before setTaskIF was called. + PeriodicTaskIF* executingTask = nullptr;//!< Pointer to the task which executes this component, is invalid before setTaskIF was called. static object_id_t powerSwitcherId; //!< Object which switches power on and off. 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. - - /** - * Set the device handler mode - * - * Sets #timeoutStart with every call. - * - * Sets #transitionTargetMode if necessary so transitional states can be entered from everywhere without breaking the state machine - * (which relies on a correct #transitionTargetMode). - * - * The submode is left unchanged. - * - * - * @param newMode - */ - void setMode(Mode_t newMode); - - /** - * @overload - * @param submode - */ - void setMode(Mode_t newMode, Submode_t submode); - /** * Helper function to report a missed reply * @@ -671,14 +707,30 @@ protected: void replyReturnvalueToCommand(ReturnValue_t status, uint32_t parameter = 0); - /** - * Send reply to a command, differentiate between raw command - * and normal command. - * @param status - * @param parameter - */ void replyToCommand(ReturnValue_t status, uint32_t parameter = 0); + /** + * Set the device handler mode + * + * Sets #timeoutStart with every call. + * + * Sets #transitionTargetMode if necessary so transitional states can be + * entered from everywhere without breaking the state machine + * (which relies on a correct #transitionTargetMode). + * + * The submode is left unchanged. + * + * + * @param newMode + */ + void setMode(Mode_t newMode); + + /** + * @overload + * @param submode + */ + void setMode(Mode_t newMode, Submode_t submode); + /** * Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW). * @@ -708,55 +760,6 @@ protected: */ virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom); - /** - * This is a helper method to facilitate inserting entries in the command map. - * @param deviceCommand Identifier of the command to add. - * @param maxDelayCycles The maximum number of delay cycles the command waits until it times out. - * @param periodic Indicates if the reply is periodic (i.e. it is sent by the device repeatedly without request) or not. - * Default is aperiodic (0) - * @param hasDifferentReplyId - * @param replyId - * @return RETURN_OK when the command was successfully inserted, COMMAND_MAP_ERROR else. - */ - ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, uint8_t periodic = 0, - bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); - /** - * This is a helper method to insert replies in the reply map. - * @param deviceCommand Identifier of the reply to add. - * @param maxDelayCycles The maximum number of delay cycles the reply waits until it times out. - * @param periodic Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. - * Default is aperiodic (0) - * @return RETURN_OK when the command was successfully inserted, COMMAND_MAP_ERROR else. - */ - ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, uint8_t periodic = 0); - /** - * A simple command to add a command to the commandList. - * @param deviceCommand The command to add - * @return RETURN_OK if the command was successfully inserted, RETURN_FAILED else. - */ - ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); - /** - * This is a helper method to facilitate updating entries in the reply map. - * @param deviceCommand Identifier of the reply to update. - * @param delayCycles The current number of delay cycles to wait. As stated in #fillCommandAndCookieMap, to disable periodic commands, this is set to zero. - * @param maxDelayCycles The maximum number of delay cycles the reply waits until it times out. By passing 0 the entry remains untouched. - * @param periodic Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. - * Default is aperiodic (0). Warning: The setting always overrides the value that was entered in the map. - * @return RETURN_OK when the reply was successfully updated, COMMAND_MAP_ERROR else. - */ - ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, - uint16_t delayCycles, uint16_t maxDelayCycles, - uint8_t periodic = 0); - /** - * Returns the delay cycle count of a reply. - * A count != 0 indicates that the command is already executed. - * @param deviceCommand The command to look for - * @return The current delay count. If the command does not exist (should never happen) it returns 0. - */ - uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand); - /** * Is the combination of mode and submode valid? * @@ -776,6 +779,7 @@ protected: * * @return The Rmap action to execute in this step */ + virtual CommunicationAction_t getComAction(); /** @@ -798,6 +802,14 @@ protected: */ virtual ReturnValue_t buildChildRawCommand(); + /** + * Returns the delay cycle count of a reply. + * A count != 0 indicates that the command is already executed. + * @param deviceCommand The command to look for + * @return The current delay count. If the command does not exist (should never happen) it returns 0. + */ + uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand); + /** * Construct a command reply containing a raw reply. * @@ -861,6 +873,14 @@ protected: */ ReturnValue_t getStateOfSwitches(void); + /** + * set all datapool variables that are update periodically in normal mode invalid + * + * Child classes should provide an implementation which sets all those variables invalid + * which are set periodically during any normal mode. + */ + virtual void setNormalDatapoolEntriesInvalid() = 0; + /** * build a list of sids and pass it to the #hkSwitcher */ @@ -889,6 +909,7 @@ protected: virtual void startTransition(Mode_t mode, Submode_t submode); virtual void setToExternalControl(); virtual void announceMode(bool recursive); + virtual ReturnValue_t letChildHandleMessage(CommandMessage *message); /** @@ -954,13 +975,12 @@ protected: DeviceCommandMap deviceCommandMap; ActionHelper actionHelper; - private: /** * State a cookie is in. * - * Used to keep track of the state of the communication. + * Used to keep track of the state of the RMAP communication. */ enum CookieState_t { COOKIE_UNUSED, //!< The Cookie is unused @@ -1034,20 +1054,22 @@ private: * - checks whether commanded mode transitions are required and calls handleCommandedModeTransition() * - does the necessary action for the current mode or calls doChildStateMachine in modes @c MODE_TO_ON and @c MODE_TO_OFF * - actions that happen in transitions (eg setting a timeout) are handled in setMode() - * - Maybe export this into own class to increase modularity of software - * and reduce the massive class size ? */ void doStateMachine(void); void buildRawDeviceCommand(CommandMessage* message); void buildInternalCommand(void); +// /** +// * Send a reply with the current mode and submode. +// */ +// void announceMode(void); + /** * Decrement the counter for the timout of replies. * * This is called at the beginning of each cycle. It checks whether a reply has timed out (that means a reply was expected * but not received). - * In case the reply is periodic, the counter is simply set back to a specified value. */ void decrementDeviceReplyMap(void); @@ -1114,8 +1136,8 @@ private: * - @c RETURN_FAILED IPCStore is NULL * - the return value from the IPCStore if it was not @c RETURN_OK */ - ReturnValue_t getStorageData(store_address_t storageAddress, - uint8_t ** data, size_t * len); + ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, + uint32_t *len); /** * set all switches returned by getSwitches() @@ -1144,16 +1166,9 @@ private: * - @c RETURN_FAILED when cookies could not be changed, eg because the newChannel is not enabled * - @c returnvalues of RMAPChannelIF::isActive() */ - //ReturnValue_t switchCookieChannel(object_id_t newChannelId); + ReturnValue_t switchCookieChannel(object_id_t newChannelId); - /** - * Handle device handler messages (e.g. commands sent by PUS Service 2) - * @param message - * @return - */ ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); - - }; #endif /* DEVICEHANDLERBASE_H_ */ diff --git a/housekeeping/HasHkPoolParametersIF.h b/housekeeping/HasHkPoolParametersIF.h new file mode 100644 index 00000000..5ec9beef --- /dev/null +++ b/housekeeping/HasHkPoolParametersIF.h @@ -0,0 +1,32 @@ +#ifndef FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ +#define FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ +#include +#include +#include + +class HousekeepingManager; +/** + * @brief Type definition for local pool entries. + */ +using lp_id_t = uint32_t; +using LocalDataPoolMap = std::map; +using LocalDataPoolMapIter = LocalDataPoolMap::iterator; + +/** + * @brief Interface for the local housekeeping managers used by the device + * handler. + */ +class HasHkPoolParametersIF { +public: + virtual~ HasHkPoolParametersIF() {}; + + virtual MessageQueueId_t getCommandQueue() const = 0; + virtual ReturnValue_t initializeHousekeepingPoolEntries( + LocalDataPoolMap& localDataPoolMap) = 0; + virtual float setMinimalHkSamplingFrequency() = 0; + virtual HousekeepingManager* getHkManagerHandle() = 0; +}; + + + +#endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */ diff --git a/housekeeping/HousekeepingManager.cpp b/housekeeping/HousekeepingManager.cpp new file mode 100644 index 00000000..05df0ffc --- /dev/null +++ b/housekeeping/HousekeepingManager.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +HousekeepingManager::HousekeepingManager(HasHkPoolParametersIF* owner) { + //todo :: nullptr check owner. + if(owner == nullptr) { + sif::error << "HkManager: Invalid supplied owner!" << std::endl; + std::exit(0); + } + this->owner = owner; + mutex = MutexFactory::instance()->createMutex(); + owner->setMinimalHkSamplingFrequency(); +} + +HousekeepingManager::~HousekeepingManager() {} + +ReturnValue_t HousekeepingManager::initializeHousekeepingPoolEntriesOnce() { + if(not mapInitialized) { + ReturnValue_t result = owner->initializeHousekeepingPoolEntries(localDpMap); + if(result == HasReturnvaluesIF::RETURN_OK) { + mapInitialized = true; + } + return result; + } + sif::warning << "hk manager says no" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t HousekeepingManager::handleHousekeepingMessage( + CommandMessage *message) { + return HasReturnvaluesIF::RETURN_OK; +} + +MutexIF* HousekeepingManager::getMutexHandle() { + return mutex; +} + +void HousekeepingManager::setMinimalSamplingFrequency(float frequencySeconds) { + this->samplingFrequency = frequencySeconds; + +} + +void HousekeepingManager::generateHousekeepingPacket(DataSetIF *dataSet) { +} + +void HousekeepingManager::setHkPacketQueue(MessageQueueIF *msgQueue) { + this->hkPacketQueue = msgQueue; +} diff --git a/housekeeping/HousekeepingManager.h b/housekeeping/HousekeepingManager.h new file mode 100644 index 00000000..feec69fc --- /dev/null +++ b/housekeeping/HousekeepingManager.h @@ -0,0 +1,95 @@ +#ifndef FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ +#define FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +class HousekeepingManager { +public: + static constexpr float MINIMAL_SAMPLING_FREQUENCY = 0.2; + + HousekeepingManager(HasHkPoolParametersIF* owner); + virtual~ HousekeepingManager(); + + MutexIF* getMutexHandle(); + + // propably will just call respective local data set functions. + void generateHousekeepingPacket(DataSetIF* dataSet); + ReturnValue_t handleHousekeepingMessage(CommandMessage* message); + + /** + * Read a variable by supplying its local pool ID and assign the pool + * entry to the supplied PoolEntry pointer. The type of the pool entry + * is deduced automatically. This call is not thread-safe! + * @tparam T Type of the pool entry + * @param localPoolId Pool ID of the variable to read + * @param poolVar [out] Corresponding pool entry will be assigned to the + * supplied pointer. + * @return + */ + template + ReturnValue_t fetchPoolEntry(lp_id_t localPoolId, PoolEntry *poolEntry); + void setMinimalSamplingFrequency(float frequencySeconds); + + /** + * This function is used to fill the local data pool map with pool + * entries. The default implementation is empty. + * @param localDataPoolMap + * @return + */ + ReturnValue_t initializeHousekeepingPoolEntriesOnce(); + + void setHkPacketQueue(MessageQueueIF* msgQueue); +private: + //! this depends on the PST frequency.. maybe it would be better to just + //! set this manually with a global configuration value which is also + //! passed to the PST. Or force setting this in device handler. + float samplingFrequency = MINIMAL_SAMPLING_FREQUENCY; + + //! This is the map holding the actual data. Should only be initialized + //! once ! + bool mapInitialized = false; + LocalDataPoolMap localDpMap; + + //! Every housekeeping data manager has a mutex to protect access + //! to it's data pool. + MutexIF * mutex = nullptr; + + //! The class which actually owns the manager (and its datapool). + HasHkPoolParametersIF* owner = nullptr; + + //! Used for replies. + //! (maybe we dont need this, the sender can be retrieved from command + //! message..) + MessageQueueIF* hkReplyQueue = nullptr; + //! Used for HK packets, which are generated without requests. + MessageQueueIF* hkPacketQueue = nullptr; +}; + +template inline +ReturnValue_t HousekeepingManager::fetchPoolEntry(lp_id_t localPoolId, + PoolEntry *poolEntry) { + auto poolIter = localDpMap.find(localPoolId); + if (poolIter == localDpMap.end()) { + // todo: special returnvalue. + return HasReturnvaluesIF::RETURN_FAILED; + } + + poolEntry = dynamic_cast< PoolEntry* >(poolIter->second); + if(poolEntry == nullptr) { + // todo: special returnvalue. + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +#endif /* FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ */ diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp new file mode 100644 index 00000000..65d87e9e --- /dev/null +++ b/housekeeping/HousekeepingMessage.cpp @@ -0,0 +1,10 @@ +#include + +void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message, + set_t setId, store_address_t packet) { + message->setCommand(ADD_HK_REPORT_STRUCT); + message->setParameter(setId); + message->setParameter2(packet.raw); +} + +//void Housekeeping diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h new file mode 100644 index 00000000..80dc83a6 --- /dev/null +++ b/housekeeping/HousekeepingMessage.h @@ -0,0 +1,87 @@ +#ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ +#define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ +#include +#include +#include + +/** + * the sid consists of the target object ID and... something else I forgot. + * Propably a special HK id to distinguish multiple hk pool packages + * inside a handler or controller + */ +typedef uint32_t set_t; + +union sid_t { + static constexpr uint64_t INVALID_ADDRESS = std::numeric_limits::max(); + sid_t(): raw(INVALID_ADDRESS) {} + + struct { + object_id_t objectId ; + set_t hkId; + }; + /** + * Alternative access to the raw value. + */ + uint64_t raw; +}; +class HousekeepingMessage { +public: + /** + * No instances of a message shall be created, instead + * a CommandMessage instance is manipulated. + */ + HousekeepingMessage() = delete; + HousekeepingMessage(const HousekeepingMessage&) = delete; + HousekeepingMessage operator=(const HousekeepingMessage &) = delete; + + static constexpr uint8_t MESSAGE_ID = MESSAGE_TYPE::HOUSEKEEPING; + static constexpr Command_t ADD_HK_REPORT_STRUCT = + MAKE_COMMAND_ID(1); + static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT = + MAKE_COMMAND_ID(2); + + static constexpr Command_t DELETE_HK_REPORT_STRUCT = MAKE_COMMAND_ID(3); + static constexpr Command_t DELETE_DIAGNOSTICS_REPORT_STRUCT = + MAKE_COMMAND_ID(4); + + static constexpr Command_t ENABLE_PERIODIC_HK_GENERATION = + MAKE_COMMAND_ID(5); + static constexpr Command_t DISABLE_PERIODIC_HK_REPORT_GENERATION = + MAKE_COMMAND_ID(6); + + static constexpr Command_t ENABLE_PERIODIC_DIAGNOSTICS_GENERATION = + MAKE_COMMAND_ID(7); + static constexpr Command_t DISABLE_PERIODIC_DIAGNOSTICS_GENERATION = + MAKE_COMMAND_ID(8); + + static constexpr Command_t REPORT_HK_REPORT_STRUCTURES = MAKE_COMMAND_ID(9); + static constexpr Command_t REPORT_DIAGNOSTICS_REPORT_STRUCTURES = + MAKE_COMMAND_ID(11); + + static constexpr Command_t HK_DEFINITIONS_REPORT = MAKE_COMMAND_ID(10); + static constexpr Command_t DIAGNOSTICS_DEFINITION_REPORT = MAKE_COMMAND_ID(12); + + static constexpr Command_t HK_REPORT = MAKE_COMMAND_ID(25); + static constexpr Command_t DIAGNOSTICS_REPORT = MAKE_COMMAND_ID(26); + + static constexpr Command_t GENERATE_ONE_PARAMETER_REPORT = + MAKE_COMMAND_ID(27); + static constexpr Command_t GENERATE_ONE_DIAGNOSTICS_REPORT = + MAKE_COMMAND_ID(28); + + static constexpr Command_t APPEND_PARAMETERS_TO_PARAMETER_REPORT_STRUCTURE = + MAKE_COMMAND_ID(29); + static constexpr Command_t APPEND_PARAMETERS_TO_DIAGNOSTICS_REPORT_STRUCTURE = + MAKE_COMMAND_ID(30); + + static constexpr Command_t MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL = + MAKE_COMMAND_ID(31); + static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = + MAKE_COMMAND_ID(32); + + static void setAddHkReportStructMessage(CommandMessage* message, + set_t setId, store_address_t packet); +}; + + +#endif /* FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ */ diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 81c4a0e5..72ba434a 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -1,6 +1,6 @@ #include "InternalErrorReporter.h" -#include +#include #include #include @@ -20,13 +20,13 @@ InternalErrorReporter::~InternalErrorReporter() { ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { - DataSet mySet; - PoolVariable queueHitsInPool(queuePoolId, &mySet, + GlobDataSet mySet; + gp_uint32_t queueHitsInPool(queuePoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); - PoolVariable tmHitsInPool(tmPoolId, &mySet, + gp_uint32_t tmHitsInPool(tmPoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); - PoolVariable storeHitsInPool(storePoolId, &mySet, + gp_uint32_t storeHitsInPool(storePoolId, &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); diff --git a/monitoring/MonitorBase.h b/monitoring/MonitorBase.h index 79622645..d66e956d 100644 --- a/monitoring/MonitorBase.h +++ b/monitoring/MonitorBase.h @@ -1,7 +1,7 @@ #ifndef MONITORBASE_H_ #define MONITORBASE_H_ -#include +#include #include #include #include @@ -48,7 +48,7 @@ public: protected: virtual ReturnValue_t fetchSample(T* sample) { - DataSet mySet; + GlobDataSet mySet; PIDReader parameter(this->parameterId, &mySet); mySet.read(); if (!parameter.isValid()) { diff --git a/power/Fuse.cpp b/power/Fuse.cpp index 04079bb0..eee91984 100644 --- a/power/Fuse.cpp +++ b/power/Fuse.cpp @@ -12,7 +12,7 @@ Fuse::Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, SystemObject(fuseObjectId), oldFuseState(0), fuseId(fuseId), powerIF( NULL), currentLimit(fuseObjectId, 1, ids.pidCurrent, confirmationCount, maxCurrent, FUSE_CURRENT_HIGH), powerMonitor(fuseObjectId, 2, - DataPool::poolIdAndPositionToPid(ids.poolIdPower, 0), + GlobalDataPool::poolIdAndPositionToPid(ids.poolIdPower, 0), confirmationCount), set(), voltage(ids.pidVoltage, &set), current( ids.pidCurrent, &set), state(ids.pidState, &set), power( ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE), commandQueue( diff --git a/power/Fuse.h b/power/Fuse.h index aee03778..a826a125 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -1,7 +1,7 @@ #ifndef FUSE_H_ #define FUSE_H_ -#include +#include #include #include #include @@ -83,11 +83,11 @@ private: }; PowerMonitor powerMonitor; - DataSet set; + GlobDataSet set; PIDReader voltage; PIDReader current; PIDReader state; - db_float_t power; + gp_float_t power; MessageQueueIF* commandQueue; ParameterHelper parameterHelper; HealthHelper healthHelper; diff --git a/power/PowerSensor.h b/power/PowerSensor.h index 922560d0..566f93ca 100644 --- a/power/PowerSensor.h +++ b/power/PowerSensor.h @@ -1,7 +1,7 @@ #ifndef POWERSENSOR_H_ #define POWERSENSOR_H_ -#include +#include #include #include #include @@ -53,12 +53,12 @@ private: MessageQueueIF* commandQueue; ParameterHelper parameterHelper; HealthHelper healthHelper; - DataSet set; + GlobDataSet set; //Variables in PIDReader current; PIDReader voltage; //Variables out - db_float_t power; + gp_float_t power; static const uint8_t MODULE_ID_CURRENT = 1; static const uint8_t MODULE_ID_VOLTAGE = 2; diff --git a/thermal/CoreComponent.cpp b/thermal/CoreComponent.cpp index 304712ef..657e79cb 100644 --- a/thermal/CoreComponent.cpp +++ b/thermal/CoreComponent.cpp @@ -2,7 +2,7 @@ CoreComponent::CoreComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId, uint32_t targetStatePoolId, - uint32_t currentStatePoolId, uint32_t requestPoolId, DataSet* dataSet, + uint32_t currentStatePoolId, uint32_t requestPoolId, GlobDataSet* dataSet, AbstractTemperatureSensor* sensor, AbstractTemperatureSensor* firstRedundantSensor, AbstractTemperatureSensor* secondRedundantSensor, @@ -18,14 +18,14 @@ CoreComponent::CoreComponent(object_id_t reportingObjectId, uint8_t domainId, AbstractTemperatureSensor::ZERO_KELVIN_C), parameters( parameters), temperatureMonitor(reportingObjectId, domainId + 1, - DataPool::poolIdAndPositionToPid(temperaturePoolId, 0), + GlobalDataPool::poolIdAndPositionToPid(temperaturePoolId, 0), COMPONENT_TEMP_CONFIRMATION), domainId(domainId) { if (thermalModule != NULL) { thermalModule->registerComponent(this, priority); } //Set thermal state once, then leave to operator. - DataSet mySet; - PoolVariable writableTargetState(targetStatePoolId, &mySet, + GlobDataSet mySet; + gp_uint8_t writableTargetState(targetStatePoolId, &mySet, PoolVariableIF::VAR_WRITE); writableTargetState = initialTargetState; mySet.commit(PoolVariableIF::VALID); @@ -70,8 +70,8 @@ float CoreComponent::getLowerOpLimit() { } ReturnValue_t CoreComponent::setTargetState(int8_t newState) { - DataSet mySet; - PoolVariable writableTargetState(targetState.getDataPoolId(), + GlobDataSet mySet; + gp_uint8_t writableTargetState(targetState.getDataPoolId(), &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if ((writableTargetState == STATE_REQUEST_OPERATIONAL) diff --git a/thermal/CoreComponent.h b/thermal/CoreComponent.h index da77c65b..0b87d889 100644 --- a/thermal/CoreComponent.h +++ b/thermal/CoreComponent.h @@ -1,7 +1,7 @@ #ifndef MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ #define MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ -#include +#include #include #include #include @@ -23,7 +23,7 @@ public: CoreComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId, uint32_t targetStatePoolId, uint32_t currentStatePoolId, - uint32_t requestPoolId, DataSet *dataSet, + uint32_t requestPoolId, GlobDataSet *dataSet, AbstractTemperatureSensor *sensor, AbstractTemperatureSensor *firstRedundantSensor, AbstractTemperatureSensor *secondRedundantSensor, @@ -58,10 +58,10 @@ protected: AbstractTemperatureSensor *secondRedundantSensor; ThermalModuleIF *thermalModule; - db_float_t temperature; - db_int8_t targetState; - db_int8_t currentState; - db_uint8_t heaterRequest; + gp_float_t temperature; + gp_int8_t targetState; + gp_int8_t currentState; + gp_uint8_t heaterRequest; bool isHeating; diff --git a/thermal/ThermalModule.h b/thermal/ThermalModule.h index e65560cd..65fa13a6 100644 --- a/thermal/ThermalModule.h +++ b/thermal/ThermalModule.h @@ -1,7 +1,7 @@ #ifndef THERMALMODULE_H_ #define THERMALMODULE_H_ -#include +#include #include #include #include @@ -23,10 +23,10 @@ public: }; ThermalModule(uint32_t moduleTemperaturePoolId, uint32_t currentStatePoolId, - uint32_t targetStatePoolId, DataSet *dataSet, Parameters parameters, + uint32_t targetStatePoolId, GlobDataSet *dataSet, Parameters parameters, RedundantHeater::Parameters heaterParameters); - ThermalModule(uint32_t moduleTemperaturePoolId, DataSet *dataSet); + ThermalModule(uint32_t moduleTemperaturePoolId, GlobDataSet *dataSet); virtual ~ThermalModule(); From 5b8a6e35dcc3e36715e2eaa39345744e3b2ebaef Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 13:37:50 +0200 Subject: [PATCH 02/14] renaming complete, pool in namespace --- datapool/PIDReader.h | 2 +- datapool/PoolRawAccess.cpp | 4 ++-- datapoolglob/DataPoolAdmin.cpp | 10 +++++----- datapoolglob/GlobalDataPool.h | 3 +++ datapoolglob/GlobalDataSet.cpp | 4 ++-- datapoolglob/GlobalPoolVariable.tpp | 4 ++-- datapoolglob/GlobalPoolVector.h | 4 ++-- devicehandlers/DeviceHandlerBase.cpp | 2 +- devicehandlers/DeviceHandlerBase.h | 3 ++- framework.mk | 2 ++ thermal/TemperatureSensor.h | 8 ++++---- thermal/ThermalComponent.cpp | 6 +++--- thermal/ThermalComponent.h | 2 +- thermal/ThermalModule.cpp | 8 ++++---- thermal/ThermalModule.h | 6 +++--- 15 files changed, 37 insertions(+), 31 deletions(-) diff --git a/datapool/PIDReader.h b/datapool/PIDReader.h index 3a815cee..f83fa3b9 100644 --- a/datapool/PIDReader.h +++ b/datapool/PIDReader.h @@ -17,7 +17,7 @@ protected: uint8_t valid; ReturnValue_t read() { uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId); - PoolEntry* read_out = ::dataPool.getData( + PoolEntry* read_out = glob::dataPool.getData( GlobalDataPool::PIDToDataPoolId(parameterId), arrayIndex); if (read_out != NULL) { valid = read_out->valid; diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index 97bdc2b3..aea84612 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -19,7 +19,7 @@ PoolRawAccess::~PoolRawAccess() { } ReturnValue_t PoolRawAccess::read() { - PoolEntryIF* read_out = ::dataPool.getRawData(dataPoolId); + PoolEntryIF* read_out = glob::dataPool.getRawData(dataPoolId); if (read_out != NULL) { valid = read_out->getValid(); if (read_out->getSize() > arrayEntry) { @@ -52,7 +52,7 @@ ReturnValue_t PoolRawAccess::read() { } ReturnValue_t PoolRawAccess::commit() { - PoolEntryIF* write_back = ::dataPool.getRawData(dataPoolId); + PoolEntryIF* write_back = glob::dataPool.getRawData(dataPoolId); if ((write_back != NULL) && (readWriteMode != VAR_READ)) { write_back->setValid(valid); uint8_t array_position = arrayEntry * typeSize; diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index 59bd9f30..2779ce5c 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -38,7 +38,7 @@ ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, uint8_t valid = data[4]; - uint32_t poolId = ::dataPool.PIDToDataPoolId(address); + uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); GlobDataSet mySet; PoolRawAccess variable(poolId, 0, &mySet, PoolVariableIF::VAR_READ_WRITE); @@ -90,8 +90,8 @@ void DataPoolAdmin::handleCommand() { ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, const uint8_t* data, uint32_t size, uint8_t** dataPointer) { - uint32_t poolId = ::dataPool.PIDToDataPoolId(address); - uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); + uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); + uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address); GlobDataSet testSet; PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet, PoolVariableIF::VAR_READ); @@ -129,8 +129,8 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, uint8_t** dataPointer, uint8_t* copyHere) { - uint32_t poolId = ::dataPool.PIDToDataPoolId(address); - uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); + uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); + uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address); GlobDataSet testSet; PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet, PoolVariableIF::VAR_READ); diff --git a/datapoolglob/GlobalDataPool.h b/datapoolglob/GlobalDataPool.h index e0c086ad..42921a77 100644 --- a/datapoolglob/GlobalDataPool.h +++ b/datapoolglob/GlobalDataPool.h @@ -142,5 +142,8 @@ public: }; //We assume someone globally instantiates a DataPool. +namespace glob { extern GlobalDataPool dataPool; +} + #endif /* DATAPOOL_H_ */ diff --git a/datapoolglob/GlobalDataSet.cpp b/datapoolglob/GlobalDataSet.cpp index 7409dbbd..6e09a398 100644 --- a/datapoolglob/GlobalDataSet.cpp +++ b/datapoolglob/GlobalDataSet.cpp @@ -111,11 +111,11 @@ ReturnValue_t GlobDataSet::handleUnreadDatasetCommit() { } ReturnValue_t GlobDataSet::unlockDataPool() { - return ::dataPool.freeDataPoolLock(); + return glob::dataPool.freeDataPoolLock(); } ReturnValue_t GlobDataSet::lockDataPool() { - return ::dataPool.lockDataPool(); + return glob::dataPool.lockDataPool(); } ReturnValue_t GlobDataSet::serialize(uint8_t** buffer, size_t* size, diff --git a/datapoolglob/GlobalPoolVariable.tpp b/datapoolglob/GlobalPoolVariable.tpp index 287f06dd..21b648e6 100644 --- a/datapoolglob/GlobalPoolVariable.tpp +++ b/datapoolglob/GlobalPoolVariable.tpp @@ -13,7 +13,7 @@ inline GlobPoolVar::GlobPoolVar(uint32_t set_id, template inline ReturnValue_t GlobPoolVar::read() { - PoolEntry* read_out = ::dataPool.getData(dataPoolId, 1); + PoolEntry* read_out = glob::dataPool.getData(dataPoolId, 1); if (read_out != NULL) { valid = read_out->valid; value = *(read_out->address); @@ -29,7 +29,7 @@ inline ReturnValue_t GlobPoolVar::read() { template inline ReturnValue_t GlobPoolVar::commit() { - PoolEntry* write_back = ::dataPool.getData(dataPoolId, 1); + PoolEntry* write_back = glob::dataPool.getData(dataPoolId, 1); if ((write_back != NULL) && (readWriteMode != VAR_READ)) { write_back->valid = valid; *(write_back->address) = value; diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h index 47381aec..8d2488ea 100644 --- a/datapoolglob/GlobalPoolVector.h +++ b/datapoolglob/GlobalPoolVector.h @@ -50,7 +50,7 @@ protected: * The operation does NOT provide any mutual exclusive protection by itself. */ ReturnValue_t read() { - PoolEntry* read_out = ::dataPool.getData(this->dataPoolId, + PoolEntry* read_out = glob::dataPool.getData(this->dataPoolId, vector_size); if (read_out != NULL) { this->valid = read_out->valid; @@ -74,7 +74,7 @@ protected: * */ ReturnValue_t commit() { - PoolEntry* write_back = ::dataPool.getData(this->dataPoolId, + PoolEntry* write_back = glob::dataPool.getData(this->dataPoolId, vector_size); if ((write_back != NULL) && (this->readWriteMode != VAR_READ)) { write_back->valid = valid; diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 0549bd45..740bb383 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1141,7 +1141,7 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, } ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result = acceptExternalDeviceCommands(); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 379992b1..82cf6cab 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -482,7 +482,8 @@ public: virtual void setParentQueue(MessageQueueId_t parentQueueId); ReturnValue_t executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size); + MessageQueueId_t commandedBy, const uint8_t* data, + size_t size) override; Mode_t getTransitionSourceMode() const; Submode_t getTransitionSourceSubMode() const; virtual void getMode(Mode_t *mode, Submode_t *submode); diff --git a/framework.mk b/framework.mk index 6f64b720..cb3e4f22 100644 --- a/framework.mk +++ b/framework.mk @@ -8,6 +8,8 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/controller/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/coordinates/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datalinklayer/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapool/*.cpp) +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapoolglob/*.cpp) +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapoollocal/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/devicehandlers/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/eventmatching/*.cpp) diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index 96dedc99..cd277784 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -2,7 +2,7 @@ #define TEMPERATURESENSOR_H_ #include -#include +#include #include /** @@ -68,12 +68,12 @@ public: TemperatureSensor(object_id_t setObjectid, inputType *inputValue, PoolVariableIF *poolVariable, uint8_t vectorIndex, uint32_t datapoolId, Parameters parameters = {0, 0, 0, 0, 0, 0}, - DataSet *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) : + GlobDataSet *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) : AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters), inputValue(inputValue), poolVariable(poolVariable), outputTemperature(datapoolId, outputSet, PoolVariableIF::VAR_WRITE), sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, - DataPool::poolIdAndPositionToPid(poolVariable->getDataPoolId(), vectorIndex), + GlobalDataPool::poolIdAndPositionToPid(poolVariable->getDataPoolId(), vectorIndex), DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit, TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), oldTemperature(20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) { @@ -111,7 +111,7 @@ protected: PoolVariableIF *poolVariable; - PoolVariable outputTemperature; + gp_float_t outputTemperature; LimitMonitor sensorMonitor; diff --git a/thermal/ThermalComponent.cpp b/thermal/ThermalComponent.cpp index ffe7ba7b..d7024662 100644 --- a/thermal/ThermalComponent.cpp +++ b/thermal/ThermalComponent.cpp @@ -3,7 +3,7 @@ ThermalComponent::ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId, uint32_t targetStatePoolId, uint32_t currentStatePoolId, - uint32_t requestPoolId, DataSet* dataSet, + uint32_t requestPoolId, GlobDataSet* dataSet, AbstractTemperatureSensor* sensor, AbstractTemperatureSensor* firstRedundantSensor, AbstractTemperatureSensor* secondRedundantSensor, @@ -22,8 +22,8 @@ ThermalComponent::~ThermalComponent() { } ReturnValue_t ThermalComponent::setTargetState(int8_t newState) { - DataSet mySet; - PoolVariable writableTargetState(targetState.getDataPoolId(), + GlobDataSet mySet; + gp_int8_t writableTargetState(targetState.getDataPoolId(), &mySet, PoolVariableIF::VAR_READ_WRITE); mySet.read(); if ((writableTargetState == STATE_REQUEST_OPERATIONAL) diff --git a/thermal/ThermalComponent.h b/thermal/ThermalComponent.h index afe9aa10..195f03b1 100644 --- a/thermal/ThermalComponent.h +++ b/thermal/ThermalComponent.h @@ -44,7 +44,7 @@ public: */ ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId, uint32_t targetStatePoolId, uint32_t currentStatePoolId, uint32_t requestPoolId, - DataSet *dataSet, AbstractTemperatureSensor *sensor, + GlobDataSet *dataSet, AbstractTemperatureSensor *sensor, AbstractTemperatureSensor *firstRedundantSensor, AbstractTemperatureSensor *secondRedundantSensor, ThermalModuleIF *thermalModule, Parameters parameters, diff --git a/thermal/ThermalModule.cpp b/thermal/ThermalModule.cpp index 24a4c90d..9dc1f237 100644 --- a/thermal/ThermalModule.cpp +++ b/thermal/ThermalModule.cpp @@ -6,7 +6,7 @@ ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, uint32_t currentStatePoolId, uint32_t targetStatePoolId, - DataSet *dataSet, Parameters parameters, + GlobDataSet *dataSet, Parameters parameters, RedundantHeater::Parameters heaterParameters) : oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating( false), parameters(parameters), moduleTemperature( @@ -16,7 +16,7 @@ ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, heater = new RedundantHeater(heaterParameters); } -ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, DataSet* dataSet) : +ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, GlobDataSet* dataSet) : oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating( false), parameters( { 0, 0 }), moduleTemperature( moduleTemperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), heater( @@ -250,8 +250,8 @@ bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus( } void ThermalModule::setHeating(bool on) { - DataSet mySet; - PoolVariable writableTargetState(targetState.getDataPoolId(), + GlobDataSet mySet; + gp_int8_t writableTargetState(targetState.getDataPoolId(), &mySet, PoolVariableIF::VAR_WRITE); if (on) { writableTargetState = STATE_REQUEST_HEATING; diff --git a/thermal/ThermalModule.h b/thermal/ThermalModule.h index 65fa13a6..b9e8d8b8 100644 --- a/thermal/ThermalModule.h +++ b/thermal/ThermalModule.h @@ -70,12 +70,12 @@ protected: Parameters parameters; - db_float_t moduleTemperature; + gp_float_t moduleTemperature; RedundantHeater *heater; - db_int8_t currentState; - db_int8_t targetState; + gp_int8_t currentState; + gp_int8_t targetState; std::list sensors; std::list components; From 9056ad36ed69575e499376558839d0bc044ca4d3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 14:13:31 +0200 Subject: [PATCH 03/14] object manager better output --- datapoolglob/GlobalPoolVector.h | 3 +++ objectmanager/ObjectManager.cpp | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h index 8d2488ea..63536934 100644 --- a/datapoolglob/GlobalPoolVector.h +++ b/datapoolglob/GlobalPoolVector.h @@ -220,4 +220,7 @@ public: } }; +template +using gp_vec_t = GlobPoolVector; + #endif /* POOLVECTOR_H_ */ diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 2f99e1a5..1912715d 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -67,9 +67,9 @@ void ObjectManager::initialize() { return_value = it->second->initialize(); if ( return_value != RETURN_OK ) { object_id_t var = it->first; - sif::error << "Object " << std::hex << (int) var - << " failed to initialize with code 0x" << return_value - << std::dec << std::endl; + sif::error << "Object 0x" << std::hex << std::setw(8) << + std::setfill('0')<< var << " failed to initialize " << + "with code 0x" << return_value << std::dec << std::endl; error_count++; } } From e9a4056deb17756f70973d6f383182fbabdf90b2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 15:19:24 +0200 Subject: [PATCH 04/14] added DHB cookie init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (why was that never a problem beofre????) ¯\_(ツ)_/¯ --- devicehandlers/DeviceHandlerBase.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 740bb383..22224c12 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -23,8 +23,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, size_t cmdQueueSize) : SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), - deviceCommunicationId(deviceCommunication), deviceThermalStatePoolId( - thermalStatePoolId),deviceThermalRequestPoolId(thermalRequestPoolId), + deviceCommunicationId(deviceCommunication), comCookie(comCookie), + deviceThermalStatePoolId(thermalStatePoolId), + deviceThermalRequestPoolId(thermalRequestPoolId), healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), From 8b1fef730dcb4cd4f21c3f90121b1c6a74758f63 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 18:02:58 +0200 Subject: [PATCH 05/14] resolved conflict --- devicehandlers/DeviceHandlerBase.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index c48fbe5e..454f0751 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -614,11 +614,7 @@ protected: /** * Cookie used for communication */ -<<<<<<< HEAD - CookieIF * comCookie = nullptr; -======= CookieIF * comCookie; ->>>>>>> mueller_framework struct DeviceCommandInfo { bool isExecuting; //!< Indicates if the command is already executing. From 9da0b0b2b299b7abeb9b73dd8fdb624942de996c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 22:16:25 +0200 Subject: [PATCH 06/14] glob pool vec implementation in tpp file --- datapoolglob/GlobalPoolVector.h | 270 ++++++++++++------------------ datapoolglob/GlobalPoolVector.tpp | 83 +++++++++ 2 files changed, 186 insertions(+), 167 deletions(-) create mode 100644 datapoolglob/GlobalPoolVector.tpp diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h index 63536934..d55fd777 100644 --- a/datapoolglob/GlobalPoolVector.h +++ b/datapoolglob/GlobalPoolVector.h @@ -1,5 +1,5 @@ -#ifndef POOLVECTOR_H_ -#define POOLVECTOR_H_ +#ifndef GLOBALPOOLVECTOR_H_ +#define GLOBALPOOLVECTOR_H_ #include #include @@ -8,139 +8,79 @@ #include /** - * \brief This is the access class for array-type data pool entries. + * @brief This is the access class for array-type data pool entries. * - * \details To ensure safe usage of the data pool, operation is not done directly on the data pool - * entries, but on local copies. This class provides simple type- and length-safe access - * to vector-style data pool entries (i.e. entries with length > 1). - * The class can be instantiated as read-write and read only. - * It provides a commit-and-roll-back semantic, which means that no array entry in - * the data pool is changed until the commit call is executed. - * There are two template parameters: - * \tparam T This template parameter specifies the data type of an array entry. Currently, all - * plain data types are supported, but in principle any type is possible. - * \tparam vector_size This template parameter specifies the vector size of this entry. - * Using a template parameter for this is not perfect, but avoids dynamic memory allocation. - * \ingroup data_pool + * @details + * To ensure safe usage of the data pool, operation is not done directly on the + * data pool entries, but on local copies. This class provides simple type- + * and length-safe access to vector-style data pool entries (i.e. entries with + * length > 1). The class can be instantiated as read-write and read only. + * + * It provides a commit-and-roll-back semantic, which means that no array + * entry in the data pool is changed until the commit call is executed. + * There are two template parameters: + * @tparam T + * This template parameter specifies the data type of an array entry. Currently, + * all plain data types are supported, but in principle any type is possible. + * @tparam vector_size + * This template parameter specifies the vector size of this entry. Using a + * template parameter for this is not perfect, but avoids + * dynamic memory allocation. + * @ingroup data_pool */ -template +template class GlobPoolVector: public PoolVariableIF { -private: - /** - * \brief To access the correct data pool entry on read and commit calls, the data pool id - * is stored. - */ - uint32_t dataPoolId; - /** - * \brief The valid information as it was stored in the data pool is copied to this attribute. - */ - uint8_t valid; - /** - * \brief The information whether the class is read-write or read-only is stored here. - */ - ReadWriteMode_t readWriteMode; - -protected: - /** - * \brief This is a call to read the array's values from the global data pool. - * \details When executed, this operation tries to fetch the pool entry with matching - * data pool id from the global data pool and copies all array values and the valid - * information to its local attributes. In case of a failure (wrong type, size or - * pool id not found), the variable is set to zero and invalid. - * The operation does NOT provide any mutual exclusive protection by itself. - */ - ReturnValue_t read() { - PoolEntry* read_out = glob::dataPool.getData(this->dataPoolId, - vector_size); - if (read_out != NULL) { - this->valid = read_out->valid; - memcpy(this->value, read_out->address, read_out->getByteSize()); - - return HasReturnvaluesIF::RETURN_OK; - - } else { - memset(this->value, 0, vector_size * sizeof(T)); - sif::error << "PoolVector: read of DP Variable 0x" << std::hex - << dataPoolId << std::dec << " failed." << std::endl; - this->valid = INVALID; - return HasReturnvaluesIF::RETURN_FAILED; - } - } - /** - * \brief The commit call copies the array values back to the data pool. - * \details It checks type and size, as well as if the variable is writable. If so, - * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. - * - */ - ReturnValue_t commit() { - PoolEntry* write_back = glob::dataPool.getData(this->dataPoolId, - vector_size); - if ((write_back != NULL) && (this->readWriteMode != VAR_READ)) { - write_back->valid = valid; - memcpy(write_back->address, this->value, write_back->getByteSize()); - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } - } public: /** - * \brief This is the local copy of the data pool entry. - * \detials The user can work on this attribute - * just like he would on a local array of this type. - */ - T value[vector_size]; - /** - * \brief In the constructor, the variable can register itself in a DataSet (if not NULL is - * passed). - * \details It DOES NOT fetch the current value from the data pool, but sets the value - * attribute to default (0). The value is fetched within the read() operation. - * \param set_id This is the id in the global data pool this instance of the access class - * corresponds to. - * \param dataSet The data set in which the variable shall register itself. If NULL, - * the variable is not registered. - * \param setWritable If this flag is set to true, changes in the value attribute can be - * written back to the data pool, otherwise not. + * @brief In the constructor, the variable can register itself in a + * DataSet (if no nullptr is passed). + * @details + * It DOES NOT fetch the current value from the data pool, but sets the + * value attribute to default (0). The value is fetched within the + * read() operation. + * @param set_id + * This is the id in the global data pool this instance of the access + * class corresponds to. + * @param dataSet + * The data set in which the variable shall register itself. If nullptr, + * the variable is not registered. + * @param setWritable + * If this flag is set to true, changes in the value attribute can be + * written back to the data pool, otherwise not. */ GlobPoolVector(uint32_t set_id, DataSetIF* set, - ReadWriteMode_t setReadWriteMode) : - dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) { - memset(this->value, 0, vector_size * sizeof(T)); - if (set != NULL) { - set->registerVariable(this); - } - } + ReadWriteMode_t setReadWriteMode); + /** - * Copy ctor to copy classes containing Pool Variables. + * @brief This is the local copy of the data pool entry. + * @details The user can work on this attribute + * just like he would on a local array of this type. */ -// PoolVector(const PoolVector& rhs) { -// PoolVector temp(rhs.dataPoolId, rhs.) -// memcpy(value, rhs.value, sizeof(T)*vector_size); -// } + T value[vectorSize]; /** - * \brief The classes destructor is empty. - * \details If commit() was not called, the local value is + * @brief The classes destructor is empty. + * @details If commit() was not called, the local value is * discarded and not written back to the data pool. */ - ~GlobPoolVector() { - } - ; + ~GlobPoolVector() {}; /** - * \brief The operation returns the number of array entries in this variable. + * @brief The operation returns the number of array entries + * in this variable. */ uint8_t getSize() { - return vector_size; + return vectorSize; } /** - * \brief This operation returns the data pool id of the variable. + * @brief This operation returns the data pool id of the variable. */ uint32_t getDataPoolId() const { return dataPoolId; } /** - * This operation sets the data pool id of the variable. - * The method is necessary to set id's of data pool member variables with bad initialization. + * @brief This operation sets the data pool id of the variable. + * @details + * The method is necessary to set id's of data pool member variables + * with bad initialization. */ void setDataPoolId(uint32_t poolId) { dataPoolId = poolId; @@ -151,9 +91,10 @@ public: ReadWriteMode_t getReadWriteMode() const { return readWriteMode; } - ; + + /** - * \brief With this call, the valid information of the variable is returned. + * @brief With this call, the valid information of the variable is returned. */ bool isValid() const { if (valid != INVALID) @@ -161,65 +102,60 @@ public: else return false; } + void setValid(uint8_t valid) {this->valid = valid;} + uint8_t getValid() {return valid;} - void setValid(uint8_t valid) { - this->valid = valid; - } - - uint8_t getValid() { - return valid; - } - - T &operator [](int i) { - return value[i]; - } - - const T &operator [](int i) const { - return value[i]; - } - - GlobPoolVector &operator=( - GlobPoolVector newPoolVector) { - - for (uint16_t i = 0; i < vector_size; i++) { - this->value[i] = newPoolVector.value[i]; - } - return *this; - } + T &operator [](int i) {return value[i];} + const T &operator [](int i) const {return value[i];} virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override { - uint16_t i; - ReturnValue_t result; - for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::serialize(&(value[i]), buffer, size, - max_size, bigEndian); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - } - return result; - } - - virtual size_t getSerializedSize() const override { - return vector_size * SerializeAdapter::getSerializedSize(value); - } + const size_t max_size, bool bigEndian) const override; + virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override { - uint16_t i; - ReturnValue_t result; - for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, - bigEndian); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - } - return result; - } + bool bigEndian) override; +protected: + /** + * @brief This is a call to read the array's values + * from the global data pool. + * @details + * When executed, this operation tries to fetch the pool entry with matching + * data pool id from the global data pool and copies all array values + * and the valid information to its local attributes. + * In case of a failure (wrong type, size or pool id not found), the + * variable is set to zero and invalid. The operation does NOT provide + * any mutual exclusive protection by itself. + */ + ReturnValue_t read(); + + /** + * @brief The commit call copies the array values back to the data pool. + * @details + * It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the valid flag is automatically set to "valid". + * The operation does NOT provide any mutual exclusive protection by itself. + */ + ReturnValue_t commit(); +private: + /** + * @brief To access the correct data pool entry on read and commit calls, + * the data pool id is stored. + */ + uint32_t dataPoolId; + /** + * @brief The valid information as it was stored in the data pool + * is copied to this attribute. + */ + uint8_t valid; + /** + * @brief The information whether the class is read-write or + * read-only is stored here. + */ + ReadWriteMode_t readWriteMode; }; +#include + template using gp_vec_t = GlobPoolVector; diff --git a/datapoolglob/GlobalPoolVector.tpp b/datapoolglob/GlobalPoolVector.tpp new file mode 100644 index 00000000..0b43191b --- /dev/null +++ b/datapoolglob/GlobalPoolVector.tpp @@ -0,0 +1,83 @@ +#ifndef GLOBALPOOLVECTOR_TPP_ +#define GLOBALPOOLVECTOR_TPP_ + + +template +inline GlobPoolVector::GlobPoolVector(uint32_t set_id, + DataSetIF* set, ReadWriteMode_t setReadWriteMode) : + dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) { + memset(this->value, 0, vectorSize * sizeof(T)); + if (set != nullptr) { + set->registerVariable(this); + } +} + +template +inline ReturnValue_t GlobPoolVector::read() { + PoolEntry* read_out = glob::dataPool.getData(this->dataPoolId, + vectorSize); + if (read_out != nullptr) { + this->valid = read_out->valid; + memcpy(this->value, read_out->address, read_out->getByteSize()); + + return HasReturnvaluesIF::RETURN_OK; + + } else { + memset(this->value, 0, vectorSize * sizeof(T)); + sif::error << "PoolVector: Read of DP Variable 0x" << std::hex + << std::setw(8) << std::setfill('0') << dataPoolId << + std::dec << " failed." << std::endl; + this->valid = INVALID; + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +template +inline ReturnValue_t GlobPoolVector::commit() { + PoolEntry* writeBack = glob::dataPool.getData(this->dataPoolId, + vectorSize); + if ((writeBack != nullptr) && (this->readWriteMode != VAR_READ)) { + writeBack->valid = valid; + memcpy(writeBack->address, this->value, writeBack->getByteSize()); + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +template +inline ReturnValue_t GlobPoolVector::serialize(uint8_t** buffer, + size_t* size, const size_t max_size, bool bigEndian) const { + uint16_t i; + ReturnValue_t result; + for (i = 0; i < vectorSize; i++) { + result = SerializeAdapter::serialize(&(value[i]), buffer, size, + max_size, bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; +} + +template +inline size_t GlobPoolVector::getSerializedSize() const { + return vectorSize * SerializeAdapter::getSerializedSize(value); +} + +template +inline ReturnValue_t GlobPoolVector::deSerialize( + const uint8_t** buffer, size_t* size, bool bigEndian) { + uint16_t i; + ReturnValue_t result; + for (i = 0; i < vectorSize; i++) { + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, + bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; +} + +#endif From 71f1722b886d002a0b8fe550771ee1ed4cde1cc3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 22:20:54 +0200 Subject: [PATCH 07/14] removed old poolVar file --- datapool/PoolVariable.h | 294 ------------------------ datapoolglob/GlobalPoolVariable.h | 4 +- datapoolglob/GlobalPoolVariable.tpp | 5 +- datapoolglob/GlobalPoolVector.h | 1 - devicehandlers/DeviceHandlerBase.cpp | 2 +- internalError/InternalErrorReporter.cpp | 2 +- power/PowerSensor.h | 2 +- thermal/CoreComponent.h | 2 +- thermal/ThermalModule.h | 2 +- 9 files changed, 11 insertions(+), 303 deletions(-) delete mode 100644 datapool/PoolVariable.h diff --git a/datapool/PoolVariable.h b/datapool/PoolVariable.h deleted file mode 100644 index f5442a25..00000000 --- a/datapool/PoolVariable.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * \file PoolVariable.h - * - * \brief This file contains the PoolVariable class, which locally represents a non-array data pool variable. - * - * \date 10/17/2012 - * - * \author Bastian Baetz - */ - -#ifndef POOLVARIABLE_H_ -#define POOLVARIABLE_H_ - -#include -#include -#include -#include -#include - -template class PoolVarList; - -/** - * \brief This is the access class for non-array data pool entries. - * - * \details To ensure safe usage of the data pool, operation is not done directly on the data pool - * entries, but on local copies. This class provides simple type-safe access to single - * data pool entries (i.e. entries with length = 1). - * The class can be instantiated as read-write and read only. - * It provides a commit-and-roll-back semantic, which means that the variable's value in - * the data pool is not changed until the commit call is executed. - * \tparam T The template parameter sets the type of the variable. Currently, all plain data types - * are supported, but in principle any type is possible. - * \ingroup data_pool - */ -template -class PoolVariable: public PoolVariableIF { - template friend class PoolVarList; -protected: - /** - * \brief To access the correct data pool entry on read and commit calls, the data pool id - * is stored. - */ - uint32_t dataPoolId; - /** - * \brief The valid information as it was stored in the data pool is copied to this attribute. - */ - uint8_t valid; - /** - * \brief The information whether the class is read-write or read-only is stored here. - */ - ReadWriteMode_t readWriteMode; - /** - * \brief This is a call to read the value from the global data pool. - * \details When executed, this operation tries to fetch the pool entry with matching - * data pool id from the global data pool and copies the value and the valid - * information to its local attributes. In case of a failure (wrong type or - * pool id not found), the variable is set to zero and invalid. - * The operation does NOT provide any mutual exclusive protection by itself. - */ - ReturnValue_t read() { - PoolEntry* read_out = ::dataPool.getData(dataPoolId, 1); - if (read_out != NULL) { - valid = read_out->valid; - value = *(read_out->address); - return HasReturnvaluesIF::RETURN_OK; - } else { - value = 0; - valid = false; - sif::error << "PoolVariable: read of DP Variable 0x" << std::hex - << dataPoolId << std::dec << " failed." << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - } - /** - * \brief The commit call writes back the variable's value to the data pool. - * \details It checks type and size, as well as if the variable is writable. If so, - * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. - * - */ - ReturnValue_t commit() { - PoolEntry* write_back = ::dataPool.getData(dataPoolId, 1); - if ((write_back != NULL) && (readWriteMode != VAR_READ)) { - write_back->valid = valid; - *(write_back->address) = value; - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } - } - /** - * Empty ctor for List initialization - */ - PoolVariable() : - dataPoolId(PoolVariableIF::NO_PARAMETER), valid( - PoolVariableIF::INVALID), readWriteMode(VAR_READ), value(0) { - - } -public: - /** - * \brief This is the local copy of the data pool entry. - * \details The user can work on this attribute - * just like he would on a simple local variable. - */ - T value; - /** - * \brief In the constructor, the variable can register itself in a DataSet (if not NULL is - * passed). - * \details It DOES NOT fetch the current value from the data pool, but sets the value - * attribute to default (0). The value is fetched within the read() operation. - * \param set_id This is the id in the global data pool this instance of the access class - * corresponds to. - * \param dataSet The data set in which the variable shall register itself. If NULL, - * the variable is not registered. - * \param setReadWriteMode - */ - PoolVariable(uint32_t set_id, DataSetIF* dataSet, - ReadWriteMode_t setReadWriteMode) : - dataPoolId(set_id), valid(PoolVariableIF::INVALID), readWriteMode( - setReadWriteMode), value(0) { - if (dataSet != NULL) { - dataSet->registerVariable(this); - } - } - /** - * Copy ctor to copy classes containing Pool Variables. - */ - PoolVariable(const PoolVariable& rhs) : - dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode( - rhs.readWriteMode), value(rhs.value) { - } - - /** - * \brief The classes destructor is empty. - * \details If commit() was not called, the local value is - * discarded and not written back to the data pool. - */ - ~PoolVariable() { - - } - /** - * \brief This operation returns the data pool id of the variable. - */ - uint32_t getDataPoolId() const { - return dataPoolId; - } - /** - * This operation sets the data pool id of the variable. - * The method is necessary to set id's of data pool member variables with bad initialization. - */ - void setDataPoolId(uint32_t poolId) { - dataPoolId = poolId; - } - /** - * This method returns if the variable is write-only, read-write or read-only. - */ - ReadWriteMode_t getReadWriteMode() const { - return readWriteMode; - } - /** - * \brief With this call, the valid information of the variable is returned. - */ - bool isValid() const { - if (valid) - return true; - else - return false; - } - - uint8_t getValid() { - return valid; - } - - void setValid(uint8_t valid) { - this->valid = valid; - } - - operator T() { - return value; - } - - operator T() const { - return value; - } - - PoolVariable &operator=(T newValue) { - value = newValue; - return *this; - } - - PoolVariable &operator=(PoolVariable newPoolVariable) { - value = newPoolVariable.value; - return *this; - } - - virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&value, buffer, size, max_size, - bigEndian); - } - - virtual size_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&value); - } - - virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&value, buffer, size, bigEndian); - } -}; - -typedef PoolVariable db_uint8_t; -typedef PoolVariable db_uint16_t; -typedef PoolVariable db_uint32_t; -typedef PoolVariable db_int8_t; -typedef PoolVariable db_int16_t; -typedef PoolVariable db_int32_t; -typedef PoolVariable db_bool_t; -typedef PoolVariable db_float_t; -typedef PoolVariable db_double_t; -//Alternative (but I thing this is not as useful: code duplication, differences too small): - -//template -//class PoolReader : public PoolVariableIF { -//private: -// uint32_t parameter_id; -// uint8_t valid; -//public: -// T value; -// PoolReader( uint32_t set_id, DataSetIF* set ) : parameter_id(set_id), valid(false), value(0) { -// set->registerVariable( this ); -// } -// -// ~PoolReader() {}; -// -// uint8_t commit() { -// return HasReturnvaluesIF::RETURN_OK; -// } -// -// uint8_t read() { -// PoolEntry* read_out = ::dataPool.getData( parameter_id, 1 ); -// if ( read_out != NULL ) { -// valid = read_out->valid; -// value = *(read_out->address); -// return HasReturnvaluesIF::RETURN_OK; -// } else { -// value = 0; -// valid = false; -// return CHECKOUT_FAILED; -// } -// } -// uint32_t getParameterId() { return parameter_id; } -// bool isWritable() { return false; }; -// bool isValid() { if (valid) return true; else return false; } -//}; -// -//template -//class PoolWriter : public PoolVariableIF { -//private: -// uint32_t parameter_id; -//public: -// T value; -// PoolWriter( uint32_t set_id, DataSetIF* set ) : parameter_id(set_id), value(0) { -// set->registerVariable( this ); -// } -// -// ~PoolWriter() {}; -// -// uint8_t commit() { -// PoolEntry* write_back = ::dataPool.getData( parameter_id, 1 ); -// if ( write_back != NULL ) { -// write_back->valid = true; -// *(write_back->address) = value; -// return HasReturnvaluesIF::RETURN_OK; -// } else { -// return CHECKOUT_FAILED; -// } -// } -// uint8_t read() { -// PoolEntry* read_out = ::dataPool.getData( parameter_id, 1 ); -// if ( read_out != NULL ) { -// value = *(read_out->address); -// return HasReturnvaluesIF::RETURN_OK; -// } else { -// value = 0; -// return CHECKOUT_FAILED; -// } -// } -// uint32_t getParameterId() { return parameter_id; } -// bool isWritable() { return true; }; -// bool isValid() { return false; } -//}; - -#endif /* POOLVARIABLE_H_ */ diff --git a/datapoolglob/GlobalPoolVariable.h b/datapoolglob/GlobalPoolVariable.h index 9f80492b..eee9afc1 100644 --- a/datapoolglob/GlobalPoolVariable.h +++ b/datapoolglob/GlobalPoolVariable.h @@ -1,5 +1,5 @@ -#ifndef POOLVARIABLE_H_ -#define POOLVARIABLE_H_ +#ifndef GLOBALPOOLVARIABLE_H_ +#define GLOBALPOOLVARIABLE_H_ #include #include diff --git a/datapoolglob/GlobalPoolVariable.tpp b/datapoolglob/GlobalPoolVariable.tpp index 21b648e6..d55ea4e0 100644 --- a/datapoolglob/GlobalPoolVariable.tpp +++ b/datapoolglob/GlobalPoolVariable.tpp @@ -1,4 +1,5 @@ -#pragma once +#ifndef GLOBALPOOLVARIABLE_TPP_ +#define GLOBALPOOLVARIABLE_TPP_ template inline GlobPoolVar::GlobPoolVar(uint32_t set_id, @@ -82,3 +83,5 @@ template inline void GlobPoolVar::setValid(uint8_t valid) { this->valid = valid; } + +#endif diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h index d55fd777..24303457 100644 --- a/datapoolglob/GlobalPoolVector.h +++ b/datapoolglob/GlobalPoolVector.h @@ -111,7 +111,6 @@ public: virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t max_size, bool bigEndian) const override; virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) override; protected: diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 5bd4c56e..f46f854b 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 72ba434a..a1e96695 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -1,7 +1,7 @@ #include "InternalErrorReporter.h" #include -#include +#include #include #include diff --git a/power/PowerSensor.h b/power/PowerSensor.h index 566f93ca..f94088a8 100644 --- a/power/PowerSensor.h +++ b/power/PowerSensor.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include diff --git a/thermal/CoreComponent.h b/thermal/CoreComponent.h index 0b87d889..a0736c71 100644 --- a/thermal/CoreComponent.h +++ b/thermal/CoreComponent.h @@ -2,7 +2,7 @@ #define MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ #include -#include +#include #include #include #include diff --git a/thermal/ThermalModule.h b/thermal/ThermalModule.h index b9e8d8b8..21414f15 100644 --- a/thermal/ThermalModule.h +++ b/thermal/ThermalModule.h @@ -2,7 +2,7 @@ #define THERMALMODULE_H_ #include -#include +#include #include #include #include "ThermalModuleIF.h" From 1d28e1398ea927a74a0fc492e4db468122d41afa Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 23:41:28 +0200 Subject: [PATCH 08/14] DataSetBase class finished --- datapool/DataSetBase.cpp | 148 ++++++++++++++++++++++++ datapool/DataSetBase.h | 135 +++++++++++++++++++++ datapool/DataSetIF.h | 21 ++++ datapool/PIDReader.h | 2 +- datapool/PoolRawAccess.cpp | 2 +- datapool/PoolRawAccessHelper.cpp | 6 +- datapool/PoolRawAccessHelper.h | 1 + datapool/PoolVariableIF.h | 1 + datapoolglob/DataPoolAdmin.cpp | 4 +- datapoolglob/GlobalDataSet.cpp | 140 ++-------------------- datapoolglob/GlobalDataSet.h | 126 +++----------------- datapoolglob/GlobalPoolVariable.h | 2 +- devicehandlers/DeviceHandlerBase.cpp | 2 +- internalError/InternalErrorReporter.cpp | 2 +- power/Fuse.h | 1 + thermal/TemperatureSensor.h | 1 + 16 files changed, 344 insertions(+), 250 deletions(-) create mode 100644 datapool/DataSetBase.cpp create mode 100644 datapool/DataSetBase.h diff --git a/datapool/DataSetBase.cpp b/datapool/DataSetBase.cpp new file mode 100644 index 00000000..6ff2fc83 --- /dev/null +++ b/datapool/DataSetBase.cpp @@ -0,0 +1,148 @@ +#include +#include + +DataSetBase::DataSetBase() { + for (uint8_t count = 0; count < DATA_SET_MAX_SIZE; count++) { + registeredVariables[count] = nullptr; + } +} + +DataSetBase::~DataSetBase() {} + +ReturnValue_t DataSetBase::registerVariable( + PoolVariableIF *variable) { + if (state != States::DATA_SET_UNINITIALISED) { + sif::error << "DataSet::registerVariable: " + "Call made in wrong position." << std::endl; + return DataSetIF::DATA_SET_UNINITIALISED; + } + if (variable == nullptr) { + sif::error << "DataSet::registerVariable: " + "Pool variable is nullptr." << std::endl; + return DataSetIF::POOL_VAR_NULL; + } + if (fillCount >= DATA_SET_MAX_SIZE) { + sif::error << "DataSet::registerVariable: " + "DataSet is full." << std::endl; + return DataSetIF::DATA_SET_FULL; + } + registeredVariables[fillCount] = variable; + fillCount++; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t DataSetBase::read() { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if (state == States::DATA_SET_UNINITIALISED) { + lockDataPool(); + for (uint16_t count = 0; count < fillCount; count++) { + if (registeredVariables[count]->getReadWriteMode() + != PoolVariableIF::VAR_WRITE + && registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + ReturnValue_t status = registeredVariables[count]->read(); + if (status != HasReturnvaluesIF::RETURN_OK) { + result = INVALID_PARAMETER_DEFINITION; + break; + } + } + } + state = States::DATA_SET_WAS_READ; + unlockDataPool(); + } + else { + sif::error << "DataSet::read(): " + "Call made in wrong position." << std::endl; + result = SET_WAS_ALREADY_READ; + } + return result; +} + +ReturnValue_t DataSetBase::commit() { + if (state == States::DATA_SET_WAS_READ) { + handleAlreadyReadDatasetCommit(); + return HasReturnvaluesIF::RETURN_OK; + } + else { + return handleUnreadDatasetCommit(); + } +} + +ReturnValue_t DataSetBase::lockDataPool() { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t DataSetBase::unlockDataPool() { + return HasReturnvaluesIF::RETURN_FAILED; +} + +void DataSetBase::handleAlreadyReadDatasetCommit() { + lockDataPool(); + for (uint16_t count = 0; count < fillCount; count++) { + if (registeredVariables[count]->getReadWriteMode() + != PoolVariableIF::VAR_READ + && registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + registeredVariables[count]->commit(); + } + } + state = States::DATA_SET_UNINITIALISED; + unlockDataPool(); +} + +ReturnValue_t DataSetBase::handleUnreadDatasetCommit() { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + lockDataPool(); + for (uint16_t count = 0; count < fillCount; count++) { + if (registeredVariables[count]->getReadWriteMode() + == PoolVariableIF::VAR_WRITE + && registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + registeredVariables[count]->commit(); + } else if (registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) { + if (result != COMMITING_WITHOUT_READING) { + sif::error << "DataSet::commit(): commit-without-read call made " + "with non write-only variable." << std::endl; + result = COMMITING_WITHOUT_READING; + } + } + } + state = States::DATA_SET_UNINITIALISED; + unlockDataPool(); + return result; +} + +ReturnValue_t DataSetBase::serialize(uint8_t** buffer, size_t* size, + const size_t maxSize, bool bigEndian) const { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + for (uint16_t count = 0; count < fillCount; count++) { + result = registeredVariables[count]->serialize(buffer, size, maxSize, + bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; +} + +ReturnValue_t DataSetBase::deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + for (uint16_t count = 0; count < fillCount; count++) { + result = registeredVariables[count]->deSerialize(buffer, size, + bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; +} + +size_t DataSetBase::getSerializedSize() const { + uint32_t size = 0; + for (uint16_t count = 0; count < fillCount; count++) { + size += registeredVariables[count]->getSerializedSize(); + } + return size; +} diff --git a/datapool/DataSetBase.h b/datapool/DataSetBase.h new file mode 100644 index 00000000..6b468c11 --- /dev/null +++ b/datapool/DataSetBase.h @@ -0,0 +1,135 @@ +#ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_ +#define FRAMEWORK_DATAPOOL_DATASETBASE_H_ +#include +#include + +/** + * @brief The DataSetBase class manages a set of locally checked out variables. + * @details + * This class manages a list, where a set of local variables (or pool variables) + * are registered. They are checked-out (i.e. their values are looked + * up and copied) with the read call. After the user finishes working with the + * pool variables, he can write back all variable values to the pool with + * the commit call. The data set manages locking and freeing the data pool, + * to ensure that all values are read and written back at once. + * + * An internal state manages usage of this class. Variables may only be + * registered before the read call is made, and the commit call only + * after the read call. + * + * If pool variables are writable and not committed until destruction + * of the set, the DataSet class automatically sets the valid flag in the + * data pool to invalid (without) changing the variable's value. + * + * The base class lockDataPo + * @author Bastian Baetz + * @ingroup data_pool + */ +class DataSetBase: public DataSetIF, + public SerializeIF, + public HasReturnvaluesIF { +public: + + /** + * @brief Creates an empty dataset. Use registerVariable or + * supply a pointer to this dataset to PoolVariable + * initializations to register pool variables. + */ + DataSetBase(); + virtual~ DataSetBase(); + + /** + * @brief The read call initializes reading out all registered variables. + * @details + * It iterates through the list of registered variables and calls all read() + * functions of the registered pool variables (which read out their values + * from the data pool) which are not write-only. + * In case of an error (e.g. a wrong data type, or an invalid data pool id), + * 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. + * @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 SET_WAS_ALREADY_READ if read() is called twice without calling + * commit() in between + */ + virtual ReturnValue_t read(); + + /** + * @brief The commit call initializes writing back the registered variables. + * @details + * It iterates through the list of registered variables and calls the + * commit() method of the remaining registered variables (which write back + * their values to the pool). + * + * The data pool is locked during the whole commit operation and + * freed afterwards. The state changes to "was committed" after this operation. + * + * 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. + * @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 + */ + virtual ReturnValue_t commit(); + + /* DataSetIF implementation */ + virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override; + /** + * Provides the means to lock the underlying data structure to ensure + * thread-safety. Default implementation is empty + * @return Always returns -@c RETURN_OK + */ + virtual ReturnValue_t lockDataPool() override; + /** + * Provides the means to unlock the underlying data structure to ensure + * thread-safety. Default implementation is empty + * @return Always returns -@c RETURN_OK + */ + virtual ReturnValue_t unlockDataPool() override; + + /* SerializeIF implementations */ + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t maxSize, bool bigEndian) const override; + virtual size_t getSerializedSize() const override; + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) override; + + //SHOULDDO we could use a linked list of datapool variables + //!< This definition sets the maximum number of variables to + //! register in one DataSet. + static const uint8_t DATA_SET_MAX_SIZE = 63; +protected: + + /** + * @brief The fill_count attribute ensures that the variables + * register in the correct array position and that the maximum + * number of variables is not exceeded. + */ + uint16_t fillCount = 0; + /** + * States of the seet. + */ + enum class States { + DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED + DATA_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; + + /** + * @brief This array represents all pool variables registered in this set. + */ + PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE] = { }; + + void handleAlreadyReadDatasetCommit(); + ReturnValue_t handleUnreadDatasetCommit(); +}; + +#endif /* FRAMEWORK_DATAPOOL_DATASETBASE_H_ */ diff --git a/datapool/DataSetIF.h b/datapool/DataSetIF.h index 4e351416..d9cc4966 100644 --- a/datapool/DataSetIF.h +++ b/datapool/DataSetIF.h @@ -16,6 +16,17 @@ class PoolVariableIF; */ class DataSetIF { public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS; + static constexpr ReturnValue_t INVALID_PARAMETER_DEFINITION = + MAKE_RETURN_CODE( 0x01 ); + static constexpr ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 ); + static constexpr ReturnValue_t COMMITING_WITHOUT_READING = + MAKE_RETURN_CODE(0x03); + + static constexpr ReturnValue_t DATA_SET_UNINITIALISED = MAKE_RETURN_CODE( 0x04 ); + static constexpr ReturnValue_t DATA_SET_FULL = MAKE_RETURN_CODE( 0x05 ); + static constexpr ReturnValue_t POOL_VAR_NULL = MAKE_RETURN_CODE( 0x06 ); + /** * @brief This is an empty virtual destructor, * as it is proposed for C++ interfaces. @@ -29,7 +40,17 @@ public: */ virtual ReturnValue_t registerVariable( PoolVariableIF* variable ) = 0; + /** + * @brief Most underlying data structures will have a pool like structure + * and will require a lock and unlock mechanism to ensure + * thread-safety + * @return Lock operation result + */ virtual ReturnValue_t lockDataPool() = 0; + /** + * @brief Unlock call corresponding to the lock call. + * @return Unlock operation result + */ virtual ReturnValue_t unlockDataPool() = 0; }; diff --git a/datapool/PIDReader.h b/datapool/PIDReader.h index f83fa3b9..11206611 100644 --- a/datapool/PIDReader.h +++ b/datapool/PIDReader.h @@ -1,9 +1,9 @@ #ifndef PIDREADER_H_ #define PIDREADER_H_ #include +#include #include #include -#include #include #include diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index aea84612..c0bd3c09 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -1,6 +1,6 @@ +#include #include #include -#include #include #include diff --git a/datapool/PoolRawAccessHelper.cpp b/datapool/PoolRawAccessHelper.cpp index cf02b20a..6e289303 100644 --- a/datapool/PoolRawAccessHelper.cpp +++ b/datapool/PoolRawAccessHelper.cpp @@ -6,10 +6,12 @@ */ #include +#include +#include +#include #include - -#include +#include PoolRawAccessHelper::PoolRawAccessHelper(uint32_t * poolIdBuffer_, uint8_t numberOfParameters_): diff --git a/datapool/PoolRawAccessHelper.h b/datapool/PoolRawAccessHelper.h index ab881a5f..f2434241 100644 --- a/datapool/PoolRawAccessHelper.h +++ b/datapool/PoolRawAccessHelper.h @@ -7,6 +7,7 @@ #ifndef FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ #define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ +#include #include #include diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 9935ef75..0cbc18c5 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -18,6 +18,7 @@ * @ingroup data_pool */ class PoolVariableIF : public SerializeIF { + friend class DataSetBase; friend class GlobDataSet; friend class LocalDataSet; protected: diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index 2779ce5c..f32ff567 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -1,5 +1,7 @@ -#include #include +#include +#include +#include #include #include #include diff --git a/datapoolglob/GlobalDataSet.cpp b/datapoolglob/GlobalDataSet.cpp index 6e09a398..503d068e 100644 --- a/datapoolglob/GlobalDataSet.cpp +++ b/datapoolglob/GlobalDataSet.cpp @@ -1,61 +1,12 @@ -#include #include +#include #include -GlobDataSet::GlobDataSet() : - fill_count(0), state(DATA_SET_UNINITIALISED) { - for (unsigned count = 0; count < DATA_SET_MAX_SIZE; count++) { - registeredVariables[count] = nullptr; - } -} +GlobDataSet::GlobDataSet(): DataSetBase() {} -GlobDataSet::~GlobDataSet() { - //Don't do anything with your variables, they are dead already! - // (Destructor is already called) -} - -ReturnValue_t GlobDataSet::registerVariable(PoolVariableIF* variable) { - if (state != DATA_SET_UNINITIALISED) { - sif::error << "DataSet::registerVariable: Call made in wrong position." << std::endl; - return DATA_SET_UNINITIALISED; - } - if (variable == nullptr) { - sif::error << "DataSet::registerVariable: Pool variable is nullptr." << std::endl; - return POOL_VAR_NULL; - } - if (fill_count >= DATA_SET_MAX_SIZE) { - sif::error << "DataSet::registerVariable: DataSet is full." << std::endl; - return DATA_SET_FULL; - } - registeredVariables[fill_count] = variable; - fill_count++; - return RETURN_OK; -} - -ReturnValue_t GlobDataSet::read() { - ReturnValue_t result = RETURN_OK; - if (state == DATA_SET_UNINITIALISED) { - lockDataPool(); - for (uint16_t count = 0; count < fill_count; count++) { - if (registeredVariables[count]->getReadWriteMode() - != PoolVariableIF::VAR_WRITE - && registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - ReturnValue_t status = registeredVariables[count]->read(); - if (status != RETURN_OK) { - result = INVALID_PARAMETER_DEFINITION; - break; - } - } - } - state = DATA_SET_WAS_READ; - unlockDataPool(); - } else { - sif::error << "DataSet::read(): Call made in wrong position." << std::endl; - result = SET_WAS_ALREADY_READ; - } - return result; -} +// Don't do anything with your variables, they are dead already! +// (Destructor is already called) +GlobDataSet::~GlobDataSet() {} ReturnValue_t GlobDataSet::commit(bool valid) { setEntriesValid(valid); @@ -64,50 +15,7 @@ ReturnValue_t GlobDataSet::commit(bool valid) { } ReturnValue_t GlobDataSet::commit() { - if (state == DATA_SET_WAS_READ) { - handleAlreadyReadDatasetCommit(); - return RETURN_OK; - } - else { - return handleUnreadDatasetCommit(); - } -} - -void GlobDataSet::handleAlreadyReadDatasetCommit() { - lockDataPool(); - for (uint16_t count = 0; count < fill_count; count++) { - if (registeredVariables[count]->getReadWriteMode() - != PoolVariableIF::VAR_READ - && registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commit(); - } - } - state = DATA_SET_UNINITIALISED; - unlockDataPool(); -} - -ReturnValue_t GlobDataSet::handleUnreadDatasetCommit() { - ReturnValue_t result = RETURN_OK; - lockDataPool(); - for (uint16_t count = 0; count < fill_count; count++) { - if (registeredVariables[count]->getReadWriteMode() - == PoolVariableIF::VAR_WRITE - && registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commit(); - } else if (registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - if (result != COMMITING_WITHOUT_READING) { - sif::error << "DataSet::commit(): commit-without-read call made " - "with non write-only variable." << std::endl; - result = COMMITING_WITHOUT_READING; - } - } - } - state = DATA_SET_UNINITIALISED; - unlockDataPool(); - return result; + return DataSetBase::commit(); } ReturnValue_t GlobDataSet::unlockDataPool() { @@ -118,29 +26,8 @@ ReturnValue_t GlobDataSet::lockDataPool() { return glob::dataPool.lockDataPool(); } -ReturnValue_t GlobDataSet::serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - ReturnValue_t result = RETURN_FAILED; - for (uint16_t count = 0; count < fill_count; count++) { - result = registeredVariables[count]->serialize(buffer, size, max_size, - bigEndian); - if (result != RETURN_OK) { - return result; - } - } - return result; -} - -size_t GlobDataSet::getSerializedSize() const { - uint32_t size = 0; - for (uint16_t count = 0; count < fill_count; count++) { - size += registeredVariables[count]->getSerializedSize(); - } - return size; -} - void GlobDataSet::setEntriesValid(bool valid) { - for (uint16_t count = 0; count < fill_count; count++) { + for (uint16_t count = 0; count < fillCount; count++) { if (registeredVariables[count]->getReadWriteMode() != PoolVariableIF::VAR_READ) { registeredVariables[count]->setValid(valid); @@ -152,15 +39,4 @@ void GlobDataSet::setSetValid(bool valid) { this->valid = valid; } -ReturnValue_t GlobDataSet::deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) { - ReturnValue_t result = RETURN_FAILED; - for (uint16_t count = 0; count < fill_count; count++) { - result = registeredVariables[count]->deSerialize(buffer, size, - bigEndian); - if (result != RETURN_OK) { - return result; - } - } - return result; -} + diff --git a/datapoolglob/GlobalDataSet.h b/datapoolglob/GlobalDataSet.h index 365de380..c2e0b577 100644 --- a/datapoolglob/GlobalDataSet.h +++ b/datapoolglob/GlobalDataSet.h @@ -1,63 +1,32 @@ #ifndef DATASET_H_ #define DATASET_H_ -#include -#include -#include +#include -#include /** * @brief The DataSet class manages a set of locally checked out variables * for the global data pool. - * * @details - * This class manages a list, where a set of local variables (or pool variables) - * are registered. They are checked-out (i.e. their values are looked - * up and copied) with the read call. After the user finishes working with the - * pool variables, he can write back all variable values to the pool with - * the commit call. The data set manages locking and freeing the data pool, - * to ensure that all values are read and written back at once. + * This class uses the read-commit() semantic provided by the DataSetBase class. + * It extends the base class by using the global data pool, + * having a valid state and implementing lock und unlock calls for the global + * datapool. * - * An internal state manages usage of this class. Variables may only be - * registered before the read call is made, and the commit call only - * after the read call. - * - * If pool variables are writable and not committed until destruction - * of the set, the DataSet class automatically sets the valid flag in the - * data pool to invalid (without) changing the variable's value. + * For more information on how this class works, see the DataSetBase + * documentation. * @author Bastian Baetz * @ingroup data_pool */ -class GlobDataSet: public DataSetIF, public HasReturnvaluesIF, public SerializeIF { +class GlobDataSet: public DataSetBase { public: - //SHOULDDO we could use a linked list of datapool variables - //!< This definition sets the maximum number of variables to - //! register in one DataSet. - static const uint8_t DATA_SET_MAX_SIZE = 63; - - static constexpr uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS; - static constexpr ReturnValue_t INVALID_PARAMETER_DEFINITION = - MAKE_RETURN_CODE( 0x01 ); - static constexpr ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 ); - static constexpr ReturnValue_t COMMITING_WITHOUT_READING = - MAKE_RETURN_CODE(0x03); - - static constexpr ReturnValue_t DATA_SET_UNINITIALIZED = MAKE_RETURN_CODE( 0x04 ); - static constexpr ReturnValue_t DATA_SET_FULL = MAKE_RETURN_CODE( 0x05 ); - static constexpr ReturnValue_t POOL_VAR_NULL = MAKE_RETURN_CODE( 0x06 ); /** - * @brief The constructor simply sets the fill_count to zero and sets - * the state to "uninitialized". + * @brief Creates an empty GlobDataSet. Use registerVariable or + * supply a pointer to this dataset to PoolVariable + * initializations to register pool variables. */ GlobDataSet(); - /** - * @brief This operation is used to register the local variables in the set. - * @details It stores the pool variable pointer in a variable list. - */ - ReturnValue_t registerVariable(PoolVariableIF* variable) override; - /** * @brief The destructor automatically manages writing the valid * information of variables. @@ -67,42 +36,7 @@ public: * For each, the valid flag in the data pool is set to "invalid". */ ~GlobDataSet(); - /** - * @brief The read call initializes reading out all registered variables. - * @details - * It iterates through the list of registered variables and calls all read() - * functions of the registered pool variables (which read out their values - * from the data pool) which are not write-only. - * In case of an error (e.g. a wrong data type, or an invalid data pool id), - * 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. - * @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 SET_WAS_ALREADY_READ if read() is called twice without calling - * commit() in between - */ - ReturnValue_t read(); - /** - * @brief The commit call initializes writing back the registered variables. - * @details - * It iterates through the list of registered variables and calls the - * commit() method of the remaining registered variables (which write back - * their values to the pool). - * - * The data pool is locked during the whole commit operation and - * freed afterwards. The state changes to "was committed" after this operation. - * - * 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. - * @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 - */ - ReturnValue_t commit(void); + /** * Variant of method above which sets validity of all elements of the set. * @param valid Validity information from PoolVariableIF. @@ -111,6 +45,7 @@ public: * contains non write-only variables */ ReturnValue_t commit(bool valid); + ReturnValue_t commit() override; /** * Set all entries @@ -126,45 +61,16 @@ public: */ void setEntriesValid(bool valid); - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override; - - size_t getSerializedSize() const override; - - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override; private: - - /** - * @brief This array represents all pool variables registered in this set. - */ - PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE]; - /** - * \brief The fill_count attribute ensures that the variables register in the correct array - * position and that the maximum number of variables is not exceeded. - */ - uint16_t fill_count; - /** - * States of the seet. - */ - enum States { - DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED - DATA_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; - /** * If the valid state of a dataset is always relevant to the whole * data set we can use this flag. */ bool valid = false; + /** * @brief This is a small helper function to facilitate locking - * the underlying data data pool structure + * the global data pool. * @details * It makes use of the lockDataPool method offered by the DataPool class. */ @@ -172,7 +78,7 @@ private: /** * @brief This is a small helper function to facilitate - * unlocking the underlying data data pool structure + * unlocking the global data pool * @details * It makes use of the freeDataPoolLock method offered by the DataPool class. */ diff --git a/datapoolglob/GlobalPoolVariable.h b/datapoolglob/GlobalPoolVariable.h index eee9afc1..cfa28e11 100644 --- a/datapoolglob/GlobalPoolVariable.h +++ b/datapoolglob/GlobalPoolVariable.h @@ -2,9 +2,9 @@ #define GLOBALPOOLVARIABLE_H_ #include +#include #include #include -#include #include #include diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index f46f854b..8efc33d5 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1,10 +1,10 @@ +#include #include #include #include #include #include -#include #include #include #include diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index a1e96695..30a02b44 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -1,6 +1,6 @@ +#include #include "InternalErrorReporter.h" -#include #include #include diff --git a/power/Fuse.h b/power/Fuse.h index a826a125..44f8964f 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -2,6 +2,7 @@ #define FUSE_H_ #include +#include #include #include #include diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index cd277784..27885b8b 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -3,6 +3,7 @@ #include #include +#include #include /** From d1b315c7df5882427c41c77bf732f606c73ab50b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 23:54:56 +0200 Subject: [PATCH 09/14] pool raw access adaptions --- datapool/PoolRawAccess.cpp | 146 ++++++++++++-------- datapool/PoolRawAccess.h | 275 ++++++++++++++++++++++--------------- 2 files changed, 250 insertions(+), 171 deletions(-) diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index c0bd3c09..778e1b9c 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -1,54 +1,76 @@ #include -#include #include #include #include PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, - DataSetIF* data_set, ReadWriteMode_t setReadWriteMode) : - dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(Type::UNKNOWN_TYPE), typeSize( - 0), arraySize(0), sizeTillEnd(0), readWriteMode(setReadWriteMode) { + DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode) : + dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), + type(Type::UNKNOWN_TYPE), typeSize(0), arraySize(0), sizeTillEnd(0), + readWriteMode(setReadWriteMode) { memset(value, 0, sizeof(value)); - if (data_set != NULL) { - data_set->registerVariable(this); + if (dataSet != nullptr) { + dataSet->registerVariable(this); } } -PoolRawAccess::~PoolRawAccess() { - -} +PoolRawAccess::~PoolRawAccess() {} ReturnValue_t PoolRawAccess::read() { - PoolEntryIF* read_out = glob::dataPool.getRawData(dataPoolId); - if (read_out != NULL) { - valid = read_out->getValid(); - if (read_out->getSize() > arrayEntry) { - arraySize = read_out->getSize(); - typeSize = read_out->getByteSize() / read_out->getSize(); - type = read_out->getType(); - if (typeSize <= sizeof(value)) { - uint16_t arrayPosition = arrayEntry * typeSize; - sizeTillEnd = read_out->getByteSize() - arrayPosition; - uint8_t* ptr = - &((uint8_t*) read_out->getRawData())[arrayPosition]; - memcpy(value, ptr, typeSize); - return HasReturnvaluesIF::RETURN_OK; - } else { - //Error value type too large. - } - } else { - //Error index requested too large + ReturnValue_t result = RETURN_FAILED; + PoolEntryIF* readOut = glob::dataPool.getRawData(dataPoolId); + if (readOut != nullptr) { + result = handleReadOut(readOut); + if(result == RETURN_OK) { + return result; } } else { - //Error entry does not exist. + result = READ_ENTRY_NON_EXISTENT; } + handleReadError(result); + return result; +} + +ReturnValue_t PoolRawAccess::handleReadOut(PoolEntryIF* readOut) { + ReturnValue_t result = RETURN_FAILED; + valid = readOut->getValid(); + if (readOut->getSize() > arrayEntry) { + arraySize = readOut->getSize(); + typeSize = readOut->getByteSize() / readOut->getSize(); + type = readOut->getType(); + if (typeSize <= sizeof(value)) { + uint16_t arrayPosition = arrayEntry * typeSize; + sizeTillEnd = readOut->getByteSize() - arrayPosition; + uint8_t* ptr = &((uint8_t*) readOut->getRawData())[arrayPosition]; + memcpy(value, ptr, typeSize); + return RETURN_OK; + } else { + result = READ_TYPE_TOO_LARGE; + } + } else { + //debug << "PoolRawAccess: Size: " << (int)read_out->getSize() << std::endl; + result = READ_INDEX_TOO_LARGE; + } + return result; +} + +void PoolRawAccess::handleReadError(ReturnValue_t result) { sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId - << std::dec << " failed." << std::endl; + << std::dec << " failed, "; + if(result == READ_TYPE_TOO_LARGE) { + sif::error << "type too large." << std::endl; + } + else if(result == READ_INDEX_TOO_LARGE) { + sif::error << "index too large." << std::endl; + } + else if(result == READ_ENTRY_NON_EXISTENT) { + sif::error << "entry does not exist." << std::endl; + } + valid = INVALID; typeSize = 0; sizeTillEnd = 0; memset(value, 0, sizeof(value)); - return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t PoolRawAccess::commit() { @@ -71,7 +93,9 @@ uint8_t* PoolRawAccess::getEntry() { ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, uint32_t* writtenBytes, uint32_t max_size) { uint8_t* data_ptr = getEntry(); -// debug << "PoolRawAccess::getEntry: Array position: " << index * size_of_type << " Size of T: " << (int)size_of_type << " ByteSize: " << byte_size << " Position: " << *size << std::endl; + // debug << "PoolRawAccess::getEntry: Array position: " << + // index * size_of_type << " Size of T: " << (int)size_of_type << + // " ByteSize: " << byte_size << " Position: " << *size << std::endl; if (typeSize == 0) return DATA_POOL_ACCESS_FAILED; if (typeSize > max_size) @@ -89,6 +113,32 @@ ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, return HasReturnvaluesIF::RETURN_OK; } + +ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const { + if (typeSize + *size <= max_size) { + if (bigEndian) { +#ifndef BYTE_ORDER_SYSTEM +#error BYTE_ORDER_SYSTEM not defined +#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + for (uint8_t count = 0; count < typeSize; count++) { + (*buffer)[count] = value[typeSize - count - 1]; + } +#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + memcpy(*buffer, value, typeSize); +#endif + } else { + memcpy(*buffer, value, typeSize); + } + *size += typeSize; + (*buffer) += typeSize; + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::BUFFER_TOO_SHORT; + } +} + + Type PoolRawAccess::getType() { return type; } @@ -145,29 +195,6 @@ uint16_t PoolRawAccess::getSizeTillEnd() const { return sizeTillEnd; } -ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - if (typeSize + *size <= max_size) { - if (bigEndian) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - (*buffer)[count] = value[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(*buffer, value, typeSize); -#endif - } else { - memcpy(*buffer, value, typeSize); - } - *size += typeSize; - (*buffer) += typeSize; - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::BUFFER_TOO_SHORT; - } -} size_t PoolRawAccess::getSerializedSize() const { return typeSize; @@ -175,8 +202,9 @@ size_t PoolRawAccess::getSerializedSize() const { ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) { + // TODO: Needs to be tested!!! if (*size >= typeSize) { - + *size -= typeSize; if (bigEndian) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined @@ -187,12 +215,14 @@ ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, size_t* size, #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN memcpy(value, *buffer, typeSize); #endif - } else { + } + else { memcpy(value, *buffer, typeSize); } *buffer += typeSize; return HasReturnvaluesIF::RETURN_OK; - } else { + } + else { return SerializeIF::STREAM_TOO_SHORT; } } diff --git a/datapool/PoolRawAccess.h b/datapool/PoolRawAccess.h index f32aac51..452b5397 100644 --- a/datapool/PoolRawAccess.h +++ b/datapool/PoolRawAccess.h @@ -2,36 +2,187 @@ #define POOLRAWACCESS_H_ #include +#include #include #include /** - * This class allows accessing Data Pool variables as raw bytes. - * This is necessary to have an access method for HK data, as the PID's alone do not - * provide a type information. - * \ingroup data_pool + * @brief This class allows accessing Data Pool variables as raw bytes. + * @details + * This is necessary to have an access method for HK data, as the PID's alone + * do not provide type information. Please note that the the raw pool access + * read() and commit() calls are not thread-safe. + * + * Please supply a data set and use the data set read(), commit() calls for + * thread-safe data pool access. + * @ingroup data_pool */ -class PoolRawAccess: public PoolVariableIF { +class PoolRawAccess: public PoolVariableIF, HasReturnvaluesIF { +public: + /** + * This constructor is used to access a data pool entry with a + * given ID if the target type is not known. A DataSet object is supplied + * and the data pool entry with the given ID is registered to that data set. + * Please note that a pool raw access buffer only has a buffer + * with a size of double. As such, for vector entries which have + * @param data_pool_id Target data pool entry ID + * @param arrayEntry + * @param data_set Dataset to register data pool entry to + * @param setReadWriteMode + * @param registerVectors If set to true, the constructor checks if + * there are multiple vector entries to registers + * and registers all of them recursively into the data_set + * + */ + PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry, + DataSetIF* data_set, ReadWriteMode_t setReadWriteMode = + PoolVariableIF::VAR_READ); + + /** + * @brief This operation returns a pointer to the entry fetched. + * @details Return pointer to the buffer containing the raw data + * Size and number of data can be retrieved by other means. + */ + uint8_t* getEntry(); + /** + * @brief This operation returns the fetched entry from the data pool and + * flips the bytes, if necessary. + * @details It makes use of the getEntry call of this function, but additionally flips the + * bytes to big endian, which is the default for external communication (as House- + * keeping telemetry). To achieve this, the data is copied directly to the passed + * buffer, if it fits in the given max_size. + * @param buffer A pointer to a buffer to write to + * @param writtenBytes The number of bytes written is returned with this value. + * @param max_size The maximum size that the function may write to buffer. + * @return - @c RETURN_OK if entry could be acquired + * - @c RETURN_FAILED else. + */ + ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size, + uint32_t max_size); + + /** + * @brief Serialize raw pool entry into provided buffer directly + * @param buffer Provided buffer. Raw pool data will be copied here + * @param size [out] Increment provided size value by serialized size + * @param max_size Maximum allowed serialization size + * @param bigEndian Specify endianess + * @return - @c RETURN_OK if serialization was successfull + * - @c SerializeIF::BUFFER_TOO_SHORT if range check failed + */ + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const; + + /** + * With this method, the content can be set from a big endian buffer safely. + * @param buffer Pointer to the data to set + * @param size Size of the data to write. Must fit this->size. + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure + */ + ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer, + uint32_t setSize); + /** + * @brief This operation returns the type of the entry currently stored. + */ + Type getType(); + /** + * @brief This operation returns the size of the entry currently stored. + */ + uint8_t getSizeOfType(); + /** + * + * @return the size of the datapool array + */ + uint8_t getArraySize(); + /** + * @brief This operation returns the data pool id of the variable. + */ + uint32_t getDataPoolId() const; + + static const uint8_t INTERFACE_ID = CLASS_ID::POOL_RAW_ACCESS_CLASS; + static const ReturnValue_t INCORRECT_SIZE = MAKE_RETURN_CODE(0x01); + static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02); + static const ReturnValue_t READ_TYPE_TOO_LARGE = MAKE_RETURN_CODE(0x03); + static const ReturnValue_t READ_INDEX_TOO_LARGE = MAKE_RETURN_CODE(0x04); + static const ReturnValue_t READ_ENTRY_NON_EXISTENT = MAKE_RETURN_CODE(0x05); + static const uint8_t RAW_MAX_SIZE = sizeof(double); + uint8_t value[RAW_MAX_SIZE]; + + + /** + * @brief The classes destructor is empty. If commit() was not called, the local value is + * discarded and not written back to the data pool. + */ + ~PoolRawAccess(); + + /** + * This method returns if the variable is read-write or read-only. + */ + ReadWriteMode_t getReadWriteMode() const; + /** + * @brief With this call, the valid information of the variable is returned. + */ + bool isValid() const; + + void setValid(uint8_t valid); + /** + * Getter for the remaining size. + */ + uint16_t getSizeTillEnd() const; + + size_t getSerializedSize() const; + + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian); + +protected: + /** + * @brief This is a call to read the value from the global data pool. + * @details When executed, this operation tries to fetch the pool entry with matching + * data pool id from the global data pool and copies the value and the valid + * information to its local attributes. In case of a failure (wrong type or + * pool id not found), the variable is set to zero and invalid. + * The operation does NOT provide any mutual exclusive protection by itself ! + * If reading from the data pool without information about the type is desired, + * initialize the raw pool access by supplying a data set and using the data set + * read function, which calls this read function. + * @return -@c RETURN_OK Read successfull + * -@c READ_TYPE_TOO_LARGE + * -@c READ_INDEX_TOO_LARGE + * -@c READ_ENTRY_NON_EXISTENT + */ + ReturnValue_t read(); + /** + * @brief The commit call writes back the variable's value to the data pool. + * @details It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the valid flag is automatically set to "valid". + * The operation does NOT provide any mutual exclusive protection by itself. + * + */ + ReturnValue_t commit(); + + ReturnValue_t handleReadOut(PoolEntryIF* read_out); + void handleReadError(ReturnValue_t result); private: /** - * \brief To access the correct data pool entry on read and commit calls, the data pool id + * @brief To access the correct data pool entry on read and commit calls, the data pool id * is stored. */ uint32_t dataPoolId; /** - * \brief The array entry that is fetched from the data pool. + * @brief The array entry that is fetched from the data pool. */ uint8_t arrayEntry; /** - * \brief The valid information as it was stored in the data pool is copied to this attribute. + * @brief The valid information as it was stored in the data pool is copied to this attribute. */ uint8_t valid; /** - * \brief This value contains the type of the data pool entry. + * @brief This value contains the type of the data pool entry. */ Type type; /** - * \brief This value contains the size of the data pool entry in bytes. + * @brief This value contains the size of the data pool entry type in bytes. */ uint8_t typeSize; /** @@ -43,111 +194,9 @@ private: */ uint16_t sizeTillEnd; /** - * \brief The information whether the class is read-write or read-only is stored here. + * @brief The information whether the class is read-write or read-only is stored here. */ ReadWriteMode_t readWriteMode; - static const uint8_t RAW_MAX_SIZE = sizeof(double); -protected: - /** - * \brief This is a call to read the value from the global data pool. - * \details When executed, this operation tries to fetch the pool entry with matching - * data pool id from the global data pool and copies the value and the valid - * information to its local attributes. In case of a failure (wrong type or - * pool id not found), the variable is set to zero and invalid. - * The operation does NOT provide any mutual exclusive protection by itself. - */ - ReturnValue_t read(); - /** - * \brief The commit call writes back the variable's value to the data pool. - * \details It checks type and size, as well as if the variable is writable. If so, - * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. - * - */ - ReturnValue_t commit(); -public: - static const uint8_t INTERFACE_ID = CLASS_ID::POOL_RAW_ACCESS_CLASS; - static const ReturnValue_t INCORRECT_SIZE = MAKE_RETURN_CODE(0x01); - static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02); - uint8_t value[RAW_MAX_SIZE]; - PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry, - DataSetIF* data_set, ReadWriteMode_t setReadWriteMode = - PoolVariableIF::VAR_READ); - /** - * \brief The classes destructor is empty. If commit() was not called, the local value is - * discarded and not written back to the data pool. - */ - ~PoolRawAccess(); - /** - * \brief This operation returns a pointer to the entry fetched. - * \details This means, it does not return a pointer to byte "index", but to the start byte of - * array entry "index". Example: If the original data pool array consists of an double - * array of size four, getEntry(1) returns &(this->value[8]). - */ - uint8_t* getEntry(); - /** - * \brief This operation returns the fetched entry from the data pool and - * flips the bytes, if necessary. - * \details It makes use of the getEntry call of this function, but additionally flips the - * bytes to big endian, which is the default for external communication (as House- - * keeping telemetry). To achieve this, the data is copied directly to the passed - * buffer, if it fits in the given max_size. - * \param buffer A pointer to a buffer to write to - * \param writtenBytes The number of bytes written is returned with this value. - * \param max_size The maximum size that the function may write to buffer. - * \return - \c RETURN_OK if entry could be acquired - * - \c RETURN_FAILED else. - */ - ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size, - uint32_t max_size); - /** - * With this method, the content can be set from a big endian buffer safely. - * @param buffer Pointer to the data to set - * @param size Size of the data to write. Must fit this->size. - * @return - \c RETURN_OK on success - * - \c RETURN_FAILED on failure - */ - ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer, - uint32_t setSize); - /** - * \brief This operation returns the type of the entry currently stored. - */ - Type getType(); - /** - * \brief This operation returns the size of the entry currently stored. - */ - uint8_t getSizeOfType(); - /** - * - * @return the size of the datapool array - */ - uint8_t getArraySize(); - /** - * \brief This operation returns the data pool id of the variable. - */ - uint32_t getDataPoolId() const; - /** - * This method returns if the variable is read-write or read-only. - */ - ReadWriteMode_t getReadWriteMode() const; - /** - * \brief With this call, the valid information of the variable is returned. - */ - bool isValid() const; - - void setValid(uint8_t valid); - /** - * Getter for the remaining size. - */ - uint16_t getSizeTillEnd() const; - - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const; - - size_t getSerializedSize() const; - - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian); }; #endif /* POOLRAWACCESS_H_ */ From 767850e12546ddb7b17d344ee32a1c5bb389a593 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 23:58:57 +0200 Subject: [PATCH 10/14] deleted poolvector --- datapool/PoolVector.h | 233 ------------------------------------------ 1 file changed, 233 deletions(-) delete mode 100644 datapool/PoolVector.h diff --git a/datapool/PoolVector.h b/datapool/PoolVector.h deleted file mode 100644 index 3df61528..00000000 --- a/datapool/PoolVector.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * \file PoolVector.h - * - * \brief This file contains the PoolVector class, the header only class to handle data pool vectors. - * - * \date 10/23/2012 - * - * \author Bastian Baetz - */ - -#ifndef POOLVECTOR_H_ -#define POOLVECTOR_H_ - -#include -#include -#include -#include -#include - -/** - * \brief This is the access class for array-type data pool entries. - * - * \details To ensure safe usage of the data pool, operation is not done directly on the data pool - * entries, but on local copies. This class provides simple type- and length-safe access - * to vector-style data pool entries (i.e. entries with length > 1). - * The class can be instantiated as read-write and read only. - * It provides a commit-and-roll-back semantic, which means that no array entry in - * the data pool is changed until the commit call is executed. - * There are two template parameters: - * \tparam T This template parameter specifies the data type of an array entry. Currently, all - * plain data types are supported, but in principle any type is possible. - * \tparam vector_size This template parameter specifies the vector size of this entry. - * Using a template parameter for this is not perfect, but avoids dynamic memory allocation. - * \ingroup data_pool - */ -template -class PoolVector: public PoolVariableIF { -private: - /** - * \brief To access the correct data pool entry on read and commit calls, the data pool id - * is stored. - */ - uint32_t dataPoolId; - /** - * \brief The valid information as it was stored in the data pool is copied to this attribute. - */ - uint8_t valid; - /** - * \brief The information whether the class is read-write or read-only is stored here. - */ - ReadWriteMode_t readWriteMode; - -protected: - /** - * \brief This is a call to read the array's values from the global data pool. - * \details When executed, this operation tries to fetch the pool entry with matching - * data pool id from the global data pool and copies all array values and the valid - * information to its local attributes. In case of a failure (wrong type, size or - * pool id not found), the variable is set to zero and invalid. - * The operation does NOT provide any mutual exclusive protection by itself. - */ - ReturnValue_t read() { - PoolEntry* read_out = ::dataPool.getData(this->dataPoolId, - vector_size); - if (read_out != NULL) { - this->valid = read_out->valid; - memcpy(this->value, read_out->address, read_out->getByteSize()); - - return HasReturnvaluesIF::RETURN_OK; - - } else { - memset(this->value, 0, vector_size * sizeof(T)); - sif::error << "PoolVector: read of DP Variable 0x" << std::hex - << dataPoolId << std::dec << " failed." << std::endl; - this->valid = INVALID; - return HasReturnvaluesIF::RETURN_FAILED; - } - } - /** - * \brief The commit call copies the array values back to the data pool. - * \details It checks type and size, as well as if the variable is writable. If so, - * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. - * - */ - ReturnValue_t commit() { - PoolEntry* write_back = ::dataPool.getData(this->dataPoolId, - vector_size); - if ((write_back != NULL) && (this->readWriteMode != VAR_READ)) { - write_back->valid = valid; - memcpy(write_back->address, this->value, write_back->getByteSize()); - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } - } -public: - /** - * \brief This is the local copy of the data pool entry. - * \detials The user can work on this attribute - * just like he would on a local array of this type. - */ - T value[vector_size]; - /** - * \brief In the constructor, the variable can register itself in a DataSet (if not NULL is - * passed). - * \details It DOES NOT fetch the current value from the data pool, but sets the value - * attribute to default (0). The value is fetched within the read() operation. - * \param set_id This is the id in the global data pool this instance of the access class - * corresponds to. - * \param dataSet The data set in which the variable shall register itself. If NULL, - * the variable is not registered. - * \param setWritable If this flag is set to true, changes in the value attribute can be - * written back to the data pool, otherwise not. - */ - PoolVector(uint32_t set_id, DataSetIF* set, - ReadWriteMode_t setReadWriteMode) : - dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) { - memset(this->value, 0, vector_size * sizeof(T)); - if (set != NULL) { - set->registerVariable(this); - } - } - /** - * Copy ctor to copy classes containing Pool Variables. - */ -// PoolVector(const PoolVector& rhs) { -// PoolVector temp(rhs.dataPoolId, rhs.) -// memcpy(value, rhs.value, sizeof(T)*vector_size); -// } - /** - * \brief The classes destructor is empty. - * \details If commit() was not called, the local value is - * discarded and not written back to the data pool. - */ - ~PoolVector() { - } - ; - /** - * \brief The operation returns the number of array entries in this variable. - */ - uint8_t getSize() { - return vector_size; - } - /** - * \brief This operation returns the data pool id of the variable. - */ - uint32_t getDataPoolId() const { - return dataPoolId; - } - /** - * This operation sets the data pool id of the variable. - * The method is necessary to set id's of data pool member variables with bad initialization. - */ - void setDataPoolId(uint32_t poolId) { - dataPoolId = poolId; - } - /** - * This method returns if the variable is write-only, read-write or read-only. - */ - ReadWriteMode_t getReadWriteMode() const { - return readWriteMode; - } - ; - /** - * \brief With this call, the valid information of the variable is returned. - */ - bool isValid() const { - if (valid != INVALID) - return true; - else - return false; - } - - void setValid(uint8_t valid) { - this->valid = valid; - } - - uint8_t getValid() { - return valid; - } - - T &operator [](int i) { - return value[i]; - } - - const T &operator [](int i) const { - return value[i]; - } - - PoolVector &operator=( - PoolVector newPoolVector) { - - for (uint16_t i = 0; i < vector_size; i++) { - this->value[i] = newPoolVector.value[i]; - } - return *this; - } - - virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - uint16_t i; - ReturnValue_t result; - for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::serialize(&(value[i]), buffer, size, - max_size, bigEndian); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - } - return result; - } - - virtual size_t getSerializedSize() const { - return vector_size * SerializeAdapter::getSerializedSize(value); - } - - virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) { - uint16_t i; - ReturnValue_t result; - for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, - bigEndian); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - } - return result; - } -}; - -#endif /* POOLVECTOR_H_ */ From 355bc2b9057da4f79ead6aa0e7882b9220edffd7 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 18 May 2020 15:42:47 +0200 Subject: [PATCH 11/14] improvements --- datapoolglob/GlobalPoolVariable.h | 2 +- datapoollocal/LocalPoolVariable.h | 5 +++-- datapoollocal/LocalPoolVariable.tpp | 5 ++++- globalfunctions/Type.h | 3 +++ housekeeping/HasHkPoolParametersIF.h | 5 +---- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/datapoolglob/GlobalPoolVariable.h b/datapoolglob/GlobalPoolVariable.h index cfa28e11..eb44c307 100644 --- a/datapoolglob/GlobalPoolVariable.h +++ b/datapoolglob/GlobalPoolVariable.h @@ -32,7 +32,7 @@ class GlobPoolVar: public PoolVariableIF { template friend class PoolVarList; static_assert(not std::is_same::value, "Do not use boolean for the PoolEntry type, use uint8_t instead!" - "Warum? Darum :-)"); + "There is no boolean type in CCSDS."); public: /** * @brief In the constructor, the variable can register itself in a diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index 44c16a7c..39c92f60 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ +#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ #include #include @@ -100,4 +101,4 @@ using lp_int64_t = LocalPoolVar; using lp_float_t = LocalPoolVar; using lp_double_t = LocalPoolVar; - +#endif diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index fdd18bcd..4bc4c662 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -1,4 +1,5 @@ -#pragma once +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ +#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ #include #include @@ -107,3 +108,5 @@ inline ReturnValue_t LocalPoolVar::deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) { return AutoSerializeAdapter::deSerialize(&value, buffer, size, bigEndian); } + +#endif diff --git a/globalfunctions/Type.h b/globalfunctions/Type.h index f4146f4e..e46a37e4 100644 --- a/globalfunctions/Type.h +++ b/globalfunctions/Type.h @@ -4,6 +4,9 @@ #include #include +/** + * @brief Type definition for CCSDS or ECSS. + */ class Type: public SerializeIF { public: enum ActualType_t { diff --git a/housekeeping/HasHkPoolParametersIF.h b/housekeeping/HasHkPoolParametersIF.h index 5ec9beef..ac248cf3 100644 --- a/housekeeping/HasHkPoolParametersIF.h +++ b/housekeeping/HasHkPoolParametersIF.h @@ -13,8 +13,7 @@ using LocalDataPoolMap = std::map; using LocalDataPoolMapIter = LocalDataPoolMap::iterator; /** - * @brief Interface for the local housekeeping managers used by the device - * handler. + * @brief */ class HasHkPoolParametersIF { public: @@ -27,6 +26,4 @@ public: virtual HousekeepingManager* getHkManagerHandle() = 0; }; - - #endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */ From 2f16b1e7336a1b174bfc0da4ae5437c925c6ac21 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 25 May 2020 13:48:43 +0200 Subject: [PATCH 12/14] moved some files --- datapool/PoolRawAccessHelper.h | 2 +- datapoolglob/DataPoolAdmin.cpp | 2 +- datapoolglob/DataPoolParameterWrapper.cpp | 2 +- {datapool => datapoolglob}/PIDReader.h | 0 {datapool => datapoolglob}/PIDReaderList.h | 8 ++++---- {datapool => datapoolglob}/PoolRawAccess.cpp | 2 +- {datapool => datapoolglob}/PoolRawAccess.h | 0 monitoring/MonitorBase.h | 2 +- power/Fuse.h | 2 +- power/PowerSensor.h | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) rename {datapool => datapoolglob}/PIDReader.h (100%) rename {datapool => datapoolglob}/PIDReaderList.h (73%) rename {datapool => datapoolglob}/PoolRawAccess.cpp (99%) rename {datapool => datapoolglob}/PoolRawAccess.h (100%) diff --git a/datapool/PoolRawAccessHelper.h b/datapool/PoolRawAccessHelper.h index f2434241..52d9ebe5 100644 --- a/datapool/PoolRawAccessHelper.h +++ b/datapool/PoolRawAccessHelper.h @@ -7,9 +7,9 @@ #ifndef FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ #define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ -#include #include #include +#include /** * @brief This helper function simplifies accessing data pool entries diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index f32ff567..05de1eb2 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -1,7 +1,7 @@ #include -#include #include #include +#include #include #include #include diff --git a/datapoolglob/DataPoolParameterWrapper.cpp b/datapoolglob/DataPoolParameterWrapper.cpp index d93cd88e..062cff12 100644 --- a/datapoolglob/DataPoolParameterWrapper.cpp +++ b/datapoolglob/DataPoolParameterWrapper.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include diff --git a/datapool/PIDReader.h b/datapoolglob/PIDReader.h similarity index 100% rename from datapool/PIDReader.h rename to datapoolglob/PIDReader.h diff --git a/datapool/PIDReaderList.h b/datapoolglob/PIDReaderList.h similarity index 73% rename from datapool/PIDReaderList.h rename to datapoolglob/PIDReaderList.h index 07d1b8e6..0b838508 100644 --- a/datapool/PIDReaderList.h +++ b/datapoolglob/PIDReaderList.h @@ -1,8 +1,8 @@ -#ifndef FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ -#define FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ +#ifndef FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ +#define FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ -#include #include +#include template class PIDReaderList { private: @@ -24,4 +24,4 @@ public: -#endif /* FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ */ +#endif /* FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ */ diff --git a/datapool/PoolRawAccess.cpp b/datapoolglob/PoolRawAccess.cpp similarity index 99% rename from datapool/PoolRawAccess.cpp rename to datapoolglob/PoolRawAccess.cpp index 778e1b9c..cc04f9b9 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapoolglob/PoolRawAccess.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/datapool/PoolRawAccess.h b/datapoolglob/PoolRawAccess.h similarity index 100% rename from datapool/PoolRawAccess.h rename to datapoolglob/PoolRawAccess.h diff --git a/monitoring/MonitorBase.h b/monitoring/MonitorBase.h index d66e956d..f18ca4b5 100644 --- a/monitoring/MonitorBase.h +++ b/monitoring/MonitorBase.h @@ -2,7 +2,7 @@ #define MONITORBASE_H_ #include -#include +#include #include #include #include diff --git a/power/Fuse.h b/power/Fuse.h index 44f8964f..0f258b63 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include diff --git a/power/PowerSensor.h b/power/PowerSensor.h index f94088a8..0fb47506 100644 --- a/power/PowerSensor.h +++ b/power/PowerSensor.h @@ -2,8 +2,8 @@ #define POWERSENSOR_H_ #include -#include #include +#include #include #include #include From a37f01cd0ee31c57f8f76f3b299c2f51718e9d85 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 25 May 2020 23:11:56 +0200 Subject: [PATCH 13/14] improved readability of mode explanations --- devicehandlers/DeviceHandlerIF.h | 60 ++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/devicehandlers/DeviceHandlerIF.h b/devicehandlers/DeviceHandlerIF.h index 34aa4114..59ee1853 100644 --- a/devicehandlers/DeviceHandlerIF.h +++ b/devicehandlers/DeviceHandlerIF.h @@ -28,19 +28,57 @@ public: // MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted // MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on. - static const Mode_t MODE_NORMAL = 2; //!< The device is powered on and the device handler periodically sends commands. The commands to be sent are selected by the handler according to the submode. - static const Mode_t MODE_RAW = 3; //!< The device is powered on and ready to perform operations. In this mode, raw commands can be sent. The device handler will send all replies received from the command back to the commanding object. - static const Mode_t MODE_ERROR_ON = 4; //!4< The device is shut down but the switch could not be turned off, so the device still is powered. In this mode, only a mode change to @c MODE_OFF can be commanded, which tries to switch off the device again. - static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The device handler performs all commands to get the device in a state ready to perform commands. When this is completed, the mode changes to @c MODE_ON. - static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6; //!< This is a transitional state which can not be commanded. The device handler performs all actions and commands to get the device shut down. When the device is off, the mode changes to @c MODE_OFF. - static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON; //!< It is possible to set the mode to _MODE_TO_ON to use the to on transition if available. + //!< The device is powered on and the device handler periodically sends + //! commands. The commands to be sent are selected by the handler + //! according to the submode. + static const Mode_t MODE_NORMAL = 2; + //! The device is powered on and ready to perform operations. In this mode, + //! raw commands can be sent. The device handler will send all replies + //! received from the command back to the commanding object. + static const Mode_t MODE_RAW = 3; + //! The device is shut down but the switch could not be turned off, so the + //! device still is powered. In this mode, only a mode change to @c MODE_OFF + //! can be commanded, which tries to switch off the device again. + static const Mode_t MODE_ERROR_ON = 4; + //! This is a transitional state which can not be commanded. The device + //! handler performs all commands to get the device in a state ready to + //! perform commands. When this is completed, the mode changes to @c MODE_ON. + static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5; + //! This is a transitional state which can not be commanded. + //! The device handler performs all actions and commands to get the device + //! shut down. When the device is off, the mode changes to @c MODE_OFF. + static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6; + //! It is possible to set the mode to _MODE_TO_ON to use the to on + //! transition if available. + static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON; + //! It is possible to set the mode to _MODE_TO_RAW to use the to raw + //! transition if available. static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW; + //! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal + //! transition if available. static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL; - static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1; //!< This is a transitional state which can not be commanded. The device is shut down and ready to be switched off. After the command to set the switch off has been sent, the mode changes to @c MODE_WAIT_OFF - static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2; //!< This is a transitional state which can not be commanded. The device will be switched on in this state. After the command to set the switch on has been sent, the mode changes to @c MODE_WAIT_ON - static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3; //!< This is a transitional state which can not be commanded. The switch has been commanded off and the handler waits for it to be off. When the switch is off, the mode changes to @c MODE_OFF. - static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4; //!< This is a transitional state which can not be commanded. The switch has been commanded on and the handler waits for it to be on. When the switch is on, the mode changes to @c MODE_TO_ON. - static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The switch has been commanded off and is off now. This state is only to do an RMAP cycle once more where the doSendRead() function will set the mode to MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board + //! This is a transitional state which can not be commanded. + //! The device is shut down and ready to be switched off. + //! After the command to set the switch off has been sent, + //! the mode changes to @c MODE_WAIT_OFF + static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1; + //! This is a transitional state which can not be commanded. The device + //! will be switched on in this state. After the command to set the switch + //! on has been sent, the mode changes to @c MODE_WAIT_ON. + static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2; + //! This is a transitional state which can not be commanded. The switch has + //! been commanded off and the handler waits for it to be off. + //! When the switch is off, the mode changes to @c MODE_OFF. + static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3; + //! This is a transitional state which can not be commanded. The switch + //! has been commanded on and the handler waits for it to be on. + //! When the switch is on, the mode changes to @c MODE_TO_ON. + static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4; + //! This is a transitional state which can not be commanded. The switch has + //! been commanded off and is off now. This state is only to do an RMAP + //! cycle once more where the doSendRead() function will set the mode to + //! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board. + static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH; static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW); From 18d19fbb2c7575cf7b880e0caebf5cbcbc447358 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 25 May 2020 23:12:25 +0200 Subject: [PATCH 14/14] < removed --- devicehandlers/DeviceHandlerIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerIF.h b/devicehandlers/DeviceHandlerIF.h index 59ee1853..f6b29e25 100644 --- a/devicehandlers/DeviceHandlerIF.h +++ b/devicehandlers/DeviceHandlerIF.h @@ -28,7 +28,7 @@ public: // MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted // MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on. - //!< The device is powered on and the device handler periodically sends + //! The device is powered on and the device handler periodically sends //! commands. The commands to be sent are selected by the handler //! according to the submode. static const Mode_t MODE_NORMAL = 2;