Merge branch 'mueller_framework' into front_branch

This commit is contained in:
Robin Müller 2020-06-10 01:19:00 +02:00
commit b6427d017b
25 changed files with 299 additions and 167 deletions

View File

@ -10,7 +10,7 @@ class ActionMessage {
private:
ActionMessage();
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::ACTION;
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);

View File

@ -1,6 +1,7 @@
#include <framework/datapoollocal/LocalDataPoolManager.h>
#include <framework/datapoollocal/LocalDataSet.h>
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <framework/objectmanager/frameworkObjects.h>
#include <framework/ipc/MutexFactory.h>
#include <framework/ipc/MutexHelper.h>
@ -13,7 +14,15 @@ LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner) {
}
this->owner = owner;
mutex = MutexFactory::instance()->createMutex();
//owner->setMinimalHkSamplingFrequency();
if(mutex == nullptr) {
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
"Could not create mutex." << std::endl;
}
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if(ipcStore == nullptr) {
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
"Could not set IPC store." << std::endl;
}
}
LocalDataPoolManager::~LocalDataPoolManager() {}
@ -32,7 +41,7 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
}
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
CommandMessage *message) {
MessageQueueMessage *message) {
return HasReturnvaluesIF::RETURN_OK;
}
@ -52,32 +61,37 @@ MutexIF* LocalDataPoolManager::getMutexHandle() {
return mutex;
}
//void HousekeepingManager::setMinimalSamplingFrequency(float frequencySeconds) {
// this->samplingFrequency = frequencySeconds;
//
//}
void LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) {
ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) {
LocalDataSet* dataSetToSerialize = dynamic_cast<LocalDataSet*>(
owner->getDataSetHandle(sid));
if(dataSetToSerialize == nullptr) {
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
" Set ID not found" << std::endl;
return;
return HasReturnvaluesIF::RETURN_FAILED;
}
store_address_t storeId;
size_t hkSize = dataSetToSerialize->getSerializedSize();
uint8_t* storePtr = nullptr;
ReturnValue_t result = ipcStore->getFreeElement(&storeId, hkSize,&storePtr);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "HousekeepingManager::generateHousekeepingPacket: "
"Could not get free element from IPC store." << std::endl;
return result;
}
std::array<uint8_t, 256> testBuffer = {};
uint8_t* dataPtr = testBuffer.data();
size_t size = 0;
dataSetToSerialize->serialize(&dataPtr, &size, testBuffer.size(),
false);
// and now we send it to the TM funnel or somewhere else
dataSetToSerialize->serialize(&storePtr, &size, hkSize, false);
// and now we have to set a HK message and send it the queue.
return HasReturnvaluesIF::RETURN_OK;
}
void LocalDataPoolManager::setHkPacketQueue(MessageQueueIF *msgQueue) {
this->hkPacketQueue = msgQueue;
}
void LocalDataPoolManager::setHkReplyQueue(MessageQueueIF *replyQueue) {
this->hkReplyQueue = replyQueue;
}
const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
return owner;
}

View File

