From 73215baf118066c2eb5278416f302216a243cd9d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 15 Oct 2020 13:43:23 +0200 Subject: [PATCH 01/37] init commit --- storagemanager/ConstStorageAccessor.h | 2 - storagemanager/LocalPool.cpp | 346 ++++++++++++++++++++++++++ storagemanager/LocalPool.h | 233 ++++++++++------- storagemanager/PoolManager.cpp | 59 +++++ storagemanager/PoolManager.h | 41 ++- storagemanager/StorageAccessor.h | 2 - storagemanager/StorageManagerIF.h | 23 +- storagemanager/storeAddress.h | 13 +- 8 files changed, 612 insertions(+), 107 deletions(-) create mode 100644 storagemanager/LocalPool.cpp create mode 100644 storagemanager/PoolManager.cpp diff --git a/storagemanager/ConstStorageAccessor.h b/storagemanager/ConstStorageAccessor.h index 96d2dca2c..570c20ce5 100644 --- a/storagemanager/ConstStorageAccessor.h +++ b/storagemanager/ConstStorageAccessor.h @@ -20,9 +20,7 @@ class StorageManagerIF; */ class ConstStorageAccessor { //! StorageManager classes have exclusive access to private variables. - template friend class PoolManager; - template friend class LocalPool; public: /** diff --git a/storagemanager/LocalPool.cpp b/storagemanager/LocalPool.cpp new file mode 100644 index 000000000..8e5f4d488 --- /dev/null +++ b/storagemanager/LocalPool.cpp @@ -0,0 +1,346 @@ +#include "LocalPool.h" +#include + +LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig, + bool registered, bool spillsToHigherPools): + SystemObject(setObjectId, registered), + NUMBER_OF_POOLS(poolConfig.size()), + spillsToHigherPools(spillsToHigherPools) { + if(NUMBER_OF_POOLS == 0) { + sif::error << "LocalPool::LocalPool: Passed pool configuration is " + << " invalid!" << std::endl; + } + max_pools_t index = 0; + for (const auto& currentPoolConfig: poolConfig) { + this->numberOfElements[index] = currentPoolConfig.first; + this->elementSizes[index] = currentPoolConfig.second; + store[index] = std::vector( + numberOfElements[index] * elementSizes[index]); + sizeLists[index] = std::vector(numberOfElements[index]); + for(auto& size: sizeLists[index]) { + size = STORAGE_FREE; + } + index++; + } +} + +LocalPool::~LocalPool(void) {} + + +ReturnValue_t LocalPool::addData(store_address_t* storageId, + const uint8_t* data, size_t size, bool ignoreFault) { + ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); + if (status == RETURN_OK) { + write(*storageId, data, size); + } + return status; +} + +ReturnValue_t LocalPool::getData(store_address_t packetId, + const uint8_t **packetPtr, size_t *size) { + uint8_t* tempData = nullptr; + ReturnValue_t status = modifyData(packetId, &tempData, size); + *packetPtr = tempData; + return status; +} + +ReturnValue_t LocalPool::getData(store_address_t storeId, + ConstStorageAccessor& storeAccessor) { + uint8_t* tempData = nullptr; + ReturnValue_t status = modifyData(storeId, &tempData, + &storeAccessor.size_); + storeAccessor.assignStore(this); + storeAccessor.constDataPointer = tempData; + return status; +} + +ConstAccessorPair LocalPool::getData(store_address_t storeId) { + uint8_t* tempData = nullptr; + ConstStorageAccessor constAccessor(storeId, this); + ReturnValue_t status = modifyData(storeId, &tempData, &constAccessor.size_); + constAccessor.constDataPointer = tempData; + return ConstAccessorPair(status, std::move(constAccessor)); +} + +ReturnValue_t LocalPool::getFreeElement(store_address_t *storageId, + const size_t size, uint8_t **pData, bool ignoreFault) { + ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); + if (status == RETURN_OK) { + *pData = &store[storageId->poolIndex][getRawPosition(*storageId)]; + } + else { + *pData = nullptr; + } + return status; +} + + +AccessorPair LocalPool::modifyData(store_address_t storeId) { + StorageAccessor accessor(storeId, this); + ReturnValue_t status = modifyData(storeId, &accessor.dataPointer, + &accessor.size_); + accessor.assignConstPointer(); + return AccessorPair(status, std::move(accessor)); +} + +ReturnValue_t LocalPool::modifyData(store_address_t storeId, + StorageAccessor& storeAccessor) { + storeAccessor.assignStore(this); + ReturnValue_t status = modifyData(storeId, &storeAccessor.dataPointer, + &storeAccessor.size_); + storeAccessor.assignConstPointer(); + return status; +} + +ReturnValue_t LocalPool::modifyData(store_address_t storeId, + uint8_t **packetPtr, size_t *size) { + ReturnValue_t status = RETURN_FAILED; + if (storeId.poolIndex >= NUMBER_OF_POOLS) { + return ILLEGAL_STORAGE_ID; + } + if ((storeId.packetIndex >= numberOfElements[storeId.poolIndex])) { + return ILLEGAL_STORAGE_ID; + } + + if (sizeLists[storeId.poolIndex][storeId.packetIndex] + != STORAGE_FREE) { + size_type packetPosition = getRawPosition(storeId); + *packetPtr = &store[storeId.poolIndex][packetPosition]; + *size = sizeLists[storeId.poolIndex][storeId.packetIndex]; + status = RETURN_OK; + } + else { + status = DATA_DOES_NOT_EXIST; + } + return status; +} + +ReturnValue_t LocalPool::deleteData(store_address_t storeId) { +#if FSFW_DEBUGGING == 1 + sif::debug << "Delete: Pool: " << std::dec << storeId.poolIndex + << " Index: " << storeId.packetIndex << std::endl; + +#endif + ReturnValue_t status = RETURN_OK; + size_type pageSize = getPageSize(storeId.poolIndex); + if ((pageSize != 0) and + (storeId.packetIndex < numberOfElements[storeId.poolIndex])) { + uint16_t packetPosition = getRawPosition(storeId); + uint8_t* ptr = &store[storeId.poolIndex][packetPosition]; + std::memset(ptr, 0, pageSize); + //Set free list + sizeLists[storeId.poolIndex][storeId.packetIndex] = STORAGE_FREE; + } + else { + //pool_index or packet_index is too large + sif::error << "LocalPool::deleteData: Illegal store ID, no deletion!" + << std::endl; + status = ILLEGAL_STORAGE_ID; + } + return status; +} + +ReturnValue_t LocalPool::deleteData(uint8_t *ptr, size_t size, + store_address_t *storeId) { + store_address_t localId; + ReturnValue_t result = ILLEGAL_ADDRESS; + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + //Not sure if new allocates all stores in order. so better be careful. + if ((store[n].data() <= ptr) and + (&store[n][numberOfElements[n]*elementSizes[n]] > ptr)) { + localId.poolIndex = n; + uint32_t deltaAddress = ptr - store[n].data(); + // Getting any data from the right "block" is ok. + // This is necessary, as IF's sometimes don't point to the first + // element of an object. + localId.packetIndex = deltaAddress / elementSizes[n]; + result = deleteData(localId); +#if FSFW_DEBUGGING == 1 + if (deltaAddress % elementSizes[n] != 0) { + sif::error << "LocalPool::deleteData: Address not aligned!" + << std::endl; + } +#endif + break; + } + } + if (storeId != nullptr) { + *storeId = localId; + } + return result; +} + + +ReturnValue_t LocalPool::initialize() { + ReturnValue_t result = SystemObject::initialize(); + if (result != RETURN_OK) { + return result; + } + internalErrorReporter = objectManager->get( + objects::INTERNAL_ERROR_REPORTER); + if (internalErrorReporter == nullptr){ + return ObjectManagerIF::INTERNAL_ERR_REPORTER_UNINIT; + } + + //Check if any pool size is large than the maximum allowed. + for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) { + if (elementSizes[count] >= STORAGE_FREE) { + sif::error << "LocalPool::initialize: Pool is too large! " + "Max. allowed size is: " << (STORAGE_FREE - 1) << std::endl; + return StorageManagerIF::POOL_TOO_LARGE; + } + } + return HasReturnvaluesIF::RETURN_OK; +} + +void LocalPool::clearStore() { + for(auto& sizeList: sizeLists) { + for(auto& size: sizeList) { + size = STORAGE_FREE; + } +// std::memset(sizeList[index], 0xff, +// numberOfElements[index] * sizeof(size_type)); + } + +} + +ReturnValue_t LocalPool::reserveSpace(const size_t size, + store_address_t *storeId, bool ignoreFault) { + ReturnValue_t status = getPoolIndex(size, &storeId->poolIndex); + if (status != RETURN_OK) { + sif::error << "LocalPool( " << std::hex << getObjectId() << std::dec + << " )::reserveSpace: Packet too large." << std::endl; + return status; + } + status = findEmpty(storeId->poolIndex, &storeId->packetIndex); + while (status != RETURN_OK && spillsToHigherPools) { + status = getPoolIndex(size, &storeId->poolIndex, storeId->poolIndex + 1); + if (status != RETURN_OK) { + //We don't find any fitting pool anymore. + break; + } + status = findEmpty(storeId->poolIndex, &storeId->packetIndex); + } + if (status == RETURN_OK) { +#if FSFW_DEBUGGING == 1 + sif::debug << "Reserve: Pool: " << std::dec + << storeId->poolIndex << " Index: " << storeId->packetIndex + << std::endl; +#endif + sizeLists[storeId->poolIndex][storeId->packetIndex] = size; + } + else { + if ((not ignoreFault) and (internalErrorReporter != nullptr)) { + internalErrorReporter->storeFull(); + } + } + return status; +} + +void LocalPool::write(store_address_t storeId, const uint8_t *data, + size_t size) { + uint8_t* ptr = nullptr; + size_type packetPosition = getRawPosition(storeId); + + // Size was checked before calling this function. + ptr = &store[storeId.poolIndex][packetPosition]; + std::memcpy(ptr, data, size); + sizeLists[storeId.poolIndex][storeId.packetIndex] = size; +} + +LocalPool::size_type LocalPool::getPageSize(max_pools_t poolIndex) { + if (poolIndex < NUMBER_OF_POOLS) { + return elementSizes[poolIndex]; + } + else { + return 0; + } +} + +void LocalPool::setToSpillToHigherPools(bool enable) { + this->spillsToHigherPools = enable; +} + +ReturnValue_t LocalPool::getPoolIndex(size_t packetSize, uint16_t *poolIndex, + uint16_t startAtIndex) { + for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) { +#if FSFW_DEBUGGING == 1 + sif::debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " + << n << ", Element Size: " << elementSizes[n] << std::endl; +#endif + if (elementSizes[n] >= packetSize) { + *poolIndex = n; + return RETURN_OK; + } + } + return DATA_TOO_LARGE; +} + +LocalPool::size_type LocalPool::getRawPosition(store_address_t storeId) { + return storeId.packetIndex * elementSizes[storeId.poolIndex]; +} + +ReturnValue_t LocalPool::findEmpty(n_pool_elem_t poolIndex, uint16_t *element) { + ReturnValue_t status = DATA_STORAGE_FULL; + for (uint16_t foundElement = 0; foundElement < numberOfElements[poolIndex]; + foundElement++) { + if (sizeLists[poolIndex][foundElement] == STORAGE_FREE) { + *element = foundElement; + status = RETURN_OK; + break; + } + } + return status; +} + +size_t LocalPool::getTotalSize(size_t* additionalSize) { + size_t totalSize = 0; + size_t sizesSize = 0; + for(uint8_t idx = 0; idx < NUMBER_OF_POOLS; idx ++) { + totalSize += elementSizes[idx] * numberOfElements[idx]; + sizesSize += numberOfElements[idx] * sizeof(size_type); + } + if(additionalSize != nullptr) { + *additionalSize = sizesSize; + } + return totalSize; +} + +void LocalPool::getFillCount(uint8_t *buffer, uint8_t *bytesWritten) { + if(bytesWritten == nullptr or buffer == nullptr) { + return; + } + + uint16_t reservedHits = 0; + uint8_t idx = 0; + uint16_t sum = 0; + for(; idx < NUMBER_OF_POOLS; idx ++) { + for(const auto& size: sizeLists[idx]) { + if(size != STORAGE_FREE) { + reservedHits++; + } + } + buffer[idx] = static_cast(reservedHits) / + numberOfElements[idx] * 100; + *bytesWritten += 1; + sum += buffer[idx]; + reservedHits = 0; + } + buffer[idx] = sum / NUMBER_OF_POOLS; + *bytesWritten += 1; +} + + +void LocalPool::clearPage(max_pools_t pageIndex) { + if(pageIndex >= NUMBER_OF_POOLS) { + return; + } + + // Mark the storage as free + for(auto& size: sizeLists[pageIndex]) { + size = STORAGE_FREE; + } + + // Set all the page content to 0. + std::memset(store[pageIndex].data(), 0, elementSizes[pageIndex]); +} diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 3a94c03db..db7711520 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -7,57 +7,93 @@ #include "../serviceinterface/ServiceInterfaceStream.h" #include "../internalError/InternalErrorReporterIF.h" #include "../storagemanager/StorageAccessor.h" -#include + +#include +#include +#include +#include /** - * @brief The LocalPool class provides an intermediate data storage with - * a fixed pool size policy. - * @details The class implements the StorageManagerIF interface. While the - * total number of pools is fixed, the element sizes in one pool and - * the number of pool elements per pool are set on construction. - * The full amount of memory is allocated on construction. - * The overhead is 4 byte per pool element to store the size - * information of each stored element. - * To maintain an "empty" information, the pool size is limited to - * 0xFFFF-1 bytes. - * It is possible to store empty packets in the pool. - * The local pool is NOT thread-safe. - * @author Bastian Baetz + * @brief The LocalPool class provides an intermediate data storage with + * a fixed pool size policy. + * @details + * The class implements the StorageManagerIF interface. While the total number + * of pools is fixed, the element sizes in one pool and the number of pool + * elements per pool are set on construction. The full amount of memory is + * allocated on construction. + * The overhead is 4 byte per pool element to store the size information of + * each stored element. To maintain an "empty" information, the pool size is + * limited to 0xFFFF-1 bytes. + * It is possible to store empty packets in the pool. + * The local pool is NOT thread-safe. */ -template class LocalPool: public SystemObject, public StorageManagerIF { public: - /** - * @brief This definition generally sets the number of different sized pools. - * @details This must be less than the maximum number of pools (currently 0xff). - */ - // static const uint32_t NUMBER_OF_POOLS; - /** - * @brief This is the default constructor for a pool manager instance. - * @details By passing two arrays of size NUMBER_OF_POOLS, the constructor - * allocates memory (with @c new) for store and size_list. These - * regions are all set to zero on start up. - * @param setObjectId The object identifier to be set. This allows for - * multiple instances of LocalPool in the system. - * @param element_sizes An array of size NUMBER_OF_POOLS in which the size - * of a single element in each pool is determined. - * The sizes must be provided in ascending order. - * - * @param n_elements An array of size NUMBER_OF_POOLS in which the - * number of elements for each pool is determined. - * The position of these values correspond to those in - * element_sizes. - * @param registered Register the pool in object manager or not. - * Default is false (local pool). - * @param spillsToHigherPools A variable to determine whether - * higher n pools are used if the store is full. - */ - LocalPool(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS], - bool registered = false, - bool spillsToHigherPools = false); + using pool_elem_size_t = size_type; + using n_pool_elem_t = uint16_t; + using LocalPoolCfgPair = std::pair; + + // The configuration needs to be provided with the pool sizes ascending + // but the number of pool elements as the first value is more intuitive. + // Therefore, a custom comparator was provided. + struct LocalPoolConfigCmp + { + bool operator ()(const LocalPoolCfgPair &a, + const LocalPoolCfgPair &b) const + { + if(a.second < b.second) { + return true; + } + else if(a.second > b.second) { + return false; + } + else { + if(a.first < b.first) { + return true; + } + else { + return false; + } + } + } + }; + using LocalPoolConfig = std::multiset; + + /** + * @brief This definition generally sets the number of + * different sized pools. It is derived from the number of pairs + * inside the LocalPoolConfig set on object creation. + * @details + * This must be less than the maximum number of pools (currently 0xff). + */ + const max_pools_t NUMBER_OF_POOLS; + + /** + * @brief This is the default constructor for a pool manager instance. + * @details + * The pool is configured by passing a set of pairs into the constructor. + * The first value of that pair determines the number of one elements on + * the respective page of the pool while the second value determines how + * many elements with that size are created on that page. + * All regions are to zero on start up. + * @param setObjectId The object identifier to be set. This allows for + * multiple instances of LocalPool in the system. + * @param poolConfig + * This is a set of pairs to configure the number of pages in the pool, + * the size of an element on a page, the number of elements on a page + * and the total size of the pool at once while also implicitely + * sorting the pairs in the right order. + * @param registered + * Determines whether the pool is registered in the object manager or not. + * @param spillsToHigherPools A variable to determine whether + * higher n pools are used if the store is full. + */ + LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig, + bool registered = false, bool spillsToHigherPools = false); + + void setToSpillToHigherPools(bool enable); + /** * @brief In the LocalPool's destructor all allocated memory is freed. */ @@ -66,25 +102,49 @@ public: /** * Documentation: See StorageManagerIF.h */ - ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, + ReturnValue_t addData(store_address_t* storeId, const uint8_t * data, size_t size, bool ignoreFault = false) override; - ReturnValue_t getFreeElement(store_address_t* storageId,const size_t size, - uint8_t** p_data, bool ignoreFault = false) override; + ReturnValue_t getFreeElement(store_address_t* storeId,const size_t size, + uint8_t** pData, bool ignoreFault = false) override; - ConstAccessorPair getData(store_address_t packet_id) override; - ReturnValue_t getData(store_address_t packet_id, ConstStorageAccessor&) override; - ReturnValue_t getData(store_address_t packet_id, const uint8_t** packet_ptr, + ConstAccessorPair getData(store_address_t storeId) override; + ReturnValue_t getData(store_address_t storeId, + ConstStorageAccessor& constAccessor) override; + ReturnValue_t getData(store_address_t storeId, + const uint8_t** packet_ptr, size_t * size) override; + + AccessorPair modifyData(store_address_t storeId) override; + ReturnValue_t modifyData(store_address_t storeId, + StorageAccessor& storeAccessor) override; + ReturnValue_t modifyData(store_address_t storeId, uint8_t** packet_ptr, size_t * size) override; - AccessorPair modifyData(store_address_t packet_id) override; - ReturnValue_t modifyData(store_address_t packet_id, StorageAccessor&) override; - ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr, - size_t * size) override; - - virtual ReturnValue_t deleteData(store_address_t) override; + virtual ReturnValue_t deleteData(store_address_t storeId) override; virtual ReturnValue_t deleteData(uint8_t* ptr, size_t size, - store_address_t* storeId = NULL) override; + store_address_t* storeId = nullptr) override; + + /** + * Get the total size of allocated memory for pool data. + * There is an additional overhead of the sizes of elements which will + * be assigned to additionalSize + * @return + */ + size_t getTotalSize(size_t* additionalSize) override; + + /** + * Get the fill count of the pool. Each character inside the provided + * buffer will be assigned to a rounded percentage fill count for each + * page. The last written byte (at the index bytesWritten - 1) + * will contain the total fill count of the pool as a mean of the + * percentages of single pages. + * @param buffer + * @param maxSize + */ + void getFillCount(uint8_t* buffer, uint8_t* bytesWritten) override; + void clearStore() override; + void clearPage(max_pools_t pageIndex) override; + ReturnValue_t initialize() override; protected: /** @@ -94,43 +154,48 @@ protected: * @return - #RETURN_OK on success, * - the return codes of #getPoolIndex or #findEmpty otherwise. */ - virtual ReturnValue_t reserveSpace(const uint32_t size, + virtual ReturnValue_t reserveSpace(const size_t size, store_address_t* address, bool ignoreFault); - InternalErrorReporterIF *internalErrorReporter; private: - /** - * Indicates that this element is free. - * This value limits the maximum size of a pool. Change to larger data type - * if increase is required. - */ - static const uint32_t STORAGE_FREE = 0xFFFFFFFF; + /** + * Indicates that this element is free. + * This value limits the maximum size of a pool. + * Change to larger data type if increase is required. + */ + static const size_type STORAGE_FREE = std::numeric_limits::max(); /** * @brief In this array, the element sizes of each pool is stored. * @details The sizes are maintained for internal pool management. The sizes * must be set in ascending order on construction. */ - uint32_t element_sizes[NUMBER_OF_POOLS]; + std::vector elementSizes = + std::vector(NUMBER_OF_POOLS); /** * @brief n_elements stores the number of elements per pool. * @details These numbers are maintained for internal pool management. */ - uint16_t n_elements[NUMBER_OF_POOLS]; + std::vector numberOfElements = + std::vector(NUMBER_OF_POOLS); /** * @brief store represents the actual memory pool. * @details It is an array of pointers to memory, which was allocated with * a @c new call on construction. */ - uint8_t* store[NUMBER_OF_POOLS]; + std::vector> store = + std::vector>(NUMBER_OF_POOLS); + /** * @brief The size_list attribute stores the size values of every pool element. * @details As the number of elements is determined on construction, the size list * is also dynamically allocated there. */ - uint32_t* size_list[NUMBER_OF_POOLS]; + std::vector> sizeLists = + std::vector>(NUMBER_OF_POOLS); + //! A variable to determine whether higher n pools are used if //! the store is full. - bool spillsToHigherPools; + bool spillsToHigherPools = false; /** * @brief This method safely stores the given data in the given packet_id. * @details It also sets the size in size_list. The method does not perform @@ -139,30 +204,24 @@ private: * @param data The data to be stored. * @param size The size of the data to be stored. */ - void write(store_address_t packet_id, const uint8_t* data, size_t size); + void write(store_address_t packetId, const uint8_t* data, size_t size); /** * @brief A helper method to read the element size of a certain pool. * @param pool_index The pool in which to look. * @return Returns the size of an element or 0. */ - uint32_t getPageSize(uint16_t pool_index); - /** - * @brief This helper method looks up a fitting pool for a given size. - * @details The pools are looked up in ascending order, so the first that - * fits is used. - * @param packet_size The size of the data to be stored. - * @return Returns the pool that fits or StorageManagerIF::INVALID_ADDRESS. - */ + size_type getPageSize(max_pools_t poolIndex); + /** * @brief This helper method looks up a fitting pool for a given size. * @details The pools are looked up in ascending order, so the first that * fits is used. * @param packet_size The size of the data to be stored. * @param[out] poolIndex The fitting pool index found. - * @return - #RETURN_OK on success, - * - #DATA_TOO_LARGE otherwise. + * @return - @c RETURN_OK on success, + * - @c DATA_TOO_LARGE otherwise. */ - ReturnValue_t getPoolIndex(size_t packet_size, uint16_t* poolIndex, + ReturnValue_t getPoolIndex(size_t packetSize, uint16_t* poolIndex, uint16_t startAtIndex = 0); /** * @brief This helper method calculates the true array position in store @@ -172,7 +231,7 @@ private: * @param packet_id The packet id to look up. * @return Returns the position of the data in store. */ - uint32_t getRawPosition(store_address_t packet_id); + size_type getRawPosition(store_address_t storeId); /** * @brief This is a helper method to find an empty element in a given pool. * @details The method searches size_list for the first empty element, so @@ -182,9 +241,9 @@ private: * @return - #RETURN_OK on success, * - #DATA_STORAGE_FULL if the store is full */ - ReturnValue_t findEmpty(uint16_t pool_index, uint16_t* element); + ReturnValue_t findEmpty(n_pool_elem_t poolIndex, uint16_t* element); + + InternalErrorReporterIF *internalErrorReporter = nullptr; }; -#include "LocalPool.tpp" - #endif /* FSFW_STORAGEMANAGER_LOCALPOOL_H_ */ diff --git a/storagemanager/PoolManager.cpp b/storagemanager/PoolManager.cpp new file mode 100644 index 000000000..9c801a3da --- /dev/null +++ b/storagemanager/PoolManager.cpp @@ -0,0 +1,59 @@ +#include "PoolManager.h" + +PoolManager::PoolManager(object_id_t setObjectId, + const LocalPoolConfig& localPoolConfig): + LocalPool(setObjectId, localPoolConfig, true) { + mutex = MutexFactory::instance()->createMutex(); +} + + +PoolManager::~PoolManager(void) { + MutexFactory::instance()->deleteMutex(mutex); +} + + +ReturnValue_t PoolManager::reserveSpace(const size_t size, + store_address_t* address, bool ignoreFault) { + MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, + mutexTimeoutMs); + ReturnValue_t status = LocalPool::reserveSpace(size, + address,ignoreFault); + return status; +} + + +ReturnValue_t PoolManager::deleteData( + store_address_t storeId) { +#if FSFW_DEBUGGING == 1 + sif::debug << "PoolManager( " << translateObject(getObjectId()) << + " )::deleteData from store " << storeId.poolIndex << + ". id is "<< storeId.packetIndex << std::endl; +#endif + MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, + mutexTimeoutMs); + return LocalPool::deleteData(storeId); +} + + +ReturnValue_t PoolManager::deleteData(uint8_t* buffer, + size_t size, store_address_t* storeId) { + MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20); + ReturnValue_t status = LocalPool::deleteData(buffer, + size, storeId); + return status; +} + + +void PoolManager::setMutexTimeout( + uint32_t mutexTimeoutMs) { + this->mutexTimeoutMs = mutexTimeoutMs; +} + +ReturnValue_t PoolManager::lockMutex(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + return mutex->lockMutex(timeoutType, timeoutMs); +} + +ReturnValue_t PoolManager::unlockMutex() { + return mutex->unlockMutex(); +} diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 8cc6c0654..5786a2252 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -9,16 +9,20 @@ /** * @brief The PoolManager class provides an intermediate data storage with * a fixed pool size policy for inter-process communication. - * @details Uses local pool calls but is thread safe by protecting the call - * with a lock. + * @details + * Uses local pool calls but is thread safe by protecting most calls + * with a lock. The developer can lock the pool with the provided API + * if the lock needs to persists beyond the function call. + * + * Other than that, the class provides the same interface as the LocalPool + * class. The class is always registered as a system object as it is assumed + * it will always be used concurrently (if this is not the case, it is + * recommended to use the LocalPool class instead). * @author Bastian Baetz */ -template -class PoolManager : public LocalPool { +class PoolManager: public LocalPool { public: - PoolManager(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS]); + PoolManager(object_id_t setObjectId, const LocalPoolConfig& poolConfig); /** * @brief In the PoolManager's destructor all allocated memory @@ -26,6 +30,12 @@ public: */ virtual ~PoolManager(); + /** + * Set the default mutex timeout for internal calls. + * @param mutexTimeoutMs + */ + void setMutexTimeout(uint32_t mutexTimeoutMs); + /** * @brief LocalPool overrides for thread-safety. Decorator function * which wraps LocalPool calls with a mutex protection. @@ -34,12 +44,23 @@ public: ReturnValue_t deleteData(uint8_t* buffer, size_t size, store_address_t* storeId = nullptr) override; - void setMutexTimeout(uint32_t mutexTimeoutMs); + /** + * The developer is allowed to lock the mutex in case the lock needs + * to persist beyond the function calls which are not protected by the + * class. + * @param timeoutType + * @param timeoutMs + * @return + */ + ReturnValue_t lockMutex(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs); + ReturnValue_t unlockMutex(); + protected: //! Default mutex timeout value to prevent permanent blocking. uint32_t mutexTimeoutMs = 20; - ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, + ReturnValue_t reserveSpace(const size_t size, store_address_t* address, bool ignoreFault) override; /** @@ -51,6 +72,4 @@ protected: MutexIF* mutex; }; -#include "PoolManager.tpp" - #endif /* FSFW_STORAGEMANAGER_POOLMANAGER_H_ */ diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index 5cf15d509..d5b383eb6 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -10,9 +10,7 @@ class StorageManagerIF; */ class StorageAccessor: public ConstStorageAccessor { //! StorageManager classes have exclusive access to private variables. - template friend class PoolManager; - template friend class LocalPool; public: StorageAccessor(store_address_t storeId); diff --git a/storagemanager/StorageManagerIF.h b/storagemanager/StorageManagerIF.h index 834e75637..769616d78 100644 --- a/storagemanager/StorageManagerIF.h +++ b/storagemanager/StorageManagerIF.h @@ -28,6 +28,9 @@ using ConstAccessorPair = std::pair; */ class StorageManagerIF : public HasReturnvaluesIF { public: + using size_type = size_t; + using max_pools_t = uint8_t; + static const uint8_t INTERFACE_ID = CLASS_ID::STORAGE_MANAGER_IF; //!< The unique ID for return codes for this interface. static const ReturnValue_t DATA_TOO_LARGE = MAKE_RETURN_CODE(1); //!< This return code indicates that the data to be stored is too large for the store. static const ReturnValue_t DATA_STORAGE_FULL = MAKE_RETURN_CODE(2); //!< This return code indicates that a data storage is full. @@ -40,7 +43,9 @@ public: static const Event GET_DATA_FAILED = MAKE_EVENT(0, SEVERITY::LOW); static const Event STORE_DATA_FAILED = MAKE_EVENT(1, SEVERITY::LOW); - static const uint32_t INVALID_ADDRESS = 0xFFFFFFFF; //!< Indicates an invalid (i.e unused) storage address. + //!< Indicates an invalid (i.e unused) storage address. + static const uint32_t INVALID_ADDRESS = 0xFFFFFFFF; + /** * @brief This is the empty virtual destructor as required for C++ interfaces. */ @@ -164,6 +169,22 @@ public: * Use with care! */ virtual void clearStore() = 0; + + /** + * Clears a page in the store. Use with care! + * @param pageIndex + */ + virtual void clearPage(uint8_t pageIndex) = 0; + + /** + * Get the fill count of the pool. The exact form will be implementation + * dependant. + * @param buffer + * @param bytesWritten + */ + virtual void getFillCount(uint8_t* buffer, uint8_t* bytesWritten) = 0; + + virtual size_t getTotalSize(size_t* additionalSize) = 0; }; #endif /* FSFW_STORAGEMANAGER_STORAGEMANAGERIF_H_ */ diff --git a/storagemanager/storeAddress.h b/storagemanager/storeAddress.h index 044c07908..ea72f6f89 100644 --- a/storagemanager/storeAddress.h +++ b/storagemanager/storeAddress.h @@ -3,16 +3,21 @@ #include +namespace storeId { +static constexpr uint32_t INVALID_STORE_ADDRESS = 0xffffffff; +} + /** * This union defines the type that identifies where a data packet is * stored in the store. It comprises of a raw part to read it as raw value and * a structured part to use it in pool-like stores. */ union store_address_t { + /** * Default Constructor, initializing to INVALID_ADDRESS */ - store_address_t():raw(0xFFFFFFFF){} + store_address_t(): raw(storeId::INVALID_STORE_ADDRESS){} /** * Constructor to create an address object using the raw address * @@ -28,7 +33,7 @@ union store_address_t { * @param packetIndex */ store_address_t(uint16_t poolIndex, uint16_t packetIndex): - pool_index(poolIndex),packet_index(packetIndex){} + poolIndex(poolIndex), packetIndex(packetIndex){} /** * A structure with two elements to access the store address pool-like. */ @@ -36,11 +41,11 @@ union store_address_t { /** * The index in which pool the packet lies. */ - uint16_t pool_index; + uint16_t poolIndex; /** * The position in the chosen pool. */ - uint16_t packet_index; + uint16_t packetIndex; }; /** * Alternative access to the raw value. From 67e33918e0fb07fe3dd6afbfda9eb5bbfcd044fe Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 15 Oct 2020 13:44:09 +0200 Subject: [PATCH 02/37] event manager uses refactored pool now --- events/EventManager.cpp | 18 +++++++++--------- events/EventManager.h | 10 +++++++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/events/EventManager.cpp b/events/EventManager.cpp index e71951e36..57bda13fb 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -1,23 +1,23 @@ #include "EventManager.h" -#include "EventMessage.h" #include "../serviceinterface/ServiceInterfaceStream.h" #include "../ipc/QueueFactory.h" #include "../ipc/MutexFactory.h" -const uint16_t EventManager::POOL_SIZES[N_POOLS] = { - sizeof(EventMatchTree::Node), sizeof(EventIdRangeMatcher), - sizeof(ReporterRangeMatcher) }; // If one checks registerListener calls, there are around 40 (to max 50) // objects registering for certain events. // Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher. // So a good guess is 75 to a max of 100 pools required for each, which fits well. -// SHOULDDO: Shouldn't this be in the config folder and passed via ctor? -const uint16_t EventManager::N_ELEMENTS[N_POOLS] = { 240, 120, 120 }; +// This should be configurable.. +const LocalPool::LocalPoolConfig EventManager::poolConfig = { + {240, sizeof(EventMatchTree::Node)}, + {120, sizeof(EventIdRangeMatcher)}, + {120, sizeof(ReporterRangeMatcher)} +}; EventManager::EventManager(object_id_t setObjectId) : SystemObject(setObjectId), - factoryBackend(0, POOL_SIZES, N_ELEMENTS, false, true) { + factoryBackend(0, poolConfig, false, true) { mutex = MutexFactory::instance()->createMutex(); eventReportQueue = QueueFactory::instance()->createMessageQueue( MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE); @@ -109,13 +109,13 @@ ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, return result; } -#ifdef DEBUG +#if FSFW_DEBUG_OUTPUT == 1 void EventManager::printEvent(EventMessage* message) { const char *string = 0; switch (message->getSeverity()) { case SEVERITY::INFO: -#ifdef DEBUG_INFO_EVENT +#if DEBUG_INFO_EVENT == 1 string = translateObject(message->getReporter()); sif::info << "EVENT: "; if (string != 0) { diff --git a/events/EventManager.h b/events/EventManager.h index 2602aeb23..fe35d9d3e 100644 --- a/events/EventManager.h +++ b/events/EventManager.h @@ -8,9 +8,11 @@ #include "../tasks/ExecutableObjectIF.h" #include "../ipc/MessageQueueIF.h" #include "../ipc/MutexIF.h" +#include + #include -#ifdef DEBUG +#if FSFW_DEBUG_OUTPUT == 1 // forward declaration, should be implemented by mission extern const char* translateObject(object_id_t object); extern const char* translateEvents(Event event); @@ -49,13 +51,15 @@ protected: MutexIF* mutex = nullptr; static const uint8_t N_POOLS = 3; - LocalPool factoryBackend; + LocalPool factoryBackend; + static const LocalPool::LocalPoolConfig poolConfig; + static const uint16_t POOL_SIZES[N_POOLS]; static const uint16_t N_ELEMENTS[N_POOLS]; void notifyListeners(EventMessage *message); -#ifdef DEBUG +#if FSFW_DEBUG_OUTPUT == 1 void printEvent(EventMessage *message); #endif From 7d358483dd1f684609d52f144e64aa02e1e82425 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 15 Oct 2020 13:44:59 +0200 Subject: [PATCH 03/37] added back config includes --- storagemanager/LocalPool.cpp | 1 + storagemanager/PoolManager.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/storagemanager/LocalPool.cpp b/storagemanager/LocalPool.cpp index 8e5f4d488..48934a0c8 100644 --- a/storagemanager/LocalPool.cpp +++ b/storagemanager/LocalPool.cpp @@ -1,4 +1,5 @@ #include "LocalPool.h" +#include #include LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig, diff --git a/storagemanager/PoolManager.cpp b/storagemanager/PoolManager.cpp index 9c801a3da..85376b282 100644 --- a/storagemanager/PoolManager.cpp +++ b/storagemanager/PoolManager.cpp @@ -1,4 +1,5 @@ #include "PoolManager.h" +#include PoolManager::PoolManager(object_id_t setObjectId, const LocalPoolConfig& localPoolConfig): From bd2f8b3e8ce09c6328519a9047d7144ff7932d37 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 15 Oct 2020 13:45:47 +0200 Subject: [PATCH 04/37] packet matcher uses refactored pool now --- tmtcpacket/packetmatcher/PacketMatchTree.cpp | 28 ++++++++++++-------- tmtcpacket/packetmatcher/PacketMatchTree.h | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/tmtcpacket/packetmatcher/PacketMatchTree.cpp b/tmtcpacket/packetmatcher/PacketMatchTree.cpp index a45796576..ac72b3e77 100644 --- a/tmtcpacket/packetmatcher/PacketMatchTree.cpp +++ b/tmtcpacket/packetmatcher/PacketMatchTree.cpp @@ -3,19 +3,30 @@ #include "ServiceMatcher.h" #include "SubserviceMatcher.h" +// This should be configurable.. +const LocalPool::LocalPoolConfig PacketMatchTree::poolConfig = { + {10, sizeof(ServiceMatcher)}, + {20, sizeof(SubServiceMatcher)}, + {2, sizeof(ApidMatcher)}, + {40, sizeof(PacketMatchTree::Node)} +}; + PacketMatchTree::PacketMatchTree(Node* root) : - MatchTree(root, 2), factoryBackend(0, POOL_SIZES, - N_ELEMENTS, false, true), factory(&factoryBackend) { + MatchTree(root, 2), + factoryBackend(0, poolConfig, false, true), + factory(&factoryBackend) { } PacketMatchTree::PacketMatchTree(iterator root) : - MatchTree(root.element, 2), factoryBackend(0, - POOL_SIZES, N_ELEMENTS, false, true), factory(&factoryBackend) { + MatchTree(root.element, 2), + factoryBackend(0, poolConfig, false, true), + factory(&factoryBackend) { } PacketMatchTree::PacketMatchTree() : - MatchTree((Node*) NULL, 2), factoryBackend(0, - POOL_SIZES, N_ELEMENTS, false, true), factory(&factoryBackend) { + MatchTree((Node*) NULL, 2), + factoryBackend(0, poolConfig, false, true), + factory(&factoryBackend) { } PacketMatchTree::~PacketMatchTree() { @@ -172,11 +183,6 @@ ReturnValue_t PacketMatchTree::initialize() { return factoryBackend.initialize(); } -const uint16_t PacketMatchTree::POOL_SIZES[N_POOLS] = { sizeof(ServiceMatcher), - sizeof(SubServiceMatcher), sizeof(ApidMatcher), - sizeof(PacketMatchTree::Node) }; -//Maximum number of types and subtypes to filter should be more than sufficient. -const uint16_t PacketMatchTree::N_ELEMENTS[N_POOLS] = { 10, 20, 2, 40 }; ReturnValue_t PacketMatchTree::changeMatch(bool addToMatch, uint16_t apid, uint8_t type, uint8_t subtype) { diff --git a/tmtcpacket/packetmatcher/PacketMatchTree.h b/tmtcpacket/packetmatcher/PacketMatchTree.h index 86fb087ed..54fc856c7 100644 --- a/tmtcpacket/packetmatcher/PacketMatchTree.h +++ b/tmtcpacket/packetmatcher/PacketMatchTree.h @@ -23,8 +23,9 @@ protected: ReturnValue_t cleanUpElement(iterator position); private: static const uint8_t N_POOLS = 4; - LocalPool factoryBackend; + LocalPool factoryBackend; PlacementFactory factory; + static const LocalPool::LocalPoolConfig poolConfig; static const uint16_t POOL_SIZES[N_POOLS]; static const uint16_t N_ELEMENTS[N_POOLS]; template From 6ea933492368e31217851717f9d880c033cfce17 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 29 Oct 2020 17:57:27 +0100 Subject: [PATCH 05/37] parameter updates --- parameters/HasParametersIF.h | 42 ++++++++++------- parameters/ParameterHelper.cpp | 80 +++++++++++++++++---------------- parameters/ParameterMessage.cpp | 20 ++++++++- parameters/ParameterMessage.h | 35 ++++++++++++++- parameters/ParameterWrapper.cpp | 55 ++++++++++++++++++++--- parameters/ParameterWrapper.h | 23 +++++++--- 6 files changed, 186 insertions(+), 69 deletions(-) diff --git a/parameters/HasParametersIF.h b/parameters/HasParametersIF.h index 005403fa5..c4fd81b34 100644 --- a/parameters/HasParametersIF.h +++ b/parameters/HasParametersIF.h @@ -1,12 +1,16 @@ #ifndef FSFW_PARAMETERS_HASPARAMETERSIF_H_ #define FSFW_PARAMETERS_HASPARAMETERSIF_H_ -#include "../parameters/ParameterWrapper.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include +#include "ParameterWrapper.h" +#include -/** Each parameter is identified with a unique parameter ID */ -typedef uint32_t ParameterId_t; +/** + * Each parameter is identified with a unique parameter ID + * The first byte of the parameter ID will denote the domain ID. + * The second and third byte will be the unique identifier number. + */ +using ParameterId_t = uint32_t; /** * @brief This interface is used by components which have modifiable @@ -19,13 +23,13 @@ typedef uint32_t ParameterId_t; * The second and third byte represent the matrix ID, which can represent * a 8-bit row and column number and the last byte... * - * Yeah, it it matrix ID oder parameter ID now and is index a 16 bit number + * Yeah, is it matrix ID or parameter ID now and is index a 16 bit number * of a 8 bit number now? */ class HasParametersIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::HAS_PARAMETERS_IF; - static const ReturnValue_t INVALID_MATRIX_ID = MAKE_RETURN_CODE(0x01); + static const ReturnValue_t INVALID_IDENTIFIER_ID = MAKE_RETURN_CODE(0x01); static const ReturnValue_t INVALID_DOMAIN_ID = MAKE_RETURN_CODE(0x02); static const ReturnValue_t INVALID_VALUE = MAKE_RETURN_CODE(0x03); static const ReturnValue_t READ_ONLY = MAKE_RETURN_CODE(0x05); @@ -34,17 +38,24 @@ public: return id >> 24; } - static uint16_t getMatrixId(ParameterId_t id) { - return id >> 8; + static uint8_t getUniqueIdentifierId(ParameterId_t id) { + return id >> 16; } - static uint8_t getIndex(ParameterId_t id) { + /** + * Get the index of a parameter. Please note that the index is always a + * linear index. For a vector, this is straightforward. + * For a matrix, the linear indexing run from left to right, top to bottom. + * @param id + * @return + */ + static uint16_t getIndex(ParameterId_t id) { return id; } - static uint32_t getFullParameterId(uint8_t domainId, uint16_t parameterId, - uint8_t index) { - return (domainId << 24) + (parameterId << 8) + index; + static uint32_t getFullParameterId(uint8_t domainId, + uint8_t uniqueIdentifier, uint16_t linearIndex) { + return (domainId << 24) + (uniqueIdentifier << 16) + linearIndex; } virtual ~HasParametersIF() {} @@ -56,11 +67,12 @@ public: * @param parameterId * @param parameterWrapper * @param newValues - * @param startAtIndex + * @param startAtIndex Linear index, runs left to right, top to bottom for + * matrix indexes. * @return */ - virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, - ParameterWrapper *parameterWrapper, + virtual ReturnValue_t getParameter(uint8_t domainId, + uint16_t uniqueIdentifier, ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex) = 0; }; diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 659b00def..d2193b289 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -9,15 +9,20 @@ ParameterHelper::~ParameterHelper() { } ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { + if(storage == nullptr) { + // ParameterHelper was not initialized + return HasReturnvaluesIF::RETURN_FAILED; + } + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; switch (message->getCommand()) { case ParameterMessage::CMD_PARAMETER_DUMP: { ParameterWrapper description; uint8_t domain = HasParametersIF::getDomain( ParameterMessage::getParameterId(message)); - uint16_t parameterId = HasParametersIF::getMatrixId( + uint8_t uniqueIdentifier = HasParametersIF::getUniqueIdentifierId( ParameterMessage::getParameterId(message)); - result = owner->getParameter(domain, parameterId, + result = owner->getParameter(domain, uniqueIdentifier, &description, &description, 0); if (result == HasReturnvaluesIF::RETURN_OK) { result = sendParameter(message->getSender(), @@ -26,49 +31,48 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { } break; case ParameterMessage::CMD_PARAMETER_LOAD: { - uint8_t domain = HasParametersIF::getDomain( - ParameterMessage::getParameterId(message)); - uint16_t parameterId = HasParametersIF::getMatrixId( - ParameterMessage::getParameterId(message)); - uint8_t index = HasParametersIF::getIndex( - ParameterMessage::getParameterId(message)); + ParameterId_t parameterId = 0; + uint8_t ptc = 0; + uint8_t pfc = 0; + uint8_t rows = 0; + uint8_t columns = 0; + store_address_t storeId = ParameterMessage::getParameterLoadCommand( + message, ¶meterId, &ptc, &pfc, &rows, &columns); + Type type(Type::getActualType(ptc, pfc)); - const uint8_t *storedStream = nullptr; - size_t storedStreamSize = 0; - result = storage->getData( - ParameterMessage::getStoreId(message), &storedStream, - &storedStreamSize); + uint8_t domain = HasParametersIF::getDomain(parameterId); + uint8_t uniqueIdentifier = HasParametersIF::getUniqueIdentifierId( + parameterId); + uint16_t linearIndex = HasParametersIF::getIndex(parameterId); + + ConstStorageAccessor accessor(storeId); + result = storage->getData(storeId, accessor); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "ParameterHelper::handleParameterMessage: Getting" - " store data failed for load command." << std::endl; + << " store data failed for load command." << std::endl; break; } ParameterWrapper streamWrapper; - result = streamWrapper.set(storedStream, storedStreamSize); - if (result != HasReturnvaluesIF::RETURN_OK) { - storage->deleteData(ParameterMessage::getStoreId(message)); - break; + result = streamWrapper.set(type, rows, columns, accessor.data(), + accessor.size()); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; } ParameterWrapper ownerWrapper; - result = owner->getParameter(domain, parameterId, &ownerWrapper, - &streamWrapper, index); + result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper, + &streamWrapper, linearIndex); + + result = ownerWrapper.copyFrom(&streamWrapper, linearIndex); if (result != HasReturnvaluesIF::RETURN_OK) { - storage->deleteData(ParameterMessage::getStoreId(message)); - break; + return result; } - result = ownerWrapper.copyFrom(&streamWrapper, index); - - storage->deleteData(ParameterMessage::getStoreId(message)); - - if (result == HasReturnvaluesIF::RETURN_OK) { - result = sendParameter(message->getSender(), - ParameterMessage::getParameterId(message), &ownerWrapper); - } - } + result = sendParameter(message->getSender(), + ParameterMessage::getParameterId(message), &ownerWrapper); break; + } default: return HasReturnvaluesIF::RETURN_FAILED; } @@ -113,15 +117,13 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, } ReturnValue_t ParameterHelper::initialize() { - ownerQueueId = owner->getCommandQueue(); + ownerQueueId = owner->getCommandQueue(); - - storage = objectManager->get(objects::IPC_STORE); - if (storage == NULL) { - return HasReturnvaluesIF::RETURN_FAILED; - } else { - return HasReturnvaluesIF::RETURN_OK; - } + storage = objectManager->get(objects::IPC_STORE); + if (storage == nullptr) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, diff --git a/parameters/ParameterMessage.cpp b/parameters/ParameterMessage.cpp index e9f3191fc..af1f9ce83 100644 --- a/parameters/ParameterMessage.cpp +++ b/parameters/ParameterMessage.cpp @@ -25,10 +25,26 @@ void ParameterMessage::setParameterDumpReply(CommandMessage* message, } void ParameterMessage::setParameterLoadCommand(CommandMessage* message, - ParameterId_t id, store_address_t storageID) { + ParameterId_t id, store_address_t storeId, uint8_t ptc, uint8_t pfc, + uint8_t rows = 1, uint8_t columns = 1) { message->setCommand(CMD_PARAMETER_LOAD); message->setParameter(id); - message->setParameter2(storageID.raw); + message->setParameter2(storeId.raw); + uint32_t packedParameterSettings = (ptc << 24) | (pfc << 16) | + (rows << 8) | columns; + message->setParameter3(packedParameterSettings); +} + +store_address_t ParameterMessage::getParameterLoadCommand( + const CommandMessage *message, ParameterId_t* parameterId, uint8_t *ptc, + uint8_t *pfc, uint8_t *rows, uint8_t *columns) { + *parameterId = message->getParameter2(); + uint32_t packedParamSettings = message->getParameter3(); + *ptc = packedParamSettings >> 24 & 0xff; + *pfc = packedParamSettings >> 16 & 0xff; + *rows = packedParamSettings >> 8 & 0xff; + *columns = packedParamSettings & 0xff; + return message->getParameter2(); } void ParameterMessage::clear(CommandMessage* message) { diff --git a/parameters/ParameterMessage.h b/parameters/ParameterMessage.h index 31d7fe0bc..fd4481eec 100644 --- a/parameters/ParameterMessage.h +++ b/parameters/ParameterMessage.h @@ -5,6 +5,20 @@ #include "../ipc/CommandMessage.h" #include "../storagemanager/StorageManagerIF.h" +/** + * @brief ParameterMessage interface + * @details + * General structure of a parameter message: + * 1. 4-byte Object ID + * 2. 4-byte Parameter ID, first byte is Domain ID, second byte is unique + * identifier, third and fourth byte is linear index to start from + * 3. 4-byte Parameter Settings. First byte and second byte are the PTC and PFC + * ECSS type identifiers (see ECSS-E-ST-70-41C15 p.428 or Type class in + * globalfunctions). Third byte is the number of rows and fourth byte + * is the number of columns. For single variable parameters, this will + * be [1, 1]. + * + */ class ParameterMessage { private: ParameterMessage(); @@ -20,8 +34,27 @@ public: ParameterId_t id); static void setParameterDumpReply(CommandMessage* message, ParameterId_t id, store_address_t storageID); + + /** + * Command to set a load parameter message. The CCSDS / ECSS type in + * form of a PTC and a PFC is expected. See ECSS-E-ST-70-41C15 p.428 + * for all types or the Type class in globalfunctions. + * @param message + * @param id + * @param storeId + * @param ptc Type information according to CCSDS/ECSS standards + * @param pfc Type information according to CCSDS/ECSS standards + * @param rows Set number of rows in parameter set, minimum one. + * @param columns Set number of columns in parameter set, minimum one + */ static void setParameterLoadCommand(CommandMessage* message, - ParameterId_t id, store_address_t storageID); + ParameterId_t id, store_address_t storeId, uint8_t ptc, + uint8_t pfc, uint8_t rows, uint8_t columns); + + static store_address_t getParameterLoadCommand( + const CommandMessage* message, ParameterId_t* parameterId, + uint8_t* ptc, uint8_t* pfc, uint8_t* rows, uint8_t* columns) ; + static void clear(CommandMessage* message); }; diff --git a/parameters/ParameterWrapper.cpp b/parameters/ParameterWrapper.cpp index 6adc6857c..239555162 100644 --- a/parameters/ParameterWrapper.cpp +++ b/parameters/ParameterWrapper.cpp @@ -115,7 +115,7 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, uint8_t fromColumns) { //treat from as a continuous Stream as we copy all of it - const uint8_t *fromAsStream = (const uint8_t*) from; + const uint8_t *fromAsStream = reinterpret_cast(from); size_t streamSize = fromRows * fromColumns * sizeof(T); ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; @@ -123,8 +123,8 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { //get the start element of this row in data - T *dataWithDataType = ((T*) data) - + (((startingRow + fromRow) * columns) + startingColumn); + uint16_t offset = (((startingRow + fromRow) * columns) + startingColumn); + T *dataWithDataType = static_cast(data) + offset; for (uint8_t fromColumn = 0; fromColumn < fromColumns; fromColumn++) { result = SerializeAdapter::deSerialize( @@ -159,6 +159,23 @@ ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer, return copyFrom(&streamDescription, startWritingAtIndex); } +ReturnValue_t ParameterWrapper::set(Type type, uint8_t rows, uint8_t columns, + const void *data, size_t dataSize) { + this->type = type; + this->rows = rows; + this->columns = columns; + + size_t expectedSize = type.getSize() * rows * columns; + if (expectedSize < dataSize) { + return SerializeIF::STREAM_TOO_SHORT; + } + + this->data = nullptr; + this->readonlyData = data; + pointsToStream = true; + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t ParameterWrapper::set(const uint8_t *stream, size_t streamSize, const uint8_t **remainingStream, size_t *remainingSize) { ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream, @@ -202,11 +219,13 @@ ReturnValue_t ParameterWrapper::set(const uint8_t *stream, size_t streamSize, ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, uint16_t startWritingAtIndex) { - if (data == NULL) { + // TODO: Optional diagnostic output (which can be disabled in FSFWConfig) + // to determined faulty implementations and configuration errors quickly. + if (data == nullptr) { return READONLY; } - if (from->readonlyData == NULL) { + if (from->readonlyData == nullptr) { return SOURCE_NOT_SET; } @@ -214,9 +233,16 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, return DATATYPE_MISSMATCH; } + // The smallest allowed value for rows and columns is one. + if(rows == 0 or columns == 0) { + return COLUMN_OR_ROWS_ZERO; + } + //check if from fits into this - uint8_t startingRow = startWritingAtIndex / columns; - uint8_t startingColumn = startWritingAtIndex % columns; + uint8_t startingRow = 0; + uint8_t startingColumn = 0; + ParameterWrapper::convertLinearIndexToRowAndColumn(startWritingAtIndex, + &startingRow, &startingColumn); if ((from->rows > (rows - startingRow)) || (from->columns > (columns - startingColumn))) { @@ -279,3 +305,18 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, return result; } + +void ParameterWrapper::convertLinearIndexToRowAndColumn(uint16_t index, + uint8_t *row, uint8_t *column) { + if(row == nullptr or column == nullptr) { + return; + } + // Integer division. + *row = index / columns; + *column = index % columns; +} + +uint16_t ParameterWrapper::convertRowAndColumnToLinearIndex(uint8_t row, + uint8_t column) { + return row * columns + column; +} diff --git a/parameters/ParameterWrapper.h b/parameters/ParameterWrapper.h index f07205d4b..168a535f2 100644 --- a/parameters/ParameterWrapper.h +++ b/parameters/ParameterWrapper.h @@ -22,6 +22,7 @@ public: static const ReturnValue_t SOURCE_NOT_SET = MAKE_RETURN_CODE(0x05); static const ReturnValue_t OUT_OF_BOUNDS = MAKE_RETURN_CODE(0x06); static const ReturnValue_t NOT_SET = MAKE_RETURN_CODE(0x07); + static const ReturnValue_t COLUMN_OR_ROWS_ZERO = MAKE_RETURN_CODE(0x08); ParameterWrapper(); ParameterWrapper(Type type, uint8_t rows, uint8_t columns, void *data); @@ -68,7 +69,7 @@ public: template void set(const T *readonlyData, uint8_t rows, uint8_t columns) { - this->data = NULL; + this->data = nullptr; this->readonlyData = readonlyData; this->type = PodTypeConversion::type; this->rows = rows; @@ -97,14 +98,19 @@ public: } template void setMatrix(T& member) { - this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0])); + this->set(member[0], sizeof(member)/sizeof(member[0]), + sizeof(member[0])/sizeof(member[0][0])); } template void setMatrix(const T& member) { - this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0])); + this->set(member[0], sizeof(member)/sizeof(member[0]), + sizeof(member[0])/sizeof(member[0][0])); } + ReturnValue_t set(Type type, uint8_t rows, uint8_t columns, + const void *data, size_t dataSize); + ReturnValue_t set(const uint8_t *stream, size_t streamSize, const uint8_t **remainingStream = nullptr, size_t *remainingSize = nullptr); @@ -113,6 +119,13 @@ public: uint16_t startWritingAtIndex); private: + + void convertLinearIndexToRowAndColumn(uint16_t index, + uint8_t *row, uint8_t *column); + + uint16_t convertRowAndColumnToLinearIndex(uint8_t row, + uint8_t column); + bool pointsToStream = false; Type type; @@ -148,9 +161,9 @@ inline ReturnValue_t ParameterWrapper::getElement(T *value, uint8_t row, if (pointsToStream) { const uint8_t *streamWithType = static_cast(readonlyData); streamWithType += (row * columns + column) * type.getSize(); - int32_t size = type.getSize(); + size_t size = type.getSize(); return SerializeAdapter::deSerialize(value, &streamWithType, - &size, true); + &size, SerializeIF::Endianness::BIG); } else { const T *dataWithType = static_cast(readonlyData); From 0304f61bdeb3035137bea029b145bacd34b5dd75 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 Nov 2020 11:00:13 +0100 Subject: [PATCH 06/37] has parametersIF doc improved --- parameters/HasParametersIF.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/parameters/HasParametersIF.h b/parameters/HasParametersIF.h index c4fd81b34..19c12d81f 100644 --- a/parameters/HasParametersIF.h +++ b/parameters/HasParametersIF.h @@ -1,8 +1,8 @@ #ifndef FSFW_PARAMETERS_HASPARAMETERSIF_H_ #define FSFW_PARAMETERS_HASPARAMETERSIF_H_ -#include "../returnvalues/HasReturnvaluesIF.h" #include "ParameterWrapper.h" +#include "../returnvalues/HasReturnvaluesIF.h" #include /** @@ -20,11 +20,10 @@ using ParameterId_t = uint32_t; * ID is the domain ID which can be used to identify unqiue spacecraft domains * (e.g. control and sensor domain in the AOCS controller). * - * The second and third byte represent the matrix ID, which can represent - * a 8-bit row and column number and the last byte... + * The second byte is a unique identfier ID. * - * Yeah, is it matrix ID or parameter ID now and is index a 16 bit number - * of a 8 bit number now? + * The third and fourth byte can be used as a linear index for matrix or array + * parameter entries. */ class HasParametersIF { public: @@ -61,6 +60,10 @@ public: virtual ~HasParametersIF() {} /** + * This is the generic function overriden by child classes to set + * parameters. To set a parameter, the parameter wrapper is used with + * a variety of set functions. The provided values can be checked with + * newValues. * Always set parameter before checking newValues! * * @param domainId From 7c75c6e8cc22a4b8540f8866a5425f101bcfea6e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 Nov 2020 11:14:07 +0100 Subject: [PATCH 07/37] parameter helper update --- parameters/ParameterHelper.cpp | 166 ++++++++++++++++----------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index d2193b289..22465ca33 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -3,7 +3,7 @@ #include "../objectmanager/ObjectManagerIF.h" ParameterHelper::ParameterHelper(ReceivesParameterMessagesIF* owner) : - owner(owner) {} +owner(owner) {} ParameterHelper::~ParameterHelper() { } @@ -14,106 +14,106 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; - switch (message->getCommand()) { - case ParameterMessage::CMD_PARAMETER_DUMP: { - ParameterWrapper description; - uint8_t domain = HasParametersIF::getDomain( - ParameterMessage::getParameterId(message)); - uint8_t uniqueIdentifier = HasParametersIF::getUniqueIdentifierId( - ParameterMessage::getParameterId(message)); - result = owner->getParameter(domain, uniqueIdentifier, - &description, &description, 0); - if (result == HasReturnvaluesIF::RETURN_OK) { - result = sendParameter(message->getSender(), - ParameterMessage::getParameterId(message), &description); - } - } - break; - case ParameterMessage::CMD_PARAMETER_LOAD: { - ParameterId_t parameterId = 0; - uint8_t ptc = 0; - uint8_t pfc = 0; - uint8_t rows = 0; - uint8_t columns = 0; - store_address_t storeId = ParameterMessage::getParameterLoadCommand( - message, ¶meterId, &ptc, &pfc, &rows, &columns); - Type type(Type::getActualType(ptc, pfc)); + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + switch (message->getCommand()) { + case ParameterMessage::CMD_PARAMETER_DUMP: { + ParameterWrapper description; + uint8_t domain = HasParametersIF::getDomain( + ParameterMessage::getParameterId(message)); + uint8_t uniqueIdentifier = HasParametersIF::getUniqueIdentifierId( + ParameterMessage::getParameterId(message)); + result = owner->getParameter(domain, uniqueIdentifier, + &description, &description, 0); + if (result == HasReturnvaluesIF::RETURN_OK) { + result = sendParameter(message->getSender(), + ParameterMessage::getParameterId(message), &description); + } + } + break; + case ParameterMessage::CMD_PARAMETER_LOAD: { + ParameterId_t parameterId = 0; + uint8_t ptc = 0; + uint8_t pfc = 0; + uint8_t rows = 0; + uint8_t columns = 0; + store_address_t storeId = ParameterMessage::getParameterLoadCommand( + message, ¶meterId, &ptc, &pfc, &rows, &columns); + Type type(Type::getActualType(ptc, pfc)); - uint8_t domain = HasParametersIF::getDomain(parameterId); - uint8_t uniqueIdentifier = HasParametersIF::getUniqueIdentifierId( - parameterId); - uint16_t linearIndex = HasParametersIF::getIndex(parameterId); + uint8_t domain = HasParametersIF::getDomain(parameterId); + uint8_t uniqueIdentifier = HasParametersIF::getUniqueIdentifierId( + parameterId); + uint16_t linearIndex = HasParametersIF::getIndex(parameterId); - ConstStorageAccessor accessor(storeId); - result = storage->getData(storeId, accessor); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "ParameterHelper::handleParameterMessage: Getting" - << " store data failed for load command." << std::endl; - break; - } + ConstStorageAccessor accessor(storeId); + result = storage->getData(storeId, accessor); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "ParameterHelper::handleParameterMessage: Getting" + << " store data failed for load command." << std::endl; + break; + } - ParameterWrapper streamWrapper; - result = streamWrapper.set(type, rows, columns, accessor.data(), - accessor.size()); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + ParameterWrapper streamWrapper; + result = streamWrapper.set(type, rows, columns, accessor.data(), + accessor.size()); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - ParameterWrapper ownerWrapper; - result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper, - &streamWrapper, linearIndex); + ParameterWrapper ownerWrapper; + result = owner->getParameter(domain, uniqueIdentifier, &ownerWrapper, + &streamWrapper, linearIndex); - result = ownerWrapper.copyFrom(&streamWrapper, linearIndex); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + result = ownerWrapper.copyFrom(&streamWrapper, linearIndex); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } result = sendParameter(message->getSender(), ParameterMessage::getParameterId(message), &ownerWrapper); - break; - } - default: - return HasReturnvaluesIF::RETURN_FAILED; - } + break; + } + default: + return HasReturnvaluesIF::RETURN_FAILED; + } - if (result != HasReturnvaluesIF::RETURN_OK) { - rejectCommand(message->getSender(), result, message->getCommand()); - } + if (result != HasReturnvaluesIF::RETURN_OK) { + rejectCommand(message->getSender(), result, message->getCommand()); + } - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, - const ParameterWrapper* description) { - size_t serializedSize = description->getSerializedSize(); + const ParameterWrapper* description) { + size_t serializedSize = description->getSerializedSize(); - uint8_t *storeElement; - store_address_t address; + uint8_t *storeElement; + store_address_t address; - ReturnValue_t result = storage->getFreeElement(&address, serializedSize, - &storeElement); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + ReturnValue_t result = storage->getFreeElement(&address, serializedSize, + &storeElement); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - size_t storeElementSize = 0; + size_t storeElementSize = 0; - result = description->serialize(&storeElement, &storeElementSize, - serializedSize, SerializeIF::Endianness::BIG); + result = description->serialize(&storeElement, &storeElementSize, + serializedSize, SerializeIF::Endianness::BIG); - if (result != HasReturnvaluesIF::RETURN_OK) { - storage->deleteData(address); - return result; - } + if (result != HasReturnvaluesIF::RETURN_OK) { + storage->deleteData(address); + return result; + } - CommandMessage reply; + CommandMessage reply; - ParameterMessage::setParameterDumpReply(&reply, id, address); + ParameterMessage::setParameterDumpReply(&reply, id, address); - MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); + MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t ParameterHelper::initialize() { @@ -127,8 +127,8 @@ ReturnValue_t ParameterHelper::initialize() { } void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, - Command_t initialCommand) { - CommandMessage reply; - reply.setReplyRejected(reason, initialCommand); - MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); + Command_t initialCommand) { + CommandMessage reply; + reply.setReplyRejected(reason, initialCommand); + MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); } From 5865e56c54209ffe3076fda86cf94e02a706df25 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 Nov 2020 11:15:42 +0100 Subject: [PATCH 08/37] indentation fixed --- parameters/ParameterHelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 22465ca33..23d1a1f35 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -2,8 +2,8 @@ #include "ParameterMessage.h" #include "../objectmanager/ObjectManagerIF.h" -ParameterHelper::ParameterHelper(ReceivesParameterMessagesIF* owner) : -owner(owner) {} +ParameterHelper::ParameterHelper(ReceivesParameterMessagesIF* owner): + owner(owner) {} ParameterHelper::~ParameterHelper() { } From 9086ee2ffed94f5bd2343105ad6ccd81bc7de3ab Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 13:24:29 +0100 Subject: [PATCH 09/37] added new tests --- unittest/tests/storagemanager/TestPool.cpp | 591 ++++++++++----------- 1 file changed, 295 insertions(+), 296 deletions(-) diff --git a/unittest/tests/storagemanager/TestPool.cpp b/unittest/tests/storagemanager/TestPool.cpp index f278c40c7..daeb6bb52 100644 --- a/unittest/tests/storagemanager/TestPool.cpp +++ b/unittest/tests/storagemanager/TestPool.cpp @@ -1,296 +1,295 @@ -//#include "CatchDefinitions.h" -// -//#include -//#include -//#include -// -//#include -//#include -// -//#include -// -// -//TEST_CASE( "Local Pool Simple Tests [1 Pool]" , "[TestPool]") { -//// uint16_t numberOfElements[1] = {1}; -//// uint16_t sizeofElements[1] = {10}; -// LocalPool::LocalPoolConfig config = {{1, 10}}; -// LocalPool simplePool(0, config); -// std::array testDataArray; -// std::array receptionArray; -// store_address_t testStoreId; -// ReturnValue_t result = retval::CATCH_FAILED; -// uint8_t *pointer = nullptr; -// const uint8_t * constPointer = nullptr; -// -// for(size_t i = 0; i < testDataArray.size(); i++) { -// testDataArray[i] = i; -// } -// size_t size = 10; -// -// SECTION ( "Basic tests") { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// result = simplePool.getData(testStoreId, &constPointer, &size); -// REQUIRE(result == retval::CATCH_OK); -// memcpy(receptionArray.data(), constPointer, size); -// for(size_t i = 0; i < size; i++) { -// CHECK(receptionArray[i] == i ); -// } -// memset(receptionArray.data(), 0, size); -// result = simplePool.modifyData(testStoreId, &pointer, &size); -// memcpy(receptionArray.data(), pointer, size); -// REQUIRE(result == retval::CATCH_OK); -// for(size_t i = 0; i < size; i++) { -// CHECK(receptionArray[i] == i ); -// } -// result = simplePool.deleteData(testStoreId); -// REQUIRE(result == retval::CATCH_OK); -// result = simplePool.addData(&testStoreId, testDataArray.data(), 15); -// CHECK (result == (int) StorageManagerIF::DATA_TOO_LARGE); -// } -// -// SECTION ( "Reservation Tests ") { -// pointer = nullptr; -// result = simplePool.getFreeElement(&testStoreId, size, &pointer); -// REQUIRE (result == retval::CATCH_OK); -// memcpy(pointer, testDataArray.data(), size); -// constPointer = nullptr; -// result = simplePool.getData(testStoreId, &constPointer, &size); -// -// REQUIRE (result == retval::CATCH_OK); -// memcpy(receptionArray.data(), constPointer, size); -// for(size_t i = 0; i < size; i++) { -// CHECK(receptionArray[i] == i ); -// } -// } -// -// SECTION ( "Add, delete, add, add when full") { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// result = simplePool.getData(testStoreId, &constPointer, &size); -// REQUIRE( result == retval::CATCH_OK); -// memcpy(receptionArray.data(), constPointer, size); -// for(size_t i = 0; i < size; i++) { -// CHECK(receptionArray[i] == i ); -// } -// -// result = simplePool.deleteData(testStoreId); -// REQUIRE(result == retval::CATCH_OK); -// -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// result = simplePool.getData(testStoreId, &constPointer, &size); -// REQUIRE( result == retval::CATCH_OK); -// memcpy(receptionArray.data(), constPointer, size); -// for(size_t i = 0; i < size; i++) { -// CHECK(receptionArray[i] == i ); -// } -// -// store_address_t newAddress; -// result = simplePool.addData(&newAddress, testDataArray.data(), size); -// REQUIRE(result == (int) StorageManagerIF::DATA_STORAGE_FULL); -// -// // Packet Index to high intentionally -// newAddress.packetIndex = 2; -// pointer = testDataArray.data(); -// result = simplePool.modifyData(newAddress, &pointer, &size); -// REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID); -// -// result = simplePool.deleteData(newAddress); -// REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID); -// -// newAddress.packetIndex = 0; -// newAddress.poolIndex = 2; -// result = simplePool.deleteData(newAddress); -// REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID); -// } -// -// SECTION ( "Initialize and clear store, delete with pointer") { -// result = simplePool.initialize(); -// REQUIRE(result == retval::CATCH_OK); -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// simplePool.clearStore(); -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// result = simplePool.modifyData(testStoreId, &pointer, &size); -// REQUIRE(result == retval::CATCH_OK); -// store_address_t newId; -// result = simplePool.deleteData(pointer, size, &testStoreId); -// REQUIRE(result == retval::CATCH_OK); -// REQUIRE(testStoreId.raw != (uint32_t) StorageManagerIF::INVALID_ADDRESS); -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// } -//} -// -//int runIdx = 0; -// -//TEST_CASE( "Local Pool Extended Tests [3 Pools]" , "[TestPool2]") { -// LocalPool::LocalPoolConfig* config; -// if(runIdx == 0) { -// config = new LocalPool::LocalPoolConfig{{10, 5}, {5, 10}, {2, 20}}; -// } -// else { -// // shufle the order, they should be sort implictely so that the -// // order is ascending for the page sizes. -// config = new LocalPool::LocalPoolConfig{{5, 10}, {2, 20}, {10, 5}}; -// size_t lastSize = 0; -// for(const auto& pair: *config) { -// CHECK(pair.second > lastSize); -// lastSize = pair.second; -// } -// } -// runIdx++; -// -// LocalPool simplePool(0, *config); -// std::array testDataArray; -// std::array receptionArray; -// store_address_t testStoreId; -// ReturnValue_t result = retval::CATCH_FAILED; -// for(size_t i = 0; i < testDataArray.size(); i++) { -// testDataArray[i] = i; -// } -// size_t size = 0; -// -// SECTION ("Basic tests") { -// size = 8; -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// // Should be on second page of the pool now for 8 bytes -// CHECK(testStoreId.poolIndex == 1); -// CHECK(testStoreId.packetIndex == 0); -// -// size = 15; -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// // Should be on third page of the pool now for 15 bytes -// CHECK(testStoreId.poolIndex == 2); -// CHECK(testStoreId.packetIndex == 0); -// -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// // Should be on third page of the pool now for 15 bytes -// CHECK(testStoreId.poolIndex == 2); -// CHECK(testStoreId.packetIndex == 1); -// -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// // Should be on third page of the pool now for 15 bytes -// REQUIRE(result == (int) LocalPool::DATA_STORAGE_FULL); -// -// size = 8; -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// // Should still work -// CHECK(testStoreId.poolIndex == 1); -// CHECK(testStoreId.packetIndex == 1); -// -// // fill the rest of the pool -// for(uint8_t idx = 2; idx < 5; idx++) { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// CHECK(testStoreId.poolIndex == 1); -// CHECK(testStoreId.packetIndex == idx); -// } -// } -// -// SECTION ("Fill Count and Clearing") { -// //SECTION("Basic tests"); -// uint8_t bytesWritten = 0; -// simplePool.getFillCount(receptionArray.data(), &bytesWritten); -// // fill count should be all zeros now. -// CHECK(bytesWritten == 4); -// CHECK(receptionArray[0] == 0); -// CHECK(receptionArray[1] == 0); -// CHECK(receptionArray[2] == 0); -// CHECK(receptionArray[3] == 0); -// -// // now fill the store completely. -// size = 5; -// for(uint8_t idx = 0; idx < 10; idx++) { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// CHECK(testStoreId.poolIndex == 0); -// CHECK(testStoreId.packetIndex == idx); -// } -// size = 10; -// for(uint8_t idx = 0; idx < 5; idx++) { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// CHECK(testStoreId.poolIndex == 1); -// CHECK(testStoreId.packetIndex == idx); -// } -// size = 20; -// for(uint8_t idx = 0; idx < 2; idx++) { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// CHECK(testStoreId.poolIndex == 2); -// CHECK(testStoreId.packetIndex == idx); -// } -// bytesWritten = 0; -// simplePool.getFillCount(receptionArray.data(), &bytesWritten); -// // fill count should be all 100 now. -// CHECK(bytesWritten == 4); -// CHECK(receptionArray[0] == 100); -// CHECK(receptionArray[1] == 100); -// CHECK(receptionArray[2] == 100); -// CHECK(receptionArray[3] == 100); -// -// // now clear the store -// simplePool.clearStore(); -// bytesWritten = 0; -// simplePool.getFillCount(receptionArray.data(), &bytesWritten); -// CHECK(bytesWritten == 4); -// CHECK(receptionArray[0] == 0); -// CHECK(receptionArray[1] == 0); -// CHECK(receptionArray[2] == 0); -// CHECK(receptionArray[3] == 0); -// -// // now fill one page -// size = 5; -// for(uint8_t idx = 0; idx < 10; idx++) { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// CHECK(testStoreId.poolIndex == 0); -// CHECK(testStoreId.packetIndex == idx); -// } -// bytesWritten = 0; -// simplePool.getFillCount(receptionArray.data(), &bytesWritten); -// // First page full, median fill count is 33 % -// CHECK(bytesWritten == 4); -// CHECK(receptionArray[0] == 100); -// CHECK(receptionArray[1] == 0); -// CHECK(receptionArray[2] == 0); -// CHECK(receptionArray[3] == 33); -// -// // now fill second page -// size = 10; -// for(uint8_t idx = 0; idx < 5; idx++) { -// result = simplePool.addData(&testStoreId, testDataArray.data(), size); -// REQUIRE(result == retval::CATCH_OK); -// CHECK(testStoreId.poolIndex == 1); -// CHECK(testStoreId.packetIndex == idx); -// } -// bytesWritten = 0; -// simplePool.getFillCount(receptionArray.data(), &bytesWritten); -// // First and second page full, median fill count is 66 % -// CHECK(bytesWritten == 4); -// CHECK(receptionArray[0] == 100); -// CHECK(receptionArray[1] == 100); -// CHECK(receptionArray[2] == 0); -// CHECK(receptionArray[3] == 66); -// -// // now clear first page -// simplePool.clearPage(0); -// bytesWritten = 0; -// simplePool.getFillCount(receptionArray.data(), &bytesWritten); -// // Second page full, median fill count is 33 % -// CHECK(bytesWritten == 4); -// CHECK(receptionArray[0] == 0); -// CHECK(receptionArray[1] == 100); -// CHECK(receptionArray[2] == 0); -// CHECK(receptionArray[3] == 33); -// } -// -// delete(config); -//} +#include "CatchDefinitions.h" + +#include +#include + +#include +#include + +#include + + +TEST_CASE( "Local Pool Simple Tests [1 Pool]" , "[TestPool]") { +// uint16_t numberOfElements[1] = {1}; +// uint16_t sizeofElements[1] = {10}; + LocalPool::LocalPoolConfig config = {{1, 10}}; + LocalPool simplePool(0, config); + std::array testDataArray; + std::array receptionArray; + store_address_t testStoreId; + ReturnValue_t result = retval::CATCH_FAILED; + uint8_t *pointer = nullptr; + const uint8_t * constPointer = nullptr; + + for(size_t i = 0; i < testDataArray.size(); i++) { + testDataArray[i] = i; + } + size_t size = 10; + + SECTION ( "Basic tests") { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + result = simplePool.getData(testStoreId, &constPointer, &size); + REQUIRE(result == retval::CATCH_OK); + memcpy(receptionArray.data(), constPointer, size); + for(size_t i = 0; i < size; i++) { + CHECK(receptionArray[i] == i ); + } + memset(receptionArray.data(), 0, size); + result = simplePool.modifyData(testStoreId, &pointer, &size); + memcpy(receptionArray.data(), pointer, size); + REQUIRE(result == retval::CATCH_OK); + for(size_t i = 0; i < size; i++) { + CHECK(receptionArray[i] == i ); + } + result = simplePool.deleteData(testStoreId); + REQUIRE(result == retval::CATCH_OK); + result = simplePool.addData(&testStoreId, testDataArray.data(), 15); + CHECK (result == (int) StorageManagerIF::DATA_TOO_LARGE); + } + + SECTION ( "Reservation Tests ") { + pointer = nullptr; + result = simplePool.getFreeElement(&testStoreId, size, &pointer); + REQUIRE (result == retval::CATCH_OK); + memcpy(pointer, testDataArray.data(), size); + constPointer = nullptr; + result = simplePool.getData(testStoreId, &constPointer, &size); + + REQUIRE (result == retval::CATCH_OK); + memcpy(receptionArray.data(), constPointer, size); + for(size_t i = 0; i < size; i++) { + CHECK(receptionArray[i] == i ); + } + } + + SECTION ( "Add, delete, add, add when full") { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + result = simplePool.getData(testStoreId, &constPointer, &size); + REQUIRE( result == retval::CATCH_OK); + memcpy(receptionArray.data(), constPointer, size); + for(size_t i = 0; i < size; i++) { + CHECK(receptionArray[i] == i ); + } + + result = simplePool.deleteData(testStoreId); + REQUIRE(result == retval::CATCH_OK); + + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + result = simplePool.getData(testStoreId, &constPointer, &size); + REQUIRE( result == retval::CATCH_OK); + memcpy(receptionArray.data(), constPointer, size); + for(size_t i = 0; i < size; i++) { + CHECK(receptionArray[i] == i ); + } + + store_address_t newAddress; + result = simplePool.addData(&newAddress, testDataArray.data(), size); + REQUIRE(result == (int) StorageManagerIF::DATA_STORAGE_FULL); + + // Packet Index to high intentionally + newAddress.packetIndex = 2; + pointer = testDataArray.data(); + result = simplePool.modifyData(newAddress, &pointer, &size); + REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID); + + result = simplePool.deleteData(newAddress); + REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID); + + newAddress.packetIndex = 0; + newAddress.poolIndex = 2; + result = simplePool.deleteData(newAddress); + REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID); + } + + SECTION ( "Initialize and clear store, delete with pointer") { + result = simplePool.initialize(); + REQUIRE(result == retval::CATCH_OK); + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + simplePool.clearStore(); + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + result = simplePool.modifyData(testStoreId, &pointer, &size); + REQUIRE(result == retval::CATCH_OK); + store_address_t newId; + result = simplePool.deleteData(pointer, size, &testStoreId); + REQUIRE(result == retval::CATCH_OK); + REQUIRE(testStoreId.raw != (uint32_t) StorageManagerIF::INVALID_ADDRESS); + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + } +} + +int runIdx = 0; + +TEST_CASE( "Local Pool Extended Tests [3 Pools]" , "[TestPool2]") { + LocalPool::LocalPoolConfig* config; + if(runIdx == 0) { + config = new LocalPool::LocalPoolConfig{{10, 5}, {5, 10}, {2, 20}}; + } + else { + // shufle the order, they should be sort implictely so that the + // order is ascending for the page sizes. + config = new LocalPool::LocalPoolConfig{{5, 10}, {2, 20}, {10, 5}}; + size_t lastSize = 0; + for(const auto& pair: *config) { + CHECK(pair.second > lastSize); + lastSize = pair.second; + } + } + runIdx++; + + LocalPool simplePool(0, *config); + std::array testDataArray; + std::array receptionArray; + store_address_t testStoreId; + ReturnValue_t result = retval::CATCH_FAILED; + for(size_t i = 0; i < testDataArray.size(); i++) { + testDataArray[i] = i; + } + size_t size = 0; + + SECTION ("Basic tests") { + size = 8; + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + // Should be on second page of the pool now for 8 bytes + CHECK(testStoreId.poolIndex == 1); + CHECK(testStoreId.packetIndex == 0); + + size = 15; + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + // Should be on third page of the pool now for 15 bytes + CHECK(testStoreId.poolIndex == 2); + CHECK(testStoreId.packetIndex == 0); + + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + // Should be on third page of the pool now for 15 bytes + CHECK(testStoreId.poolIndex == 2); + CHECK(testStoreId.packetIndex == 1); + + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + // Should be on third page of the pool now for 15 bytes + REQUIRE(result == (int) LocalPool::DATA_STORAGE_FULL); + + size = 8; + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + // Should still work + CHECK(testStoreId.poolIndex == 1); + CHECK(testStoreId.packetIndex == 1); + + // fill the rest of the pool + for(uint8_t idx = 2; idx < 5; idx++) { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + CHECK(testStoreId.poolIndex == 1); + CHECK(testStoreId.packetIndex == idx); + } + } + + SECTION ("Fill Count and Clearing") { + //SECTION("Basic tests"); + uint8_t bytesWritten = 0; + simplePool.getFillCount(receptionArray.data(), &bytesWritten); + // fill count should be all zeros now. + CHECK(bytesWritten == 4); + CHECK(receptionArray[0] == 0); + CHECK(receptionArray[1] == 0); + CHECK(receptionArray[2] == 0); + CHECK(receptionArray[3] == 0); + + // now fill the store completely. + size = 5; + for(uint8_t idx = 0; idx < 10; idx++) { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + CHECK(testStoreId.poolIndex == 0); + CHECK(testStoreId.packetIndex == idx); + } + size = 10; + for(uint8_t idx = 0; idx < 5; idx++) { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + CHECK(testStoreId.poolIndex == 1); + CHECK(testStoreId.packetIndex == idx); + } + size = 20; + for(uint8_t idx = 0; idx < 2; idx++) { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + CHECK(testStoreId.poolIndex == 2); + CHECK(testStoreId.packetIndex == idx); + } + bytesWritten = 0; + simplePool.getFillCount(receptionArray.data(), &bytesWritten); + // fill count should be all 100 now. + CHECK(bytesWritten == 4); + CHECK(receptionArray[0] == 100); + CHECK(receptionArray[1] == 100); + CHECK(receptionArray[2] == 100); + CHECK(receptionArray[3] == 100); + + // now clear the store + simplePool.clearStore(); + bytesWritten = 0; + simplePool.getFillCount(receptionArray.data(), &bytesWritten); + CHECK(bytesWritten == 4); + CHECK(receptionArray[0] == 0); + CHECK(receptionArray[1] == 0); + CHECK(receptionArray[2] == 0); + CHECK(receptionArray[3] == 0); + + // now fill one page + size = 5; + for(uint8_t idx = 0; idx < 10; idx++) { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + CHECK(testStoreId.poolIndex == 0); + CHECK(testStoreId.packetIndex == idx); + } + bytesWritten = 0; + simplePool.getFillCount(receptionArray.data(), &bytesWritten); + // First page full, median fill count is 33 % + CHECK(bytesWritten == 4); + CHECK(receptionArray[0] == 100); + CHECK(receptionArray[1] == 0); + CHECK(receptionArray[2] == 0); + CHECK(receptionArray[3] == 33); + + // now fill second page + size = 10; + for(uint8_t idx = 0; idx < 5; idx++) { + result = simplePool.addData(&testStoreId, testDataArray.data(), size); + REQUIRE(result == retval::CATCH_OK); + CHECK(testStoreId.poolIndex == 1); + CHECK(testStoreId.packetIndex == idx); + } + bytesWritten = 0; + simplePool.getFillCount(receptionArray.data(), &bytesWritten); + // First and second page full, median fill count is 66 % + CHECK(bytesWritten == 4); + CHECK(receptionArray[0] == 100); + CHECK(receptionArray[1] == 100); + CHECK(receptionArray[2] == 0); + CHECK(receptionArray[3] == 66); + + // now clear first page + simplePool.clearPage(0); + bytesWritten = 0; + simplePool.getFillCount(receptionArray.data(), &bytesWritten); + // Second page full, median fill count is 33 % + CHECK(bytesWritten == 4); + CHECK(receptionArray[0] == 0); + CHECK(receptionArray[1] == 100); + CHECK(receptionArray[2] == 0); + CHECK(receptionArray[3] == 33); + } + + delete(config); +} From 378cbab64d0449c78aafc97922ea20118f842d57 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 13:25:00 +0100 Subject: [PATCH 10/37] removed config includes --- storagemanager/LocalPool.cpp | 1 - storagemanager/PoolManager.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/storagemanager/LocalPool.cpp b/storagemanager/LocalPool.cpp index 48934a0c8..8e5f4d488 100644 --- a/storagemanager/LocalPool.cpp +++ b/storagemanager/LocalPool.cpp @@ -1,5 +1,4 @@ #include "LocalPool.h" -#include #include LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig, diff --git a/storagemanager/PoolManager.cpp b/storagemanager/PoolManager.cpp index 85376b282..9c801a3da 100644 --- a/storagemanager/PoolManager.cpp +++ b/storagemanager/PoolManager.cpp @@ -1,5 +1,4 @@ #include "PoolManager.h" -#include PoolManager::PoolManager(object_id_t setObjectId, const LocalPoolConfig& localPoolConfig): From 9ebf259a9e0ac9c10e501182bd18916bfef41a56 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 13:50:33 +0100 Subject: [PATCH 11/37] added back config --- storagemanager/LocalPool.cpp | 9 +++++---- storagemanager/PoolManager.cpp | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/storagemanager/LocalPool.cpp b/storagemanager/LocalPool.cpp index 8e5f4d488..74e362d49 100644 --- a/storagemanager/LocalPool.cpp +++ b/storagemanager/LocalPool.cpp @@ -1,4 +1,5 @@ #include "LocalPool.h" +#include #include LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig, @@ -116,7 +117,7 @@ ReturnValue_t LocalPool::modifyData(store_address_t storeId, } ReturnValue_t LocalPool::deleteData(store_address_t storeId) { -#if FSFW_DEBUGGING == 1 +#if FSFW_VERBOSE_PRINTOUT == 2 sif::debug << "Delete: Pool: " << std::dec << storeId.poolIndex << " Index: " << storeId.packetIndex << std::endl; @@ -155,7 +156,7 @@ ReturnValue_t LocalPool::deleteData(uint8_t *ptr, size_t size, // element of an object. localId.packetIndex = deltaAddress / elementSizes[n]; result = deleteData(localId); -#if FSFW_DEBUGGING == 1 +#if FSFW_VERBOSE_PRINTOUT == 2 if (deltaAddress % elementSizes[n] != 0) { sif::error << "LocalPool::deleteData: Address not aligned!" << std::endl; @@ -222,7 +223,7 @@ ReturnValue_t LocalPool::reserveSpace(const size_t size, status = findEmpty(storeId->poolIndex, &storeId->packetIndex); } if (status == RETURN_OK) { -#if FSFW_DEBUGGING == 1 +#if FSFW_VERBOSE_PRINTOUT == 2 sif::debug << "Reserve: Pool: " << std::dec << storeId->poolIndex << " Index: " << storeId->packetIndex << std::endl; @@ -264,7 +265,7 @@ void LocalPool::setToSpillToHigherPools(bool enable) { ReturnValue_t LocalPool::getPoolIndex(size_t packetSize, uint16_t *poolIndex, uint16_t startAtIndex) { for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) { -#if FSFW_DEBUGGING == 1 +#if FSFW_VERBOSE_PRINTOUT == 2 sif::debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << n << ", Element Size: " << elementSizes[n] << std::endl; #endif diff --git a/storagemanager/PoolManager.cpp b/storagemanager/PoolManager.cpp index 9c801a3da..3b7b549bd 100644 --- a/storagemanager/PoolManager.cpp +++ b/storagemanager/PoolManager.cpp @@ -1,4 +1,5 @@ #include "PoolManager.h" +#include PoolManager::PoolManager(object_id_t setObjectId, const LocalPoolConfig& localPoolConfig): @@ -24,7 +25,7 @@ ReturnValue_t PoolManager::reserveSpace(const size_t size, ReturnValue_t PoolManager::deleteData( store_address_t storeId) { -#if FSFW_DEBUGGING == 1 +#if FSFW_VERBOSE_PRINTOUT == 2 sif::debug << "PoolManager( " << translateObject(getObjectId()) << " )::deleteData from store " << storeId.poolIndex << ". id is "<< storeId.packetIndex << std::endl; From 2930b2dd5ac533188d3a8969ddf70f44a587f169 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 13:52:40 +0100 Subject: [PATCH 12/37] changelog update --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 96f5703c5..7637700c6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,3 +5,7 @@ - vRequestContextSwitchFromISR is declared extern "C" so it can be defined in a C file without issues + +### Local Pool + +- Interface of LocalPools has change. LocalPool is not a template anymore. Instead the size and bucket number of the pools per page and the number of pages are passed to the ctor instead of two ctor arguments and a template parameter From 8c14cdfbd84654b6761f96769cdefdc98f542043 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 15:34:56 +0100 Subject: [PATCH 13/37] changelog update --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 35547c2ce..16275d7aa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,4 +14,4 @@ a C file without issues ### Local Pool -- Interface of LocalPools has change. LocalPool is not a template anymore. Instead the size and bucket number of the pools per page and the number of pages are passed to the ctor instead of two ctor arguments and a template parameter +- Interface of LocalPools has changed. LocalPool is not a template anymore. Instead the size and bucket number of the pools per page and the number of pages are passed to the ctor instead of two ctor arguments and a template parameter From 09caeffbc7a82ee262723ec13933fe65fc10be0f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 17:15:25 +0100 Subject: [PATCH 14/37] added new interface for file systems --- memory/HasFileSystemIF.h | 80 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 memory/HasFileSystemIF.h diff --git a/memory/HasFileSystemIF.h b/memory/HasFileSystemIF.h new file mode 100644 index 000000000..dcec6346e --- /dev/null +++ b/memory/HasFileSystemIF.h @@ -0,0 +1,80 @@ +#ifndef FSFW_MEMORY_HASFILESYSTEMIF_H_ +#define FSFW_MEMORY_HASFILESYSTEMIF_H_ + +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../returnvalues/FwClassIds.h" +#include "../ipc/messageQueueDefinitions.h" + +#include + +/** + * @brief Generic interface for objects which expose a file system to enable + * message based file handling. + * @author J. Meier, R. Mueller + */ +class HasFileSystemIF { +public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::FILE_SYSTEM; + + static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x00); + static constexpr ReturnValue_t FILE_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01); + static constexpr ReturnValue_t FILE_LOCKED = MAKE_RETURN_CODE(0x02); + + static constexpr ReturnValue_t DIRECTORY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03); + static constexpr ReturnValue_t DIRECTORY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x04); + static constexpr ReturnValue_t DIRECTORY_NOT_EMPTY = MAKE_RETURN_CODE(0x05); + + + static constexpr ReturnValue_t SEQUENCE_PACKET_MISSING_WRITE = MAKE_RETURN_CODE(0x06); //! P1: Sequence number missing + static constexpr ReturnValue_t SEQUENCE_PACKET_MISSING_READ = MAKE_RETURN_CODE(0x07); //! P1: Sequence number missing + + virtual ~HasFileSystemIF() {} + /** + * Function to get the MessageQueueId_t of the implementing object + * @return MessageQueueId_t of the object + */ + virtual MessageQueueId_t getCommandQueue() const = 0; + + /** + * Generic function to append to file. + * @param dirname Directory of the file + * @param filename The filename of the file + * @param data The data to write to the file + * @param size The size of the data to write + * @param packetNumber Current packet number. Can be used to verify that + * there are no missing packets. + * @param args Any other arguments which an implementation might require. + * @param bytesWritten Actual bytes written to file + * For large files the write procedure must be split in multiple calls + * to writeToFile + */ + virtual ReturnValue_t appendToFile(const char* repositoryPath, + const char* filename, const uint8_t* data, size_t size, + uint16_t packetNumber, void* args = nullptr) = 0; + + /** + * Generic function to create a new file. + * @param repositoryPath + * @param filename + * @param data + * @param size + * @param args Any other arguments which an implementation might require. + * @return + */ + virtual ReturnValue_t createFile(const char* repositoryPath, + const char* filename, const uint8_t* data = nullptr, + size_t size = 0, void* args = nullptr) = 0; + + /** + * Generic function to delete a file. + * @param repositoryPath + * @param filename + * @param args + * @return + */ + virtual ReturnValue_t deleteFile(const char* repositoryPath, + const char* filename, void* args = nullptr) = 0; +}; + + +#endif /* FSFW_MEMORY_HASFILESYSTEMIF_H_ */ From f1c5f192134656c7bf2683cb2497cef81cbc747b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 1 Dec 2020 17:17:53 +0100 Subject: [PATCH 15/37] changelog update --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index a6686478c..2791c761b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,3 +11,7 @@ a C file without issues - It is now possible to change the message queue depth for the telecommand verification service (PUS1) - The same is possible for the event reporting service (PUS5) - PUS Health Service added, which allows to command and retrieve health via PUS packets + +### File System Interface + +- A new interfaces specifies the functions for a software object which exposes the file system of a given hardware to use message based file handling (e.g. PUS commanding) From 74ba8b76644c31405d67878421b2081306eab453 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 13:10:33 +0100 Subject: [PATCH 16/37] changel og updated --- CHANGELOG | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index a6686478c..62a6b0a9c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,3 +11,19 @@ a C file without issues - It is now possible to change the message queue depth for the telecommand verification service (PUS1) - The same is possible for the event reporting service (PUS5) - PUS Health Service added, which allows to command and retrieve health via PUS packets + +### Parameter Service + +- The API of the parameter service has been changed to prevent incosistencies +and clarify usage when inspecting the code. +- The parameter ID now consists of: + 1. Domain ID (1 byte) + 2. Unique Identifier (1 byte) + 3. Linear Index (2 bytes) +The linear index can be used for arrays as well as matrices. +The parameter load command now explicitely expects the ECSS PTC and PFC +information as well as the rows and column number. Rows and column will +default to one, which is equivalent to one scalar parameter (the most +important use-case) + + From 3f9f062435061c32818c4c4ddb078cb328ea8f4d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 13:11:52 +0100 Subject: [PATCH 17/37] changelog update --- CHANGELOG | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 62a6b0a9c..8341e1389 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,8 +14,8 @@ a C file without issues ### Parameter Service -- The API of the parameter service has been changed to prevent incosistencies -and clarify usage when inspecting the code. +- The API of the parameter service has been changed to prevent inconsistencies +between documentation and actual code and to clarify usage. - The parameter ID now consists of: 1. Domain ID (1 byte) 2. Unique Identifier (1 byte) From 795ff585f858f7ca4a155eaf7bf704964ad6f13d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 13:14:30 +0100 Subject: [PATCH 18/37] controller base update --- controller/ControllerBase.cpp | 41 ++++++++++-------- controller/ControllerBase.h | 78 +++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 48 deletions(-) diff --git a/controller/ControllerBase.cpp b/controller/ControllerBase.cpp index 695517310..45e678eb4 100644 --- a/controller/ControllerBase.cpp +++ b/controller/ControllerBase.cpp @@ -1,16 +1,16 @@ -#include "../subsystem/SubsystemBase.h" #include "ControllerBase.h" + #include "../subsystem/SubsystemBase.h" #include "../ipc/QueueFactory.h" #include "../action/HasActionsIF.h" -ControllerBase::ControllerBase(uint32_t setObjectId, uint32_t parentId, +ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth) : - SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode( - SUBMODE_NONE), commandQueue(NULL), modeHelper( - this), healthHelper(this, setObjectId),hkSwitcher(this),executingTask(NULL) { - commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth); - + SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), + submode(SUBMODE_NONE), modeHelper(this), + healthHelper(this, setObjectId), hkSwitcher(this) { + commandQueue = QueueFactory::instance()->createMessageQueue( + commandQueueDepth); } ControllerBase::~ControllerBase() { @@ -24,9 +24,9 @@ ReturnValue_t ControllerBase::initialize() { } MessageQueueId_t parentQueue = 0; - if (parentId != 0) { + if (parentId != objects::NO_OBJECT) { SubsystemBase *parent = objectManager->get(parentId); - if (parent == NULL) { + if (parent == nullptr) { return RETURN_FAILED; } parentQueue = parent->getCommandQueue(); @@ -56,26 +56,27 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { } void ControllerBase::handleQueue() { - CommandMessage message; - ReturnValue_t result; - for (result = commandQueue->receiveMessage(&message); result == RETURN_OK; - result = commandQueue->receiveMessage(&message)) { + CommandMessage command; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + for (result = commandQueue->receiveMessage(&command); + result == RETURN_OK; + result = commandQueue->receiveMessage(&command)) { - result = modeHelper.handleModeCommand(&message); + result = modeHelper.handleModeCommand(&command); if (result == RETURN_OK) { continue; } - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); if (result == RETURN_OK) { continue; } - result = handleCommandMessage(&message); + result = handleCommandMessage(&command); if (result == RETURN_OK) { continue; } - message.setToUnknownCommand(); - commandQueue->reply(&message); + command.setToUnknownCommand(); + commandQueue->reply(&command); } } @@ -135,3 +136,7 @@ void ControllerBase::setTaskIF(PeriodicTaskIF* task_){ void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { } + +ReturnValue_t ControllerBase::initializeAfterTaskCreation() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/controller/ControllerBase.h b/controller/ControllerBase.h index f5182ceb3..25d3ab1f3 100644 --- a/controller/ControllerBase.h +++ b/controller/ControllerBase.h @@ -1,5 +1,5 @@ -#ifndef CONTROLLERBASE_H_ -#define CONTROLLERBASE_H_ +#ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_ +#define FSFW_CONTROLLER_CONTROLLERBASE_H_ #include "../health/HasHealthIF.h" #include "../health/HealthHelper.h" @@ -7,73 +7,91 @@ #include "../modes/ModeHelper.h" #include "../objectmanager/SystemObject.h" #include "../tasks/ExecutableObjectIF.h" +#include "../tasks/PeriodicTaskIF.h" #include "../datapool/HkSwitchHelper.h" - +/** + * @brief Generic base class for controller classes + * @details + * Implements common interfaces for controllers, which generally have + * a mode and a health state. This avoids boilerplate code. + */ class ControllerBase: public HasModesIF, public HasHealthIF, public ExecutableObjectIF, public SystemObject, public HasReturnvaluesIF { public: - static const Mode_t MODE_NORMAL = 2; - ControllerBase(uint32_t setObjectId, uint32_t parentId, + ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3); virtual ~ControllerBase(); - ReturnValue_t initialize(); + /** SystemObject override */ + virtual ReturnValue_t initialize() override; - virtual MessageQueueId_t getCommandQueue() const; + virtual MessageQueueId_t getCommandQueue() const override; - virtual ReturnValue_t performOperation(uint8_t opCode); - - virtual ReturnValue_t setHealth(HealthState health); - - virtual HasHealthIF::HealthState getHealth(); - - /** - * Implementation of ExecutableObjectIF function - * - * Used to setup the reference of the task, that executes this component - * @param task_ Pointer to the taskIF of this task - */ - virtual void setTaskIF(PeriodicTaskIF* task_); + /** HasHealthIF overrides */ + virtual ReturnValue_t setHealth(HealthState health) override; + virtual HasHealthIF::HealthState getHealth() override; + /** ExecutableObjectIF overrides */ + virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual void setTaskIF(PeriodicTaskIF* task) override; + virtual ReturnValue_t initializeAfterTaskCreation() override; protected: - const uint32_t parentId; + + /** + * Implemented by child class. Handle command messages which are not + * mode or health messages. + * @param message + * @return + */ + virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0; + + /** + * Periodic helper, implemented by child class. + */ + virtual void performControlOperation() = 0; + + virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t *msToReachTheMode) = 0; + + const object_id_t parentId; Mode_t mode; Submode_t submode; - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; ModeHelper modeHelper; HealthHelper healthHelper; + // Is this still needed? HkSwitchHelper hkSwitcher; /** - * Pointer to the task which executes this component, is invalid before setTaskIF was called. + * Pointer to the task which executes this component, + * is invalid before setTaskIF was called. */ - PeriodicTaskIF* executingTask; + PeriodicTaskIF* executingTask = nullptr; - void handleQueue(); + /** Handle mode and health messages */ + virtual void handleQueue(); - virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0; - virtual void performControlOperation() = 0; - virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t *msToReachTheMode) = 0; + /** Mode helpers */ virtual void modeChanged(Mode_t mode, Submode_t submode); virtual void startTransition(Mode_t mode, Submode_t submode); virtual void getMode(Mode_t *mode, Submode_t *submode); virtual void setToExternalControl(); virtual void announceMode(bool recursive); + /** HK helpers */ virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); }; -#endif /* CONTROLLERBASE_H_ */ +#endif /* FSFW_CONTROLLER_CONTROLLERBASE_H_ */ From 5e092778edcce53ba6bdc89c8b5e0b9a7b9482b8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 13:17:28 +0100 Subject: [PATCH 19/37] some minor changes --- datalinklayer/MapPacketExtraction.cpp | 17 +++++------------ datalinklayer/MapPacketExtraction.h | 8 +------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/datalinklayer/MapPacketExtraction.cpp b/datalinklayer/MapPacketExtraction.cpp index d64348e15..45f7d3f8b 100644 --- a/datalinklayer/MapPacketExtraction.cpp +++ b/datalinklayer/MapPacketExtraction.cpp @@ -1,10 +1,3 @@ -/** - * @file MapPacketExtraction.cpp - * @brief This file defines the MapPacketExtraction class. - * @date 26.03.2013 - * @author baetz - */ - #include "MapPacketExtraction.h" #include "../ipc/QueueFactory.h" #include "../serviceinterface/ServiceInterfaceStream.h" @@ -12,14 +5,14 @@ #include "../tmtcpacket/SpacePacketBase.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../tmtcservices/TmTcMessage.h" -#include +#include MapPacketExtraction::MapPacketExtraction(uint8_t setMapId, object_id_t setPacketDestination) : - lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), bufferPosition( - packetBuffer), packetDestination(setPacketDestination), packetStore( - NULL), tcQueueId(MessageQueueIF::NO_QUEUE) { - memset(packetBuffer, 0, sizeof(packetBuffer)); + lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), + bufferPosition(packetBuffer), packetDestination(setPacketDestination), + packetStore(NULL), tcQueueId(MessageQueueIF::NO_QUEUE) { + std::memset(packetBuffer, 0, sizeof(packetBuffer)); } ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) { diff --git a/datalinklayer/MapPacketExtraction.h b/datalinklayer/MapPacketExtraction.h index 507f13dbe..eff9b7c3c 100644 --- a/datalinklayer/MapPacketExtraction.h +++ b/datalinklayer/MapPacketExtraction.h @@ -1,10 +1,3 @@ -/** - * @file MapPacketExtraction.h - * @brief This file defines the MapPacketExtraction class. - * @date 26.03.2013 - * @author baetz - */ - #ifndef MAPPACKETEXTRACTION_H_ #define MAPPACKETEXTRACTION_H_ @@ -20,6 +13,7 @@ class StorageManagerIF; * The class implements the full MAP Packet Extraction functionality as described in the CCSDS * TC Space Data Link Protocol. It internally stores incomplete segmented packets until they are * fully received. All found packets are forwarded to a single distribution entity. + * @author B. Baetz */ class MapPacketExtraction: public MapPacketExtractionIF { private: From f7f062570e63a249eea95d51312b0dbb0dd104d3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 13:21:44 +0100 Subject: [PATCH 20/37] new internal error reporter using local pools --- internalError/InternalErrorDataset.h | 34 +++++++ internalError/InternalErrorReporter.cpp | 127 ++++++++++++++++++------ internalError/InternalErrorReporter.h | 66 +++++++++--- 3 files changed, 182 insertions(+), 45 deletions(-) create mode 100644 internalError/InternalErrorDataset.h diff --git a/internalError/InternalErrorDataset.h b/internalError/InternalErrorDataset.h new file mode 100644 index 000000000..fa91116d4 --- /dev/null +++ b/internalError/InternalErrorDataset.h @@ -0,0 +1,34 @@ +#ifndef FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ +#define FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ + +#include +#include + +enum errorPoolIds { + TM_HITS, + QUEUE_HITS, + STORE_HITS +}; + + +class InternalErrorDataset: public StaticLocalDataSet<3 * sizeof(uint32_t)> { +public: + static constexpr uint8_t ERROR_SET_ID = 0; + + InternalErrorDataset(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, ERROR_SET_ID) {} + + InternalErrorDataset(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId , ERROR_SET_ID)) {} + + lp_var_t tmHits = lp_var_t(hkManager->getOwner(), + TM_HITS, this); + lp_var_t queueHits = lp_var_t(hkManager->getOwner(), + QUEUE_HITS, this); + lp_var_t storeHits = lp_var_t(hkManager->getOwner(), + STORE_HITS, this); +}; + + + +#endif /* FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ */ diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 861e1595e..8d5c792b8 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -1,17 +1,17 @@ #include "InternalErrorReporter.h" -#include "../datapool/DataSet.h" -#include "../datapool/PoolVariable.h" +#include "../ipc/QueueFactory.h" #include "../ipc/MutexFactory.h" - #include "../serviceinterface/ServiceInterfaceStream.h" InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, - uint32_t queuePoolId, uint32_t tmPoolId, uint32_t storePoolId) : - SystemObject(setObjectId), mutex(NULL), queuePoolId(queuePoolId), tmPoolId( - tmPoolId), storePoolId( - storePoolId), queueHits(0), tmHits(0), storeHits( - 0) { + uint32_t messageQueueDepth) : + SystemObject(setObjectId), + commandQueue(QueueFactory::instance()-> + createMessageQueue(messageQueueDepth)), + poolManager(this, commandQueue), + internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID), + internalErrorDataset(this) { mutex = MutexFactory::instance()->createMutex(); } @@ -19,28 +19,42 @@ InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); } +void InternalErrorReporter::setDiagnosticPrintout(bool enable) { + this->diagnosticPrintout = enable; +} + ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { - - DataSet mySet; - PoolVariable queueHitsInPool(queuePoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - PoolVariable tmHitsInPool(tmPoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - - PoolVariable storeHitsInPool(storePoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - mySet.read(); + internalErrorDataset.read(INTERNAL_ERROR_MUTEX_TIMEOUT); uint32_t newQueueHits = getAndResetQueueHits(); uint32_t newTmHits = getAndResetTmHits(); uint32_t newStoreHits = getAndResetStoreHits(); - queueHitsInPool.value += newQueueHits; - tmHitsInPool.value += newTmHits; - storeHitsInPool.value += newStoreHits; +#ifdef DEBUG + if(diagnosticPrintout) { + if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) { + sif::debug << "InternalErrorReporter::performOperation: Errors " + << "occured!" << std::endl; + sif::debug << "Queue errors: " << newQueueHits << std::endl; + sif::debug << "TM errors: " << newTmHits << std::endl; + sif::debug << "Store errors: " << newStoreHits << std::endl; + } + } +#endif - mySet.commit(PoolVariableIF::VALID); + internalErrorDataset.queueHits.value += newQueueHits; + internalErrorDataset.storeHits.value += newStoreHits; + internalErrorDataset.tmHits.value += newTmHits; + internalErrorDataset.commit(INTERNAL_ERROR_MUTEX_TIMEOUT); + + poolManager.performHkOperation(); + + CommandMessage message; + ReturnValue_t result = commandQueue->receiveMessage(&message); + if(result != MessageQueueIF::EMPTY) { + poolManager.handleHousekeepingMessage(&message); + } return HasReturnvaluesIF::RETURN_OK; } @@ -54,7 +68,7 @@ void InternalErrorReporter::lostTm() { uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = queueHits; queueHits = 0; mutex->unlockMutex(); @@ -63,21 +77,21 @@ uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t InternalErrorReporter::getQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = queueHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementQueueHits() { - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); queueHits++; mutex->unlockMutex(); } uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = tmHits; tmHits = 0; mutex->unlockMutex(); @@ -86,14 +100,14 @@ uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t InternalErrorReporter::getTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = tmHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementTmHits() { - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); tmHits++; mutex->unlockMutex(); } @@ -104,7 +118,7 @@ void InternalErrorReporter::storeFull() { uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = storeHits; storeHits = 0; mutex->unlockMutex(); @@ -113,14 +127,65 @@ uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t InternalErrorReporter::getStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); value = storeHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementStoreHits() { - mutex->lockMutex(MutexIF::BLOCKING); + mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT); storeHits++; mutex->unlockMutex(); } + +object_id_t InternalErrorReporter::getObjectId() const { + return SystemObject::getObjectId(); +} + +MessageQueueId_t InternalErrorReporter::getCommandQueue() const { + return this->commandQueue->getId(); +} + +ReturnValue_t InternalErrorReporter::initializeLocalDataPool( + LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(errorPoolIds::TM_HITS, + new PoolEntry()); + localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, + new PoolEntry()); + localDataPoolMap.emplace(errorPoolIds::STORE_HITS, + new PoolEntry()); + poolManager.subscribeForPeriodicPacket(internalErrorSid, false, + getPeriodicOperationFrequency(), true); + internalErrorDataset.setValidity(true, true); + return HasReturnvaluesIF::RETURN_OK; +} + +LocalDataPoolManager* InternalErrorReporter::getHkManagerHandle() { + return &poolManager; +} + +dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const { + return this->executingTask->getPeriodMs(); +} + +LocalPoolDataSetBase* InternalErrorReporter::getDataSetHandle(sid_t sid) { + return &internalErrorDataset; +} + +void InternalErrorReporter::setTaskIF(PeriodicTaskIF *task) { + this->executingTask = task; +} + +ReturnValue_t InternalErrorReporter::initialize() { + ReturnValue_t result = poolManager.initialize(commandQueue); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return SystemObject::initialize(); +} + +ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() { + return poolManager.initializeAfterTaskCreation(); +} + diff --git a/internalError/InternalErrorReporter.h b/internalError/InternalErrorReporter.h index 9aa24a0fa..8d33c06e2 100644 --- a/internalError/InternalErrorReporter.h +++ b/internalError/InternalErrorReporter.h @@ -1,37 +1,75 @@ -#ifndef INTERNALERRORREPORTER_H_ -#define INTERNALERRORREPORTER_H_ +#ifndef FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_ +#define FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_ #include "InternalErrorReporterIF.h" +#include "../tasks/PeriodicTaskIF.h" +#include "../internalError/InternalErrorDataset.h" +#include "../datapoollocal/LocalDataPoolManager.h" #include "../tasks/ExecutableObjectIF.h" #include "../objectmanager/SystemObject.h" #include "../ipc/MutexIF.h" +/** + * @brief This class is used to track internal errors like lost telemetry, + * failed message sending or a full store. + * @details + * All functions were kept virtual so this class can be extended easily + * to store custom internal errors (e.g. communication interface errors). + */ class InternalErrorReporter: public SystemObject, public ExecutableObjectIF, - public InternalErrorReporterIF { + public InternalErrorReporterIF, + public HasLocalDataPoolIF { public: - InternalErrorReporter(object_id_t setObjectId, uint32_t queuePoolId, - uint32_t tmPoolId, uint32_t storePoolId); + static constexpr uint8_t INTERNAL_ERROR_MUTEX_TIMEOUT = 20; + + InternalErrorReporter(object_id_t setObjectId, + uint32_t messageQueueDepth = 5); + + /** + * Enable diagnostic printout. Please note that this feature will + * only work if DEBUG has been supplied to the build defines. + * @param enable + */ + void setDiagnosticPrintout(bool enable); + virtual ~InternalErrorReporter(); - virtual ReturnValue_t performOperation(uint8_t opCode); + virtual object_id_t getObjectId() const override; + virtual MessageQueueId_t getCommandQueue() const override; + virtual ReturnValue_t initializeLocalDataPool( + LocalDataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + virtual LocalDataPoolManager* getHkManagerHandle() override; + virtual dur_millis_t getPeriodicOperationFrequency() const override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + + virtual ReturnValue_t initialize() override; + virtual ReturnValue_t initializeAfterTaskCreation() override; + virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual void queueMessageNotSent(); virtual void lostTm(); virtual void storeFull(); + + virtual void setTaskIF(PeriodicTaskIF* task) override; protected: - MutexIF* mutex; + MessageQueueIF* commandQueue; + LocalDataPoolManager poolManager; - uint32_t queuePoolId; - uint32_t tmPoolId; - uint32_t storePoolId; + PeriodicTaskIF* executingTask = nullptr; + MutexIF* mutex = nullptr; + sid_t internalErrorSid; + InternalErrorDataset internalErrorDataset; - uint32_t queueHits; - uint32_t tmHits; - uint32_t storeHits; + bool diagnosticPrintout = true; + + uint32_t queueHits = 0; + uint32_t tmHits = 0; + uint32_t storeHits = 0; uint32_t getAndResetQueueHits(); uint32_t getQueueHits(); @@ -47,4 +85,4 @@ protected: }; -#endif /* INTERNALERRORREPORTER_H_ */ +#endif /* FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_ */ From c6db9944fd57d934fed5a54f0816feeea346ebf1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 13:26:50 +0100 Subject: [PATCH 21/37] changelog update --- CHANGELOG | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index a6686478c..b8f589f88 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,3 +11,10 @@ a C file without issues - It is now possible to change the message queue depth for the telecommand verification service (PUS1) - The same is possible for the event reporting service (PUS5) - PUS Health Service added, which allows to command and retrieve health via PUS packets + +### Internal Error Reporter + +- The new internal error reporter uses the local data pools. The pool IDs for +the exisiting three error values and the new error set will be hardcoded for +now, the the constructor for the internal error reporter just takes an object +ID for now. From ec3c83bcc1e9cbf587b4602fa3d65d9f797c781e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 18:24:51 +0100 Subject: [PATCH 22/37] monitoring update --- monitoring/AbsLimitMonitor.h | 28 +++++++----- monitoring/HasMonitorsIF.h | 12 ++--- monitoring/LimitMonitor.h | 27 ++++++----- monitoring/MonitorBase.h | 64 +++++++++++++++++---------- monitoring/MonitorReporter.h | 37 +++++++++------- monitoring/MonitoringIF.h | 8 ++-- monitoring/MonitoringMessageContent.h | 37 ++++++++++------ monitoring/TriplexMonitor.h | 2 +- 8 files changed, 127 insertions(+), 88 deletions(-) diff --git a/monitoring/AbsLimitMonitor.h b/monitoring/AbsLimitMonitor.h index 2e60f6f8c..5feb369c0 100644 --- a/monitoring/AbsLimitMonitor.h +++ b/monitoring/AbsLimitMonitor.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ -#define FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ +#ifndef FSFW_MONITORING_ABSLIMITMONITOR_H_ +#define FSFW_MONITORING_ABSLIMITMONITOR_H_ #include "MonitorBase.h" #include @@ -7,9 +7,14 @@ template class AbsLimitMonitor: public MonitorBase { public: - AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, uint32_t parameterId, - uint16_t confirmationLimit, T limit, Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE, bool aboveIsViolation = true) : - MonitorBase(reporterId, monitorId, parameterId, confirmationLimit), limit(limit), violationEvent(violationEvent), aboveIsViolation(aboveIsViolation) { + AbsLimitMonitor(object_id_t reporterId, uint8_t monitorId, + gp_id_t globalPoolId, uint16_t confirmationLimit, T limit, + Event violationEvent = MonitoringIF::VALUE_OUT_OF_RANGE, + bool aboveIsViolation = true) : + MonitorBase(reporterId, monitorId, globalPoolId, + confirmationLimit), + limit(limit), violationEvent(violationEvent), + aboveIsViolation(aboveIsViolation) { } virtual ~AbsLimitMonitor() { } @@ -32,8 +37,9 @@ public: const ParameterWrapper *newValues, uint16_t startAtIndex) { ReturnValue_t result = this->MonitorBase::getParameter(domainId, parameterId, parameterWrapper, newValues, startAtIndex); - //We'll reuse the DOMAIN_ID of MonitorReporter, as we know the parameterIds used there. - if (result != this->INVALID_MATRIX_ID) { + // We'll reuse the DOMAIN_ID of MonitorReporter, + // as we know the parameterIds used there. + if (result != this->INVALID_IDENTIFIER_ID) { return result; } switch (parameterId) { @@ -41,7 +47,7 @@ public: parameterWrapper->set(this->limit); break; default: - return this->INVALID_MATRIX_ID; + return this->INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } @@ -59,7 +65,9 @@ protected: void sendTransitionEvent(T currentValue, ReturnValue_t state) { switch (state) { case MonitoringIF::OUT_OF_RANGE: - EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->parameterId); + EventManagerIF::triggerEvent(this->reportingId, + violationEvent, this->globalPoolId.objectId, + this->globalPoolId.localPoolId); break; default: break; @@ -70,4 +78,4 @@ protected: const bool aboveIsViolation; }; -#endif /* FRAMEWORK_MONITORING_ABSLIMITMONITOR_H_ */ +#endif /* FSFW_MONITORING_ABSLIMITMONITOR_H_ */ diff --git a/monitoring/HasMonitorsIF.h b/monitoring/HasMonitorsIF.h index 85d92b6b9..04f634374 100644 --- a/monitoring/HasMonitorsIF.h +++ b/monitoring/HasMonitorsIF.h @@ -1,11 +1,5 @@ -/** - * @file HasMonitorsIF.h - * @brief This file defines the HasMonitorsIF class. - * @date 28.07.2014 - * @author baetz - */ -#ifndef HASMONITORSIF_H_ -#define HASMONITORSIF_H_ +#ifndef FSFW_MONITORING_HASMONITORSIF_H_ +#define FSFW_MONITORING_HASMONITORSIF_H_ #include "../events/EventReportingProxyIF.h" #include "../objectmanager/ObjectManagerIF.h" @@ -27,4 +21,4 @@ public: } }; -#endif /* HASMONITORSIF_H_ */ +#endif /* FSFW_MONITORING_HASMONITORSIF_H_ */ diff --git a/monitoring/LimitMonitor.h b/monitoring/LimitMonitor.h index 66e6725e8..c4448ceda 100644 --- a/monitoring/LimitMonitor.h +++ b/monitoring/LimitMonitor.h @@ -12,13 +12,15 @@ template class LimitMonitor: public MonitorBase { public: - LimitMonitor(object_id_t reporterId, uint8_t monitorId, uint32_t parameterId, - uint16_t confirmationLimit, T lowerLimit, T upperLimit, - Event belowLowEvent = MonitoringIF::VALUE_BELOW_LOW_LIMIT, + LimitMonitor(object_id_t reporterId, uint8_t monitorId, + gp_id_t globalPoolId, uint16_t confirmationLimit, T lowerLimit, + T upperLimit, Event belowLowEvent = + MonitoringIF::VALUE_BELOW_LOW_LIMIT, Event aboveHighEvent = MonitoringIF::VALUE_ABOVE_HIGH_LIMIT) : - MonitorBase(reporterId, monitorId, parameterId, confirmationLimit), lowerLimit( - lowerLimit), upperLimit(upperLimit), belowLowEvent( - belowLowEvent), aboveHighEvent(aboveHighEvent) { + MonitorBase(reporterId, monitorId, globalPoolId, + confirmationLimit), + lowerLimit(lowerLimit), upperLimit(upperLimit), + belowLowEvent(belowLowEvent), aboveHighEvent(aboveHighEvent) { } virtual ~LimitMonitor() { } @@ -41,7 +43,7 @@ public: ReturnValue_t result = this->MonitorBase::getParameter(domainId, parameterId, parameterWrapper, newValues, startAtIndex); //We'll reuse the DOMAIN_ID of MonitorReporter, as we know the parameterIds used there. - if (result != this->INVALID_MATRIX_ID) { + if (result != this->INVALID_IDENTIFIER_ID) { return result; } switch (parameterId) { @@ -52,12 +54,13 @@ public: parameterWrapper->set(this->upperLimit); break; default: - return this->INVALID_MATRIX_ID; + return this->INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } bool isOutOfLimits() { - if (this->oldState == MonitoringIF::ABOVE_HIGH_LIMIT || this->oldState == MonitoringIF::BELOW_LOW_LIMIT) { + if (this->oldState == MonitoringIF::ABOVE_HIGH_LIMIT or + this->oldState == MonitoringIF::BELOW_LOW_LIMIT) { return true; } else { return false; @@ -76,10 +79,12 @@ protected: void sendTransitionEvent(T currentValue, ReturnValue_t state) { switch (state) { case MonitoringIF::BELOW_LOW_LIMIT: - EventManagerIF::triggerEvent(this->reportingId, belowLowEvent, this->parameterId); + EventManagerIF::triggerEvent(this->reportingId, belowLowEvent, + this->globalPoolId.objectId, this->globalPoolId.localPoolId); break; case MonitoringIF::ABOVE_HIGH_LIMIT: - EventManagerIF::triggerEvent(this->reportingId, aboveHighEvent, this->parameterId); + EventManagerIF::triggerEvent(this->reportingId, aboveHighEvent, + this->globalPoolId.objectId, this->globalPoolId.localPoolId); break; default: break; diff --git a/monitoring/MonitorBase.h b/monitoring/MonitorBase.h index b2d0e6cbb..530a38409 100644 --- a/monitoring/MonitorBase.h +++ b/monitoring/MonitorBase.h @@ -1,39 +1,50 @@ -#ifndef MONITORBASE_H_ -#define MONITORBASE_H_ +#ifndef FSFW_MONITORING_MONITORBASE_H_ +#define FSFW_MONITORING_MONITORBASE_H_ -#include "../datapool/DataSet.h" -#include "../datapool/PIDReader.h" #include "LimitViolationReporter.h" #include "MonitoringIF.h" #include "MonitoringMessageContent.h" #include "MonitorReporter.h" +#include "../datapoollocal/LocalPoolVariable.h" + + /** - * Base class for monitoring of parameters. - * Can be used anywhere, specializations need to implement checkSample and should override sendTransitionEvent. - * Manages state handling, enabling and disabling of events/reports and forwarding of transition - * reports via MonitorReporter. In addition, it provides default implementations for fetching the parameter sample from - * the data pool and a simple confirmation counter. + * @brief Base class for monitoring of parameters. + * @details + * Can be used anywhere, specializations need to implement checkSample and + * should override sendTransitionEvent. + * Manages state handling, enabling and disabling of events/reports and + * forwarding of transition reports via MonitorReporter. + * + * In addition, it provides default implementations for fetching the + * parameter sample from the data pool and a simple confirmation counter. */ template class MonitorBase: public MonitorReporter { public: + MonitorBase(object_id_t reporterId, uint8_t monitorId, - uint32_t parameterId, uint16_t confirmationLimit) : - MonitorReporter(reporterId, monitorId, parameterId, confirmationLimit) { + gp_id_t globalPoolId, uint16_t confirmationLimit): + MonitorReporter(reporterId, monitorId, globalPoolId, + confirmationLimit), + poolVariable(globalPoolId) { } + virtual ~MonitorBase() { } + virtual ReturnValue_t check() { - //1. Fetch sample of type T, return validity. + // 1. Fetch sample of type T, return validity. T sample = 0; ReturnValue_t validity = fetchSample(&sample); - //2. If returning from fetch != OK, parameter is invalid. Report (if oldState is != invalidity). + // 2. If returning from fetch != OK, parameter is invalid. + // Report (if oldState is != invalidity). if (validity != HasReturnvaluesIF::RETURN_OK) { this->monitorStateIs(validity, sample, 0); - //3. Otherwise, check sample. } else { + //3. Otherwise, check sample. this->oldState = doCheck(sample); } return this->oldState; @@ -43,20 +54,25 @@ public: ReturnValue_t currentState = checkSample(sample, &crossedLimit); return this->monitorStateIs(currentState,sample, crossedLimit); } - //Abstract or default. + + // Abstract or default. virtual ReturnValue_t checkSample(T sample, T* crossedLimit) = 0; protected: + virtual ReturnValue_t fetchSample(T* sample) { - DataSet mySet; - PIDReader parameter(this->parameterId, &mySet); - mySet.read(); - if (!parameter.isValid()) { - return MonitoringIF::INVALID; - } - *sample = parameter.value; - return HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = poolVariable.read(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (not poolVariable.isValid()) { + return MonitoringIF::INVALID; + } + *sample = poolVariable.value; + return HasReturnvaluesIF::RETURN_OK; } + + LocalPoolVar poolVariable; }; -#endif /* MONITORBASE_H_ */ +#endif /* FSFW_MONITORING_MONITORBASE_H_ */ diff --git a/monitoring/MonitorReporter.h b/monitoring/MonitorReporter.h index ca2b534b9..9028e7e4a 100644 --- a/monitoring/MonitorReporter.h +++ b/monitoring/MonitorReporter.h @@ -1,10 +1,12 @@ -#ifndef FRAMEWORK_MONITORING_MONITORREPORTER_H_ -#define FRAMEWORK_MONITORING_MONITORREPORTER_H_ +#ifndef FSFW_MONITORING_MONITORREPORTER_H_ +#define FSFW_MONITORING_MONITORREPORTER_H_ -#include "../events/EventManagerIF.h" #include "LimitViolationReporter.h" #include "MonitoringIF.h" #include "MonitoringMessageContent.h" + +#include "../datapoollocal/locPoolDefinitions.h" +#include "../events/EventManagerIF.h" #include "../parameters/HasParametersIF.h" template @@ -14,11 +16,14 @@ public: static const uint8_t ENABLED = 1; static const uint8_t DISABLED = 0; - MonitorReporter(object_id_t reportingId, uint8_t monitorId, uint32_t parameterId, uint16_t confirmationLimit) : - monitorId(monitorId), parameterId(parameterId), reportingId( - reportingId), oldState(MonitoringIF::UNCHECKED), reportingEnabled( - ENABLED), eventEnabled(ENABLED), currentCounter(0), confirmationLimit( - confirmationLimit) { + // TODO: Adapt to use SID instead of parameter ID. + + MonitorReporter(object_id_t reportingId, uint8_t monitorId, + gp_id_t globalPoolId, uint16_t confirmationLimit) : + monitorId(monitorId), globalPoolId(globalPoolId), + reportingId(reportingId), oldState(MonitoringIF::UNCHECKED), + reportingEnabled(ENABLED), eventEnabled(ENABLED), currentCounter(0), + confirmationLimit(confirmationLimit) { } virtual ~MonitorReporter() { @@ -63,7 +68,7 @@ public: parameterWrapper->set(this->eventEnabled); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } @@ -91,7 +96,7 @@ public: protected: const uint8_t monitorId; - const uint32_t parameterId; + const gp_id_t globalPoolId; object_id_t reportingId; ReturnValue_t oldState; @@ -148,7 +153,8 @@ protected: case HasReturnvaluesIF::RETURN_OK: break; default: - EventManagerIF::triggerEvent(reportingId, MonitoringIF::MONITOR_CHANGED_STATE, state); + EventManagerIF::triggerEvent(reportingId, + MonitoringIF::MONITOR_CHANGED_STATE, state); break; } } @@ -159,14 +165,15 @@ protected: * @param crossedLimit The limit crossed (if applicable). * @param state Current state the monitor is in. */ - virtual void sendTransitionReport(T parameterValue, T crossedLimit, ReturnValue_t state) { - MonitoringReportContent report(parameterId, + virtual void sendTransitionReport(T parameterValue, T crossedLimit, + ReturnValue_t state) { + MonitoringReportContent report(globalPoolId, parameterValue, crossedLimit, oldState, state); LimitViolationReporter::sendLimitViolationReport(&report); } ReturnValue_t setToState(ReturnValue_t state) { if (oldState != state && reportingEnabled) { - MonitoringReportContent report(parameterId, 0, 0, oldState, + MonitoringReportContent report(globalPoolId, 0, 0, oldState, state); LimitViolationReporter::sendLimitViolationReport(&report); oldState = state; @@ -175,4 +182,4 @@ protected: } }; -#endif /* FRAMEWORK_MONITORING_MONITORREPORTER_H_ */ +#endif /* FSFW_MONITORING_MONITORREPORTER_H_ */ diff --git a/monitoring/MonitoringIF.h b/monitoring/MonitoringIF.h index 44218c36d..aa266f337 100644 --- a/monitoring/MonitoringIF.h +++ b/monitoring/MonitoringIF.h @@ -1,8 +1,8 @@ -#ifndef MONITORINGIF_H_ -#define MONITORINGIF_H_ +#ifndef FSFW_MONITORING_MONITORINGIF_H_ +#define FSFW_MONITORING_MONITORINGIF_H_ -#include "../memory/HasMemoryIF.h" #include "MonitoringMessage.h" +#include "../memory/HasMemoryIF.h" #include "../serialize/SerializeIF.h" class MonitoringIF : public SerializeIF { @@ -64,4 +64,4 @@ public: -#endif /* MONITORINGIF_H_ */ +#endif /* FSFW_MONITORING_MONITORINGIF_H_ */ diff --git a/monitoring/MonitoringMessageContent.h b/monitoring/MonitoringMessageContent.h index c82506f3a..44d326565 100644 --- a/monitoring/MonitoringMessageContent.h +++ b/monitoring/MonitoringMessageContent.h @@ -3,6 +3,7 @@ #include "HasMonitorsIF.h" #include "MonitoringIF.h" +#include "../datapoollocal/locPoolDefinitions.h" #include "../objectmanager/ObjectManagerIF.h" #include "../serialize/SerialBufferAdapter.h" #include "../serialize/SerialFixedArrayListAdapter.h" @@ -16,12 +17,17 @@ void setStaticFrameworkObjectIds(); } //PID(uint32_t), TYPE, LIMIT_ID, value,limitValue, previous, later, timestamp +/** + * @brief Does magic. + * @tparam T + */ template class MonitoringReportContent: public SerialLinkedListAdapter { friend void (Factory::setStaticFrameworkObjectIds)(); public: SerializeElement monitorId; - SerializeElement parameterId; + SerializeElement parameterObjectId; + SerializeElement localPoolId; SerializeElement parameterValue; SerializeElement limitValue; SerializeElement oldState; @@ -30,20 +36,23 @@ public: SerializeElement> timestampSerializer; TimeStamperIF* timeStamper; MonitoringReportContent() : - SerialLinkedListAdapter( - LinkedElement::Iterator(¶meterId)), monitorId(0), parameterId( - 0), parameterValue(0), limitValue(0), oldState(0), newState( - 0), rawTimestamp( { 0 }), timestampSerializer(rawTimestamp, + SerialLinkedListAdapter(¶meterObjectId), + monitorId(0), parameterObjectId(0), + localPoolId(0), parameterValue(0), + limitValue(0), oldState(0), newState(0), + rawTimestamp( { 0 }), timestampSerializer(rawTimestamp, sizeof(rawTimestamp)), timeStamper(NULL) { setAllNext(); } - MonitoringReportContent(uint32_t setPID, T value, T limitValue, + MonitoringReportContent(gp_id_t globalPoolId, T value, T limitValue, ReturnValue_t oldState, ReturnValue_t newState) : - SerialLinkedListAdapter( - LinkedElement::Iterator(¶meterId)), monitorId(0), parameterId( - setPID), parameterValue(value), limitValue(limitValue), oldState( - oldState), newState(newState), timestampSerializer(rawTimestamp, - sizeof(rawTimestamp)), timeStamper(NULL) { + SerialLinkedListAdapter(¶meterObjectId), + monitorId(0), parameterObjectId(globalPoolId.objectId), + localPoolId(globalPoolId.localPoolId), + parameterValue(value), limitValue(limitValue), + oldState(oldState), newState(newState), + timestampSerializer(rawTimestamp, sizeof(rawTimestamp)), + timeStamper(NULL) { setAllNext(); if (checkAndSetStamper()) { timeStamper->addTimeStamp(rawTimestamp, sizeof(rawTimestamp)); @@ -53,16 +62,16 @@ private: static object_id_t timeStamperId; void setAllNext() { - parameterId.setNext(¶meterValue); + parameterObjectId.setNext(¶meterValue); parameterValue.setNext(&limitValue); limitValue.setNext(&oldState); oldState.setNext(&newState); newState.setNext(×tampSerializer); } bool checkAndSetStamper() { - if (timeStamper == NULL) { + if (timeStamper == nullptr) { timeStamper = objectManager->get( timeStamperId ); - if ( timeStamper == NULL ) { + if ( timeStamper == nullptr ) { sif::error << "MonitoringReportContent::checkAndSetStamper: " "Stamper not found!" << std::endl; return false; diff --git a/monitoring/TriplexMonitor.h b/monitoring/TriplexMonitor.h index 9b60aeb63..c4b3c5375 100644 --- a/monitoring/TriplexMonitor.h +++ b/monitoring/TriplexMonitor.h @@ -82,7 +82,7 @@ public: parameterWrapper->set(limit); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } From 9ba8ef1ae212f9058671399933cf29335cd436f5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 18:29:28 +0100 Subject: [PATCH 23/37] power update --- power/Fuse.cpp | 33 +++++++++++++++------------- power/Fuse.h | 47 ++++++++++++++++++++++------------------ power/PowerComponent.cpp | 27 ++++++++++------------- power/PowerComponent.h | 24 +++++++++++--------- power/PowerComponentIF.h | 19 ++++++++-------- power/PowerSensor.cpp | 30 ++++++++++++++----------- power/PowerSensor.h | 38 ++++++++++++++++++-------------- power/PowerSwitchIF.h | 22 +++++++++---------- power/PowerSwitcher.cpp | 28 +++++++++++++++--------- power/PowerSwitcher.h | 17 ++++++++++----- 10 files changed, 156 insertions(+), 129 deletions(-) diff --git a/power/Fuse.cpp b/power/Fuse.cpp index 9986ab6bb..1c30d83f3 100644 --- a/power/Fuse.cpp +++ b/power/Fuse.cpp @@ -1,22 +1,25 @@ +#include "Fuse.h" + #include "../monitoring/LimitViolationReporter.h" #include "../monitoring/MonitoringMessageContent.h" #include "../objectmanager/ObjectManagerIF.h" -#include "Fuse.h" #include "../serialize/SerialFixedArrayListAdapter.h" #include "../ipc/QueueFactory.h" object_id_t Fuse::powerSwitchId = 0; -Fuse::Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, +Fuse::Fuse(object_id_t fuseObjectId, uint8_t fuseId, + sid_t variableSet, VariableIds ids, float maxCurrent, uint16_t confirmationCount) : - 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), - confirmationCount), set(), voltage(ids.pidVoltage, &set), current( - ids.pidCurrent, &set), state(ids.pidState, &set), power( - ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE), commandQueue( - NULL), parameterHelper(this), healthHelper(this, fuseObjectId) { + SystemObject(fuseObjectId), oldFuseState(0), fuseId(fuseId), + currentLimit(fuseObjectId, 1, ids.pidCurrent, confirmationCount, + maxCurrent, FUSE_CURRENT_HIGH), + powerMonitor(fuseObjectId, 2, ids.poolIdPower, + confirmationCount), + set(variableSet), voltage(ids.pidVoltage, &set), + current(ids.pidCurrent, &set), state(ids.pidState, &set), + power(ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE), + parameterHelper(this), healthHelper(this, fuseObjectId) { commandQueue = QueueFactory::instance()->createMessageQueue(); } @@ -75,7 +78,7 @@ ReturnValue_t Fuse::check() { float lowLimit = 0.0; float highLimit = RESIDUAL_POWER; calculatePowerLimits(&lowLimit, &highLimit); - result = powerMonitor.checkPower(power, lowLimit, highLimit); + result = powerMonitor.checkPower(power.value, lowLimit, highLimit); if (result == MonitoringIF::BELOW_LOW_LIMIT) { reportEvents(POWER_BELOW_LOW_LIMIT); } else if (result == MonitoringIF::ABOVE_HIGH_LIMIT) { @@ -109,7 +112,7 @@ size_t Fuse::getSerializedSize() const { } ReturnValue_t Fuse::deSerialize(const uint8_t** buffer, size_t* size, -Endianness streamEndianness) { + Endianness streamEndianness) { ReturnValue_t result = RETURN_FAILED; for (DeviceList::iterator iter = devices.begin(); iter != devices.end(); iter++) { @@ -132,7 +135,7 @@ void Fuse::calculateFusePower() { return; } //Calculate fuse power. - power = current * voltage; + power.value = current.value * voltage.value; power.setValid(PoolVariableIF::VALID); } @@ -190,12 +193,12 @@ void Fuse::checkFuseState() { reportEvents(FUSE_WENT_OFF); } } - oldFuseState = state; + oldFuseState = state.value; } float Fuse::getPower() { if (power.isValid()) { - return power; + return power.value; } else { return 0.0; } diff --git a/power/Fuse.h b/power/Fuse.h index 279642be6..e9e9290b4 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -1,16 +1,16 @@ -#ifndef FUSE_H_ -#define FUSE_H_ +#ifndef FSFW_POWER_FUSE_H_ +#define FSFW_POWER_FUSE_H_ -#include "../datapool/DataSet.h" -#include "../datapool/PIDReader.h" -#include "../devicehandlers/HealthDevice.h" -#include "../monitoring/AbsLimitMonitor.h" #include "PowerComponentIF.h" #include "PowerSwitchIF.h" + +#include "../devicehandlers/HealthDevice.h" +#include "../monitoring/AbsLimitMonitor.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../parameters/ParameterHelper.h" #include +#include "../datapoollocal/StaticLocalDataSet.h" namespace Factory { void setStaticFrameworkObjectIds(); } @@ -25,10 +25,10 @@ private: static constexpr float RESIDUAL_POWER = 0.005 * 28.5; //!< This is the upper limit of residual power lost by fuses and switches. Worst case is Fuse and one of two switches on. See PCDU ICD 1.9 p29 bottom public: struct VariableIds { - uint32_t pidVoltage; - uint32_t pidCurrent; - uint32_t pidState; - uint32_t poolIdPower; + gp_id_t pidVoltage; + gp_id_t pidCurrent; + gp_id_t pidState; + gp_id_t poolIdPower; }; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1; @@ -38,8 +38,8 @@ public: static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, SEVERITY::LOW); //!< PSS detected a fuse that violates its limits. typedef std::list DeviceList; - Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, - float maxCurrent, uint16_t confirmationCount = 2); + Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, + VariableIds ids, float maxCurrent, uint16_t confirmationCount = 2); virtual ~Fuse(); void addDevice(PowerComponentIF *set); float getPower(); @@ -69,12 +69,12 @@ public: private: uint8_t oldFuseState; uint8_t fuseId; - PowerSwitchIF *powerIF; //could be static in our case. + PowerSwitchIF *powerIF = nullptr; //could be static in our case. AbsLimitMonitor currentLimit; class PowerMonitor: public MonitorReporter { public: template - PowerMonitor(Args ... args) : + PowerMonitor(Args ... args): MonitorReporter(std::forward(args)...) { } ReturnValue_t checkPower(float sample, float lowerLimit, @@ -84,12 +84,17 @@ private: }; PowerMonitor powerMonitor; - DataSet set; - PIDReader voltage; - PIDReader current; - PIDReader state; - db_float_t power; - MessageQueueIF *commandQueue; + StaticLocalDataSet<3> set; + //LocalPoolDataSetBase* set = nullptr; + //PIDReader voltage; + //PIDReader current; + //PIDReader state; + lp_var_t voltage; + lp_var_t current; + lp_var_t state; + + lp_var_t power; + MessageQueueIF* commandQueue = nullptr; ParameterHelper parameterHelper; HealthHelper healthHelper; static object_id_t powerSwitchId; @@ -102,4 +107,4 @@ private: bool areSwitchesOfComponentOn(DeviceList::iterator iter); }; -#endif /* FUSE_H_ */ +#endif /* FSFW_POWER_FUSE_H_ */ diff --git a/power/PowerComponent.cpp b/power/PowerComponent.cpp index 6012ad4ca..c31b9a85e 100644 --- a/power/PowerComponent.cpp +++ b/power/PowerComponent.cpp @@ -1,20 +1,15 @@ -/** - * @file PowerComponent.cpp - * @brief This file defines the PowerComponent class. - * @date 28.08.2014 - * @author baetz - */ - #include "PowerComponent.h" +#include "../serialize/SerializeAdapter.h" -PowerComponent::PowerComponent() : - deviceObjectId(0), switchId1(0xFF), switchId2(0xFF), doIHaveTwoSwitches( - false), min(0.0), max(0.0), moduleId(0) { +PowerComponent::PowerComponent(): switchId1(0xFF), switchId2(0xFF), + doIHaveTwoSwitches(false) { } -PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, - uint8_t switchId1, bool twoSwitches, uint8_t switchId2) : - deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2), doIHaveTwoSwitches( - twoSwitches), min(min), max(max), moduleId(moduleId) { + +PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, + float max, uint8_t switchId1, bool twoSwitches, uint8_t switchId2) : + deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2), + doIHaveTwoSwitches(twoSwitches), min(min), max(max), + moduleId(moduleId) { } ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size, @@ -57,7 +52,7 @@ float PowerComponent::getMax() { } ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size, -Endianness streamEndianness) { + Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { @@ -80,7 +75,7 @@ ReturnValue_t PowerComponent::getParameter(uint8_t domainId, parameterWrapper->set<>(max); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } diff --git a/power/PowerComponent.h b/power/PowerComponent.h index 6d1c9c06d..c1add3b91 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -1,13 +1,17 @@ -#ifndef POWERCOMPONENT_H_ -#define POWERCOMPONENT_H_ +#ifndef FSFW_POWER_POWERCOMPONENT_H_ +#define FSFW_POWER_POWERCOMPONENT_H_ -#include "../objectmanager/SystemObjectIF.h" #include "PowerComponentIF.h" +#include "../objectmanager/frameworkObjects.h" +#include "../objectmanager/SystemObjectIF.h" + + class PowerComponent: public PowerComponentIF { public: - PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, uint8_t switchId1, - bool twoSwitches = false, uint8_t switchId2 = 0xFF); + PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, + uint8_t switchId1, bool twoSwitches = false, + uint8_t switchId2 = 0xFF); virtual object_id_t getDeviceObjectId(); @@ -31,18 +35,18 @@ public: ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex); private: - const object_id_t deviceObjectId; + const object_id_t deviceObjectId = objects::NO_OBJECT; const uint8_t switchId1; const uint8_t switchId2; const bool doIHaveTwoSwitches; - float min; - float max; + float min = 0.0; + float max = 0.0; - uint8_t moduleId; + uint8_t moduleId = 0; PowerComponent(); }; -#endif /* POWERCOMPONENT_H_ */ +#endif /* FSFW_POWER_POWERCOMPONENT_H_ */ diff --git a/power/PowerComponentIF.h b/power/PowerComponentIF.h index c2e3a6a56..f35b4d1d3 100644 --- a/power/PowerComponentIF.h +++ b/power/PowerComponentIF.h @@ -1,24 +1,23 @@ -#ifndef POWERCOMPONENTIF_H_ -#define POWERCOMPONENTIF_H_ +#ifndef FSFW_POWER_POWERCOMPONENTIF_H_ +#define FSFW_POWER_POWERCOMPONENTIF_H_ #include "../serialize/SerializeIF.h" #include "../parameters/HasParametersIF.h" +#include "../objectmanager/SystemObjectIF.h" class PowerComponentIF : public SerializeIF, public HasParametersIF { public: - virtual ~PowerComponentIF() { + virtual ~PowerComponentIF() {} - } + virtual object_id_t getDeviceObjectId() = 0; - virtual object_id_t getDeviceObjectId()=0; - - virtual uint8_t getSwitchId1()=0; - virtual uint8_t getSwitchId2()=0; - virtual bool hasTwoSwitches()=0; + virtual uint8_t getSwitchId1() = 0; + virtual uint8_t getSwitchId2() = 0; + virtual bool hasTwoSwitches() = 0; virtual float getMin() = 0; virtual float getMax() = 0; }; -#endif /* POWERCOMPONENTIF_H_ */ +#endif /* FSFW_POWER_POWERCOMPONENTIF_H_ */ diff --git a/power/PowerSensor.cpp b/power/PowerSensor.cpp index 50cb6acd2..1ef041e30 100644 --- a/power/PowerSensor.cpp +++ b/power/PowerSensor.cpp @@ -1,14 +1,18 @@ #include "PowerSensor.h" + #include "../ipc/QueueFactory.h" -PowerSensor::PowerSensor(object_id_t setId, VariableIds ids, +PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, DefaultLimits limits, SensorEvents events, uint16_t confirmationCount) : - SystemObject(setId), commandQueue(NULL), parameterHelper(this), healthHelper(this, setId), set(), current( - ids.pidCurrent, &set), voltage(ids.pidVoltage, &set), power( - ids.poolIdPower, &set, PoolVariableIF::VAR_WRITE), currentLimit( - setId, MODULE_ID_CURRENT, ids.pidCurrent, confirmationCount, + SystemObject(objectId), parameterHelper(this), + healthHelper(this, objectId), + powerSensorSet(setId), current(ids.pidCurrent, &powerSensorSet), + voltage(ids.pidVoltage, &powerSensorSet), + power(ids.poolIdPower, &powerSensorSet, PoolVariableIF::VAR_WRITE), + currentLimit(objectId, MODULE_ID_CURRENT, ids.pidCurrent, confirmationCount, limits.currentMin, limits.currentMax, events.currentLow, - events.currentHigh), voltageLimit(setId, MODULE_ID_VOLTAGE, + events.currentHigh), + voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount, limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) { commandQueue = QueueFactory::instance()->createMessageQueue(); @@ -19,13 +23,13 @@ PowerSensor::~PowerSensor() { } ReturnValue_t PowerSensor::calculatePower() { - set.read(); + powerSensorSet.read(); ReturnValue_t result1 = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t result2 = HasReturnvaluesIF::RETURN_FAILED; if (healthHelper.healthTable->isHealthy(getObjectId()) && voltage.isValid() && current.isValid()) { - result1 = voltageLimit.doCheck(voltage); - result2 = currentLimit.doCheck(current); + result1 = voltageLimit.doCheck(voltage.value); + result2 = currentLimit.doCheck(current.value); } else { voltageLimit.setToInvalid(); currentLimit.setToInvalid(); @@ -37,9 +41,9 @@ ReturnValue_t PowerSensor::calculatePower() { power.setValid(PoolVariableIF::INVALID); } else { power.setValid(PoolVariableIF::VALID); - power = current * voltage; + power.value = current.value * voltage.value; } - set.commit(); + powerSensorSet.commit(); return result1; } @@ -92,8 +96,8 @@ void PowerSensor::checkCommandQueue() { } void PowerSensor::setDataPoolEntriesInvalid() { - set.read(); - set.commit(PoolVariableIF::INVALID); + powerSensorSet.read(); + powerSensorSet.commit(PoolVariableIF::INVALID); } float PowerSensor::getPower() { diff --git a/power/PowerSensor.h b/power/PowerSensor.h index 0f973e455..a0ccb1ca7 100644 --- a/power/PowerSensor.h +++ b/power/PowerSensor.h @@ -1,9 +1,7 @@ -#ifndef POWERSENSOR_H_ -#define POWERSENSOR_H_ +#ifndef FSFW_POWER_POWERSENSOR_H_ +#define FSFW_POWER_POWERSENSOR_H_ -#include "../datapool/DataSet.h" -#include "../datapool/PIDReader.h" -#include "../datapool/PoolVariable.h" +#include "../datapoollocal/StaticLocalDataSet.h" #include "../devicehandlers/HealthDevice.h" #include "../monitoring/LimitMonitor.h" #include "../parameters/ParameterHelper.h" @@ -12,15 +10,18 @@ class PowerController; +/** + * @brief Does magic. + */ class PowerSensor: public SystemObject, public ReceivesParameterMessagesIF, public HasHealthIF { friend class PowerController; public: struct VariableIds { - uint32_t pidCurrent; - uint32_t pidVoltage; - uint32_t poolIdPower; + gp_id_t pidCurrent; + gp_id_t pidVoltage; + gp_id_t poolIdPower; }; struct DefaultLimits { float currentMin; @@ -34,8 +35,9 @@ public: Event voltageLow; Event voltageHigh; }; - PowerSensor(object_id_t setId, VariableIds setIds, DefaultLimits limits, - SensorEvents events, uint16_t confirmationCount = 0); + PowerSensor(object_id_t objectId, sid_t sid, VariableIds setIds, + DefaultLimits limits, SensorEvents events, + uint16_t confirmationCount = 0); virtual ~PowerSensor(); ReturnValue_t calculatePower(); ReturnValue_t performOperation(uint8_t opCode); @@ -50,15 +52,19 @@ public: ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex); private: - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; ParameterHelper parameterHelper; HealthHelper healthHelper; - DataSet set; + //GlobDataSet set; + StaticLocalDataSet<3> powerSensorSet; //Variables in - PIDReader current; - PIDReader voltage; + lp_var_t current; + lp_var_t voltage; + //PIDReader current; + //PIDReader voltage; //Variables out - db_float_t power; + lp_var_t power; + //gp_float_t power; static const uint8_t MODULE_ID_CURRENT = 1; static const uint8_t MODULE_ID_VOLTAGE = 2; @@ -68,4 +74,4 @@ protected: LimitMonitor voltageLimit; }; -#endif /* POWERSENSOR_H_ */ +#endif /* FSFW_POWER_POWERSENSOR_H_ */ diff --git a/power/PowerSwitchIF.h b/power/PowerSwitchIF.h index 40220fb62..1422baebc 100644 --- a/power/PowerSwitchIF.h +++ b/power/PowerSwitchIF.h @@ -1,18 +1,16 @@ -/** - * @file PowerSwitchIF.h - * @brief This file defines the PowerSwitchIF class. - * @date 20.03.2013 - * @author baetz - */ - -#ifndef POWERSWITCHIF_H_ -#define POWERSWITCHIF_H_ +#ifndef FSFW_POWER_POWERSWITCHIF_H_ +#define FSFW_POWER_POWERSWITCHIF_H_ #include "../events/Event.h" #include "../returnvalues/HasReturnvaluesIF.h" /** - * This interface defines a connection to a device that is capable of turning on and off - * switches of devices identified by a switch ID. + * + * @brief This interface defines a connection to a device that is capable of + * turning on and off switches of devices identified by a switch ID. + * @details + * The virtual functions of this interface do not allow to make any assignments + * because they can be called asynchronosuly (const ending). + * @ingroup interfaces */ class PowerSwitchIF : public HasReturnvaluesIF { public: @@ -72,4 +70,4 @@ public: }; -#endif /* POWERSWITCHIF_H_ */ +#endif /* FSFW_POWER_POWERSWITCHIF_H_ */ diff --git a/power/PowerSwitcher.cpp b/power/PowerSwitcher.cpp index 6296a04c7..ed37998ec 100644 --- a/power/PowerSwitcher.cpp +++ b/power/PowerSwitcher.cpp @@ -1,15 +1,17 @@ -#include "../objectmanager/ObjectManagerIF.h" #include "PowerSwitcher.h" + +#include "../objectmanager/ObjectManagerIF.h" #include "../serviceinterface/ServiceInterfaceStream.h" PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2, - PowerSwitcher::State_t setStartState) : - state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2), power(NULL) { + PowerSwitcher::State_t setStartState): + state(setStartState), firstSwitch(setSwitch1), + secondSwitch(setSwitch2) { } ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) { power = objectManager->get(powerSwitchId); - if (power == NULL) { + if (power == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; @@ -17,19 +19,25 @@ ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) { ReturnValue_t PowerSwitcher::getStateOfSwitches() { SwitchReturn_t result = howManySwitches(); + switch (result) { case ONE_SWITCH: return power->getSwitchState(firstSwitch); - case TWO_SWITCHES: - if ((power->getSwitchState(firstSwitch) == PowerSwitchIF::SWITCH_ON) - && (power->getSwitchState(secondSwitch) == PowerSwitchIF::SWITCH_ON)) { + case TWO_SWITCHES: { + ReturnValue_t firstSwitchState = power->getSwitchState(firstSwitch); + ReturnValue_t secondSwitchState = power->getSwitchState(firstSwitch); + if ((firstSwitchState == PowerSwitchIF::SWITCH_ON) + && (secondSwitchState == PowerSwitchIF::SWITCH_ON)) { return PowerSwitchIF::SWITCH_ON; - } else if ((power->getSwitchState(firstSwitch) == PowerSwitchIF::SWITCH_OFF) - && (power->getSwitchState(secondSwitch) == PowerSwitchIF::SWITCH_OFF)) { + } + else if ((firstSwitchState == PowerSwitchIF::SWITCH_OFF) + && (secondSwitchState == PowerSwitchIF::SWITCH_OFF)) { return PowerSwitchIF::SWITCH_OFF; - } else { + } + else { return HasReturnvaluesIF::RETURN_FAILED; } + } default: return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/power/PowerSwitcher.h b/power/PowerSwitcher.h index 0f1c02deb..f4e2138d4 100644 --- a/power/PowerSwitcher.h +++ b/power/PowerSwitcher.h @@ -1,10 +1,13 @@ -#ifndef POWERSWITCHER_H_ -#define POWERSWITCHER_H_ +#ifndef FSFW_POWER_POWERSWITCHER_H_ +#define FSFW_POWER_POWERSWITCHER_H_ + #include "PowerSwitchIF.h" + +#include "../objectmanager/SystemObjectIF.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../timemanager/Countdown.h" -class PowerSwitcher : public HasReturnvaluesIF { +class PowerSwitcher: public HasReturnvaluesIF { public: enum State_t { WAIT_OFF, @@ -16,7 +19,8 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER; static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1); static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2); - PowerSwitcher( uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH, State_t setStartState = SWITCH_IS_OFF ); + PowerSwitcher( uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH, + State_t setStartState = SWITCH_IS_OFF ); ReturnValue_t initialize(object_id_t powerSwitchId); void turnOn(); void turnOff(); @@ -29,7 +33,8 @@ public: private: uint8_t firstSwitch; uint8_t secondSwitch; - PowerSwitchIF* power; + PowerSwitchIF* power = nullptr; + static const uint8_t NO_SWITCH = 0xFF; enum SwitchReturn_t { ONE_SWITCH = 1, @@ -42,4 +47,4 @@ private: -#endif /* POWERSWITCHER_H_ */ +#endif /* FSFW_POWER_POWERSWITCHER_H_ */ From 64cf0d0a7028313a5f5ad9429d9738964902762e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Dec 2020 18:32:32 +0100 Subject: [PATCH 24/37] thermal update --- thermal/AbstractTemperatureSensor.cpp | 12 +- thermal/AbstractTemperatureSensor.h | 10 + thermal/AcceptsThermalMessagesIF.h | 22 ++ thermal/Heater.cpp | 10 +- thermal/RedundantHeater.h | 13 +- thermal/TemperatureSensor.h | 138 +++++++++---- thermal/ThermalComponent.cpp | 59 +++--- thermal/ThermalComponent.h | 49 ++++- thermal/ThermalComponentCore.cpp | 285 ++++++++++++++++++++++++++ thermal/ThermalComponentCore.h | 117 +++++++++++ thermal/ThermalComponentIF.h | 12 +- thermal/ThermalModule.cpp | 84 ++++---- thermal/ThermalModule.h | 49 +++-- thermal/ThermalMonitorReporter.cpp | 75 +++++++ thermal/ThermalMonitorReporter.h | 28 +++ thermal/tcsDefinitions.h | 2 +- 16 files changed, 796 insertions(+), 169 deletions(-) create mode 100644 thermal/AcceptsThermalMessagesIF.h create mode 100644 thermal/ThermalComponentCore.cpp create mode 100644 thermal/ThermalComponentCore.h create mode 100644 thermal/ThermalMonitorReporter.cpp create mode 100644 thermal/ThermalMonitorReporter.h diff --git a/thermal/AbstractTemperatureSensor.cpp b/thermal/AbstractTemperatureSensor.cpp index 45ebe4a2a..40b305af9 100644 --- a/thermal/AbstractTemperatureSensor.cpp +++ b/thermal/AbstractTemperatureSensor.cpp @@ -44,19 +44,19 @@ ReturnValue_t AbstractTemperatureSensor::performHealthOp() { } void AbstractTemperatureSensor::handleCommandQueue() { - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + CommandMessage command; + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); if (result == HasReturnvaluesIF::RETURN_OK) { return; } - result = parameterHelper.handleParameterMessage(&message); + result = parameterHelper.handleParameterMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { return; } - message.setToUnknownCommand(); - commandQueue->reply(&message); + command.setToUnknownCommand(); + commandQueue->reply(&command); } } diff --git a/thermal/AbstractTemperatureSensor.h b/thermal/AbstractTemperatureSensor.h index 726ab9f4c..cc064ce47 100644 --- a/thermal/AbstractTemperatureSensor.h +++ b/thermal/AbstractTemperatureSensor.h @@ -10,6 +10,16 @@ #include "ThermalModuleIF.h" #include "tcsDefinitions.h" +/** + * @defgroup thermal Thermal Components + * @brief Contains all components related to thermal tasks (sensors, heaters) + */ + +/** + * @brief Base class for Temperature Sensor, implements all important interfaces. + * Please use the TemperatureSensor class to implement the actual sensors. + * @ingroup thermal + */ class AbstractTemperatureSensor: public HasHealthIF, public SystemObject, public ExecutableObjectIF, diff --git a/thermal/AcceptsThermalMessagesIF.h b/thermal/AcceptsThermalMessagesIF.h new file mode 100644 index 000000000..5fbd6bb38 --- /dev/null +++ b/thermal/AcceptsThermalMessagesIF.h @@ -0,0 +1,22 @@ +/** + * \file AcceptsThermalMessagesIF.h + * + * \date 16.02.2020 + */ + +#ifndef FRAMEWORK_THERMAL_ACCEPTSTHERMALMESSAGESIF_H_ +#define FRAMEWORK_THERMAL_ACCEPTSTHERMALMESSAGESIF_H_ +#include "../ipc/MessageQueueSenderIF.h" + +class AcceptsThermalMessagesIF { +public: + + /** + * @brief This is the empty virtual destructor as required for C++ interfaces. + */ + virtual ~AcceptsThermalMessagesIF() { } + + virtual MessageQueueId_t getReceptionQueue() const = 0; +}; + +#endif /* FRAMEWORK_THERMAL_ACCEPTSTHERMALMESSAGESIF_H_ */ diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index 1301e2e01..ce965d5ea 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -279,14 +279,14 @@ ReturnValue_t Heater::initialize() { } void Heater::handleQueue() { - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + CommandMessage command; + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); if (result == HasReturnvaluesIF::RETURN_OK) { return; } - parameterHelper.handleParameterMessage(&message); + parameterHelper.handleParameterMessage(&command); } } @@ -301,7 +301,7 @@ ReturnValue_t Heater::getParameter(uint8_t domainId, uint16_t parameterId, parameterWrapper->set(heaterOnCountdown.timeout); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } diff --git a/thermal/RedundantHeater.h b/thermal/RedundantHeater.h index ab745a698..765375420 100644 --- a/thermal/RedundantHeater.h +++ b/thermal/RedundantHeater.h @@ -1,7 +1,7 @@ #ifndef REDUNDANTHEATER_H_ #define REDUNDANTHEATER_H_ -#include "Heater.h" +#include "../thermal/Heater.h" class RedundantHeater { public: @@ -10,15 +10,14 @@ public: Parameters(uint32_t objectIdHeater0, uint32_t objectIdHeater1, uint8_t switch0Heater0, uint8_t switch1Heater0, uint8_t switch0Heater1, uint8_t switch1Heater1) : - objectIdHeater0(objectIdHeater0), objectIdHeater1( - objectIdHeater1), switch0Heater0(switch0Heater0), switch1Heater0( - switch1Heater0), switch0Heater1(switch0Heater1), switch1Heater1( - switch1Heater1) { + objectIdHeater0(objectIdHeater0), objectIdHeater1(objectIdHeater1), + switch0Heater0(switch0Heater0),switch1Heater0(switch1Heater0), + switch0Heater1(switch0Heater1), switch1Heater1(switch1Heater1) { } Parameters() : - objectIdHeater0(0), objectIdHeater1(0), switch0Heater0(0), switch1Heater0( - 0), switch0Heater1(0), switch1Heater1(0) { + objectIdHeater0(0), objectIdHeater1(0), switch0Heater0(0), + switch1Heater0(0), switch0Heater1(0), switch1Heater1(0) { } uint32_t objectIdHeater0; diff --git a/thermal/TemperatureSensor.h b/thermal/TemperatureSensor.h index 356ca7220..f41b3761b 100644 --- a/thermal/TemperatureSensor.h +++ b/thermal/TemperatureSensor.h @@ -1,40 +1,101 @@ #ifndef TEMPERATURESENSOR_H_ #define TEMPERATURESENSOR_H_ -#include "../datapool/DataSet.h" -#include "AbstractTemperatureSensor.h" +#include "../thermal/AbstractTemperatureSensor.h" +#include "../datapoolglob/GlobalDataSet.h" +#include "../datapoolglob/GlobalPoolVariable.h" #include "../monitoring/LimitMonitor.h" -template +/** + * @brief This building block handles non-linear value conversion and + * range checks for analog temperature sensors. + * @details This class can be used to perform all necessary tasks for temperature sensors. + * A sensor can be instantiated by calling the constructor. + * The temperature is calculated from an input value with + * the calculateOutputTemperature() function. Range checking and + * limit monitoring is performed automatically. + * The inputType specifies the type of the raw input while the + * limitType specifies the type of the upper and lower limit to check against. + * @ingroup thermal + */ + +template class TemperatureSensor: public AbstractTemperatureSensor { public: + /** + * This structure contains parameters required for range checking + * and the conversion from the input value to the output temperature. + * a, b and c can be any parameters required to calculate the output + * temperature from the input value, depending on the formula used. + * + * The parameters a,b and c are used in the calculateOutputTemperature() call. + * + * The lower and upper limits can be specified in any type, for example float for C values + * or any other type for raw values. + */ struct Parameters { float a; float b; float c; - T lowerLimit; - T upperLimit; - float gradient; + limitType lowerLimit; + limitType upperLimit; + float maxGradient; }; + + /** + * Forward declaration for explicit instantiation of used parameters. + */ struct UsedParameters { UsedParameters(Parameters parameters) : - a(parameters.a), b(parameters.b), c(parameters.c), gradient( - parameters.gradient) { - } + a(parameters.a), b(parameters.b), c(parameters.c), + gradient(parameters.maxGradient) {} float a; float b; float c; float gradient; }; - static const uint16_t ADDRESS_A = 0; - static const uint16_t ADDRESS_B = 1; - static const uint16_t ADDRESS_C = 2; - static const uint16_t ADDRESS_GRADIENT = 3; + /** + * Instantiate Temperature Sensor Object. + * @param setObjectid objectId of the sensor object + * @param inputValue Input value which is converted to a temperature + * @param poolVariable Pool Variable to store the temperature value + * @param vectorIndex Vector Index for the sensor monitor + * @param parameters Calculation parameters, temperature limits, gradient limit + * @param datapoolId Datapool ID of the output temperature + * @param outputSet Output dataset for the output temperature to fetch it with read() + * @param thermalModule respective thermal module, if it has one + */ + TemperatureSensor(object_id_t setObjectid, + inputType *inputValue, PoolVariableIF *poolVariable, + uint8_t vectorIndex, uint32_t datapoolId, Parameters parameters = {0, 0, 0, 0, 0, 0}, + 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, + GlobalDataPool::poolIdAndPositionToPid(poolVariable->getDataPoolId(), vectorIndex), + DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit, + TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), + oldTemperature(20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) { + } + + +protected: + /** + * This formula is used to calculate the temperature from an input value + * with an arbitrary type. + * A default implementation is provided but can be replaced depending + * on the required calculation. + * @param inputTemperature + * @return + */ + virtual float calculateOutputTemperature(inputType inputValue) { + return parameters.a * inputValue * inputValue + + parameters.b * inputValue + parameters.c; + } - static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1; //!< Changed due to issue with later temperature checking even tough the sensor monitor was confirming already (Was 10 before with comment = Correlates to a 10s confirmation time. Chosen rather large, should not be so bad for components and helps survive glitches.) - static const uint8_t DOMAIN_ID_SENSOR = 1; private: void setInvalid() { outputTemperature = INVALID_TEMPERATURE; @@ -47,22 +108,17 @@ protected: UsedParameters parameters; - T *inputTemperature; + inputType * inputValue; PoolVariableIF *poolVariable; - PoolVariable outputTemperature; + gp_float_t outputTemperature; - LimitMonitor sensorMonitor; + LimitMonitor sensorMonitor; float oldTemperature; timeval uptimeOfOldTemperature; - virtual float calculateOutputTemperature(T inputTemperature) { - return parameters.a * inputTemperature * inputTemperature - + parameters.b * inputTemperature + parameters.c; - } - void doChildOperation() { if (!poolVariable->isValid() || !healthHelper.healthTable->isHealthy(getObjectId())) { @@ -70,7 +126,7 @@ protected: return; } - outputTemperature = calculateOutputTemperature(*inputTemperature); + outputTemperature = calculateOutputTemperature(*inputValue); outputTemperature.setValid(PoolVariableIF::VALID); timeval uptime; @@ -78,7 +134,7 @@ protected: if (uptimeOfOldTemperature.tv_sec != INVALID_UPTIME) { //In theory, we could use an AbsValueMonitor to monitor the gradient. - //But this would require storing the gradient in DP and quite some overhead. + //But this would require storing the maxGradient in DP and quite some overhead. //The concept of delta limits is a bit strange anyway. float deltaTime; float deltaTemp; @@ -96,8 +152,8 @@ protected: } } - //Check is done against raw limits. SHOULDDO: Why? Using °C would be more easy to handle. - sensorMonitor.doCheck(*inputTemperature); + //Check is done against raw limits. SHOULDDO: Why? Using �C would be more easy to handle. + sensorMonitor.doCheck(outputTemperature.value); if (sensorMonitor.isOutOfLimits()) { uptimeOfOldTemperature.tv_sec = INVALID_UPTIME; @@ -110,23 +166,6 @@ protected: } public: - TemperatureSensor(object_id_t setObjectid, - T *inputTemperature, PoolVariableIF *poolVariable, - uint8_t vectorIndex, Parameters parameters, uint32_t datapoolId, - DataSet *outputSet, ThermalModuleIF *thermalModule) : - AbstractTemperatureSensor(setObjectid, thermalModule), parameters( - parameters), inputTemperature(inputTemperature), poolVariable( - poolVariable), outputTemperature(datapoolId, outputSet, - PoolVariableIF::VAR_WRITE), sensorMonitor(setObjectid, - DOMAIN_ID_SENSOR, - DataPool::poolIdAndPositionToPid( - poolVariable->getDataPoolId(), vectorIndex), - DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, - parameters.upperLimit, TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), oldTemperature( - 20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) { - - } - float getTemperature() { return outputTemperature; } @@ -135,6 +174,15 @@ public: return outputTemperature.isValid(); } + static const uint16_t ADDRESS_A = 0; + static const uint16_t ADDRESS_B = 1; + static const uint16_t ADDRESS_C = 2; + static const uint16_t ADDRESS_GRADIENT = 3; + + static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1; //!< Changed due to issue with later temperature checking even tough the sensor monitor was confirming already (Was 10 before with comment = Correlates to a 10s confirmation time. Chosen rather large, should not be so bad for components and helps survive glitches.) + + static const uint8_t DOMAIN_ID_SENSOR = 1; + virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex) { @@ -160,7 +208,7 @@ public: parameterWrapper->set(parameters.gradient); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } diff --git a/thermal/ThermalComponent.cpp b/thermal/ThermalComponent.cpp index 5dcd0bc64..084201dd4 100644 --- a/thermal/ThermalComponent.cpp +++ b/thermal/ThermalComponent.cpp @@ -1,48 +1,46 @@ #include "ThermalComponent.h" ThermalComponent::ThermalComponent(object_id_t reportingObjectId, - uint8_t domainId, uint32_t temperaturePoolId, - uint32_t targetStatePoolId, uint32_t currentStatePoolId, - uint32_t requestPoolId, DataSet* dataSet, + uint8_t domainId, gp_id_t temperaturePoolId, + gp_id_t targetStatePoolId, gp_id_t currentStatePoolId, + gp_id_t requestPoolId, LocalPoolDataSetBase* dataSet, AbstractTemperatureSensor* sensor, AbstractTemperatureSensor* firstRedundantSensor, AbstractTemperatureSensor* secondRedundantSensor, ThermalModuleIF* thermalModule, Parameters parameters, Priority priority) : - CoreComponent(reportingObjectId, domainId, temperaturePoolId, + ThermalComponentCore(reportingObjectId, domainId, temperaturePoolId, targetStatePoolId, currentStatePoolId, requestPoolId, dataSet, - sensor, firstRedundantSensor, secondRedundantSensor, - thermalModule, { parameters.lowerOpLimit, parameters.upperOpLimit, - parameters.heaterOn, parameters.hysteresis, - parameters.heaterSwitchoff }, priority, - ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL), nopParameters( - { parameters.lowerNopLimit, parameters.upperNopLimit }) { + parameters.heaterOn, parameters.hysteresis, + parameters.heaterSwitchoff }, + ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL), + nopParameters({ parameters.lowerNopLimit, parameters.upperNopLimit }) { } ThermalComponent::~ThermalComponent() { } ReturnValue_t ThermalComponent::setTargetState(int8_t newState) { - DataSet mySet; - PoolVariable writableTargetState(targetState.getDataPoolId(), - &mySet, PoolVariableIF::VAR_READ_WRITE); - mySet.read(); - if ((writableTargetState == STATE_REQUEST_OPERATIONAL) - && (newState != STATE_REQUEST_IGNORE)) { + targetState.setReadWriteMode(pool_rwm_t::VAR_READ_WRITE); + targetState.read(); + if ((targetState == STATE_REQUEST_OPERATIONAL) + and (newState != STATE_REQUEST_IGNORE)) { return HasReturnvaluesIF::RETURN_FAILED; } switch (newState) { case STATE_REQUEST_NON_OPERATIONAL: - writableTargetState = newState; - mySet.commit(PoolVariableIF::VALID); + targetState = newState; + targetState.setValid(true); + targetState.commit(PoolVariableIF::VALID); return HasReturnvaluesIF::RETURN_OK; default: - return CoreComponent::setTargetState(newState); + return ThermalComponentCore::setTargetState(newState); } + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, uint32_t size) { +ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, size_t size) { if (size != 4 * sizeof(parameters.lowerOpLimit)) { return MonitoringIF::INVALID_SIZE; } @@ -59,11 +57,11 @@ ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, uint32_t size) { } ThermalComponentIF::State ThermalComponent::getState(float temperature, - CoreComponent::Parameters parameters, int8_t targetState) { + ThermalComponentCore::Parameters parameters, int8_t targetState) { if (temperature < nopParameters.lowerNopLimit) { return OUT_OF_RANGE_LOW; } else { - State state = CoreComponent::getState(temperature, parameters, + State state = ThermalComponentCore::getState(temperature, parameters, targetState); if (state != NON_OPERATIONAL_HIGH && state != NON_OPERATIONAL_HIGH_IGNORED) { @@ -80,18 +78,19 @@ ThermalComponentIF::State ThermalComponent::getState(float temperature, } void ThermalComponent::checkLimits(ThermalComponentIF::State state) { - if (targetState == STATE_REQUEST_OPERATIONAL || targetState == STATE_REQUEST_IGNORE) { - CoreComponent::checkLimits(state); + if ((targetState == STATE_REQUEST_OPERATIONAL) or + (targetState == STATE_REQUEST_IGNORE)) { + ThermalComponentCore::checkLimits(state); return; } - //If component is not operational, it checks the NOP limits. + // If component is not operational, it checks the NOP limits. temperatureMonitor.translateState(state, temperature.value, nopParameters.lowerNopLimit, nopParameters.upperNopLimit, false); } ThermalComponentIF::HeaterRequest ThermalComponent::getHeaterRequest( int8_t targetState, float temperature, - CoreComponent::Parameters parameters) { + ThermalComponentCore::Parameters parameters) { if (targetState == STATE_REQUEST_IGNORE) { isHeating = false; return HEATER_DONT_CARE; @@ -144,16 +143,16 @@ ThermalComponentIF::State ThermalComponent::getIgnoredState(int8_t state) { case OUT_OF_RANGE_HIGH_IGNORED: return OUT_OF_RANGE_HIGH_IGNORED; default: - return CoreComponent::getIgnoredState(state); + return ThermalComponentCore::getIgnoredState(state); } } ReturnValue_t ThermalComponent::getParameter(uint8_t domainId, uint16_t parameterId, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex) { - ReturnValue_t result = CoreComponent::getParameter(domainId, parameterId, + ReturnValue_t result = ThermalComponentCore::getParameter(domainId, parameterId, parameterWrapper, newValues, startAtIndex); - if (result != INVALID_MATRIX_ID) { + if (result != INVALID_IDENTIFIER_ID) { return result; } switch (parameterId) { @@ -164,7 +163,7 @@ ReturnValue_t ThermalComponent::getParameter(uint8_t domainId, parameterWrapper->set(nopParameters.upperNopLimit); break; default: - return INVALID_MATRIX_ID; + return INVALID_IDENTIFIER_ID; } return HasReturnvaluesIF::RETURN_OK; } diff --git a/thermal/ThermalComponent.h b/thermal/ThermalComponent.h index 932438684..0785a9141 100644 --- a/thermal/ThermalComponent.h +++ b/thermal/ThermalComponent.h @@ -1,9 +1,14 @@ -#ifndef THERMALCOMPONENT_H_ -#define THERMALCOMPONENT_H_ +#ifndef FSFW_THERMAL_THERMALCOMPONENT_H_ +#define FSFW_THERMAL_THERMALCOMPONENT_H_ -#include "CoreComponent.h" +#include "ThermalComponentCore.h" -class ThermalComponent: public CoreComponent { +/** + * @brief + * @details + * Some more documentation. + */ +class ThermalComponent: public ThermalComponentCore { public: struct Parameters { float lowerNopLimit; @@ -14,13 +19,35 @@ public: float hysteresis; float heaterSwitchoff; }; + + /** + * Non-Operational Temperatures + */ struct NopParameters { float lowerNopLimit; float upperNopLimit; }; - ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId, - uint32_t targetStatePoolId, uint32_t currentStatePoolId, uint32_t requestPoolId, - DataSet *dataSet, AbstractTemperatureSensor *sensor, + + /** + * How to use. + * @param reportingObjectId + * @param domainId + * @param temperaturePoolId + * @param targetStatePoolId + * @param currentStatePoolId + * @param requestPoolId + * @param dataSet + * @param sensor + * @param firstRedundantSensor + * @param secondRedundantSensor + * @param thermalModule + * @param parameters + * @param priority + */ + ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, + gp_id_t temperaturePoolId, gp_id_t targetStatePoolId, + gp_id_t currentStatePoolId, gp_id_t requestPoolId, + LocalPoolDataSetBase *dataSet, AbstractTemperatureSensor *sensor, AbstractTemperatureSensor *firstRedundantSensor, AbstractTemperatureSensor *secondRedundantSensor, ThermalModuleIF *thermalModule, Parameters parameters, @@ -29,7 +56,7 @@ public: ReturnValue_t setTargetState(int8_t newState); - virtual ReturnValue_t setLimits( const uint8_t* data, uint32_t size); + virtual ReturnValue_t setLimits( const uint8_t* data, size_t size); virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ParameterWrapper *parameterWrapper, @@ -39,15 +66,15 @@ protected: NopParameters nopParameters; - State getState(float temperature, CoreComponent::Parameters parameters, + State getState(float temperature, ThermalComponentCore::Parameters parameters, int8_t targetState); virtual void checkLimits(State state); virtual HeaterRequest getHeaterRequest(int8_t targetState, float temperature, - CoreComponent::Parameters parameters); + ThermalComponentCore::Parameters parameters); State getIgnoredState(int8_t state); }; -#endif /* THERMALCOMPONENT_H_ */ +#endif /* FSFW_THERMAL_THERMALCOMPONENT_H_ */ diff --git a/thermal/ThermalComponentCore.cpp b/thermal/ThermalComponentCore.cpp new file mode 100644 index 000000000..7b594d0c9 --- /dev/null +++ b/thermal/ThermalComponentCore.cpp @@ -0,0 +1,285 @@ +#include "ThermalComponentCore.h" + +ThermalComponentCore::ThermalComponentCore(object_id_t reportingObjectId, + uint8_t domainId, gp_id_t temperaturePoolId, + gp_id_t targetStatePoolId, gp_id_t currentStatePoolId, + gp_id_t requestPoolId, LocalPoolDataSetBase* dataSet, + Parameters parameters, StateRequest initialTargetState) : + temperature(temperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), + targetState(targetStatePoolId, dataSet, PoolVariableIF::VAR_READ), + currentState(currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE), + heaterRequest(requestPoolId, dataSet, PoolVariableIF::VAR_WRITE), + parameters(parameters), domainId(domainId), + temperatureMonitor(reportingObjectId, domainId + 1,temperaturePoolId, + COMPONENT_TEMP_CONFIRMATION) { + //Set thermal state once, then leave to operator. + targetState.setReadWriteMode(PoolVariableIF::VAR_WRITE); + ReturnValue_t result = targetState.read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + targetState = initialTargetState; + targetState.setValid(true); + targetState.commit(); + } + targetState.setReadWriteMode(PoolVariableIF::VAR_READ); +} + +void ThermalComponentCore::addSensor(AbstractTemperatureSensor* sensor) { + this->sensor = sensor; +} + +void ThermalComponentCore::addFirstRedundantSensor( + AbstractTemperatureSensor *firstRedundantSensor) { + this->firstRedundantSensor = firstRedundantSensor; +} + +void ThermalComponentCore::addSecondRedundantSensor( + AbstractTemperatureSensor *secondRedundantSensor) { + this->secondRedundantSensor = secondRedundantSensor; +} + +void ThermalComponentCore::addThermalModule(ThermalModule *thermalModule, + Priority priority) { + this->thermalModule = thermalModule; + if(thermalModule != nullptr) { + thermalModule->registerComponent(this, priority); + } +} + +void ThermalComponentCore::setPriority(Priority priority) { + if(priority == SAFE) { + this->isSafeComponent = true; + } +} + +ThermalComponentCore::~ThermalComponentCore() { +} + +ThermalComponentIF::HeaterRequest ThermalComponentCore::performOperation( + uint8_t opCode) { + HeaterRequest request = HEATER_DONT_CARE; + //SHOULDDO: Better pass db_float_t* to getTemperature and set it invalid if invalid. + temperature = getTemperature(); + updateMinMaxTemp(); + if (temperature != INVALID_TEMPERATURE) { + temperature.setValid(PoolVariableIF::VALID); + State state = getState(temperature.value, getParameters(), + targetState.value); + currentState = state; + checkLimits(state); + request = getHeaterRequest(targetState.value, temperature.value, + getParameters()); + } else { + temperatureMonitor.setToInvalid(); + temperature.setValid(PoolVariableIF::INVALID); + currentState = UNKNOWN; + request = HEATER_DONT_CARE; + } + currentState.setValid(PoolVariableIF::VALID); + heaterRequest = request; + heaterRequest.setValid(PoolVariableIF::VALID); + return request; +} + +void ThermalComponentCore::markStateIgnored() { + currentState = getIgnoredState(currentState.value); +} + +object_id_t ThermalComponentCore::getObjectId() { + return temperatureMonitor.getReporterId(); + return 0; +} + +float ThermalComponentCore::getLowerOpLimit() { + return parameters.lowerOpLimit; +} + + + +ReturnValue_t ThermalComponentCore::setTargetState(int8_t newState) { + targetState.setReadWriteMode(pool_rwm_t::VAR_READ_WRITE); + targetState.read(); + if((targetState == STATE_REQUEST_OPERATIONAL) and + (newState != STATE_REQUEST_IGNORE)) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + switch (newState) { + case STATE_REQUEST_HEATING: + case STATE_REQUEST_IGNORE: + case STATE_REQUEST_OPERATIONAL: + targetState = newState; + break; + case STATE_REQUEST_NON_OPERATIONAL: + default: + return INVALID_TARGET_STATE; + } + targetState.setValid(true); + targetState.commit(); + return HasReturnvaluesIF::RETURN_OK; +} + +void ThermalComponentCore::setOutputInvalid() { + temperature = INVALID_TEMPERATURE; + temperature.setValid(PoolVariableIF::INVALID); + currentState.setValid(PoolVariableIF::INVALID); + heaterRequest = HEATER_DONT_CARE; + heaterRequest.setValid(PoolVariableIF::INVALID); + temperatureMonitor.setToUnchecked(); +} + +float ThermalComponentCore::getTemperature() { + if ((sensor != nullptr) && (sensor->isValid())) { + return sensor->getTemperature(); + } + + if ((firstRedundantSensor != nullptr) && + (firstRedundantSensor->isValid())) { + return firstRedundantSensor->getTemperature(); + } + + if ((secondRedundantSensor != nullptr) && + (secondRedundantSensor->isValid())) { + return secondRedundantSensor->getTemperature(); + } + + if (thermalModule != nullptr) { + float temperature = thermalModule->getTemperature(); + if (temperature != ThermalModuleIF::INVALID_TEMPERATURE) { + return temperature; + } else { + return INVALID_TEMPERATURE; + } + } else { + return INVALID_TEMPERATURE; + } +} + +ThermalComponentIF::State ThermalComponentCore::getState(float temperature, + Parameters parameters, int8_t targetState) { + ThermalComponentIF::State state; + + if (temperature < parameters.lowerOpLimit) { + state = NON_OPERATIONAL_LOW; + } else if (temperature < parameters.upperOpLimit) { + state = OPERATIONAL; + } else { + state = NON_OPERATIONAL_HIGH; + } + if (targetState == STATE_REQUEST_IGNORE) { + state = getIgnoredState(state); + } + + return state; +} + +void ThermalComponentCore::checkLimits(ThermalComponentIF::State state) { + //Checks operational limits only. + temperatureMonitor.translateState(state, temperature.value, + getParameters().lowerOpLimit, getParameters().upperOpLimit); + +} + +ThermalComponentIF::HeaterRequest ThermalComponentCore::getHeaterRequest( + int8_t targetState, float temperature, Parameters parameters) { + if (targetState == STATE_REQUEST_IGNORE) { + isHeating = false; + return HEATER_DONT_CARE; + } + + if (temperature > parameters.upperOpLimit - parameters.heaterSwitchoff) { + isHeating = false; + return HEATER_REQUEST_EMERGENCY_OFF; + } + + float opHeaterLimit = parameters.lowerOpLimit + parameters.heaterOn; + + if (isHeating) { + opHeaterLimit += parameters.hysteresis; + } + + if (temperature < opHeaterLimit) { + isHeating = true; + return HEATER_REQUEST_EMERGENCY_ON; + } + isHeating = false; + return HEATER_DONT_CARE; +} + +ThermalComponentIF::State ThermalComponentCore::getIgnoredState(int8_t state) { + switch (state) { + case NON_OPERATIONAL_LOW: + return NON_OPERATIONAL_LOW_IGNORED; + case OPERATIONAL: + return OPERATIONAL_IGNORED; + case NON_OPERATIONAL_HIGH: + return NON_OPERATIONAL_HIGH_IGNORED; + case NON_OPERATIONAL_LOW_IGNORED: + return NON_OPERATIONAL_LOW_IGNORED; + case OPERATIONAL_IGNORED: + return OPERATIONAL_IGNORED; + case NON_OPERATIONAL_HIGH_IGNORED: + return NON_OPERATIONAL_HIGH_IGNORED; + default: + case UNKNOWN: + return UNKNOWN; + } +} + +void ThermalComponentCore::updateMinMaxTemp() { + if (temperature == INVALID_TEMPERATURE) { + return; + } + if (temperature < minTemp) { + minTemp = static_cast(temperature); + } + if (temperature > maxTemp) { + maxTemp = static_cast(temperature); + } +} + +uint8_t ThermalComponentCore::getDomainId() const { + return domainId; +} + +ThermalComponentCore::Parameters ThermalComponentCore::getParameters() { + return parameters; +} + +ReturnValue_t ThermalComponentCore::getParameter(uint8_t domainId, + uint16_t parameterId, ParameterWrapper* parameterWrapper, + const ParameterWrapper* newValues, uint16_t startAtIndex) { + ReturnValue_t result = temperatureMonitor.getParameter(domainId, + parameterId, parameterWrapper, newValues, startAtIndex); + if (result != INVALID_DOMAIN_ID) { + return result; + } + if (domainId != this->domainId) { + return INVALID_DOMAIN_ID; + } + switch (parameterId) { + case 0: + parameterWrapper->set(parameters.heaterOn); + break; + case 1: + parameterWrapper->set(parameters.hysteresis); + break; + case 2: + parameterWrapper->set(parameters.heaterSwitchoff); + break; + case 3: + parameterWrapper->set(minTemp); + break; + case 4: + parameterWrapper->set(maxTemp); + break; + case 10: + parameterWrapper->set(parameters.lowerOpLimit); + break; + case 11: + parameterWrapper->set(parameters.upperOpLimit); + break; + default: + return INVALID_IDENTIFIER_ID; + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/thermal/ThermalComponentCore.h b/thermal/ThermalComponentCore.h new file mode 100644 index 000000000..da9424e68 --- /dev/null +++ b/thermal/ThermalComponentCore.h @@ -0,0 +1,117 @@ +#ifndef FSFW_THERMAL_THERMALCOMPONENTCORE_H_ +#define FSFW_THERMAL_THERMALCOMPONENTCORE_H_ + +#include "ThermalMonitorReporter.h" +#include "ThermalComponentIF.h" +#include "AbstractTemperatureSensor.h" +#include "ThermalModule.h" + +#include "../datapoollocal/LocalPoolVariable.h" + +/** + * @brief + * @details + */ +class ThermalComponentCore: public ThermalComponentIF { +public: + struct Parameters { + float lowerOpLimit; + float upperOpLimit; + float heaterOn; + float hysteresis; + float heaterSwitchoff; + }; + + static const uint16_t COMPONENT_TEMP_CONFIRMATION = 5; + + /** + * Some documentation + * @param reportingObjectId + * @param domainId + * @param temperaturePoolId + * @param targetStatePoolId + * @param currentStatePoolId + * @param requestPoolId + * @param dataSet + * @param parameters + * @param initialTargetState + */ + ThermalComponentCore(object_id_t reportingObjectId, uint8_t domainId, + gp_id_t temperaturePoolId, gp_id_t targetStatePoolId, + gp_id_t currentStatePoolId, gp_id_t requestPoolId, + LocalPoolDataSetBase* dataSet, Parameters parameters, + StateRequest initialTargetState = + ThermalComponentIF::STATE_REQUEST_OPERATIONAL); + + void addSensor(AbstractTemperatureSensor* firstRedundantSensor); + void addFirstRedundantSensor( + AbstractTemperatureSensor* firstRedundantSensor); + void addSecondRedundantSensor( + AbstractTemperatureSensor* secondRedundantSensor); + void addThermalModule(ThermalModule* thermalModule, Priority priority); + + void setPriority(Priority priority); + + virtual ~ThermalComponentCore(); + + virtual HeaterRequest performOperation(uint8_t opCode); + + void markStateIgnored(); + + object_id_t getObjectId(); + + uint8_t getDomainId() const; + + virtual float getLowerOpLimit(); + + ReturnValue_t setTargetState(int8_t newState); + + virtual void setOutputInvalid(); + + virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, + ParameterWrapper *parameterWrapper, + const ParameterWrapper *newValues, uint16_t startAtIndex); + +protected: + + AbstractTemperatureSensor *sensor = nullptr; + AbstractTemperatureSensor *firstRedundantSensor = nullptr; + AbstractTemperatureSensor *secondRedundantSensor = nullptr; + ThermalModuleIF *thermalModule = nullptr; + + lp_var_t temperature; + lp_var_t targetState; + lp_var_t currentState; + lp_var_t heaterRequest; + + bool isHeating = false; + + bool isSafeComponent = false; + + float minTemp = 999; + + float maxTemp = AbstractTemperatureSensor::ZERO_KELVIN_C; + + Parameters parameters; + + const uint8_t domainId; + + ThermalMonitorReporter temperatureMonitor; + + virtual float getTemperature(); + virtual State getState(float temperature, Parameters parameters, + int8_t targetState); + + virtual void checkLimits(State state); + + virtual HeaterRequest getHeaterRequest(int8_t targetState, + float temperature, Parameters parameters); + + virtual State getIgnoredState(int8_t state); + + void updateMinMaxTemp(); + + virtual Parameters getParameters(); +}; + +#endif /* FSFW_THERMAL_THERMALCOMPONENT_CORE_H_ */ diff --git a/thermal/ThermalComponentIF.h b/thermal/ThermalComponentIF.h index 522d4e443..16739e362 100644 --- a/thermal/ThermalComponentIF.h +++ b/thermal/ThermalComponentIF.h @@ -49,18 +49,18 @@ public: SAFE = 0, //!< SAFE IDLE, //!< IDLE PAYLOAD, //!< PAYLOAD - NUMBER_OF_PRIORITIES //!< MAX_PRIORITY + NUMBER_OF_PRIORITIES //!< MAX_PRIORITY }; /** * The elements are ordered by priority, lowest have highest priority */ enum HeaterRequest { - HEATER_REQUEST_EMERGENCY_OFF = 0, //!< REQUEST_EMERGENCY_OFF - HEATER_REQUEST_EMERGENCY_ON, //!< REQUEST_EMERGENCY_ON - HEATER_REQUEST_OFF, //!< REQUEST_OFF - HEATER_REQUEST_ON, //!< REQUEST_ON - HEATER_DONT_CARE //!< DONT_CARE + HEATER_REQUEST_EMERGENCY_OFF = 0, //!< REQUEST_EMERGENCY_OFF + HEATER_REQUEST_EMERGENCY_ON, //!< REQUEST_EMERGENCY_ON + HEATER_REQUEST_OFF, //!< REQUEST_OFF + HEATER_REQUEST_ON, //!< REQUEST_ON + HEATER_DONT_CARE //!< DONT_CARE }; virtual ~ThermalComponentIF() { diff --git a/thermal/ThermalModule.cpp b/thermal/ThermalModule.cpp index c573008e6..2bc1741f6 100644 --- a/thermal/ThermalModule.cpp +++ b/thermal/ThermalModule.cpp @@ -1,28 +1,31 @@ -#include "../monitoring/LimitViolationReporter.h" -#include "../monitoring/MonitoringMessageContent.h" #include "ThermalModule.h" - #include "AbstractTemperatureSensor.h" -ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, - uint32_t currentStatePoolId, uint32_t targetStatePoolId, - DataSet *dataSet, Parameters parameters, +#include "../monitoring/LimitViolationReporter.h" +#include "../monitoring/MonitoringMessageContent.h" + + +ThermalModule::ThermalModule(gp_id_t moduleTemperaturePoolId, + gp_id_t currentStatePoolId, gp_id_t targetStatePoolId, + LocalPoolDataSetBase *dataSet, Parameters parameters, RedundantHeater::Parameters heaterParameters) : - oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating( - false), parameters(parameters), moduleTemperature( - moduleTemperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), currentState( - currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE), targetState( - targetStatePoolId, dataSet, PoolVariableIF::VAR_READ) { + oldStrategy(ACTIVE_SINGLE), parameters(parameters), + moduleTemperature(moduleTemperaturePoolId, dataSet, + PoolVariableIF::VAR_WRITE), + currentState(currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE), + targetState(targetStatePoolId, dataSet, PoolVariableIF::VAR_READ) { heater = new RedundantHeater(heaterParameters); } -ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, DataSet* dataSet) : - oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating( - false), parameters( { 0, 0 }), moduleTemperature( - moduleTemperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), heater( - NULL), currentState(PoolVariableIF::INVALID, dataSet, - PoolVariableIF::VAR_WRITE), targetState(PoolVariableIF::INVALID, - dataSet, PoolVariableIF::VAR_READ) { +ThermalModule::ThermalModule(gp_id_t moduleTemperaturePoolId, + LocalPoolDataSetBase* dataSet) : + oldStrategy(ACTIVE_SINGLE), parameters( { 0, 0 }), + moduleTemperature(moduleTemperaturePoolId, dataSet, + PoolVariableIF::VAR_WRITE), + currentState(gp_id_t(), dataSet, + PoolVariableIF::VAR_WRITE), + targetState(gp_id_t(), dataSet, + PoolVariableIF::VAR_READ) { } ThermalModule::~ThermalModule() { @@ -30,7 +33,7 @@ ThermalModule::~ThermalModule() { } void ThermalModule::performOperation(uint8_t opCode) { - if (heater != NULL) { + if (heater != nullptr) { heater->performOperation(0); } } @@ -42,7 +45,7 @@ void ThermalModule::performMode(Strategy strategy) { ThermalComponentIF::HeaterRequest componentHeaterRequest = letComponentsPerformAndDeciceIfWeNeedToHeat(safeOnly); - if (heater == NULL) { + if (heater == nullptr) { informComponentsAboutHeaterState(false, NONE); return; } @@ -53,8 +56,8 @@ void ThermalModule::performMode(Strategy strategy) { //Components overwrite the module request. heating = ((componentHeaterRequest == ThermalComponentIF::HEATER_REQUEST_ON) - || (componentHeaterRequest - == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON)); + or (componentHeaterRequest + == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON)); } bool dual = (strategy == ACTIVE_DUAL); @@ -76,7 +79,7 @@ void ThermalModule::performMode(Strategy strategy) { } float ThermalModule::getTemperature() { - return moduleTemperature; + return moduleTemperature.value; } void ThermalModule::registerSensor(AbstractTemperatureSensor * sensor) { @@ -85,7 +88,8 @@ void ThermalModule::registerSensor(AbstractTemperatureSensor * sensor) { void ThermalModule::registerComponent(ThermalComponentIF* component, ThermalComponentIF::Priority priority) { - components.push_back(ComponentData( { component, priority, ThermalComponentIF::HEATER_DONT_CARE })); + components.push_back(ComponentData( { component, priority, + ThermalComponentIF::HEATER_DONT_CARE })); } void ThermalModule::calculateTemperature() { @@ -94,12 +98,13 @@ void ThermalModule::calculateTemperature() { std::list::iterator iter = sensors.begin(); for (; iter != sensors.end(); iter++) { if ((*iter)->isValid()) { - moduleTemperature = moduleTemperature + (*iter)->getTemperature(); + moduleTemperature = moduleTemperature.value + + (*iter)->getTemperature(); numberOfValidSensors++; } } if (numberOfValidSensors != 0) { - moduleTemperature = moduleTemperature / numberOfValidSensors; + moduleTemperature = moduleTemperature.value / numberOfValidSensors; moduleTemperature.setValid(PoolVariableIF::VALID); } else { moduleTemperature = INVALID_TEMPERATURE; @@ -117,9 +122,10 @@ ThermalComponentIF* ThermalModule::findComponent(object_id_t objectId) { return NULL; } -ThermalComponentIF::HeaterRequest ThermalModule::letComponentsPerformAndDeciceIfWeNeedToHeat( - bool safeOnly) { - ThermalComponentIF::HeaterRequest heaterRequests[ThermalComponentIF::NUMBER_OF_PRIORITIES]; +ThermalComponentIF::HeaterRequest +ThermalModule::letComponentsPerformAndDeciceIfWeNeedToHeat(bool safeOnly) { + ThermalComponentIF::HeaterRequest + heaterRequests[ThermalComponentIF::NUMBER_OF_PRIORITIES]; survivalTargetTemp = -999; targetTemp = -999; @@ -224,7 +230,7 @@ bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus( limit = survivalTargetTemp; } - if (moduleTemperature >= limit) { + if (moduleTemperature.value >= limit) { currentState = OPERATIONAL; } else { currentState = NON_OPERATIONAL; @@ -250,15 +256,15 @@ bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus( } void ThermalModule::setHeating(bool on) { - DataSet mySet; - PoolVariable writableTargetState(targetState.getDataPoolId(), - &mySet, PoolVariableIF::VAR_WRITE); - if (on) { - writableTargetState = STATE_REQUEST_HEATING; - } else { - writableTargetState = STATE_REQUEST_PASSIVE; - } - mySet.commit(PoolVariableIF::VALID); +// GlobDataSet mySet; +// gp_int8_t writableTargetState(targetState.getDataPoolId(), +// &mySet, PoolVariableIF::VAR_WRITE); +// if (on) { +// writableTargetState = STATE_REQUEST_HEATING; +// } else { +// writableTargetState = STATE_REQUEST_PASSIVE; +// } +// mySet.commit(PoolVariableIF::VALID); } void ThermalModule::updateTargetTemperatures(ThermalComponentIF* component, diff --git a/thermal/ThermalModule.h b/thermal/ThermalModule.h index 19ab9a549..d1e4fccbf 100644 --- a/thermal/ThermalModule.h +++ b/thermal/ThermalModule.h @@ -1,16 +1,25 @@ -#ifndef THERMALMODULE_H_ -#define THERMALMODULE_H_ +#ifndef FSFW_THERMAL_THERMALMODULE_H_ +#define FSFW_THERMAL_THERMALMODULE_H_ -#include "../datapool/DataSet.h" -#include "../datapool/PoolVariable.h" -#include "../devicehandlers/HealthDevice.h" -#include "../events/EventReportingProxyIF.h" #include "ThermalModuleIF.h" -#include #include "tcsDefinitions.h" #include "RedundantHeater.h" + +//#include "../datapoolglob/GlobalDataSet.h" +//#include "../datapoolglob/GlobalPoolVariable.h" +#include "../datapoollocal/LocalPoolDataSetBase.h" +#include "../datapoollocal/LocalPoolVariable.h" +#include "../devicehandlers/HealthDevice.h" +#include "../events/EventReportingProxyIF.h" + +#include + + class PowerSwitchIF; +/** + * @brief Allows creation of different thermal control domains within a system. + */ class ThermalModule: public ThermalModuleIF { friend class ThermalController; public: @@ -19,11 +28,12 @@ public: float hysteresis; }; - ThermalModule(uint32_t moduleTemperaturePoolId, uint32_t currentStatePoolId, - uint32_t targetStatePoolId, DataSet *dataSet, Parameters parameters, - RedundantHeater::Parameters heaterParameters); + ThermalModule(gp_id_t moduleTemperaturePoolId, gp_id_t currentStatePoolId, + gp_id_t targetStatePoolId, LocalPoolDataSetBase *dataSet, + Parameters parameters, RedundantHeater::Parameters heaterParameters); - ThermalModule(uint32_t moduleTemperaturePoolId, DataSet *dataSet); + ThermalModule(gp_id_t moduleTemperaturePoolId, + LocalPoolDataSetBase *dataSet); virtual ~ThermalModule(); @@ -59,20 +69,21 @@ protected: Strategy oldStrategy; - float survivalTargetTemp; + float survivalTargetTemp = 0.0; - float targetTemp; + float targetTemp = 0.0; - bool heating; + bool heating = false; Parameters parameters; - db_float_t moduleTemperature; + lp_var_t moduleTemperature; + //gp_float_t moduleTemperature; - RedundantHeater *heater; + RedundantHeater *heater = nullptr; - db_int8_t currentState; - db_int8_t targetState; + lp_var_t currentState; + lp_var_t targetState; std::list sensors; std::list components; @@ -89,4 +100,4 @@ protected: void updateTargetTemperatures(ThermalComponentIF *component, bool isSafe); }; -#endif /* THERMALMODULE_H_ */ +#endif /* FSFW_THERMAL_THERMALMODULE_H_ */ diff --git a/thermal/ThermalMonitorReporter.cpp b/thermal/ThermalMonitorReporter.cpp new file mode 100644 index 000000000..cefc61107 --- /dev/null +++ b/thermal/ThermalMonitorReporter.cpp @@ -0,0 +1,75 @@ +#include "ThermalMonitorReporter.h" +#include "ThermalComponentIF.h" + +#include "../monitoring/MonitoringIF.h" + +ThermalMonitorReporter::~ThermalMonitorReporter() { +} + +void ThermalMonitorReporter::sendTransitionEvent(float currentValue, + ReturnValue_t state) { + switch (state) { + case MonitoringIF::BELOW_LOW_LIMIT: + EventManagerIF::triggerEvent(reportingId, + ThermalComponentIF::COMPONENT_TEMP_OOL_LOW, state); + break; + case MonitoringIF::ABOVE_HIGH_LIMIT: + EventManagerIF::triggerEvent(reportingId, + ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH, state); + break; + case ThermalComponentIF::BELOW_OPERATIONAL_LIMIT: + EventManagerIF::triggerEvent(reportingId, + ThermalComponentIF::COMPONENT_TEMP_LOW, state); + break; + case ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT: + EventManagerIF::triggerEvent(reportingId, + ThermalComponentIF::COMPONENT_TEMP_HIGH, state); + break; + default: + break; + } +} + +bool ThermalMonitorReporter::isAboveHighLimit() { + if (oldState == ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT) { + return true; + } else { + return false; + } +} + +ReturnValue_t ThermalMonitorReporter::translateState( + ThermalComponentIF::State state, float sample, float lowerLimit, + float upperLimit, bool componentIsOperational) { + if (ThermalComponentIF::isIgnoredState(state)) { + setToUnchecked(); + return MonitoringIF::UNCHECKED; + } + switch (state) { + case ThermalComponentIF::OUT_OF_RANGE_LOW: + return monitorStateIs(MonitoringIF::BELOW_LOW_LIMIT, sample, + lowerLimit); + case ThermalComponentIF::NON_OPERATIONAL_LOW: + if (componentIsOperational) { + return monitorStateIs(ThermalComponentIF::BELOW_OPERATIONAL_LIMIT, + sample, lowerLimit); + } else { + return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); + } + case ThermalComponentIF::OPERATIONAL: + return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); + case ThermalComponentIF::NON_OPERATIONAL_HIGH: + if (componentIsOperational) { + return monitorStateIs(ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT, + sample, upperLimit); + } else { + return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); + } + case ThermalComponentIF::OUT_OF_RANGE_HIGH: + return monitorStateIs(MonitoringIF::ABOVE_HIGH_LIMIT, sample, + upperLimit); + default: + //Never reached, all states covered. + return HasReturnvaluesIF::RETURN_FAILED; + } +} diff --git a/thermal/ThermalMonitorReporter.h b/thermal/ThermalMonitorReporter.h new file mode 100644 index 000000000..4fb68a991 --- /dev/null +++ b/thermal/ThermalMonitorReporter.h @@ -0,0 +1,28 @@ +#ifndef FSFW_THERMAL_THERMALMONITORREPORTER_H_ +#define FSFW_THERMAL_THERMALMONITORREPORTER_H_ + +#include "ThermalComponentIF.h" +#include "../monitoring/MonitorReporter.h" + + +/** + * @brief Monitor Reporter implementation for thermal components. + */ +class ThermalMonitorReporter: public MonitorReporter { +public: + template + ThermalMonitorReporter(Args ... args) : + MonitorReporter(std::forward(args)...) { + } + ~ThermalMonitorReporter(); + ReturnValue_t translateState(ThermalComponentIF::State state, float sample, + float lowerLimit, float upperLimit, + bool componentIsOperational = true); + + bool isAboveHighLimit(); +protected: + virtual void sendTransitionEvent(float currentValue, ReturnValue_t state); + +}; + +#endif /* FSFW_THERMAL_THERMALMONITORREPORTERREPORTER_H_ */ diff --git a/thermal/tcsDefinitions.h b/thermal/tcsDefinitions.h index ad258ced7..37e5b849d 100644 --- a/thermal/tcsDefinitions.h +++ b/thermal/tcsDefinitions.h @@ -2,7 +2,7 @@ #define TCSDEFINITIONS_H_ -static const uint32_t INVALID_TEMPERATURE = 999; +static const float INVALID_TEMPERATURE = 999; #endif /* TCSDEFINITIONS_H_ */ From 4a4634928620b68fc0aa253cf9ccd1e977a81318 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Dec 2020 15:14:39 +0100 Subject: [PATCH 25/37] minor imrpovements --- datalinklayer/MapPacketExtraction.cpp | 4 ++-- datalinklayer/MapPacketExtraction.h | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/datalinklayer/MapPacketExtraction.cpp b/datalinklayer/MapPacketExtraction.cpp index 45f7d3f8b..845ed7c17 100644 --- a/datalinklayer/MapPacketExtraction.cpp +++ b/datalinklayer/MapPacketExtraction.cpp @@ -9,9 +9,9 @@ MapPacketExtraction::MapPacketExtraction(uint8_t setMapId, object_id_t setPacketDestination) : - lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), + lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), bufferPosition(packetBuffer), packetDestination(setPacketDestination), - packetStore(NULL), tcQueueId(MessageQueueIF::NO_QUEUE) { + tcQueueId(MessageQueueIF::NO_QUEUE) { std::memset(packetBuffer, 0, sizeof(packetBuffer)); } diff --git a/datalinklayer/MapPacketExtraction.h b/datalinklayer/MapPacketExtraction.h index eff9b7c3c..ddb867fb2 100644 --- a/datalinklayer/MapPacketExtraction.h +++ b/datalinklayer/MapPacketExtraction.h @@ -1,5 +1,5 @@ -#ifndef MAPPACKETEXTRACTION_H_ -#define MAPPACKETEXTRACTION_H_ +#ifndef FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_ +#define FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_ #include "MapPacketExtractionIF.h" #include "../objectmanager/ObjectManagerIF.h" @@ -20,11 +20,12 @@ private: static const uint32_t MAX_PACKET_SIZE = 4096; uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame. uint8_t mapId; //!< MAP ID of this MAP Channel. - uint32_t packetLength; //!< Complete length of the current Space Packet. + uint32_t packetLength = 0; //!< Complete length of the current Space Packet. uint8_t* bufferPosition; //!< Position to write to in the internal Packet buffer. uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer. object_id_t packetDestination; - StorageManagerIF* packetStore; //!< Pointer to the store where full TC packets are stored. + //!< Pointer to the store where full TC packets are stored. + StorageManagerIF* packetStore = nullptr; MessageQueueId_t tcQueueId; //!< QueueId to send found packets to the distributor. /** * Debug method to print the packet Buffer's content. @@ -69,4 +70,4 @@ public: uint8_t getMapId() const; }; -#endif /* MAPPACKETEXTRACTION_H_ */ +#endif /* FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_ */ From ac5446b2b145eee8a3a5183913989b66d20fcc63 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Dec 2020 15:43:58 +0100 Subject: [PATCH 26/37] removed hk switcher helper member --- controller/ControllerBase.cpp | 7 +------ controller/ControllerBase.h | 3 --- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/controller/ControllerBase.cpp b/controller/ControllerBase.cpp index 45e678eb4..2a4024680 100644 --- a/controller/ControllerBase.cpp +++ b/controller/ControllerBase.cpp @@ -8,7 +8,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth) : SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode(SUBMODE_NONE), modeHelper(this), - healthHelper(this, setObjectId), hkSwitcher(this) { + healthHelper(this, setObjectId) { commandQueue = QueueFactory::instance()->createMessageQueue( commandQueueDepth); } @@ -44,10 +44,6 @@ ReturnValue_t ControllerBase::initialize() { return result; } - result = hkSwitcher.initialize(); - if (result != RETURN_OK) { - return result; - } return RETURN_OK; } @@ -107,7 +103,6 @@ void ControllerBase::announceMode(bool recursive) { ReturnValue_t ControllerBase::performOperation(uint8_t opCode) { handleQueue(); - hkSwitcher.performOperation(); performControlOperation(); return RETURN_OK; } diff --git a/controller/ControllerBase.h b/controller/ControllerBase.h index 25d3ab1f3..6e83fe80b 100644 --- a/controller/ControllerBase.h +++ b/controller/ControllerBase.h @@ -72,9 +72,6 @@ protected: HealthHelper healthHelper; - // Is this still needed? - HkSwitchHelper hkSwitcher; - /** * Pointer to the task which executes this component, * is invalid before setTaskIF was called. From a612e19e94a3edcbd3a5997410e8c4b87800cfb3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Dec 2020 15:49:46 +0100 Subject: [PATCH 27/37] ndentation --- internalError/InternalErrorReporter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 12f36f336..818b00cfc 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -6,8 +6,7 @@ #include "../serviceinterface/ServiceInterfaceStream.h" InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, - uint32_t messageQueueDepth) : - SystemObject(setObjectId), + uint32_t messageQueueDepth): SystemObject(setObjectId), commandQueue(QueueFactory::instance()-> createMessageQueue(messageQueueDepth)), poolManager(this, commandQueue), From 7f40566031f40d8ebe214bf29a7958731d936cd0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Dec 2020 15:50:21 +0100 Subject: [PATCH 28/37] include removed --- internalError/InternalErrorReporter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 818b00cfc..bfb672891 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -1,4 +1,3 @@ -#include "../datapoolglob/GlobalDataSet.h" #include "InternalErrorReporter.h" #include "../ipc/QueueFactory.h" From 5e2e18ac078b3ea78ab1328adda5116d532b222c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Dec 2020 15:59:30 +0100 Subject: [PATCH 29/37] device handler uses local pools now --- devicehandlers/DeviceHandlerBase.cpp | 148 +++++++++++++---------- devicehandlers/DeviceHandlerBase.h | 169 ++++++++++++++++----------- 2 files changed, 193 insertions(+), 124 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index b5d43d77d..733106e57 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -3,8 +3,6 @@ #include "DeviceTmReportingWrapper.h" #include "../serviceinterface/ServiceInterfaceStream.h" -#include "../datapoolglob/GlobalDataSet.h" -#include "../datapoolglob/GlobalPoolVariable.h" #include "../objectmanager/ObjectManager.h" #include "../storagemanager/StorageManagerIF.h" #include "../thermal/ThermalComponentIF.h" @@ -13,9 +11,11 @@ #include "../ipc/MessageQueueMessage.h" #include "../ipc/QueueFactory.h" #include "../subsystem/SubsystemBase.h" +#include "../datapoollocal/LocalPoolVariable.h" #include + object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; @@ -56,9 +56,10 @@ void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) { } void DeviceHandlerBase::setThermalStateRequestPoolIds( - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) { - this->deviceThermalRequestPoolId = thermalStatePoolId; - this->deviceThermalRequestPoolId = thermalRequestPoolId; + lp_id_t thermalStatePoolId, lp_id_t heaterRequestPoolId, + uint32_t thermalSetId) { + thermalSet = new DeviceHandlerThermalSet(this, thermalSetId, + thermalStatePoolId, heaterRequestPoolId); } @@ -86,7 +87,6 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { decrementDeviceReplyMap(); fdirInstance->checkForFailures(); hkSwitcher.performOperation(); - hkManager.performHkOperation(); performOperationHook(); return RETURN_OK; } @@ -111,6 +111,9 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { break; case CommunicationAction::GET_READ: doGetRead(); + // This will be performed after datasets have been updated by the + // custom device implementation. + hkManager.performHkOperation(); break; default: break; @@ -208,16 +211,18 @@ ReturnValue_t DeviceHandlerBase::initialize() { fillCommandAndReplyMap(); - //Set temperature target state to NON_OP. - GlobDataSet mySet; - gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, - PoolVariableIF::VAR_WRITE); - mySet.read(); - thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; - mySet.commit(PoolVariableIF::VALID); + if(thermalSet != nullptr) { + //Set temperature target state to NON_OP. + result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + thermalSet->heaterRequest.value = + ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; + thermalSet->commit(PoolVariableIF::VALID); + } + + } return RETURN_OK; - } void DeviceHandlerBase::decrementDeviceReplyMap() { @@ -505,15 +510,17 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) { } Clock::getUptime(&timeoutStart); - if (mode == MODE_OFF) { - GlobDataSet mySet; - gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, - PoolVariableIF::VAR_READ_WRITE); - mySet.read(); - if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { - thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL; + if (mode == MODE_OFF and thermalSet != nullptr) { + ReturnValue_t result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + if (thermalSet->heaterRequest.value != + ThermalComponentIF::STATE_REQUEST_IGNORE) { + thermalSet->heaterRequest.value = ThermalComponentIF:: + STATE_REQUEST_NON_OPERATIONAL; + } + thermalSet->heaterRequest.commit(PoolVariableIF::VALID); } - mySet.commit(PoolVariableIF::VALID); + } changeHK(mode, submode, true); } @@ -976,17 +983,15 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, } if ((commandedMode == MODE_ON) && (mode == MODE_OFF) - && (deviceThermalStatePoolId != PoolVariableIF::NO_PARAMETER)) { - GlobDataSet mySet; - gp_uint8_t thermalState(deviceThermalStatePoolId, &mySet, - PoolVariableIF::VAR_READ); - gp_uint8_t thermalRequest(deviceThermalRequestPoolId, &mySet, - PoolVariableIF::VAR_READ); - mySet.read(); - if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { - if (!ThermalComponentIF::isOperational(thermalState)) { + and (thermalSet != nullptr)) { + ReturnValue_t result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + if((thermalSet->heaterRequest.value != + ThermalComponentIF::STATE_REQUEST_IGNORE) and (not + ThermalComponentIF::isOperational( + thermalSet->thermalState.value))) { triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE, - thermalState); + thermalSet->thermalState.value); return NON_OP_TEMPERATURE; } } @@ -999,32 +1004,15 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commandedSubmode) { switch (commandedMode) { case MODE_ON: - if (mode == MODE_OFF) { - transitionSourceMode = _MODE_POWER_DOWN; - transitionSourceSubMode = SUBMODE_NONE; - setMode(_MODE_POWER_ON, commandedSubmode); - //already set the delay for the child transition so we don't need to call it twice - childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, - MODE_ON); - triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); - GlobDataSet mySet; - gp_int8_t thermalRequest(deviceThermalRequestPoolId, - &mySet, PoolVariableIF::VAR_READ_WRITE); - mySet.read(); - if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) { - thermalRequest = ThermalComponentIF::STATE_REQUEST_OPERATIONAL; - mySet.commit(PoolVariableIF::VALID); - } - } else { - setTransition(MODE_ON, commandedSubmode); - } + handleTransitionToOnMode(commandedMode, commandedSubmode); break; case MODE_OFF: if (mode == MODE_OFF) { triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); setMode(_MODE_POWER_DOWN, commandedSubmode); } else { - //already set the delay for the child transition so we don't need to call it twice + // already set the delay for the child transition + // so we don't need to call it twice childTransitionDelay = getTransitionDelayMs(mode, _MODE_POWER_DOWN); transitionSourceMode = _MODE_POWER_DOWN; transitionSourceSubMode = commandedSubmode; @@ -1050,6 +1038,33 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, } } +void DeviceHandlerBase::handleTransitionToOnMode(Mode_t commandedMode, + Submode_t commandedSubmode) { + if (mode == MODE_OFF) { + transitionSourceMode = _MODE_POWER_DOWN; + transitionSourceSubMode = SUBMODE_NONE; + setMode(_MODE_POWER_ON, commandedSubmode); + // already set the delay for the child transition so we don't + // need to call it twice + childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, + MODE_ON); + triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode); + if(thermalSet != nullptr) { + ReturnValue_t result = thermalSet->read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + if(thermalSet->heaterRequest != + ThermalComponentIF::STATE_REQUEST_IGNORE) { + thermalSet->heaterRequest = + ThermalComponentIF::STATE_REQUEST_OPERATIONAL; + thermalSet->commit(); + } + } + } + } else { + setTransition(MODE_ON, commandedSubmode); + } +} + void DeviceHandlerBase::getMode(Mode_t* mode, Submode_t* submode) { *mode = this->mode; *submode = this->submode; @@ -1222,10 +1237,12 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, } } //Try to cast to GlobDataSet and commit data. - if (!neverInDataPool) { - GlobDataSet* dataSet = dynamic_cast(data); - if (dataSet != NULL) { - dataSet->commit(PoolVariableIF::VALID); + if (not neverInDataPool) { + LocalPoolDataSetBase* dataSet = + dynamic_cast(data); + if (dataSet != nullptr) { + dataSet->setValidity(true, true); + dataSet->commit(); } } } @@ -1262,7 +1279,8 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (result == BUSY) { //so we can track misconfigurations sif::debug << std::hex << getObjectId() - << ": DHB::buildInternalCommand: Busy" << std::dec << std::endl; + << ": DHB::buildInternalCommand: Busy" << std::dec + << std::endl; result = NOTHING_TO_SEND; //no need to report this } } @@ -1371,8 +1389,8 @@ bool DeviceHandlerBase::commandIsExecuting(DeviceCommandId_t commandId) { void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { } -void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ - executingTask = task_; +void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task){ + executingTask = task; } // Default implementations empty. @@ -1385,6 +1403,12 @@ void DeviceHandlerBase::performOperationHook() { ReturnValue_t DeviceHandlerBase::initializeLocalDataPool( LocalDataPool &localDataPoolMap, LocalDataPoolManager& poolManager) { + if(thermalSet != nullptr) { + localDataPoolMap.emplace(thermalSet->thermalStatePoolId, + new PoolEntry); + localDataPoolMap.emplace(thermalSet->heaterRequestPoolId, + new PoolEntry); + } return RETURN_OK; } @@ -1429,3 +1453,9 @@ dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const { return pstIntervalMs; } +DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const { + if(cookieInfo.pendingCommand != deviceCommandMap.end()) { + return cookieInfo.pendingCommand->first; + } + return DeviceHandlerIF::NO_COMMAND; +} diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 627a64238..2bfa62a66 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -4,6 +4,7 @@ #include "DeviceHandlerIF.h" #include "DeviceCommunicationIF.h" #include "DeviceHandlerFailureIsolation.h" +#include "DeviceHandlerThermalSet.h" #include "../objectmanager/SystemObject.h" #include "../tasks/ExecutableObjectIF.h" @@ -103,8 +104,21 @@ public: size_t cmdQueueSize = 20); void setHkDestination(object_id_t hkDestination); - void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId); + + /** + * If the device handler is controlled by the FSFW thermal building blocks, + * this function should be called to initialize all required components. + * The device handler will then take care of creating local pool entries + * for the device thermal state and device heating request. + * Custom local pool IDs can be assigned as well. + * @param thermalStatePoolId + * @param thermalRequestPoolId + */ + void setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId = + DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID, + lp_id_t thermalRequestPoolId = + DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID, + uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID); /** * @brief Helper function to ease device handler development. * This will instruct the transition to MODE_ON immediately @@ -694,19 +708,7 @@ protected: //! and to send replies. MessageQueueIF* commandQueue = nullptr; - /** - * this is the datapool variable with the thermal state of the device - * - * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking - */ - uint32_t deviceThermalStatePoolId = PoolVariableIF::NO_PARAMETER; - - /** - * this is the datapool variable with the thermal request of the device - * - * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking - */ - uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER; + DeviceHandlerThermalSet* thermalSet = nullptr; /** * Optional Error code. Can be set in doStartUp(), doShutDown() and @@ -732,15 +734,27 @@ protected: //! before setTaskIF was called. PeriodicTaskIF* executingTask = nullptr; - static object_id_t powerSwitcherId; //!< Object which switches power on and off. + //!< Object which switches power on and off. + static object_id_t powerSwitcherId; - static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default. + //!< Object which receives RAW data by default. + static object_id_t rawDataReceiverId; + + //!< Object which may be the root cause of an identified fault. + static object_id_t defaultFdirParentId; + + /** + * Helper function to get pending command. This is useful for devices + * like SPI sensors to identify the last sent command. + * @return + */ + DeviceCommandId_t getPendingCommand() const; - static object_id_t defaultFdirParentId; //!< Object which may be the root cause of an identified fault. /** * Helper function to report a missed reply * - * Can be overwritten by children to act on missed replies or to fake reporting Id. + * Can be overwritten by children to act on missed replies or to fake + * reporting Id. * * @param id of the missed reply */ @@ -847,15 +861,18 @@ protected: /** * Build the device command to send for raw mode. * - * This is only called in @c MODE_RAW. It is for the rare case that in raw mode packets - * are to be sent by the handler itself. It is NOT needed for the raw commanding service. - * Its only current use is in the STR handler which gets its raw packets from a different - * source. - * Also it can be used for transitional commands, to get the device ready for @c MODE_RAW + * This is only called in @c MODE_RAW. It is for the rare case that in + * raw mode packets are to be sent by the handler itself. It is NOT needed + * for the raw commanding service. Its only current use is in the STR + * handler which gets its raw packets from a different source. + * Also it can be used for transitional commands, to get the device ready + * for @c MODE_RAW * - * As it is almost never used, there is a default implementation returning @c NOTHING_TO_SEND. + * As it is almost never used, there is a default implementation + * returning @c NOTHING_TO_SEND. * - * #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. + * #rawPacket and #rawPacketLen must be set by this method to the packet + * to be sent. * * @param[out] id the device command id built * @return @@ -868,7 +885,9 @@ protected: * 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. + * @return + * The current delay count. If the command does not exist (should never + * happen) it returns 0. */ uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand); @@ -878,20 +897,22 @@ protected: * It gets space in the #IPCStore, copies data there, then sends a raw reply * containing the store address. * - * This method is virtual, as the STR has a different channel to send raw replies - * and overwrites it accordingly. + * This method is virtual, as the STR has a different channel to send + * raw replies and overwrites it accordingly. * * @param data data to send * @param len length of @c data * @param sendTo the messageQueueId of the one to send to - * @param isCommand marks the raw data as a command, the message then will be of type raw_command + * @param isCommand marks the raw data as a command, the message then + * will be of type raw_command */ virtual void replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand = false); /** - * Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping is active and if so, - * does not send the Data as the wiretapping will have sent it already + * Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping + * is active and if so, does not send the data as the wiretapping will have + * sent it already */ void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len); @@ -903,17 +924,19 @@ protected: /** * Enable the reply checking for a command * - * Is only called, if the command was sent (ie the getWriteReply was successful). - * Must ensure that all replies are activated and correctly linked to the command that initiated it. - * The default implementation looks for a reply with the same id as the command id in the replyMap or - * uses the alternativeReplyId if flagged so. - * When found, copies maxDelayCycles to delayCycles in the reply information and sets the command to - * expect one reply. + * Is only called, if the command was sent (i.e. the getWriteReply was + * successful). Must ensure that all replies are activated and correctly + * linked to the command that initiated it. + * The default implementation looks for a reply with the same id as the + * command id in the replyMap or uses the alternativeReplyId if flagged so. + * When found, copies maxDelayCycles to delayCycles in the reply information + * and sets the command to expect one reply. * * Can be overwritten by the child, if a command activates multiple replies * or replyId differs from commandId. * Notes for child implementations: - * - If the command was not found in the reply map, NO_REPLY_EXPECTED MUST be returned. + * - If the command was not found in the reply map, + * NO_REPLY_EXPECTED MUST be returned. * - A failure code may be returned if something went fundamentally wrong. * * @param deviceCommand @@ -929,17 +952,20 @@ protected: * get the state of the PCDU switches in the datapool * * @return - * - @c PowerSwitchIF::SWITCH_ON if all switches specified by #switches are on - * - @c PowerSwitchIF::SWITCH_OFF one of the switches specified by #switches are off - * - @c PowerSwitchIF::RETURN_FAILED if an error occured + * - @c PowerSwitchIF::SWITCH_ON if all switches specified + * by #switches are on + * - @c PowerSwitchIF::SWITCH_OFF one of the switches specified by + * #switches are off + * - @c PowerSwitchIF::RETURN_FAILED if an error occured */ 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. + * @brief Set all datapool variables that are update periodically in + * normal mode invalid + * @details TODO: Use local pools + * Child classes should provide an implementation which sets all those + * variables invalid which are set periodically during any normal mode. */ virtual void setNormalDatapoolEntriesInvalid() = 0; @@ -949,11 +975,12 @@ protected: virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); /** - * Children can overwrite this function to suppress checking of the command Queue + * Children can overwrite this function to suppress checking of the + * command Queue * - * This can be used when the child does not want to receive a command in a certain - * situation. Care must be taken that checking is not permanentely disabled as this - * would render the handler unusable. + * This can be used when the child does not want to receive a command in + * a certain situation. Care must be taken that checking is not + * permanentely disabled as this would render the handler unusable. * * @return whether checking the queue should NOT be done */ @@ -992,17 +1019,20 @@ protected: virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const; /** - * Checks state of switches in conjunction with mode and triggers an event if they don't fit. + * Checks state of switches in conjunction with mode and triggers an event + * if they don't fit. */ virtual void checkSwitchState(); /** - * Reserved for the rare case where a device needs to perform additional operation cyclically in OFF mode. + * Reserved for the rare case where a device needs to perform additional + * operation cyclically in OFF mode. */ virtual void doOffActivity(); /** - * Reserved for the rare case where a device needs to perform additional operation cyclically in ON mode. + * Reserved for the rare case where a device needs to perform additional + * operation cyclically in ON mode. */ virtual void doOnActivity(); @@ -1043,9 +1073,10 @@ private: /** * Information about a cookie. * - * This is stored in a map for each cookie, to not only track the state, but also information - * about the sent command. Tracking this information is needed as - * the state of a commandId (waiting for reply) is done when a RMAP write reply is received. + * This is stored in a map for each cookie, to not only track the state, + * but also information about the sent command. Tracking this information + * is needed as the state of a commandId (waiting for reply) is done when a + * write reply is received. */ struct CookieInfo { CookieState_t state; @@ -1102,10 +1133,14 @@ private: /** * Handle the device handler mode. * - * - checks whether commands are valid for the current mode, rejects them accordingly - * - 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() + * - checks whether commands are valid for the current mode, rejects + * them accordingly + * - 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 (e.g. setting a timeout) are + * handled in setMode() */ void doStateMachine(void); @@ -1115,16 +1150,17 @@ private: /** * 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). + * 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). */ void decrementDeviceReplyMap(void); /** * Convenience function to handle a reply. * - * Called after scanForReply() has found a packet. Checks if the found id is in the #deviceCommandMap, if so, - * calls interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) for further action. + * Called after scanForReply() has found a packet. Checks if the found ID + * is in the #deviceCommandMap, if so, calls + * #interpretDeviceReply for further action. * * It also resets the timeout counter for the command id. * @@ -1184,7 +1220,7 @@ private: * @param[out] len * @return * - @c RETURN_OK @c data is valid - * - @c RETURN_FAILED IPCStore is NULL + * - @c RETURN_FAILED IPCStore is nullptr * - the return value from the IPCStore if it was not @c RETURN_OK */ ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, @@ -1208,6 +1244,9 @@ private: void parseReply(const uint8_t* receivedData, size_t receivedDataLen); + + void handleTransitionToOnMode(Mode_t commandedMode, + Submode_t commandedSubmode); }; #endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ From 46596f9397d7cea1a82a16f093117e64e133c919 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 8 Dec 2020 16:01:48 +0100 Subject: [PATCH 30/37] tab changed --- devicehandlers/DeviceHandlerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 733106e57..f095834e2 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -113,7 +113,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { doGetRead(); // This will be performed after datasets have been updated by the // custom device implementation. - hkManager.performHkOperation(); + hkManager.performHkOperation(); break; default: break; From ff62ab8427f84442cb14759e81fb03972caa7bfc Mon Sep 17 00:00:00 2001 From: Spacefish Date: Thu, 10 Dec 2020 16:32:52 +0100 Subject: [PATCH 31/37] removed core component --- thermal/CoreComponent.cpp | 257 -------------------------------------- thermal/CoreComponent.h | 96 -------------- 2 files changed, 353 deletions(-) delete mode 100644 thermal/CoreComponent.cpp delete mode 100644 thermal/CoreComponent.h diff --git a/thermal/CoreComponent.cpp b/thermal/CoreComponent.cpp deleted file mode 100644 index 657e79cb0..000000000 --- a/thermal/CoreComponent.cpp +++ /dev/null @@ -1,257 +0,0 @@ -#include "CoreComponent.h" - -CoreComponent::CoreComponent(object_id_t reportingObjectId, uint8_t domainId, - uint32_t temperaturePoolId, uint32_t targetStatePoolId, - uint32_t currentStatePoolId, uint32_t requestPoolId, GlobDataSet* dataSet, - AbstractTemperatureSensor* sensor, - AbstractTemperatureSensor* firstRedundantSensor, - AbstractTemperatureSensor* secondRedundantSensor, - ThermalModuleIF* thermalModule, Parameters parameters, - Priority priority, StateRequest initialTargetState) : - sensor(sensor), firstRedundantSensor(firstRedundantSensor), secondRedundantSensor( - secondRedundantSensor), thermalModule(thermalModule), temperature( - temperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), targetState( - targetStatePoolId, dataSet, PoolVariableIF::VAR_READ), currentState( - currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE), heaterRequest( - requestPoolId, dataSet, PoolVariableIF::VAR_WRITE), isHeating( - false), isSafeComponent(priority == SAFE), minTemp(999), maxTemp( - AbstractTemperatureSensor::ZERO_KELVIN_C), parameters( - parameters), temperatureMonitor(reportingObjectId, - domainId + 1, - GlobalDataPool::poolIdAndPositionToPid(temperaturePoolId, 0), - COMPONENT_TEMP_CONFIRMATION), domainId(domainId) { - if (thermalModule != NULL) { - thermalModule->registerComponent(this, priority); - } - //Set thermal state once, then leave to operator. - GlobDataSet mySet; - gp_uint8_t writableTargetState(targetStatePoolId, &mySet, - PoolVariableIF::VAR_WRITE); - writableTargetState = initialTargetState; - mySet.commit(PoolVariableIF::VALID); -} - -CoreComponent::~CoreComponent() { -} - -ThermalComponentIF::HeaterRequest CoreComponent::performOperation(uint8_t opCode) { - HeaterRequest request = HEATER_DONT_CARE; - //SHOULDDO: Better pass db_float_t* to getTemperature and set it invalid if invalid. - temperature = getTemperature(); - updateMinMaxTemp(); - if ((temperature != INVALID_TEMPERATURE)) { - temperature.setValid(PoolVariableIF::VALID); - State state = getState(temperature, getParameters(), targetState); - currentState = state; - checkLimits(state); - request = getHeaterRequest(targetState, temperature, getParameters()); - } else { - temperatureMonitor.setToInvalid(); - temperature.setValid(PoolVariableIF::INVALID); - currentState = UNKNOWN; - request = HEATER_DONT_CARE; - } - currentState.setValid(PoolVariableIF::VALID); - heaterRequest = request; - heaterRequest.setValid(PoolVariableIF::VALID); - return request; -} - -void CoreComponent::markStateIgnored() { - currentState = getIgnoredState(currentState); -} - -object_id_t CoreComponent::getObjectId() { - return temperatureMonitor.getReporterId(); -} - -float CoreComponent::getLowerOpLimit() { - return parameters.lowerOpLimit; -} - -ReturnValue_t CoreComponent::setTargetState(int8_t newState) { - GlobDataSet mySet; - gp_uint8_t writableTargetState(targetState.getDataPoolId(), - &mySet, PoolVariableIF::VAR_READ_WRITE); - mySet.read(); - if ((writableTargetState == STATE_REQUEST_OPERATIONAL) - && (newState != STATE_REQUEST_IGNORE)) { - return HasReturnvaluesIF::RETURN_FAILED; - } - switch (newState) { - case STATE_REQUEST_HEATING: - case STATE_REQUEST_IGNORE: - case STATE_REQUEST_OPERATIONAL: - writableTargetState = newState; - break; - case STATE_REQUEST_NON_OPERATIONAL: - default: - return INVALID_TARGET_STATE; - } - mySet.commit(PoolVariableIF::VALID); - return HasReturnvaluesIF::RETURN_OK; -} - -void CoreComponent::setOutputInvalid() { - temperature = INVALID_TEMPERATURE; - temperature.setValid(PoolVariableIF::INVALID); - currentState.setValid(PoolVariableIF::INVALID); - heaterRequest = HEATER_DONT_CARE; - heaterRequest.setValid(PoolVariableIF::INVALID); - temperatureMonitor.setToUnchecked(); -} - -float CoreComponent::getTemperature() { - if ((sensor != NULL) && (sensor->isValid())) { - return sensor->getTemperature(); - } - - if ((firstRedundantSensor != NULL) && (firstRedundantSensor->isValid())) { - return firstRedundantSensor->getTemperature(); - } - - if ((secondRedundantSensor != NULL) && (secondRedundantSensor->isValid())) { - return secondRedundantSensor->getTemperature(); - } - - if (thermalModule != NULL) { - float temperature = thermalModule->getTemperature(); - if (temperature != ThermalModuleIF::INVALID_TEMPERATURE) { - return temperature; - } else { - return INVALID_TEMPERATURE; - } - } else { - return INVALID_TEMPERATURE; - } -} - -ThermalComponentIF::State CoreComponent::getState(float temperature, - Parameters parameters, int8_t targetState) { - ThermalComponentIF::State state; - - if (temperature < parameters.lowerOpLimit) { - state = NON_OPERATIONAL_LOW; - } else if (temperature < parameters.upperOpLimit) { - state = OPERATIONAL; - } else { - state = NON_OPERATIONAL_HIGH; - } - if (targetState == STATE_REQUEST_IGNORE) { - state = getIgnoredState(state); - } - - return state; -} - -void CoreComponent::checkLimits(ThermalComponentIF::State state) { - //Checks operational limits only. - temperatureMonitor.translateState(state, temperature.value, - getParameters().lowerOpLimit, getParameters().upperOpLimit); - -} - -ThermalComponentIF::HeaterRequest CoreComponent::getHeaterRequest( - int8_t targetState, float temperature, Parameters parameters) { - if (targetState == STATE_REQUEST_IGNORE) { - isHeating = false; - return HEATER_DONT_CARE; - } - - if (temperature > parameters.upperOpLimit - parameters.heaterSwitchoff) { - isHeating = false; - return HEATER_REQUEST_EMERGENCY_OFF; - } - - float opHeaterLimit = parameters.lowerOpLimit + parameters.heaterOn; - - if (isHeating) { - opHeaterLimit += parameters.hysteresis; - } - - if (temperature < opHeaterLimit) { - isHeating = true; - return HEATER_REQUEST_EMERGENCY_ON; - } - isHeating = false; - return HEATER_DONT_CARE; -} - -ThermalComponentIF::State CoreComponent::getIgnoredState(int8_t state) { - switch (state) { - case NON_OPERATIONAL_LOW: - return NON_OPERATIONAL_LOW_IGNORED; - case OPERATIONAL: - return OPERATIONAL_IGNORED; - case NON_OPERATIONAL_HIGH: - return NON_OPERATIONAL_HIGH_IGNORED; - case NON_OPERATIONAL_LOW_IGNORED: - return NON_OPERATIONAL_LOW_IGNORED; - case OPERATIONAL_IGNORED: - return OPERATIONAL_IGNORED; - case NON_OPERATIONAL_HIGH_IGNORED: - return NON_OPERATIONAL_HIGH_IGNORED; - default: - case UNKNOWN: - return UNKNOWN; - } -} - -void CoreComponent::updateMinMaxTemp() { - if (temperature == INVALID_TEMPERATURE) { - return; - } - if (temperature < minTemp) { - minTemp = temperature; - } - if (temperature > maxTemp) { - maxTemp = temperature; - } -} - -uint8_t CoreComponent::getDomainId() const { - return domainId; -} - -CoreComponent::Parameters CoreComponent::getParameters() { - return parameters; -} - -ReturnValue_t CoreComponent::getParameter(uint8_t domainId, - uint16_t parameterId, ParameterWrapper* parameterWrapper, - const ParameterWrapper* newValues, uint16_t startAtIndex) { - ReturnValue_t result = temperatureMonitor.getParameter(domainId, - parameterId, parameterWrapper, newValues, startAtIndex); - if (result != INVALID_DOMAIN_ID) { - return result; - } - if (domainId != this->domainId) { - return INVALID_DOMAIN_ID; - } - switch (parameterId) { - case 0: - parameterWrapper->set(parameters.heaterOn); - break; - case 1: - parameterWrapper->set(parameters.hysteresis); - break; - case 2: - parameterWrapper->set(parameters.heaterSwitchoff); - break; - case 3: - parameterWrapper->set(minTemp); - break; - case 4: - parameterWrapper->set(maxTemp); - break; - case 10: - parameterWrapper->set(parameters.lowerOpLimit); - break; - case 11: - parameterWrapper->set(parameters.upperOpLimit); - break; - default: - return INVALID_MATRIX_ID; - } - return HasReturnvaluesIF::RETURN_OK; -} diff --git a/thermal/CoreComponent.h b/thermal/CoreComponent.h deleted file mode 100644 index 8093711d6..000000000 --- a/thermal/CoreComponent.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ -#define MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ - -#include "../datapoolglob/GlobalDataSet.h" -#include "../datapoolglob/GlobalPoolVariable.h" -#include "../thermal/ThermalComponentIF.h" -#include "../thermal/AbstractTemperatureSensor.h" -#include "../thermal/ThermalModule.h" -#include "../thermal/ThermalMonitor.h" - -// TODO: Documentaiton, how to use this? only use Thermal Component, which inherits core component? -class CoreComponent: public ThermalComponentIF { -public: - struct Parameters { - float lowerOpLimit; - float upperOpLimit; - float heaterOn; - float hysteresis; - float heaterSwitchoff; - }; - - static const uint16_t COMPONENT_TEMP_CONFIRMATION = 5; - - CoreComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId, - uint32_t targetStatePoolId, uint32_t currentStatePoolId, - uint32_t requestPoolId, GlobDataSet *dataSet, - AbstractTemperatureSensor *sensor, - AbstractTemperatureSensor *firstRedundantSensor, - AbstractTemperatureSensor *secondRedundantSensor, - ThermalModuleIF *thermalModule, Parameters parameters, - Priority priority, StateRequest initialTargetState = - ThermalComponentIF::STATE_REQUEST_OPERATIONAL); - - virtual ~CoreComponent(); - - virtual HeaterRequest performOperation(uint8_t opCode); - - void markStateIgnored(); - - object_id_t getObjectId(); - - uint8_t getDomainId() const; - - virtual float getLowerOpLimit(); - - ReturnValue_t setTargetState(int8_t newState); - - virtual void setOutputInvalid(); - - virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, - ParameterWrapper *parameterWrapper, - const ParameterWrapper *newValues, uint16_t startAtIndex); - -protected: - - AbstractTemperatureSensor *sensor; - AbstractTemperatureSensor *firstRedundantSensor; - AbstractTemperatureSensor *secondRedundantSensor; - ThermalModuleIF *thermalModule; - - gp_float_t temperature; - gp_int8_t targetState; - gp_int8_t currentState; - gp_uint8_t heaterRequest; - - bool isHeating; - - bool isSafeComponent; - - float minTemp; - - float maxTemp; - - Parameters parameters; - - ThermalMonitor temperatureMonitor; - - const uint8_t domainId; - - virtual float getTemperature(); - virtual State getState(float temperature, Parameters parameters, - int8_t targetState); - - virtual void checkLimits(State state); - - virtual HeaterRequest getHeaterRequest(int8_t targetState, - float temperature, Parameters parameters); - - virtual State getIgnoredState(int8_t state); - - void updateMinMaxTemp(); - - virtual Parameters getParameters(); -}; - -#endif /* MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ */ From 0a5099e293acc10407dcfe8078fddca303b901a3 Mon Sep 17 00:00:00 2001 From: Spacefish Date: Thu, 10 Dec 2020 16:34:25 +0100 Subject: [PATCH 32/37] deleted file which was renamed --- thermal/ThermalMonitor.cpp | 68 -------------------------------------- thermal/ThermalMonitor.h | 23 ------------- 2 files changed, 91 deletions(-) delete mode 100644 thermal/ThermalMonitor.cpp delete mode 100644 thermal/ThermalMonitor.h diff --git a/thermal/ThermalMonitor.cpp b/thermal/ThermalMonitor.cpp deleted file mode 100644 index 11abfbe54..000000000 --- a/thermal/ThermalMonitor.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "ThermalMonitor.h" -#include "ThermalComponentIF.h" -#include "../monitoring/MonitoringIF.h" -ThermalMonitor::~ThermalMonitor() { -} - -void ThermalMonitor::sendTransitionEvent(float currentValue, - ReturnValue_t state) { - switch (state) { - case MonitoringIF::BELOW_LOW_LIMIT: - EventManagerIF::triggerEvent(reportingId, - ThermalComponentIF::COMPONENT_TEMP_OOL_LOW, state); - break; - case MonitoringIF::ABOVE_HIGH_LIMIT: - EventManagerIF::triggerEvent(reportingId, - ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH, state); - break; - case ThermalComponentIF::BELOW_OPERATIONAL_LIMIT: - EventManagerIF::triggerEvent(reportingId, - ThermalComponentIF::COMPONENT_TEMP_LOW, state); - break; - case ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT: - EventManagerIF::triggerEvent(reportingId, - ThermalComponentIF::COMPONENT_TEMP_HIGH, state); - break; - default: - break; - } -} - -bool ThermalMonitor::isAboveHighLimit() { - if (oldState == ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT) { - return true; - } else { - return false; - } -} - -ReturnValue_t ThermalMonitor::translateState(ThermalComponentIF::State state, float sample, float lowerLimit, - float upperLimit, bool componentIsOperational) { - if (ThermalComponentIF::isIgnoredState(state)) { - setToUnchecked(); - return MonitoringIF::UNCHECKED; - } - switch (state) { - case ThermalComponentIF::OUT_OF_RANGE_LOW: - return monitorStateIs(MonitoringIF::BELOW_LOW_LIMIT, sample, lowerLimit); - case ThermalComponentIF::NON_OPERATIONAL_LOW: - if (componentIsOperational) { - return monitorStateIs(ThermalComponentIF::BELOW_OPERATIONAL_LIMIT, sample, lowerLimit); - } else { - return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); - } - case ThermalComponentIF::OPERATIONAL: - return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); - case ThermalComponentIF::NON_OPERATIONAL_HIGH: - if (componentIsOperational) { - return monitorStateIs(ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT, sample, upperLimit); - } else { - return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); - } - case ThermalComponentIF::OUT_OF_RANGE_HIGH: - return monitorStateIs(MonitoringIF::ABOVE_HIGH_LIMIT, sample, upperLimit); - default: - //Never reached, all states covered. - return HasReturnvaluesIF::RETURN_FAILED; - } -} diff --git a/thermal/ThermalMonitor.h b/thermal/ThermalMonitor.h deleted file mode 100644 index 5c6806c1d..000000000 --- a/thermal/ThermalMonitor.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef FRAMEWORK_THERMAL_THERMALMONITOR_H_ -#define FRAMEWORK_THERMAL_THERMALMONITOR_H_ - -#include "../monitoring/MonitorReporter.h" -#include "ThermalComponentIF.h" - -class ThermalMonitor: public MonitorReporter { -public: - template - ThermalMonitor(Args ... args) : - MonitorReporter(std::forward(args)...) { - } - ~ThermalMonitor(); - ReturnValue_t translateState(ThermalComponentIF::State state, float sample, - float lowerLimit, float upperLimit, bool componentIsOperational = true); - - bool isAboveHighLimit(); -protected: - virtual void sendTransitionEvent(float currentValue, ReturnValue_t state); - -}; - -#endif /* FRAMEWORK_THERMAL_THERMALMONITOR_H_ */ From f81c9d7ecc54442eeabfae066f4fafc7feae7698 Mon Sep 17 00:00:00 2001 From: Spacefish Date: Thu, 10 Dec 2020 16:36:09 +0100 Subject: [PATCH 33/37] resolved merge conflicts --- thermal/ThermalModule.cpp | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/thermal/ThermalModule.cpp b/thermal/ThermalModule.cpp index cc541c8cc..2bc1741f6 100644 --- a/thermal/ThermalModule.cpp +++ b/thermal/ThermalModule.cpp @@ -5,15 +5,9 @@ #include "../monitoring/MonitoringMessageContent.h" -<<<<<<< HEAD ThermalModule::ThermalModule(gp_id_t moduleTemperaturePoolId, gp_id_t currentStatePoolId, gp_id_t targetStatePoolId, LocalPoolDataSetBase *dataSet, Parameters parameters, -======= -ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, - uint32_t currentStatePoolId, uint32_t targetStatePoolId, - GlobDataSet *dataSet, Parameters parameters, ->>>>>>> upstream/development RedundantHeater::Parameters heaterParameters) : oldStrategy(ACTIVE_SINGLE), parameters(parameters), moduleTemperature(moduleTemperaturePoolId, dataSet, @@ -23,7 +17,6 @@ ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, heater = new RedundantHeater(heaterParameters); } -<<<<<<< HEAD ThermalModule::ThermalModule(gp_id_t moduleTemperaturePoolId, LocalPoolDataSetBase* dataSet) : oldStrategy(ACTIVE_SINGLE), parameters( { 0, 0 }), @@ -33,15 +26,6 @@ ThermalModule::ThermalModule(gp_id_t moduleTemperaturePoolId, PoolVariableIF::VAR_WRITE), targetState(gp_id_t(), dataSet, PoolVariableIF::VAR_READ) { -======= -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( - NULL), currentState(PoolVariableIF::INVALID, dataSet, - PoolVariableIF::VAR_WRITE), targetState(PoolVariableIF::INVALID, - dataSet, PoolVariableIF::VAR_READ) { ->>>>>>> upstream/development } ThermalModule::~ThermalModule() { @@ -272,7 +256,6 @@ bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus( } void ThermalModule::setHeating(bool on) { -<<<<<<< HEAD // GlobDataSet mySet; // gp_int8_t writableTargetState(targetState.getDataPoolId(), // &mySet, PoolVariableIF::VAR_WRITE); @@ -282,17 +265,6 @@ void ThermalModule::setHeating(bool on) { // writableTargetState = STATE_REQUEST_PASSIVE; // } // mySet.commit(PoolVariableIF::VALID); -======= - GlobDataSet mySet; - gp_int8_t writableTargetState(targetState.getDataPoolId(), - &mySet, PoolVariableIF::VAR_WRITE); - if (on) { - writableTargetState = STATE_REQUEST_HEATING; - } else { - writableTargetState = STATE_REQUEST_PASSIVE; - } - mySet.commit(PoolVariableIF::VALID); ->>>>>>> upstream/development } void ThermalModule::updateTargetTemperatures(ThermalComponentIF* component, From be9913f262e879f8c264f54550d61e983fddc1e5 Mon Sep 17 00:00:00 2001 From: Spacefish Date: Thu, 10 Dec 2020 16:40:22 +0100 Subject: [PATCH 34/37] themral module update --- thermal/ThermalModule.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/thermal/ThermalModule.cpp b/thermal/ThermalModule.cpp index 2bc1741f6..457a6743d 100644 --- a/thermal/ThermalModule.cpp +++ b/thermal/ThermalModule.cpp @@ -256,15 +256,16 @@ bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus( } void ThermalModule::setHeating(bool on) { -// GlobDataSet mySet; -// gp_int8_t writableTargetState(targetState.getDataPoolId(), -// &mySet, PoolVariableIF::VAR_WRITE); -// if (on) { -// writableTargetState = STATE_REQUEST_HEATING; -// } else { -// writableTargetState = STATE_REQUEST_PASSIVE; -// } -// mySet.commit(PoolVariableIF::VALID); + ReturnValue_t result = targetState.read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + if(on) { + targetState.value = STATE_REQUEST_HEATING; + } + else { + targetState.value = STATE_REQUEST_PASSIVE; + } + } + targetState.setValid(true); } void ThermalModule::updateTargetTemperatures(ThermalComponentIF* component, From 50ad2c03809502d9494e37bff99a54bf39fc024c Mon Sep 17 00:00:00 2001 From: Spacefish Date: Thu, 10 Dec 2020 16:57:43 +0100 Subject: [PATCH 35/37] resolved merge conflicts --- power/Fuse.h | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/power/Fuse.h b/power/Fuse.h index 8a1b29f00..b892611bc 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -1,21 +1,11 @@ #ifndef FSFW_POWER_FUSE_H_ #define FSFW_POWER_FUSE_H_ -<<<<<<< HEAD #include "PowerComponentIF.h" #include "PowerSwitchIF.h" #include "../devicehandlers/HealthDevice.h" #include "../monitoring/AbsLimitMonitor.h" -======= -#include "../datapoolglob/GlobalDataSet.h" -#include "../datapoolglob/GlobalPoolVariable.h" -#include "../datapoolglob/PIDReader.h" -#include "../devicehandlers/HealthDevice.h" -#include "../monitoring/AbsLimitMonitor.h" -#include "../power/PowerComponentIF.h" -#include "../power/PowerSwitchIF.h" ->>>>>>> upstream/development #include "../returnvalues/HasReturnvaluesIF.h" #include "../parameters/ParameterHelper.h" #include @@ -94,26 +84,14 @@ private: }; PowerMonitor powerMonitor; -<<<<<<< HEAD StaticLocalDataSet<3> set; - //LocalPoolDataSetBase* set = nullptr; - //PIDReader voltage; - //PIDReader current; - //PIDReader state; + lp_var_t voltage; lp_var_t current; lp_var_t state; lp_var_t power; MessageQueueIF* commandQueue = nullptr; -======= - GlobDataSet set; - PIDReader voltage; - PIDReader current; - PIDReader state; - gp_float_t power; - MessageQueueIF* commandQueue; ->>>>>>> upstream/development ParameterHelper parameterHelper; HealthHelper healthHelper; static object_id_t powerSwitchId; From a2823835dd8f6708fd004aef2d95d74547c7cdf7 Mon Sep 17 00:00:00 2001 From: Spacefish Date: Thu, 10 Dec 2020 17:05:41 +0100 Subject: [PATCH 36/37] explicit cast added --- parameters/ParameterWrapper.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/parameters/ParameterWrapper.cpp b/parameters/ParameterWrapper.cpp index 239555162..d9f1ef685 100644 --- a/parameters/ParameterWrapper.cpp +++ b/parameters/ParameterWrapper.cpp @@ -123,7 +123,8 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { //get the start element of this row in data - uint16_t offset = (((startingRow + fromRow) * columns) + startingColumn); + uint16_t offset = (((startingRow + fromRow) * + static_cast(columns)) + startingColumn); T *dataWithDataType = static_cast(data) + offset; for (uint8_t fromColumn = 0; fromColumn < fromColumns; fromColumn++) { @@ -296,8 +297,8 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, //need a type to do arithmetic uint8_t* typedData = static_cast(data); for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) { - size_t offset = (((startingRow + fromRow) * columns) + - startingColumn) * typeSize; + size_t offset = (((startingRow + fromRow) * static_cast( + columns)) + startingColumn) * typeSize; std::memcpy(typedData + offset, from->readonlyData, typeSize * from->columns); } From 7986584d17d65da8ed06fc217b216472e0cc12da Mon Sep 17 00:00:00 2001 From: Spacefish Date: Thu, 10 Dec 2020 17:18:46 +0100 Subject: [PATCH 37/37] updated comment --- devicehandlers/DeviceHandlerBase.h | 1 + 1 file changed, 1 insertion(+) diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 2bfa62a66..9a5287e03 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -746,6 +746,7 @@ protected: /** * Helper function to get pending command. This is useful for devices * like SPI sensors to identify the last sent command. + * This only returns the command sent in the last SEND_WRITE cycle. * @return */ DeviceCommandId_t getPendingCommand() const;