queue map manager working

This commit is contained in:
Robin Müller 2021-05-27 13:38:40 +02:00
parent e15f03fb0a
commit e6868464bf
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
3 changed files with 39 additions and 37 deletions

View File

@ -1,26 +1,23 @@
#include "MessageQueue.h" #include "MessageQueue.h"
#include "QueueMapManager.h"
#include "../../objectmanager/ObjectManagerIF.h" #include "../../objectmanager/ObjectManagerIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
// TODO I guess we should have a way of checking if we are in an ISR and then
// use the "fromISR" versions of all calls
// As a first step towards this, introduces system context variable which needs
// to be switched manually
// Haven't found function to find system context.
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
maxMessageSize(maxMessageSize) { maxMessageSize(maxMessageSize) {
handle = xQueueCreate(messageDepth, maxMessageSize); handle = xQueueCreate(messageDepth, maxMessageSize);
#if FSFW_CPP_OSTREAM_ENABLED == 1
if (handle == nullptr) { if (handle == nullptr) {
sif::error << "MessageQueue::MessageQueue:" #if FSFW_CPP_OSTREAM_ENABLED == 1
<< " Creation failed." << std::endl; sif::error << "MessageQueue::MessageQueue: Creation failed" << std::endl;
sif::error << "Specified Message Depth: " << messageDepth sif::error << "Specified Message Depth: " << messageDepth << std::endl;
<< std::endl; sif::error << "Specified Maximum Message Size: " << maxMessageSize << std::endl;
sif::error << "Specified Maximum Message Size: " #else
<< maxMessageSize << std::endl; sif::printError("MessageQueue::MessageQueue: Creation failed\n");
sif::printError("Specified Message Depth: %d\n", messageDepth);
} sif::printError("Specified MAximum Message Size: %d\n", maxMessageSize);
#endif #endif
}
QueueMapManager::instance()->addMessageQueue(handle, &queueId);
} }
MessageQueue::~MessageQueue() { MessageQueue::~MessageQueue() {
@ -62,13 +59,15 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
callContext); callContext);
} }
QueueHandle_t MessageQueue::getNativeQueueHandle() {
return handle;
}
ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault) { ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault) {
if (result != pdPASS) { if (result != pdPASS) {
if (not ignoreFault) { if (not ignoreFault) {
InternalErrorReporterIF* internalErrorReporter = objectManager-> InternalErrorReporterIF* internalErrorReporter = objectManager->
get<InternalErrorReporterIF>( get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != nullptr) { if (internalErrorReporter != nullptr) {
internalErrorReporter->queueMessageNotSent(); internalErrorReporter->queueMessageNotSent();
} }
@ -110,7 +109,7 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
} }
MessageQueueId_t MessageQueue::getId() const { MessageQueueId_t MessageQueue::getId() const {
return reinterpret_cast<MessageQueueId_t>(handle); return queueId;
} }
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
@ -132,30 +131,25 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom, MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault, CallContext callContext) { bool ignoreFault, CallContext callContext) {
BaseType_t result = pdFALSE; BaseType_t result = pdFALSE;
QueueHandle_t destination = nullptr; if(sendTo == MessageQueueIF::NO_QUEUE) {
return MessageQueueIF::DESTINATION_INVALID;
if(sendTo == MessageQueueIF::NO_QUEUE or sendTo == 0x00) {
return MessageQueueIF::DESTINATION_INVALID;
} }
else {
destination = reinterpret_cast<QueueHandle_t>(sendTo); QueueHandle_t destination = QueueMapManager::instance()->getMessageQueue(sendTo);
if(destination == nullptr) {
return MessageQueueIF::DESTINATION_INVALID;
} }
message->setSender(sentFrom); message->setSender(sentFrom);
if(callContext == CallContext::TASK) { if(callContext == CallContext::TASK) {
result = xQueueSendToBack(destination, result = xQueueSendToBack(destination, static_cast<const void*>(message->getBuffer()), 0);
static_cast<const void*>(message->getBuffer()), 0);
} }
else { else {
/* If the call context is from an interrupt, /* If the call context is from an interrupt, request a context switch if a higher priority
* request a context switch if a higher priority task task was blocked by the interrupt. */
* was blocked by the interrupt. */
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
result = xQueueSendFromISR(reinterpret_cast<QueueHandle_t>(sendTo), result = xQueueSendFromISR(reinterpret_cast<QueueHandle_t>(sendTo),
static_cast<const void*>(message->getBuffer()), static_cast<const void*>(message->getBuffer()), &xHigherPriorityTaskWoken);
&xHigherPriorityTaskWoken);
if(xHigherPriorityTaskWoken == pdTRUE) { if(xHigherPriorityTaskWoken == pdTRUE) {
TaskManagement::requestContextSwitch(callContext); TaskManagement::requestContextSwitch(callContext);
} }

View File

@ -11,11 +11,6 @@
#include <freertos/queue.h> #include <freertos/queue.h>
#include <fsfw/ipc/MessageQueueMessage.h> #include <fsfw/ipc/MessageQueueMessage.h>
// TODO: this class assumes that MessageQueueId_t is the same size as void*
// (the FreeRTOS handle type), compiler will catch this but it might be nice
// to have something checking or even an always working solution
// https://scaryreasoner.wordpress.com/2009/02/28/checking-sizeof-at-compile-time/
/** /**
* @brief This class manages sending and receiving of * @brief This class manages sending and receiving of
* message queue messages. * message queue messages.
@ -112,6 +107,8 @@ public:
bool isDefaultDestinationSet() const override; bool isDefaultDestinationSet() const override;
QueueHandle_t getNativeQueueHandle();
protected: protected:
/** /**
* @brief Implementation to be called from any send Call within * @brief Implementation to be called from any send Call within
@ -141,6 +138,8 @@ protected:
private: private:
bool defaultDestinationSet = false; bool defaultDestinationSet = false;
QueueHandle_t handle; QueueHandle_t handle;
MessageQueueId_t queueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE; MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE;
MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE; MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE;
const size_t maxMessageSize; const size_t maxMessageSize;

View File

@ -2,10 +2,19 @@
#include "../../ipc/MutexFactory.h" #include "../../ipc/MutexFactory.h"
#include "../../ipc/MutexGuard.h" #include "../../ipc/MutexGuard.h"
QueueMapManager* QueueMapManager::mqManagerInstance = nullptr;
QueueMapManager::QueueMapManager() { QueueMapManager::QueueMapManager() {
mapLock = MutexFactory::instance()->createMutex(); mapLock = MutexFactory::instance()->createMutex();
} }
QueueMapManager* QueueMapManager::instance() {
if (mqManagerInstance == nullptr){
mqManagerInstance = new QueueMapManager();
}
return QueueMapManager::mqManagerInstance;
}
ReturnValue_t QueueMapManager::addMessageQueue(QueueHandle_t queue, MessageQueueId_t* id) { ReturnValue_t QueueMapManager::addMessageQueue(QueueHandle_t queue, MessageQueueId_t* id) {
MutexGuard lock(mapLock); MutexGuard lock(mapLock);
uint32_t currentId = queueCounter++; uint32_t currentId = queueCounter++;