@ -37,15 +37,16 @@ class LocalDataPoolManager {
friend class LocalPoolVector;
friend class LocalDataSet;
public:
static constexpr float MINIMAL_SAMPLING_FREQUENCY = 0.2;
LocalDataPoolManager(OwnsLocalDataPoolIF* owner);
virtual~ LocalDataPoolManager();
/* Copying forbidden */
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
// propably will just call respective local data set functions.
void generateHousekeepingPacket(sid_t sid);
ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
ReturnValue_t generateHousekeepingPacket(sid_t sid);
ReturnValue_t handleHousekeepingMessage(MessageQueueMessage* message);
/**
* This function is used to fill the local data pool map with pool
@ -55,7 +56,12 @@ public:
*/
ReturnValue_t initializeHousekeepingPoolEntriesOnce();
//! Set the queue for HK packets, which are sent unrequested.
void setHkPacketQueue(MessageQueueIF* msgQueue);
//! Set the queue for replies. This can be set manually or by the owner
//! class if the manager if message are relayed by it.
void setHkReplyQueue(MessageQueueIF* replyQueue);
const OwnsLocalDataPoolIF* getOwner() const;
ReturnValue_t printPoolEntry(lp_id_t localPoolId);
@ -81,6 +87,8 @@ private:
//! Maybe this will just be the TM funnel.
MessageQueueIF* hkPacketQueue = nullptr;
//! Global IPC store is used to store all packets.
StorageManagerIF* ipcStore = nullptr;
/**
* Get the pointer to the mutex. Can be used to lock the data pool
* eternally. Use with care and don't forget to unlock locked mutexes!

View File

@ -8,6 +8,8 @@
#include <framework/datapoolglob/GlobalPoolVariable.h>
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
#include <framework/globalfunctions/CRC.h>
#include <framework/housekeeping/HousekeepingMessage.h>
#include <framework/ipc/MessageQueueMessage.h>
#include <framework/subsystem/SubsystemBase.h>
#include <framework/ipc/QueueFactory.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
@ -36,7 +38,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode(
SUBMODE_NONE), deviceSwitch(setDeviceSwitch) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
CommandMessage::MAX_MESSAGE_SIZE);
MessageQueueMessage::MAX_MESSAGE_SIZE);
insertInCommandMap(RAW_COMMAND_ID);
cookieInfo.state = COOKIE_UNUSED;
cookieInfo.pendingCommand = deviceCommandMap.end();
@ -212,40 +214,59 @@ void DeviceHandlerBase::readCommandQueue() {
return;
}
CommandMessage message;
ReturnValue_t result = commandQueue->receiveMessage(&message);
// This is not ideal. What if it is not a command message? (e.g. another
// message with 3 parameters). The full buffer is filled anyway
// and I could just copy the content into the other message but
// all I need are few additional functions the other message type offers.
CommandMessage cmdMessage;
ReturnValue_t result = commandQueue->receiveMessage(&cmdMessage);
if (result != RETURN_OK) {
return;
}
// This is really annoying. I can't cast a parent object to a child.
// But I want to use another message format..
// CommandMessage* cmdMessage = dynamic_cast<CommandMessage*>(msgPtr);
// if(cmdMessage == nullptr) {
// sif::error << "DeviceHandlerBase::readCommandQueue: Could not cast"
// " message to CommandMessage!" << std::endl;
// return;
// }
if(healthHelperActive) {
result = healthHelper.handleHealthCommand(&message);
result = healthHelper.handleHealthCommand(&cmdMessage);
if (result == RETURN_OK) {
return;
}
}
result = modeHelper.handleModeCommand(&message);
result = modeHelper.handleModeCommand(&cmdMessage);
if (result == RETURN_OK) {
return;
}
result = actionHelper.handleActionMessage(&message);
result = actionHelper.handleActionMessage(&cmdMessage);
if (result == RETURN_OK) {
return;
}
result = parameterHelper.handleParameterMessage(&message);
result = parameterHelper.handleParameterMessage(&cmdMessage);
if (result == RETURN_OK) {
return;
}
result = handleDeviceHandlerMessage(&message);
// HousekeepingMessage* hkMessage = dynamic_cast<HousekeepingMessage*>(msgPtr);
// result = hkManager.handleHousekeepingMessage(hkMessage);
// if (result == RETURN_OK) {
// return;
// }
result = handleDeviceHandlerMessage(&cmdMessage);
if (result == RETURN_OK) {
return;
}
result = letChildHandleMessage(&message);
result = letChildHandleMessage(&cmdMessage);
if (result == RETURN_OK) {
return;
}

View File

@ -25,7 +25,7 @@ public:
/**
* These are the commands that can be sent to a DeviceHandlerBase
*/
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::DEVICE_HANDLER_COMMAND;
static const uint8_t MESSAGE_ID = messagetypes::DEVICE_HANDLER_COMMAND;
static const Command_t CMD_RAW = MAKE_COMMAND_ID( 1 ); //!< Sends a raw command, setParameter is a ::store_id_t containing the raw packet to send
// static const Command_t CMD_DIRECT = MAKE_COMMAND_ID( 2 ); //!< Sends a direct command, setParameter is a ::DeviceCommandId_t, setParameter2 is a ::store_id_t containing the data needed for the command
static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID( 3 ); //!< Requests a IO-Board switch, setParameter() is the IO-Board identifier

View File

@ -6,7 +6,7 @@
class HealthMessage {
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::HEALTH_COMMAND;
static const uint8_t MESSAGE_ID = messagetypes::HEALTH_COMMAND;
static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1);//REPLY_COMMAND_OK/REPLY_REJECTED
static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(3); //NO REPLY!
static const Command_t HEALTH_INFO = MAKE_COMMAND_ID(5);

View File

@ -1,5 +1,13 @@
#include <framework/housekeeping/HousekeepingMessage.h>
HousekeepingMessage::HousekeepingMessage() {
}
void HousekeepingMessage::setHkReportMessage() {
}
//void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message,
// set_t setId, store_address_t packet) {
// message->setCommand(ADD_HK_REPORT_STRUCT);

View File

@ -5,12 +5,14 @@
#include <limits>
union sid_t {
static constexpr uint64_t INVALID_ADDRESS = std::numeric_limits<uint64_t>::max();
static constexpr uint64_t INVALID_ADDRESS =
std::numeric_limits<uint64_t>::max();
sid_t(): raw(INVALID_ADDRESS) {}
struct {
object_id_t objectId ;
// A generic 32 bit ID to identify unique HK packets for a single object.
// A generic 32 bit ID to identify unique HK packets for a single
// object.
// For example, the DeviceCommandId_t is used for DeviceHandlers
uint32_t ownerSetId;
};
@ -19,17 +21,19 @@ union sid_t {
*/
uint64_t raw;
};
class HousekeepingMessage {
class HousekeepingMessage: public MessageQueueMessage {
public:
/**
* No instances of a message shall be created, instead
* a CommandMessage instance is manipulated.
*/
HousekeepingMessage() = delete;
HousekeepingMessage(const HousekeepingMessage&) = delete;
HousekeepingMessage operator=(const HousekeepingMessage &) = delete;
HousekeepingMessage();
// HousekeepingMessage(const HousekeepingMessage&) = delete;
// HousekeepingMessage operator=(const HousekeepingMessage &) = delete;
static constexpr uint8_t MESSAGE_ID = MESSAGE_TYPE::HOUSEKEEPING;
static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING;
static constexpr Command_t ADD_HK_REPORT_STRUCT =
MAKE_COMMAND_ID(1);
static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT =
@ -76,6 +80,7 @@ public:
// static void setAddHkReportStructMessage(CommandMessage* message,
// DevisetId, store_address_t packet);
static void setHkReportMessage();
};

View File

@ -1,10 +1,3 @@
/**
* @file CommandMessage.cpp
* @brief This file defines the CommandMessage class.
* @date 20.06.2013
* @author baetz
*/
#include <framework/devicehandlers/DeviceHandlerMessage.h>
#include <framework/health/HealthMessage.h>
#include <framework/ipc/CommandMessage.h>
@ -15,7 +8,8 @@
#include <framework/tmstorage/TmStoreMessage.h>
#include <framework/parameters/ParameterMessage.h>
namespace MESSAGE_TYPE {
namespace messagetypes {
// Implemented in config.
void clearMissionMessage(CommandMessage* message);
}
@ -39,6 +33,10 @@ Command_t CommandMessage::getCommand() const {
return command;
}
uint8_t CommandMessage::getMessageType() const {
return getCommand() >> 8 & 0xff;
}
void CommandMessage::setCommand(Command_t command) {
memcpy(getData(), &command, sizeof(command));
}
@ -66,36 +64,36 @@ void CommandMessage::setParameter2(uint32_t parameter2) {
}
void CommandMessage::clearCommandMessage() {
switch((getCommand()>>8) & 0xff){
case MESSAGE_TYPE::MODE_COMMAND:
switch(getMessageType()){
case messagetypes::MODE_COMMAND:
ModeMessage::clear(this);
break;
case MESSAGE_TYPE::HEALTH_COMMAND:
case messagetypes::HEALTH_COMMAND:
HealthMessage::clear(this);
break;
case MESSAGE_TYPE::MODE_SEQUENCE:
case messagetypes::MODE_SEQUENCE:
ModeSequenceMessage::clear(this);
break;
case MESSAGE_TYPE::ACTION:
case messagetypes::ACTION:
ActionMessage::clear(this);
break;
case MESSAGE_TYPE::DEVICE_HANDLER_COMMAND:
case messagetypes::DEVICE_HANDLER_COMMAND:
DeviceHandlerMessage::clear(this);
break;
case MESSAGE_TYPE::MEMORY:
case messagetypes::MEMORY:
MemoryMessage::clear(this);
break;
case MESSAGE_TYPE::MONITORING:
case messagetypes::MONITORING:
MonitoringMessage::clear(this);
break;
case MESSAGE_TYPE::TM_STORE:
case messagetypes::TM_STORE:
TmStoreMessage::clear(this);
break;
case MESSAGE_TYPE::PARAMETER:
case messagetypes::PARAMETER:
ParameterMessage::clear(this);
break;
default:
MESSAGE_TYPE::clearMissionMessage(this);
messagetypes::clearMissionMessage(this);
break;
}
}

View File

@ -1,13 +1,5 @@
/**
* @file CommandMessage.h
* @brief This file defines the CommandMessage class.
* @date 20.06.2013
* @author baetz
*/
#ifndef COMMANDMESSAGE_H_
#define COMMANDMESSAGE_H_
#ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_
#define FRAMEWORK_IPC_COMMANDMESSAGE_H_
#include <framework/ipc/FwMessageTypes.h>
#include <config/ipc/MissionMessageTypes.h>
@ -15,10 +7,11 @@
#include <framework/ipc/MessageQueueMessage.h>
#define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number))
typedef ReturnValue_t Command_t;
typedef uint16_t Command_t;
/**
* @brief Used to pass command messages between tasks
* @brief Used to pass command messages between tasks
* @author Bastian Baetz
*/
class CommandMessage : public MessageQueueMessage {
public:
@ -26,13 +19,17 @@ public:
static const ReturnValue_t UNKNOW_COMMAND = MAKE_RETURN_CODE(0x01);
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::COMMAND;
static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 );//!< Used internally, will be ignored
static const uint8_t MESSAGE_ID = messagetypes::COMMAND;
//! Used internally, will be ignored
static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 );
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 3 );
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 );//!< Reply indicating that the current command was rejected, par1 should contain the error code
//! Reply indicating that the current command was rejected,
//! par1 should contain the error code
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 );
/**
* This is the size of a message as it is seen by the MessageQueue
* This is the size of a message as it is seen by the MessageQueue.
* 14 of the 24 available MessageQueueMessage bytes are used.
*/
static const size_t COMMAND_MESSAGE_SIZE = HEADER_SIZE
+ sizeof(Command_t) + 2 * sizeof(uint32_t);
@ -40,11 +37,13 @@ public:
/**
* Default Constructor, does not initialize anything.
*
* This constructor should be used when receiving a Message, as the content is filled by the MessageQueue.
* This constructor should be used when receiving a Message, as the
* content is filled by the MessageQueue.
*/
CommandMessage();
/**
* This constructor creates a new message with all message content initialized
* This constructor creates a new message with all message content
* initialized
*
* @param command The DeviceHandlerCommand_t that will be sent
* @param parameter1 The first parameter
@ -60,12 +59,14 @@ public:
}
/**
* Read the DeviceHandlerCommand_t that is stored in the message, usually used after receiving
* Read the DeviceHandlerCommand_t that is stored in the message,
* usually used after receiving.
*
* @return the Command stored in the Message
*/
Command_t getCommand() const;
uint8_t getMessageType() const;
/**
* Set the DeviceHandlerCOmmand_t of the message
*
@ -126,7 +127,8 @@ public:
* Is needed quite often, so we better code it once only.
*/
void setToUnknownCommand();
void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE);
void setReplyRejected(ReturnValue_t reason,
Command_t initialCommand = CMD_NONE);
size_t getMinimumMessageSize() const;
};

