From e15f03fb0abf2484b03fe15ef923d868f8a74bde Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 May 2021 13:12:34 +0200 Subject: [PATCH] added FreeRTOS queue map manager --- osal/FreeRTOS/CMakeLists.txt | 1 + osal/FreeRTOS/QueueMapManager.cpp | 49 +++++++++++++++++++++++ osal/FreeRTOS/QueueMapManager.h | 50 ++++++++++++++++++++++++ osal/host/QueueMapManager.cpp | 65 +++++++++++++++---------------- osal/host/QueueMapManager.h | 49 ++++++++++++----------- 5 files changed, 157 insertions(+), 57 deletions(-) create mode 100644 osal/FreeRTOS/QueueMapManager.cpp create mode 100644 osal/FreeRTOS/QueueMapManager.h diff --git a/osal/FreeRTOS/CMakeLists.txt b/osal/FreeRTOS/CMakeLists.txt index 95462010..4da24a71 100644 --- a/osal/FreeRTOS/CMakeLists.txt +++ b/osal/FreeRTOS/CMakeLists.txt @@ -15,6 +15,7 @@ target_sources(${LIB_FSFW_NAME} TaskFactory.cpp Timekeeper.cpp TaskManagement.cpp + QueueMapManager.cpp ) # FreeRTOS is required to link the FSFW now. It is recommended to compile diff --git a/osal/FreeRTOS/QueueMapManager.cpp b/osal/FreeRTOS/QueueMapManager.cpp new file mode 100644 index 00000000..520e54cd --- /dev/null +++ b/osal/FreeRTOS/QueueMapManager.cpp @@ -0,0 +1,49 @@ +#include "QueueMapManager.h" +#include "../../ipc/MutexFactory.h" +#include "../../ipc/MutexGuard.h" + +QueueMapManager::QueueMapManager() { + mapLock = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t QueueMapManager::addMessageQueue(QueueHandle_t queue, MessageQueueId_t* id) { + MutexGuard lock(mapLock); + uint32_t currentId = queueCounter++; + auto returnPair = queueMap.emplace(currentId, queue); + if(not returnPair.second) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "QueueMapManager::addMessageQueue This ID is already " + "inside the map!" << std::endl; +#else + sif::printError("QueueMapManager::addMessageQueue This ID is already " + "inside the map!\n"); +#endif + return HasReturnvaluesIF::RETURN_FAILED; + } + if (id != nullptr) { + *id = currentId; + } + return HasReturnvaluesIF::RETURN_OK; + +} + +QueueHandle_t QueueMapManager::getMessageQueue(MessageQueueId_t messageQueueId) const { + auto queueIter = queueMap.find(messageQueueId); + if(queueIter != queueMap.end()) { + return queueIter->second; + } + else { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId << + " does not exists in the map!" << std::endl; +#else + sif::printWarning("QueueMapManager::getQueueHandle: The ID %d does not exist in the map!\n", + messageQueueId); +#endif + } + return nullptr; +} + +QueueMapManager::~QueueMapManager() { + MutexFactory::instance()->deleteMutex(mapLock); +} diff --git a/osal/FreeRTOS/QueueMapManager.h b/osal/FreeRTOS/QueueMapManager.h new file mode 100644 index 00000000..91a839f0 --- /dev/null +++ b/osal/FreeRTOS/QueueMapManager.h @@ -0,0 +1,50 @@ +#ifndef FSFW_OSAL_FREERTOS_QUEUEMAPMANAGER_H_ +#define FSFW_OSAL_FREERTOS_QUEUEMAPMANAGER_H_ + +#include "../../ipc/MutexIF.h" +#include "../../ipc/messageQueueDefinitions.h" +#include "../../ipc/MessageQueueIF.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" + +#include + +using QueueMap = std::map; + +class QueueMapManager { +public: + + //! Returns the single instance of QueueMapManager + static QueueMapManager* instance(); + + /** + * Insert a message queue and the corresponding QueueHandle into the map + * @param queue The message queue to insert. + * @param id The passed value will be set unless a nullptr is passed + * @return + */ + ReturnValue_t addMessageQueue(QueueHandle_t queue, MessageQueueId_t* id); + + /** + * Get the message queue handle by providing a message queue ID. Returns nullptr + * if the queue ID does not exist in the internal map. + * @param messageQueueId + * @return + */ + QueueHandle_t getMessageQueue(MessageQueueId_t messageQueueId) const; + +private: + //! External instantiation forbidden. Constructor still required for singleton instantiation. + QueueMapManager(); + ~QueueMapManager(); + + uint32_t queueCounter = 0; + MutexIF* mapLock; + QueueMap queueMap; + static QueueMapManager* mqManagerInstance; +}; + + + +#endif /* FSFW_OSAL_FREERTOS_QUEUEMAPMANAGER_H_ */ diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index c9100fe9..879bc36d 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -15,52 +15,49 @@ QueueMapManager::~QueueMapManager() { } QueueMapManager* QueueMapManager::instance() { - if (mqManagerInstance == nullptr){ - mqManagerInstance = new QueueMapManager(); - } - return QueueMapManager::mqManagerInstance; + if (mqManagerInstance == nullptr){ + mqManagerInstance = new QueueMapManager(); + } + return QueueMapManager::mqManagerInstance; } ReturnValue_t QueueMapManager::addMessageQueue( - MessageQueueIF* queueToInsert, MessageQueueId_t* id) { - /* Not thread-safe, but it is assumed all message queues are created at software initialization - now. If this is to be made thread-safe in the future, it propably would be sufficient to lock - the increment operation here. */ - uint32_t currentId = queueCounter++; - auto returnPair = queueMap.emplace(currentId, queueToInsert); - if(not returnPair.second) { - /* This should never happen for the atomic variable. */ + MessageQueueIF* queueToInsert, MessageQueueId_t* id) { + MutexGuard lock(mapLock); + uint32_t currentId = queueCounter++; + auto returnPair = queueMap.emplace(currentId, queueToInsert); + if(not returnPair.second) { + /* This should never happen for the atomic variable. */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "QueueMapManager::addMessageQueue This ID is already " - "inside the map!" << std::endl; + sif::error << "QueueMapManager::addMessageQueue This ID is already " + "inside the map!" << std::endl; #else - sif::printError("QueueMapManager::addMessageQueue This ID is already " + sif::printError("QueueMapManager::addMessageQueue This ID is already " "inside the map!\n"); #endif - return HasReturnvaluesIF::RETURN_FAILED; - } - if (id != nullptr) { - *id = currentId; - } - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_FAILED; + } + if (id != nullptr) { + *id = currentId; + } + return HasReturnvaluesIF::RETURN_OK; } MessageQueueIF* QueueMapManager::getMessageQueue( - MessageQueueId_t messageQueueId) const { - MutexGuard(mapLock, MutexIF::TimeoutType::WAITING, 50); - auto queueIter = queueMap.find(messageQueueId); - if(queueIter != queueMap.end()) { - return queueIter->second; - } - else { + MessageQueueId_t messageQueueId) const { + auto queueIter = queueMap.find(messageQueueId); + if(queueIter != queueMap.end()) { + return queueIter->second; + } + else { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId << - " does not exists in the map!" << std::endl; + sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId << + " does not exists in the map!" << std::endl; #else - sif::printWarning("QueueMapManager::getQueueHandle: The ID %d does not exist in the map!\n", - messageQueueId); + sif::printWarning("QueueMapManager::getQueueHandle: The ID %d does not exist in the map!\n", + messageQueueId); #endif - return nullptr; - } + } + return nullptr; } diff --git a/osal/host/QueueMapManager.h b/osal/host/QueueMapManager.h index 90c39c2f..e274bed2 100644 --- a/osal/host/QueueMapManager.h +++ b/osal/host/QueueMapManager.h @@ -15,33 +15,36 @@ using QueueMap = std::unordered_map; */ class QueueMapManager { public: - //! Returns the single instance of SemaphoreFactory. - static QueueMapManager* instance(); - /** - * Insert a message queue into the map and returns a message queue ID - * @param queue The message queue to insert. - * @param id The passed value will be set unless a nullptr is passed - * @return - */ - ReturnValue_t addMessageQueue(MessageQueueIF* queue, MessageQueueId_t* - id = nullptr); - /** - * Get the message queue handle by providing a message queue ID. - * @param messageQueueId - * @return - */ - MessageQueueIF* getMessageQueue(MessageQueueId_t messageQueueId) const; + + //! Returns the single instance of QueueMapManager. + static QueueMapManager* instance(); + + /** + * Insert a message queue into the map and returns a message queue ID + * @param queue The message queue to insert. + * @param id The passed value will be set unless a nullptr is passed + * @return + */ + ReturnValue_t addMessageQueue(MessageQueueIF* queue, MessageQueueId_t* + id = nullptr); + /** + * Get the message queue handle by providing a message queue ID. Returns nullptr + * if the queue ID is not contained inside the internal map. + * @param messageQueueId + * @return + */ + MessageQueueIF* getMessageQueue(MessageQueueId_t messageQueueId) const; private: - //! External instantiation is forbidden. - QueueMapManager(); - ~QueueMapManager(); + //! External instantiation is forbidden. Constructor still required for singleton instantiation. + QueueMapManager(); + ~QueueMapManager(); - uint32_t queueCounter = 0; - MutexIF* mapLock; - QueueMap queueMap; - static QueueMapManager* mqManagerInstance; + uint32_t queueCounter = 0; + MutexIF* mapLock; + QueueMap queueMap; + static QueueMapManager* mqManagerInstance; };