Merge remote-tracking branch 'ksat/mueller/master' into mueller/master
This commit is contained in:
commit
43d4953e4a
@ -1,5 +1,5 @@
|
|||||||
target_sources(${LIB_FSFW_NAME}
|
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||||
PRIVATE
|
MemoryHelper.cpp
|
||||||
MemoryHelper.cpp
|
MemoryMessage.cpp
|
||||||
MemoryMessage.cpp
|
GenericFileSystemMessage.cpp
|
||||||
)
|
)
|
132
memory/GenericFileSystemMessage.cpp
Normal file
132
memory/GenericFileSystemMessage.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include "GenericFileSystemMessage.h"
|
||||||
|
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setCreateFileCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_CREATE_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setDeleteFileCommand(
|
||||||
|
CommandMessage* message, store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_DELETE_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setCreateDirectoryCommand(
|
||||||
|
CommandMessage* message, store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_CREATE_DIRECTORY);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setReportFileAttributesCommand(CommandMessage *message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_REPORT_FILE_ATTRIBUTES);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setReportFileAttributesReply(CommandMessage *message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(REPLY_REPORT_FILE_ATTRIBUTES);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setDeleteDirectoryCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_DELETE_DIRECTORY);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setLockFileCommand(CommandMessage *message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_LOCK_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setUnlockFileCommand(CommandMessage *message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_UNLOCK_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setSuccessReply(CommandMessage *message) {
|
||||||
|
message->setCommand(COMPLETION_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setFailureReply(CommandMessage *message,
|
||||||
|
ReturnValue_t errorCode, uint32_t errorParam) {
|
||||||
|
message->setCommand(COMPLETION_FAILED);
|
||||||
|
message->setParameter(errorCode);
|
||||||
|
message->setParameter2(errorParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
store_address_t GenericFileSystemMessage::getStoreId(const CommandMessage* message) {
|
||||||
|
store_address_t temp;
|
||||||
|
temp.raw = message->getParameter2();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t GenericFileSystemMessage::getFailureReply(
|
||||||
|
const CommandMessage *message, uint32_t* errorParam) {
|
||||||
|
if(errorParam != nullptr) {
|
||||||
|
*errorParam = message->getParameter2();
|
||||||
|
}
|
||||||
|
return message->getParameter();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setFinishStopWriteCommand(CommandMessage *message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_FINISH_APPEND_TO_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setFinishStopWriteReply(CommandMessage *message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(REPLY_FINISH_APPEND);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setCopyCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_COPY_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setWriteCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_APPEND_TO_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setReadCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(CMD_READ_FROM_FILE);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setFinishAppendReply(CommandMessage* message,
|
||||||
|
store_address_t storageID) {
|
||||||
|
message->setCommand(REPLY_FINISH_APPEND);
|
||||||
|
message->setParameter2(storageID.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setReadReply(CommandMessage* message,
|
||||||
|
bool readFinished, store_address_t storeId) {
|
||||||
|
message->setCommand(REPLY_READ_FROM_FILE);
|
||||||
|
message->setParameter(readFinished);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericFileSystemMessage::setReadFinishedReply(CommandMessage *message,
|
||||||
|
store_address_t storeId) {
|
||||||
|
message->setCommand(REPLY_READ_FINISHED_STOP);
|
||||||
|
message->setParameter2(storeId.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GenericFileSystemMessage::getReadReply(const CommandMessage *message,
|
||||||
|
store_address_t *storeId) {
|
||||||
|
if(storeId != nullptr) {
|
||||||
|
(*storeId).raw = message->getParameter2();
|
||||||
|
}
|
||||||
|
return message->getParameter();
|
||||||
|
}
|
113
memory/GenericFileSystemMessage.h
Normal file
113
memory/GenericFileSystemMessage.h
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#ifndef MISSION_MEMORY_GENERICFILESYSTEMMESSAGE_H_
|
||||||
|
#define MISSION_MEMORY_GENERICFILESYSTEMMESSAGE_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <fsfw/ipc/CommandMessageIF.h>
|
||||||
|
#include <fsfw/ipc/FwMessageTypes.h>
|
||||||
|
#include <fsfw/ipc/CommandMessage.h>
|
||||||
|
#include <fsfw/storagemanager/storeAddress.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief These messages are sent to an object implementing HasFilesystemIF.
|
||||||
|
* @details
|
||||||
|
* Enables a message-based file management. The user can add custo commands be implementing
|
||||||
|
* this generic class.
|
||||||
|
* @author Jakob Meier, R. Mueller
|
||||||
|
*/
|
||||||
|
class GenericFileSystemMessage {
|
||||||
|
public:
|
||||||
|
/* Instantiation forbidden */
|
||||||
|
GenericFileSystemMessage() = delete;
|
||||||
|
|
||||||
|
static const uint8_t MESSAGE_ID = messagetypes::FILE_SYSTEM_MESSAGE;
|
||||||
|
/* PUS standard (ECSS-E-ST-70-41C15 2016 p.654) */
|
||||||
|
static const Command_t CMD_CREATE_FILE = MAKE_COMMAND_ID(1);
|
||||||
|
static const Command_t CMD_DELETE_FILE = MAKE_COMMAND_ID(2);
|
||||||
|
/** Report file attributes */
|
||||||
|
static const Command_t CMD_REPORT_FILE_ATTRIBUTES = MAKE_COMMAND_ID(3);
|
||||||
|
static const Command_t REPLY_REPORT_FILE_ATTRIBUTES = MAKE_COMMAND_ID(4);
|
||||||
|
/** Command to lock a file, setting it read-only */
|
||||||
|
static const Command_t CMD_LOCK_FILE = MAKE_COMMAND_ID(5);
|
||||||
|
/** Command to unlock a file, enabling further operations on it */
|
||||||
|
static const Command_t CMD_UNLOCK_FILE = MAKE_COMMAND_ID(6);
|
||||||
|
/**
|
||||||
|
* Find file in repository, using a search pattern.
|
||||||
|
* Please note that * is the wildcard character.
|
||||||
|
* For example, when looking for all files which start with have the
|
||||||
|
* structure tm<something>.bin, tm*.bin can be used.
|
||||||
|
*/
|
||||||
|
static const Command_t CMD_FIND_FILE = MAKE_COMMAND_ID(7);
|
||||||
|
static const Command_t CMD_CREATE_DIRECTORY = MAKE_COMMAND_ID(9);
|
||||||
|
static const Command_t CMD_DELETE_DIRECTORY = MAKE_COMMAND_ID(10);
|
||||||
|
static const Command_t CMD_RENAME_DIRECTORY = MAKE_COMMAND_ID(11);
|
||||||
|
|
||||||
|
/** Dump contents of a repository */
|
||||||
|
static const Command_t CMD_DUMP_REPOSITORY = MAKE_COMMAND_ID(12);
|
||||||
|
/** Repository dump reply */
|
||||||
|
static const Command_t REPLY_DUMY_REPOSITORY = MAKE_COMMAND_ID(13);
|
||||||
|
static constexpr Command_t CMD_COPY_FILE = MAKE_COMMAND_ID(14);
|
||||||
|
static constexpr Command_t CMD_MOVE_FILE = MAKE_COMMAND_ID(15);
|
||||||
|
|
||||||
|
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(128);
|
||||||
|
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(129);
|
||||||
|
|
||||||
|
// These command IDs will remain until CFDP has been introduced and consolidated.
|
||||||
|
/** Append operation commands */
|
||||||
|
static const Command_t CMD_APPEND_TO_FILE = MAKE_COMMAND_ID(130);
|
||||||
|
static const Command_t CMD_FINISH_APPEND_TO_FILE = MAKE_COMMAND_ID(131);
|
||||||
|
static const Command_t REPLY_FINISH_APPEND = MAKE_COMMAND_ID(132);
|
||||||
|
|
||||||
|
static const Command_t CMD_READ_FROM_FILE = MAKE_COMMAND_ID(140);
|
||||||
|
static const Command_t REPLY_READ_FROM_FILE = MAKE_COMMAND_ID(141);
|
||||||
|
static const Command_t CMD_STOP_READ = MAKE_COMMAND_ID(142);
|
||||||
|
static const Command_t REPLY_READ_FINISHED_STOP = MAKE_COMMAND_ID(143);
|
||||||
|
|
||||||
|
static void setLockFileCommand(CommandMessage* message, store_address_t storeId);
|
||||||
|
static void setUnlockFileCommand(CommandMessage* message, store_address_t storeId);
|
||||||
|
|
||||||
|
static void setCreateFileCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setDeleteFileCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
|
||||||
|
static void setReportFileAttributesCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setReportFileAttributesReply(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
|
||||||
|
static void setCreateDirectoryCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setDeleteDirectoryCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
|
||||||
|
static void setSuccessReply(CommandMessage* message);
|
||||||
|
static void setFailureReply(CommandMessage* message,
|
||||||
|
ReturnValue_t errorCode, uint32_t errorParam = 0);
|
||||||
|
static void setCopyCommand(CommandMessage* message, store_address_t storeId);
|
||||||
|
|
||||||
|
static void setWriteCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setFinishStopWriteCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setFinishStopWriteReply(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setFinishAppendReply(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
|
||||||
|
static void setReadCommand(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setReadFinishedReply(CommandMessage* message,
|
||||||
|
store_address_t storeId);
|
||||||
|
static void setReadReply(CommandMessage* message, bool readFinished,
|
||||||
|
store_address_t storeId);
|
||||||
|
static bool getReadReply(const CommandMessage* message,
|
||||||
|
store_address_t* storeId);
|
||||||
|
|
||||||
|
static store_address_t getStoreId(const CommandMessage* message);
|
||||||
|
static ReturnValue_t getFailureReply(const CommandMessage* message,
|
||||||
|
uint32_t* errorParam = nullptr);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MISSION_MEMORY_GENERICFILESYSTEMMESSAGE_H_ */
|
@ -15,6 +15,7 @@ target_sources(${LIB_FSFW_NAME}
|
|||||||
TaskFactory.cpp
|
TaskFactory.cpp
|
||||||
Timekeeper.cpp
|
Timekeeper.cpp
|
||||||
TaskManagement.cpp
|
TaskManagement.cpp
|
||||||
|
QueueMapManager.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# FreeRTOS is required to link the FSFW now. It is recommended to compile
|
# FreeRTOS is required to link the FSFW now. It is recommended to compile
|
||||||
|
@ -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,29 +131,24 @@ 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(destination, 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);
|
||||||
|
@ -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;
|
||||||
|
58
osal/FreeRTOS/QueueMapManager.cpp
Normal file
58
osal/FreeRTOS/QueueMapManager.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "QueueMapManager.h"
|
||||||
|
#include "../../ipc/MutexFactory.h"
|
||||||
|
#include "../../ipc/MutexGuard.h"
|
||||||
|
|
||||||
|
QueueMapManager* QueueMapManager::mqManagerInstance = nullptr;
|
||||||
|
|
||||||
|
QueueMapManager::QueueMapManager() {
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
}
|
50
osal/FreeRTOS/QueueMapManager.h
Normal file
50
osal/FreeRTOS/QueueMapManager.h
Normal file
@ -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 <map>
|
||||||
|
|
||||||
|
using QueueMap = std::map<MessageQueueId_t, QueueHandle_t>;
|
||||||
|
|
||||||
|
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_ */
|
@ -15,52 +15,49 @@ QueueMapManager::~QueueMapManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueueMapManager* QueueMapManager::instance() {
|
QueueMapManager* QueueMapManager::instance() {
|
||||||
if (mqManagerInstance == nullptr){
|
if (mqManagerInstance == nullptr){
|
||||||
mqManagerInstance = new QueueMapManager();
|
mqManagerInstance = new QueueMapManager();
|
||||||
}
|
}
|
||||||
return QueueMapManager::mqManagerInstance;
|
return QueueMapManager::mqManagerInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t QueueMapManager::addMessageQueue(
|
ReturnValue_t QueueMapManager::addMessageQueue(
|
||||||
MessageQueueIF* queueToInsert, MessageQueueId_t* id) {
|
MessageQueueIF* queueToInsert, MessageQueueId_t* id) {
|
||||||
/* Not thread-safe, but it is assumed all message queues are created at software initialization
|
MutexGuard lock(mapLock);
|
||||||
now. If this is to be made thread-safe in the future, it propably would be sufficient to lock
|
uint32_t currentId = queueCounter++;
|
||||||
the increment operation here. */
|
auto returnPair = queueMap.emplace(currentId, queueToInsert);
|
||||||
uint32_t currentId = queueCounter++;
|
if(not returnPair.second) {
|
||||||
auto returnPair = queueMap.emplace(currentId, queueToInsert);
|
/* This should never happen for the atomic variable. */
|
||||||
if(not returnPair.second) {
|
|
||||||
/* This should never happen for the atomic variable. */
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "QueueMapManager::addMessageQueue This ID is already "
|
sif::error << "QueueMapManager::addMessageQueue This ID is already "
|
||||||
"inside the map!" << std::endl;
|
"inside the map!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("QueueMapManager::addMessageQueue This ID is already "
|
sif::printError("QueueMapManager::addMessageQueue This ID is already "
|
||||||
"inside the map!\n");
|
"inside the map!\n");
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if (id != nullptr) {
|
if (id != nullptr) {
|
||||||
*id = currentId;
|
*id = currentId;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueIF* QueueMapManager::getMessageQueue(
|
MessageQueueIF* QueueMapManager::getMessageQueue(
|
||||||
MessageQueueId_t messageQueueId) const {
|
MessageQueueId_t messageQueueId) const {
|
||||||
MutexGuard(mapLock, MutexIF::TimeoutType::WAITING, 50);
|
auto queueIter = queueMap.find(messageQueueId);
|
||||||
auto queueIter = queueMap.find(messageQueueId);
|
if(queueIter != queueMap.end()) {
|
||||||
if(queueIter != queueMap.end()) {
|
return queueIter->second;
|
||||||
return queueIter->second;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId <<
|
sif::warning << "QueueMapManager::getQueueHandle: The ID " << messageQueueId <<
|
||||||
" does not exists in the map!" << std::endl;
|
" does not exists in the map!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("QueueMapManager::getQueueHandle: The ID %d does not exist in the map!\n",
|
sif::printWarning("QueueMapManager::getQueueHandle: The ID %d does not exist in the map!\n",
|
||||||
messageQueueId);
|
messageQueueId);
|
||||||
#endif
|
#endif
|
||||||
return nullptr;
|
}
|
||||||
}
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,33 +15,36 @@ using QueueMap = std::unordered_map<MessageQueueId_t, MessageQueueIF*>;
|
|||||||
*/
|
*/
|
||||||
class QueueMapManager {
|
class QueueMapManager {
|
||||||
public:
|
public:
|
||||||
//! Returns the single instance of SemaphoreFactory.
|
|
||||||
static QueueMapManager* instance();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert a message queue into the map and returns a message queue ID
|
//! Returns the single instance of QueueMapManager.
|
||||||
* @param queue The message queue to insert.
|
static QueueMapManager* instance();
|
||||||
* @param id The passed value will be set unless a nullptr is passed
|
|
||||||
* @return
|
/**
|
||||||
*/
|
* Insert a message queue into the map and returns a message queue ID
|
||||||
ReturnValue_t addMessageQueue(MessageQueueIF* queue, MessageQueueId_t*
|
* @param queue The message queue to insert.
|
||||||
id = nullptr);
|
* @param id The passed value will be set unless a nullptr is passed
|
||||||
/**
|
* @return
|
||||||
* Get the message queue handle by providing a message queue ID.
|
*/
|
||||||
* @param messageQueueId
|
ReturnValue_t addMessageQueue(MessageQueueIF* queue, MessageQueueId_t*
|
||||||
* @return
|
id = nullptr);
|
||||||
*/
|
/**
|
||||||
MessageQueueIF* getMessageQueue(MessageQueueId_t messageQueueId) const;
|
* 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:
|
private:
|
||||||
//! External instantiation is forbidden.
|
//! External instantiation is forbidden. Constructor still required for singleton instantiation.
|
||||||
QueueMapManager();
|
QueueMapManager();
|
||||||
~QueueMapManager();
|
~QueueMapManager();
|
||||||
|
|
||||||
uint32_t queueCounter = 0;
|
uint32_t queueCounter = 0;
|
||||||
MutexIF* mapLock;
|
MutexIF* mapLock;
|
||||||
QueueMap queueMap;
|
QueueMap queueMap;
|
||||||
static QueueMapManager* mqManagerInstance;
|
static QueueMapManager* mqManagerInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user