View File

@ -1,9 +1,9 @@
#ifndef FRAMEWORK_IPC_FWMESSAGETYPES_H_
#define FRAMEWORK_IPC_FWMESSAGETYPES_H_
namespace MESSAGE_TYPE {
namespace messagetypes {
//Remember to add new Message Types to the clearCommandMessage function!
enum FW_MESSAGE_TYPE {
enum FsfwMessageTypes {
COMMAND = 0,
MODE_COMMAND,
HEALTH_COMMAND,

View File

@ -1,6 +1,7 @@
#ifndef MESSAGEQUEUEMESSAGE_H_
#define MESSAGEQUEUEMESSAGE_H_
#include <framework/ipc/MessageQueueMessageIF.h>
#include <framework/ipc/MessageQueueSenderIF.h>
#include <stddef.h>
@ -23,7 +24,7 @@
* receive messages from other tasks.
* @ingroup message_queue
*/
class MessageQueueMessage {
class MessageQueueMessage: public MessageQueueMessageIF {
public:
/**
* @brief The class is initialized empty with this constructor.
@ -43,6 +44,7 @@ public:
* MAX_MESSAGE_SIZE and larger than MIN_MESSAGE_SIZE.
*/
MessageQueueMessage(uint8_t* data, size_t size);
/**
* @brief The size information of each message is stored in this attribute.
* @details

View File

@ -0,0 +1,49 @@
#ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_
#define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_
#include <framework/ipc/MessageQueueSenderIF.h>
#include <cstddef>
class MessageQueueMessageIF {
public:
virtual ~MessageQueueMessageIF() {};
/**
* @brief With this method, the whole content and the message
* size is set to zero.
*/
virtual void clear() = 0;
/**
* @brief This is a debug method that prints the content
* (till messageSize) to the debug output.
*/
virtual void print() = 0;
/**
* @brief Get read-only pointer to the raw buffer.
* @return
*/
virtual const uint8_t* getBuffer() const = 0;
/**
* @brief This method is used to get the complete data of the message.
*/
virtual uint8_t* getBuffer() = 0;
/**
* @brief This method is used to set the sender's message queue id
* information prior to sending the message.
* @param setId
* The message queue id that identifies the sending message queue.
*/
virtual void setSender(MessageQueueId_t setId) = 0;
/**
* @brief This helper function is used by the MessageQueue class to
* check the size of an incoming message.
*/
virtual size_t getMinimumMessageSize() = 0;
};
#endif /* FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ */

View File

@ -16,7 +16,7 @@ class FileSystemMessage {
private:
FileSystemMessage(); //A private ctor inhibits instantiation
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::FILE_SYSTEM_MESSAGE;
static const uint8_t MESSAGE_ID = messagetypes::FILE_SYSTEM_MESSAGE;
static const Command_t CREATE_FILE = MAKE_COMMAND_ID( 0x01 );
static const Command_t DELETE_FILE = MAKE_COMMAND_ID( 0x02 );
static const Command_t WRITE_TO_FILE = MAKE_COMMAND_ID( 0x80 );

View File

@ -9,7 +9,7 @@ class MemoryMessage {
private:
MemoryMessage(); //A private ctor inhibits instantiation
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MEMORY;
static const uint8_t MESSAGE_ID = messagetypes::MEMORY;
static const Command_t CMD_MEMORY_LOAD = MAKE_COMMAND_ID( 0x01 );
static const Command_t CMD_MEMORY_DUMP = MAKE_COMMAND_ID( 0x02 );
static const Command_t CMD_MEMORY_CHECK = MAKE_COMMAND_ID( 0x03 );

View File

@ -17,7 +17,7 @@ class ModeMessage {
private:
ModeMessage();
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MODE_COMMAND;
static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND;
static const Command_t CMD_MODE_COMMAND = MAKE_COMMAND_ID(0x01);//!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies, as this will break the subsystem mode machine!!
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(0xF1);//!> Command to set the specified Mode, regardless of external control flag, replies are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies, as this will break the subsystem mode machine!!
static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);//!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ

View File

@ -6,7 +6,7 @@
class MonitoringMessage: public CommandMessage {
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MONITORING;
static const uint8_t MESSAGE_ID = messagetypes::MONITORING;
//Object id could be useful, but we better manage that on service level (register potential reporters).
static const Command_t LIMIT_VIOLATION_REPORT = MAKE_COMMAND_ID(10);
virtual ~MonitoringMessage();

View File

@ -23,6 +23,7 @@ SemaphoreFactory* SemaphoreFactory::instance() {
}
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) {
// Just gonna wait for full C++20 for now.
sif::error << "SemaphoreFactory: Binary Semaphore not implemented yet."
" Returning nullptr!\n" << std::flush;
return nullptr;
@ -30,6 +31,7 @@ SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) {
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(const uint8_t maxCount,
uint8_t initCount, uint32_t arguments) {
// Just gonna wait for full C++20 for now.
sif::error << "SemaphoreFactory: Counting Semaphore not implemented yet."
" Returning nullptr!\n" << std::flush;
return nullptr;

View File

@ -9,8 +9,9 @@
#include <errno.h>
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0),
lastPartner(0), defaultDestination(NO_QUEUE) {
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize):
id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE),
defaultDestination(MessageQueueIF::NO_QUEUE) {
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
mq_attr attributes;
this->id = 0;
@ -56,16 +57,23 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
sif::error << "MessageQueue::MessageQueue: Invalid name or attributes"
" for message size" << std::endl;
size_t defaultMqMaxMsg = 0;
// Not POSIX conformant, but should work for all UNIX systems.
// Just an additional helpful printout :-)
if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >>
defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) {
// See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html
// This happens if the msg_max value is not large enough
// It is ignored if the executable is run in privileged mode.
// Run the unlockRealtime script or grant the mode manully by using:
// Run the unlockRealtime script or grant the mode manually by using:
// sudo setcap 'CAP_SYS_RESOURCE=+ep' <pathToBinary>
// Permanent solution (EventManager has mq depth of 80):
// echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max
// Persistent solution for session:
// echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
// Permanent solution:
// sudo nano /etc/sysctl.conf
// Append at end: fs/mqueue/msg_max = <newMsgMaxLen>
// Apply changes with: sudo sysctl -p
sif::error << "MessageQueue::MessageQueue: Default MQ size "
<< defaultMqMaxMsg << " is too small for requested size "
<< messageDepth << std::endl;
@ -75,24 +83,22 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
case(EEXIST): {
// An error occured during open
// We need to distinguish if it is caused by an already created queue
if (errno == EEXIST) {
//There's another queue with the same name
//We unlink the other queue
int status = mq_unlink(name);
if (status != 0) {
sif::error << "mq_unlink Failed with status: " << strerror(errno)
<< std::endl;
}
else {
// Successful unlinking, try to open again
mqd_t tempId = mq_open(name,
O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL,
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes);
if (tempId != -1) {
//Successful mq_open
this->id = tempId;
return HasReturnvaluesIF::RETURN_OK;
}
//There's another queue with the same name
//We unlink the other queue
int status = mq_unlink(name);
if (status != 0) {
sif::error << "mq_unlink Failed with status: " << strerror(errno)
<< std::endl;
}
else {
// Successful unlinking, try to open again
mqd_t tempId = mq_open(name,
O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL,
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes);
if (tempId != -1) {
//Successful mq_open
this->id = tempId;
return HasReturnvaluesIF::RETURN_OK;
}
}
break;
@ -150,12 +156,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
//Success but no message received
return MessageQueueIF::EMPTY;
} else {
//No message was received. Keep lastPartner anyway, I might send something later.
//But still, delete packet content.
//No message was received. Keep lastPartner anyway, I might send
//something later. But still, delete packet content.
memset(message->getData(), 0, message->MAX_DATA_SIZE);
switch(errno){
case EAGAIN:
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages currently on the specified queue.
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages
//currently on the specified queue.
return MessageQueueIF::EMPTY;
case EBADF:
//mqdes doesn't represent a valid queue open for reading.
@ -165,9 +172,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
case EINVAL:
/*
* This value indicates one of the following:
* * The pointer to the buffer for storing the received message, msg_ptr, is NULL.
* * The number of bytes requested, msg_len is less than zero.
* * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags.
* - The pointer to the buffer for storing the received message,
* msg_ptr, is NULL.
* - The number of bytes requested, msg_len is less than zero.
* - msg_len is anything other than the mq_msgsize of the specified
* queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't
* been set in the queue's mq_flags.
*/
sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl;
@ -175,8 +185,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
case EMSGSIZE:
/*
* This value indicates one of the following:
* * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue.
* * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received.
* - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set,
* and the given msg_len is shorter than the mq_msgsize for
* the given queue.
* - the extended option MQ_READBUF_DYNAMIC has been set, but the
* given msg_len is too short for the message that would have
* been received.
*/
sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl;
@ -224,9 +238,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
case EINVAL:
/*
* This value indicates one of the following:
* * mq_attr is NULL.
* * MQ_MULT_NOTIFY had been set for this queue, and the given mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once MQ_MULT_NOTIFY has been turned on, it may never be turned off.
*
* - mq_attr is NULL.
* - MQ_MULT_NOTIFY had been set for this queue, and the given
* mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once
* MQ_MULT_NOTIFY has been turned on, it may never be turned off.
*/
default:
return HasReturnvaluesIF::RETURN_FAILED;
@ -275,7 +290,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
//TODO: Check if we're in ISR.
if (result != 0) {
if(!ignoreFault){
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
InternalErrorReporterIF* internalErrorReporter =
objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != NULL) {
internalErrorReporter->queueMessageNotSent();
@ -283,10 +299,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
}
switch(errno){
case EAGAIN:
//The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full.
//The O_NONBLOCK flag was set when opening the queue, or the
//MQ_NONBLOCK flag was set in its attributes, and the
//specified queue is full.
return MessageQueueIF::FULL;
case EBADF:
//mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing.
//mq_des doesn't represent a valid message queue descriptor,
//or mq_des wasn't opened for writing.
sif::error << "MessageQueue::sendMessage: Configuration error "
<< strerror(errno) << " in mq_send mqSendTo: " << sendTo
<< " sent from " << sentFrom << std::endl;
@ -296,13 +315,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
case EINVAL:
/*
* This value indicates one of the following:
* * msg_ptr is NULL.
* * msg_len is negative.
* * msg_prio is greater than MQ_PRIO_MAX.
* * msg_prio is less than 0.
* * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des,
* and msg_prio is greater than the priority of the calling process.
* */
* - msg_ptr is NULL.
* - msg_len is negative.
* - msg_prio is greater than MQ_PRIO_MAX.
* - msg_prio is less than 0.
* - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and
* msg_prio is greater than the priority of the calling process.
*/
sif::error << "MessageQueue::sendMessage: Configuration error "
<< strerror(errno) << " in mq_send" << std::endl;
/*NO BREAK*/

View File

@ -9,7 +9,7 @@ class ParameterMessage {
private:
ParameterMessage();
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::PARAMETER;
static const uint8_t MESSAGE_ID = messagetypes::PARAMETER;
static const Command_t CMD_PARAMETER_LOAD = MAKE_COMMAND_ID( 0x01 );
static const Command_t CMD_PARAMETER_DUMP = MAKE_COMMAND_ID( 0x02 );
static const Command_t REPLY_PARAMETER_DUMP = MAKE_COMMAND_ID( 0x03 );

View File

@ -84,8 +84,8 @@ public:
//! The copy ctor and copy assignemnt should be deleted implicitely
//! according to https://foonathan.net/2019/02/special-member-functions/
//! but I still deleted them to make it more explicit. (remember rule of 5).
ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete;
ConstStorageAccessor (ConstStorageAccessor&) = delete;
ConstStorageAccessor& operator= (const ConstStorageAccessor&) = delete;
ConstStorageAccessor (const ConstStorageAccessor&) = delete;
protected:
const uint8_t* constDataPointer = nullptr;
store_address_t storeId;

View File

@ -7,7 +7,7 @@
class ModeSequenceMessage {
public:
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MODE_SEQUENCE;
static const uint8_t MESSAGE_ID = messagetypes::MODE_SEQUENCE;
static const Command_t ADD_SEQUENCE = MAKE_COMMAND_ID(0x01);
static const Command_t ADD_TABLE = MAKE_COMMAND_ID(0x02);

View File

@ -41,7 +41,7 @@ public:
static store_address_t getStoreId(const CommandMessage* cmd);
virtual ~TmStoreMessage();
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::TM_STORE;
static const uint8_t MESSAGE_ID = messagetypes::TM_STORE;
static const Command_t ENABLE_STORING = MAKE_COMMAND_ID(1);
static const Command_t DELETE_STORE_CONTENT = MAKE_COMMAND_ID(2);
static const Command_t DOWNLINK_STORE_CONTENT = MAKE_COMMAND_ID(3);

View File

@ -218,7 +218,7 @@ void CommandingServiceBase::handleRequestQueue() {
}
void CommandingServiceBase::sendTmPacket(uint8_t subservice,
ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice,
const uint8_t* data, size_t dataLen, const uint8_t* headerData,
size_t headerSize) {
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
@ -228,36 +228,38 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice,
if (result == HasReturnvaluesIF::RETURN_OK) {
this->tmPacketCounter++;
}
return result;
}
void CommandingServiceBase::sendTmPacket(uint8_t subservice,
object_id_t objectId, const uint8_t *data, size_t dataLen) {
uint8_t buffer[sizeof(object_id_t)];
uint8_t* pBuffer = buffer;
size_t size = 0;
SerializeAdapter<object_id_t>::serialize(&objectId, &pBuffer, &size,
sizeof(object_id_t), true);
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
this->tmPacketCounter, data, dataLen, buffer, size);
ReturnValue_t result = tmPacketStored.sendPacket(
requestQueue->getDefaultDestination(), requestQueue->getId());
if (result == HasReturnvaluesIF::RETURN_OK) {
this->tmPacketCounter++;
}
ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice,
object_id_t objectId, const uint8_t *data, size_t dataLen) {
uint8_t buffer[sizeof(object_id_t)];
uint8_t* pBuffer = buffer;
size_t size = 0;
SerializeAdapter<object_id_t>::serialize(&objectId, &pBuffer, &size,
sizeof(object_id_t), true);
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
this->tmPacketCounter, data, dataLen, buffer, size);
ReturnValue_t result = tmPacketStored.sendPacket(
requestQueue->getDefaultDestination(), requestQueue->getId());
if (result == HasReturnvaluesIF::RETURN_OK) {
this->tmPacketCounter++;
}
return result;
}
void CommandingServiceBase::sendTmPacket(uint8_t subservice,
SerializeIF* content, SerializeIF* header) {
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
this->tmPacketCounter, content, header);
ReturnValue_t result = tmPacketStored.sendPacket(
requestQueue->getDefaultDestination(), requestQueue->getId());
if (result == HasReturnvaluesIF::RETURN_OK) {
this->tmPacketCounter++;
}
ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice,
SerializeIF* content, SerializeIF* header) {
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
this->tmPacketCounter, content, header);
ReturnValue_t result = tmPacketStored.sendPacket(
requestQueue->getDefaultDestination(), requestQueue->getId());
if (result == HasReturnvaluesIF::RETURN_OK) {
this->tmPacketCounter++;
}
return result;
}

View File

@ -212,36 +212,38 @@ protected:
*/
PeriodicTaskIF* executingTask;
// todo: why do these functions not have returnvalues? the caller should be
// able to check whether the send operations actually work.
/**
* Send TM data from pointer to data. If a header is supplied it is added before data
* @brief Send TM data from pointer to data.
* If a header is supplied it is added before data
* @param subservice Number of subservice
* @param data Pointer to the data in the Packet
* @param dataLen Lenght of data in the Packet
* @param headerData HeaderData will be placed before data
* @param headerSize Size of HeaderData
*/
void sendTmPacket(uint8_t subservice, const uint8_t *data, size_t dataLen,
const uint8_t* headerData = nullptr,size_t headerSize = 0);
ReturnValue_t sendTmPacket(uint8_t subservice, const uint8_t *data,
size_t dataLen, const uint8_t* headerData = nullptr,
size_t headerSize = 0);
/**
* To send TM packets of objects that still need to be serialized and consist of an object ID with appended data
* @brief To send TM packets of objects that still need to be serialized
* and consist of an object ID with appended data.
* @param subservice Number of subservice
* @param objectId ObjectId is placed before data
* @param data Data to append to the packet
* @param dataLen Length of Data
*/
void sendTmPacket(uint8_t subservice, object_id_t objectId,
ReturnValue_t sendTmPacket(uint8_t subservice, object_id_t objectId,
const uint8_t *data, size_t dataLen);
/**
* To send packets has data which is in form of a SerializeIF or Adapters implementing it
* @brief To send packets which are contained inside a class implementing
* SerializeIF.
* @param subservice Number of subservice
* @param content This is a pointer to the serialized packet
* @param header Serialize IF header which will be placed before content
*/
void sendTmPacket(uint8_t subservice, SerializeIF* content,
ReturnValue_t sendTmPacket(uint8_t subservice, SerializeIF* content,
SerializeIF* header = nullptr);
virtual void handleUnrequestedReply(CommandMessage *reply);