Merge remote-tracking branch 'upstram/master' into mueller_tcPacketBase
This commit is contained in:
commit
f654c4b33e
@ -49,7 +49,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
|
|||||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||||
store_address_t dataAddress) {
|
store_address_t dataAddress) {
|
||||||
const uint8_t* dataPtr = NULL;
|
const uint8_t* dataPtr = NULL;
|
||||||
uint32_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
|
@ -113,7 +113,7 @@ uint8_t CommandActionHelper::getCommandCount() const {
|
|||||||
|
|
||||||
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
||||||
const uint8_t * data = NULL;
|
const uint8_t * data = NULL;
|
||||||
uint32_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return;
|
return;
|
||||||
|
@ -44,7 +44,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy,
|
|||||||
queueToUse->sendMessage(commandedBy, &reply);
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
}
|
}
|
||||||
const uint8_t* dataPtr = NULL;
|
const uint8_t* dataPtr = NULL;
|
||||||
uint32_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
|
|
||||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Simple First-In-First-Out data structure
|
||||||
|
* @tparam T Entry Type
|
||||||
|
* @tparam capacity Maximum capacity
|
||||||
|
*/
|
||||||
template<typename T, uint8_t capacity>
|
template<typename T, uint8_t capacity>
|
||||||
class FIFO {
|
class FIFO {
|
||||||
private:
|
private:
|
||||||
@ -54,6 +59,21 @@ public:
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t peek(T * value) {
|
||||||
|
if(empty()) {
|
||||||
|
return EMPTY;
|
||||||
|
} else {
|
||||||
|
*value = data[readIndex];
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t pop() {
|
||||||
|
T value;
|
||||||
|
return this->retrieve(&value);
|
||||||
|
}
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
||||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
||||||
|
@ -215,7 +215,7 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) {
|
|||||||
ParameterMessage::getParameterId(command));
|
ParameterMessage::getParameterId(command));
|
||||||
|
|
||||||
const uint8_t *storedStream;
|
const uint8_t *storedStream;
|
||||||
uint32_t storedStreamSize;
|
size_t storedStreamSize;
|
||||||
result = storage->getData(ParameterMessage::getStoreId(command),
|
result = storage->getData(ParameterMessage::getStoreId(command),
|
||||||
&storedStream, &storedStreamSize);
|
&storedStream, &storedStreamSize);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
@ -2,15 +2,16 @@
|
|||||||
#include <framework/devicehandlers/ChildHandlerBase.h>
|
#include <framework/devicehandlers/ChildHandlerBase.h>
|
||||||
#include <framework/subsystem/SubsystemBase.h>
|
#include <framework/subsystem/SubsystemBase.h>
|
||||||
|
|
||||||
ChildHandlerBase::ChildHandlerBase(uint32_t ioBoardAddress,
|
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
|
||||||
object_id_t setObjectId, object_id_t deviceCommunication,
|
object_id_t deviceCommunication, CookieIF * comCookie,
|
||||||
uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch,
|
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
|
||||||
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
|
uint32_t thermalRequestPoolId, uint32_t parent,
|
||||||
uint32_t parent, FailureIsolationBase* customFdir, uint32_t cmdQueueSize) :
|
FailureIsolationBase* customFdir, size_t cmdQueueSize) :
|
||||||
DeviceHandlerBase(ioBoardAddress, setObjectId, maxDeviceReplyLen,
|
DeviceHandlerBase(setObjectId, deviceCommunication, comCookie,
|
||||||
setDeviceSwitch, deviceCommunication, thermalStatePoolId,
|
setDeviceSwitch, thermalStatePoolId,thermalRequestPoolId,
|
||||||
thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), cmdQueueSize), parentId(
|
(customFdir == nullptr? &childHandlerFdir : customFdir),
|
||||||
parent), childHandlerFdir(setObjectId) {
|
cmdQueueSize),
|
||||||
|
parentId(parent), childHandlerFdir(setObjectId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ChildHandlerBase::~ChildHandlerBase() {
|
ChildHandlerBase::~ChildHandlerBase() {
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
|
|
||||||
class ChildHandlerBase: public DeviceHandlerBase {
|
class ChildHandlerBase: public DeviceHandlerBase {
|
||||||
public:
|
public:
|
||||||
ChildHandlerBase(uint32_t ioBoardAddress, object_id_t setObjectId,
|
ChildHandlerBase(object_id_t setObjectId,
|
||||||
object_id_t deviceCommunication, uint32_t maxDeviceReplyLen,
|
object_id_t deviceCommunication, CookieIF * comCookie,
|
||||||
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
|
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
|
||||||
uint32_t thermalRequestPoolId, uint32_t parent,
|
uint32_t thermalRequestPoolId, uint32_t parent,
|
||||||
FailureIsolationBase* customFdir = NULL,
|
FailureIsolationBase* customFdir = nullptr,
|
||||||
uint32_t cmdQueueSize = 20);
|
size_t cmdQueueSize = 20);
|
||||||
virtual ~ChildHandlerBase();
|
virtual ~ChildHandlerBase();
|
||||||
|
|
||||||
virtual ReturnValue_t initialize();
|
virtual ReturnValue_t initialize();
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef COOKIE_H_
|
|
||||||
#define COOKIE_H_
|
|
||||||
|
|
||||||
class Cookie{
|
|
||||||
public:
|
|
||||||
virtual ~Cookie(){}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* COOKIE_H_ */
|
|
34
devicehandlers/CookieIF.h
Normal file
34
devicehandlers/CookieIF.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef COOKIE_H_
|
||||||
|
#define COOKIE_H_
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Physical address type
|
||||||
|
*/
|
||||||
|
typedef std::uint32_t address_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This datatype is used to identify different connection over a
|
||||||
|
* single interface (like RMAP or I2C)
|
||||||
|
* @details
|
||||||
|
* To use this class, implement a communication specific child cookie which
|
||||||
|
* inherits Cookie. Cookie instances are created in config/Factory.cpp by
|
||||||
|
* calling @code{.cpp} CookieIF* childCookie = new ChildCookie(...)
|
||||||
|
* @endcode .
|
||||||
|
*
|
||||||
|
* [not implemented yet]
|
||||||
|
* This cookie is then passed to the child device handlers, which stores the
|
||||||
|
* pointer and passes it to the communication interface functions.
|
||||||
|
*
|
||||||
|
* The cookie can be used to store all kinds of information
|
||||||
|
* about the communication, like slave addresses, communication status,
|
||||||
|
* communication parameters etc.
|
||||||
|
*
|
||||||
|
* @ingroup comm
|
||||||
|
*/
|
||||||
|
class CookieIF {
|
||||||
|
public:
|
||||||
|
virtual ~CookieIF() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* COOKIE_H_ */
|
@ -1,63 +1,131 @@
|
|||||||
#ifndef DEVICECOMMUNICATIONIF_H_
|
#ifndef DEVICECOMMUNICATIONIF_H_
|
||||||
#define DEVICECOMMUNICATIONIF_H_
|
#define DEVICECOMMUNICATIONIF_H_
|
||||||
|
|
||||||
#include <framework/devicehandlers/Cookie.h>
|
#include <framework/devicehandlers/CookieIF.h>
|
||||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <cstddef>
|
||||||
|
/**
|
||||||
|
* @defgroup interfaces Interfaces
|
||||||
|
* @brief Interfaces for flight software objects
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup comm Communication
|
||||||
|
* @brief Communication software components.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is an interface to decouple device communication from
|
||||||
|
* the device handler to allow reuse of these components.
|
||||||
|
* @details
|
||||||
|
* Documentation: Dissertation Baetz p.138.
|
||||||
|
* It works with the assumption that received data
|
||||||
|
* is polled by a component. There are four generic steps of device communication:
|
||||||
|
*
|
||||||
|
* 1. Send data to a device
|
||||||
|
* 2. Get acknowledgement for sending
|
||||||
|
* 3. Request reading data from a device
|
||||||
|
* 4. Read received data
|
||||||
|
*
|
||||||
|
* To identify different connection over a single interface can return
|
||||||
|
* so-called cookies to components.
|
||||||
|
* The CommunicationMessage message type can be used to extend the
|
||||||
|
* functionality of the ComIF if a separate polling task is required.
|
||||||
|
* @ingroup interfaces
|
||||||
|
* @ingroup comm
|
||||||
|
*/
|
||||||
class DeviceCommunicationIF: public HasReturnvaluesIF {
|
class DeviceCommunicationIF: public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF;
|
||||||
|
|
||||||
static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x01);
|
//! Standard Error Codes
|
||||||
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x02);
|
//! General protocol error. Define more concrete errors in child handler
|
||||||
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x03);
|
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x01);
|
||||||
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x04);
|
//! If cookie is a null pointer
|
||||||
static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x05);
|
static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x02);
|
||||||
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x06);
|
static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x03);
|
||||||
static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x07);
|
// is this needed if there is no open/close call?
|
||||||
|
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05);
|
||||||
|
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x06);
|
||||||
|
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x07);
|
||||||
|
static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x08);
|
||||||
|
|
||||||
virtual ~DeviceCommunicationIF() {
|
//! Can be used in readReceivedMessage() if no reply was received.
|
||||||
|
static const ReturnValue_t NO_REPLY_RECEIVED = MAKE_RETURN_CODE(0xA1);
|
||||||
|
|
||||||
}
|
virtual ~DeviceCommunicationIF() {}
|
||||||
|
|
||||||
virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
|
|
||||||
uint32_t maxReplyLen) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use an existing cookie to open a connection to a new DeviceCommunication.
|
* @brief Device specific initialization, using the cookie.
|
||||||
* The previous connection must not be closed.
|
* @details
|
||||||
* If the returnvalue is not RETURN_OK, the cookie is unchanged and
|
* The cookie is already prepared in the factory. If the communication
|
||||||
* can be used with the previous connection.
|
* interface needs to be set up in some way and requires cookie information,
|
||||||
|
* this can be performed in this function, which is called on device handler
|
||||||
|
* initialization.
|
||||||
|
* @param cookie
|
||||||
|
* @return
|
||||||
|
* - @c RETURN_OK if initialization was successfull
|
||||||
|
* - Everything else triggers failure event with returnvalue as parameter 1
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t initializeInterface(CookieIF * cookie) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by DHB in the SEND_WRITE doSendWrite().
|
||||||
|
* This function is used to send data to the physical device
|
||||||
|
* by implementing and calling related drivers or wrapper functions.
|
||||||
|
* @param cookie
|
||||||
|
* @param data
|
||||||
|
* @param len
|
||||||
|
* @return
|
||||||
|
* - @c RETURN_OK for successfull send
|
||||||
|
* - Everything else triggers failure event with returnvalue as parameter 1
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData,
|
||||||
|
size_t sendLen) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by DHB in the GET_WRITE doGetWrite().
|
||||||
|
* Get send confirmation that the data in sendMessage() was sent successfully.
|
||||||
|
* @param cookie
|
||||||
|
* @return - @c RETURN_OK if data was sent successfull
|
||||||
|
* - Everything else triggers falure event with
|
||||||
|
* returnvalue as parameter 1
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by DHB in the SEND_WRITE doSendRead().
|
||||||
|
* It is assumed that it is always possible to request a reply
|
||||||
|
* from a device. If a requestLen of 0 is supplied, no reply was enabled
|
||||||
|
* and communication specific action should be taken (e.g. read nothing
|
||||||
|
* or read everything).
|
||||||
*
|
*
|
||||||
* @param cookie
|
* @param cookie
|
||||||
* @param address
|
* @param requestLen Size of data to read
|
||||||
* @param maxReplyLen
|
* @return - @c RETURN_OK to confirm the request for data has been sent.
|
||||||
* @return
|
* - Everything else triggers failure event with
|
||||||
|
* returnvalue as parameter 1
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
|
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
|
||||||
uint32_t maxReplyLen) = 0;
|
size_t requestLen) = 0;
|
||||||
|
|
||||||
virtual void close(Cookie *cookie) = 0;
|
|
||||||
|
|
||||||
//SHOULDDO can data be const?
|
|
||||||
virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
|
|
||||||
uint32_t len) = 0;
|
|
||||||
|
|
||||||
virtual ReturnValue_t getSendSuccess(Cookie *cookie) = 0;
|
|
||||||
|
|
||||||
virtual ReturnValue_t requestReceiveMessage(Cookie *cookie) = 0;
|
|
||||||
|
|
||||||
virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
|
|
||||||
uint32_t *size) = 0;
|
|
||||||
|
|
||||||
virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address) = 0;
|
|
||||||
|
|
||||||
virtual uint32_t getAddress(Cookie *cookie) = 0;
|
|
||||||
|
|
||||||
virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter) = 0;
|
|
||||||
|
|
||||||
virtual uint32_t getParameter(Cookie *cookie) = 0;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by DHB in the GET_WRITE doGetRead().
|
||||||
|
* This function is used to receive data from the physical device
|
||||||
|
* by implementing and calling related drivers or wrapper functions.
|
||||||
|
* @param cookie
|
||||||
|
* @param buffer [out] Set reply here (by using *buffer = ...)
|
||||||
|
* @param size [out] size pointer to set (by using *size = ...).
|
||||||
|
* Set to 0 if no reply was received
|
||||||
|
* @return - @c RETURN_OK for successfull receive
|
||||||
|
* - @c NO_REPLY_RECEIVED if not reply was received. Setting size to
|
||||||
|
* 0 has the same effect
|
||||||
|
* - Everything else triggers failure event with
|
||||||
|
* returnvalue as parameter 1
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
|
||||||
|
size_t *size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DEVICECOMMUNICATIONIF_H_ */
|
#endif /* DEVICECOMMUNICATIONIF_H_ */
|
||||||
|
@ -1,52 +1,60 @@
|
|||||||
#include <framework/datapool/DataSet.h>
|
|
||||||
#include <framework/datapool/PoolVariable.h>
|
|
||||||
#include <framework/datapool/PoolVector.h>
|
|
||||||
#include <framework/devicehandlers/AcceptsDeviceResponsesIF.h>
|
|
||||||
#include <framework/devicehandlers/DeviceHandlerBase.h>
|
#include <framework/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
|
|
||||||
#include <framework/globalfunctions/CRC.h>
|
|
||||||
#include <framework/objectmanager/ObjectManager.h>
|
#include <framework/objectmanager/ObjectManager.h>
|
||||||
#include <framework/storagemanager/StorageManagerIF.h>
|
#include <framework/storagemanager/StorageManagerIF.h>
|
||||||
#include <framework/subsystem/SubsystemBase.h>
|
|
||||||
#include <framework/thermal/ThermalComponentIF.h>
|
#include <framework/thermal/ThermalComponentIF.h>
|
||||||
|
#include <framework/devicehandlers/AcceptsDeviceResponsesIF.h>
|
||||||
|
|
||||||
|
#include <framework/datapool/DataSet.h>
|
||||||
|
#include <framework/datapool/PoolVariable.h>
|
||||||
|
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
|
||||||
|
#include <framework/globalfunctions/CRC.h>
|
||||||
|
#include <framework/subsystem/SubsystemBase.h>
|
||||||
#include <framework/ipc/QueueFactory.h>
|
#include <framework/ipc/QueueFactory.h>
|
||||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
object_id_t DeviceHandlerBase::powerSwitcherId = 0;
|
object_id_t DeviceHandlerBase::powerSwitcherId = 0;
|
||||||
object_id_t DeviceHandlerBase::rawDataReceiverId = 0;
|
object_id_t DeviceHandlerBase::rawDataReceiverId = 0;
|
||||||
object_id_t DeviceHandlerBase::defaultFDIRParentId = 0;
|
object_id_t DeviceHandlerBase::defaultFDIRParentId = 0;
|
||||||
|
|
||||||
DeviceHandlerBase::DeviceHandlerBase(uint32_t ioBoardAddress,
|
DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
|
||||||
object_id_t setObjectId, uint32_t maxDeviceReplyLen,
|
object_id_t deviceCommunication, CookieIF * comCookie,
|
||||||
uint8_t setDeviceSwitch, object_id_t deviceCommunication,
|
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
|
||||||
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
|
uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance,
|
||||||
FailureIsolationBase* fdirInstance, uint32_t cmdQueueSize) :
|
size_t cmdQueueSize) :
|
||||||
SystemObject(setObjectId), rawPacket(0), rawPacketLen(0), mode(
|
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
|
||||||
MODE_OFF), submode(SUBMODE_NONE), pstStep(0), maxDeviceReplyLen(
|
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
||||||
maxDeviceReplyLen), wiretappingMode(OFF), defaultRawReceiver(0), storedRawData(
|
deviceCommunicationId(deviceCommunication), comCookie(comCookie),
|
||||||
StorageManagerIF::INVALID_ADDRESS), requestedRawTraffic(0), powerSwitcher(
|
deviceThermalStatePoolId(thermalStatePoolId),
|
||||||
NULL), IPCStore(NULL), deviceCommunicationId(deviceCommunication), communicationInterface(
|
deviceThermalRequestPoolId(thermalRequestPoolId),
|
||||||
NULL), cookie(
|
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
|
||||||
NULL), commandQueue(NULL), deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId(
|
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
|
||||||
thermalRequestPoolId), healthHelper(this, setObjectId), modeHelper(
|
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
|
||||||
this), parameterHelper(this), childTransitionFailure(RETURN_OK), ignoreMissedRepliesCount(
|
switchOffWasReported(false), actionHelper(this, nullptr),
|
||||||
0), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(
|
childTransitionDelay(5000),
|
||||||
fdirInstance == NULL), switchOffWasReported(false),executingTask(NULL), actionHelper(this, NULL), cookieInfo(), ioBoardAddress(
|
transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode(
|
||||||
ioBoardAddress), timeoutStart(0), childTransitionDelay(5000), transitionSourceMode(
|
SUBMODE_NONE), deviceSwitch(setDeviceSwitch) {
|
||||||
_MODE_POWER_DOWN), transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(
|
|
||||||
setDeviceSwitch) {
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
|
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
|
||||||
CommandMessage::MAX_MESSAGE_SIZE);
|
CommandMessage::MAX_MESSAGE_SIZE);
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
|
||||||
insertInCommandMap(RAW_COMMAND_ID);
|
insertInCommandMap(RAW_COMMAND_ID);
|
||||||
if (this->fdirInstance == NULL) {
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
|
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||||
|
if (comCookie == nullptr) {
|
||||||
|
sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex <<
|
||||||
|
std::setw(8) << std::setfill('0') << this->getObjectId() <<
|
||||||
|
std::dec << ": Do not pass nullptr as a cookie, consider "
|
||||||
|
<< std::setfill(' ') << "passing a dummy cookie instead!" <<
|
||||||
|
std::endl;
|
||||||
|
}
|
||||||
|
if (this->fdirInstance == nullptr) {
|
||||||
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
|
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
|
||||||
defaultFDIRParentId);
|
defaultFDIRParentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceHandlerBase::~DeviceHandlerBase() {
|
DeviceHandlerBase::~DeviceHandlerBase() {
|
||||||
communicationInterface->close(cookie);
|
delete comCookie;
|
||||||
if (defaultFDIRUsed) {
|
if (defaultFDIRUsed) {
|
||||||
delete fdirInstance;
|
delete fdirInstance;
|
||||||
}
|
}
|
||||||
@ -56,7 +64,7 @@ DeviceHandlerBase::~DeviceHandlerBase() {
|
|||||||
ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
|
ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
|
||||||
this->pstStep = counter;
|
this->pstStep = counter;
|
||||||
|
|
||||||
if (counter == 0) {
|
if (getComAction() == SEND_WRITE) {
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
readCommandQueue();
|
readCommandQueue();
|
||||||
doStateMachine();
|
doStateMachine();
|
||||||
@ -64,11 +72,12 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
|
|||||||
decrementDeviceReplyMap();
|
decrementDeviceReplyMap();
|
||||||
fdirInstance->checkForFailures();
|
fdirInstance->checkForFailures();
|
||||||
hkSwitcher.performOperation();
|
hkSwitcher.performOperation();
|
||||||
|
performOperationHook();
|
||||||
}
|
}
|
||||||
if (mode == MODE_OFF) {
|
if (mode == MODE_OFF) {
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
switch (getRmapAction()) {
|
switch (getComAction()) {
|
||||||
case SEND_WRITE:
|
case SEND_WRITE:
|
||||||
if ((cookieInfo.state == COOKIE_UNUSED)) {
|
if ((cookieInfo.state == COOKIE_UNUSED)) {
|
||||||
buildInternalCommand();
|
buildInternalCommand();
|
||||||
@ -91,13 +100,91 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
|
|||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t DeviceHandlerBase::initialize() {
|
||||||
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
communicationInterface = objectManager->get<DeviceCommunicationIF>(
|
||||||
|
deviceCommunicationId);
|
||||||
|
if (communicationInterface == NULL) {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = communicationInterface->initializeInterface(comCookie);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
|
if (IPCStore == NULL) {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
|
||||||
|
AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
||||||
|
|
||||||
|
if (rawReceiver == NULL) {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultRawReceiver = rawReceiver->getDeviceQueue();
|
||||||
|
|
||||||
|
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
|
||||||
|
if (powerSwitcher == NULL) {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = healthHelper.initialize();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = modeHelper.initialize();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = actionHelper.initialize(commandQueue);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = fdirInstance->initialize();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = parameterHelper.initialize();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = hkSwitcher.initialize();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fillCommandAndReplyMap();
|
||||||
|
|
||||||
|
//Set temperature target state to NON_OP.
|
||||||
|
DataSet mySet;
|
||||||
|
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet,
|
||||||
|
PoolVariableIF::VAR_WRITE);
|
||||||
|
mySet.read();
|
||||||
|
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||||
|
mySet.commit(PoolVariableIF::VALID);
|
||||||
|
|
||||||
|
return RETURN_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::decrementDeviceReplyMap() {
|
void DeviceHandlerBase::decrementDeviceReplyMap() {
|
||||||
for (std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
|
for (std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
|
||||||
deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) {
|
deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) {
|
||||||
if (iter->second.delayCycles != 0) {
|
if (iter->second.delayCycles != 0) {
|
||||||
iter->second.delayCycles--;
|
iter->second.delayCycles--;
|
||||||
if (iter->second.delayCycles == 0) {
|
if (iter->second.delayCycles == 0) {
|
||||||
if (iter->second.periodic != 0) {
|
if (iter->second.periodic) {
|
||||||
iter->second.delayCycles = iter->second.maxDelayCycles;
|
iter->second.delayCycles = iter->second.maxDelayCycles;
|
||||||
}
|
}
|
||||||
replyToReply(iter, TIMEOUT);
|
replyToReply(iter, TIMEOUT);
|
||||||
@ -256,55 +343,49 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand,
|
||||||
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
uint16_t maxDelayCycles, size_t replyLen, bool periodic,
|
||||||
uint8_t periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
||||||
//No need to check, as we may try to insert multiple times.
|
//No need to check, as we may try to insert multiple times.
|
||||||
insertInCommandMap(deviceCommand);
|
insertInCommandMap(deviceCommand);
|
||||||
if (hasDifferentReplyId) {
|
if (hasDifferentReplyId) {
|
||||||
return insertInReplyMap(replyId, maxDelayCycles, periodic);
|
return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic);
|
||||||
} else {
|
} else {
|
||||||
return insertInReplyMap(deviceCommand, maxDelayCycles, periodic);
|
return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
||||||
uint16_t maxDelayCycles, uint8_t periodic) {
|
uint16_t maxDelayCycles, size_t replyLen, bool periodic) {
|
||||||
DeviceReplyInfo info;
|
DeviceReplyInfo info;
|
||||||
info.maxDelayCycles = maxDelayCycles;
|
info.maxDelayCycles = maxDelayCycles;
|
||||||
info.periodic = periodic;
|
info.periodic = periodic;
|
||||||
info.delayCycles = 0;
|
info.delayCycles = 0;
|
||||||
|
info.replyLen = replyLen;
|
||||||
info.command = deviceCommandMap.end();
|
info.command = deviceCommandMap.end();
|
||||||
std::pair<std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator, bool> returnValue;
|
auto resultPair = deviceReplyMap.emplace(replyId, info);
|
||||||
returnValue = deviceReplyMap.insert(
|
if (resultPair.second) {
|
||||||
std::pair<DeviceCommandId_t, DeviceReplyInfo>(replyId, info));
|
|
||||||
if (returnValue.second) {
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInCommandMap(
|
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
|
||||||
DeviceCommandId_t deviceCommand) {
|
|
||||||
DeviceCommandInfo info;
|
DeviceCommandInfo info;
|
||||||
info.expectedReplies = 0;
|
info.expectedReplies = 0;
|
||||||
info.isExecuting = false;
|
info.isExecuting = false;
|
||||||
info.sendReplyTo = NO_COMMANDER;
|
info.sendReplyTo = NO_COMMANDER;
|
||||||
std::pair<std::map<DeviceCommandId_t, DeviceCommandInfo>::iterator, bool> returnValue;
|
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
|
||||||
returnValue = deviceCommandMap.insert(
|
if (resultPair.second) {
|
||||||
std::pair<DeviceCommandId_t, DeviceCommandInfo>(deviceCommand,
|
|
||||||
info));
|
|
||||||
if (returnValue.second) {
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(
|
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
|
||||||
DeviceCommandId_t deviceReply, uint16_t delayCycles,
|
uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) {
|
||||||
uint16_t maxDelayCycles, uint8_t periodic) {
|
|
||||||
std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
|
std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
|
||||||
deviceReplyMap.find(deviceReply);
|
deviceReplyMap.find(deviceReply);
|
||||||
if (iter == deviceReplyMap.end()) {
|
if (iter == deviceReplyMap.end()) {
|
||||||
@ -429,7 +510,7 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
|
|||||||
void DeviceHandlerBase::doSendWrite() {
|
void DeviceHandlerBase::doSendWrite() {
|
||||||
if (cookieInfo.state == COOKIE_WRITE_READY) {
|
if (cookieInfo.state == COOKIE_WRITE_READY) {
|
||||||
|
|
||||||
ReturnValue_t result = communicationInterface->sendMessage(cookie,
|
ReturnValue_t result = communicationInterface->sendMessage(comCookie,
|
||||||
rawPacket, rawPacketLen);
|
rawPacket, rawPacketLen);
|
||||||
|
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
@ -450,12 +531,14 @@ void DeviceHandlerBase::doGetWrite() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
ReturnValue_t result = communicationInterface->getSendSuccess(cookie);
|
ReturnValue_t result = communicationInterface->getSendSuccess(comCookie);
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
if (wiretappingMode == RAW) {
|
if (wiretappingMode == RAW) {
|
||||||
replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true);
|
replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true);
|
||||||
}
|
}
|
||||||
//We need to distinguish here, because a raw command never expects a reply. (Could be done in eRIRM, but then child implementations need to be careful.
|
|
||||||
|
//We need to distinguish here, because a raw command never expects a reply.
|
||||||
|
//(Could be done in eRIRM, but then child implementations need to be careful.
|
||||||
result = enableReplyInReplyMap(cookieInfo.pendingCommand);
|
result = enableReplyInReplyMap(cookieInfo.pendingCommand);
|
||||||
} else {
|
} else {
|
||||||
//always generate a failure event, so that FDIR knows what's up
|
//always generate a failure event, so that FDIR knows what's up
|
||||||
@ -471,7 +554,17 @@ void DeviceHandlerBase::doGetWrite() {
|
|||||||
void DeviceHandlerBase::doSendRead() {
|
void DeviceHandlerBase::doSendRead() {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
|
||||||
result = communicationInterface->requestReceiveMessage(cookie);
|
size_t requestLen = 0;
|
||||||
|
if(cookieInfo.pendingCommand != deviceCommandMap.end()) {
|
||||||
|
DeviceReplyIter iter = deviceReplyMap.find(
|
||||||
|
cookieInfo.pendingCommand->first);
|
||||||
|
if(iter != deviceReplyMap.end()) {
|
||||||
|
requestLen = iter->second.replyLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = communicationInterface->requestReceiveMessage(comCookie, requestLen);
|
||||||
|
|
||||||
if (result == RETURN_OK) {
|
if (result == RETURN_OK) {
|
||||||
cookieInfo.state = COOKIE_READ_SENT;
|
cookieInfo.state = COOKIE_READ_SENT;
|
||||||
} else {
|
} else {
|
||||||
@ -485,10 +578,10 @@ void DeviceHandlerBase::doSendRead() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::doGetRead() {
|
void DeviceHandlerBase::doGetRead() {
|
||||||
uint32_t receivedDataLen;
|
size_t receivedDataLen;
|
||||||
uint8_t *receivedData;
|
uint8_t *receivedData;
|
||||||
DeviceCommandId_t foundId = 0xFFFFFFFF;
|
DeviceCommandId_t foundId = 0xFFFFFFFF;
|
||||||
uint32_t foundLen = 0;
|
size_t foundLen = 0;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
|
||||||
if (cookieInfo.state != COOKIE_READ_SENT) {
|
if (cookieInfo.state != COOKIE_READ_SENT) {
|
||||||
@ -498,8 +591,8 @@ void DeviceHandlerBase::doGetRead() {
|
|||||||
|
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
|
|
||||||
result = communicationInterface->readReceivedMessage(cookie, &receivedData,
|
result = communicationInterface->readReceivedMessage(comCookie,
|
||||||
&receivedDataLen);
|
&receivedData, &receivedDataLen);
|
||||||
|
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result);
|
triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result);
|
||||||
@ -508,7 +601,7 @@ void DeviceHandlerBase::doGetRead() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (receivedDataLen == 0)
|
if (receivedDataLen == 0 or result == DeviceCommunicationIF::NO_REPLY_RECEIVED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (wiretappingMode == RAW) {
|
if (wiretappingMode == RAW) {
|
||||||
@ -539,6 +632,8 @@ void DeviceHandlerBase::doGetRead() {
|
|||||||
break;
|
break;
|
||||||
case IGNORE_REPLY_DATA:
|
case IGNORE_REPLY_DATA:
|
||||||
break;
|
break;
|
||||||
|
case IGNORE_FULL_PACKET:
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
//We need to wait for timeout.. don't know what command failed and who sent it.
|
//We need to wait for timeout.. don't know what command failed and who sent it.
|
||||||
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
||||||
@ -558,10 +653,10 @@ void DeviceHandlerBase::doGetRead() {
|
|||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
|
ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
|
||||||
uint8_t * *data, uint32_t * len) {
|
uint8_t * *data, uint32_t * len) {
|
||||||
uint32_t lenTmp;
|
size_t lenTmp;
|
||||||
|
|
||||||
if (IPCStore == NULL) {
|
if (IPCStore == nullptr) {
|
||||||
*data = NULL;
|
*data = nullptr;
|
||||||
*len = 0;
|
*len = 0;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -572,90 +667,10 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
|
|||||||
} else {
|
} else {
|
||||||
triggerEvent(StorageManagerIF::GET_DATA_FAILED, result,
|
triggerEvent(StorageManagerIF::GET_DATA_FAILED, result,
|
||||||
storageAddress.raw);
|
storageAddress.raw);
|
||||||
*data = NULL;
|
*data = nullptr;
|
||||||
*len = 0;
|
*len = 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::initialize() {
|
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
communicationInterface = objectManager->get<DeviceCommunicationIF>(
|
|
||||||
deviceCommunicationId);
|
|
||||||
if (communicationInterface == NULL) {
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = communicationInterface->open(&cookie, ioBoardAddress,
|
|
||||||
maxDeviceReplyLen);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
|
||||||
if (IPCStore == NULL) {
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
|
|
||||||
AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
|
||||||
|
|
||||||
if (rawReceiver == NULL) {
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultRawReceiver = rawReceiver->getDeviceQueue();
|
|
||||||
|
|
||||||
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
|
|
||||||
if (powerSwitcher == NULL) {
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = healthHelper.initialize();
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = modeHelper.initialize();
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = actionHelper.initialize(commandQueue);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = fdirInstance->initialize();
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = parameterHelper.initialize();
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = hkSwitcher.initialize();
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fillCommandAndReplyMap();
|
|
||||||
|
|
||||||
//Set temperature target state to NON_OP.
|
|
||||||
DataSet mySet;
|
|
||||||
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet,
|
|
||||||
PoolVariableIF::VAR_WRITE);
|
|
||||||
mySet.read();
|
|
||||||
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
|
||||||
mySet.commit(PoolVariableIF::VALID);
|
|
||||||
|
|
||||||
return RETURN_OK;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
|
void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
|
||||||
@ -687,8 +702,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Default child implementations
|
//Default child implementations
|
||||||
|
DeviceHandlerIF::CommunicationAction_t DeviceHandlerBase::getComAction() {
|
||||||
DeviceHandlerBase::RmapAction_t DeviceHandlerBase::getRmapAction() {
|
|
||||||
switch (pstStep) {
|
switch (pstStep) {
|
||||||
case 0:
|
case 0:
|
||||||
return SEND_WRITE;
|
return SEND_WRITE;
|
||||||
@ -727,7 +741,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
|
|||||||
|
|
||||||
if (info->delayCycles != 0) {
|
if (info->delayCycles != 0) {
|
||||||
|
|
||||||
if (info->periodic != 0) {
|
if (info->periodic) {
|
||||||
info->delayCycles = info->maxDelayCycles;
|
info->delayCycles = info->maxDelayCycles;
|
||||||
} else {
|
} else {
|
||||||
info->delayCycles = 0;
|
info->delayCycles = 0;
|
||||||
@ -748,20 +762,20 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) {
|
//ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) {
|
||||||
DeviceCommunicationIF *newCommunication = objectManager->get<
|
// DeviceCommunicationIF *newCommunication = objectManager->get<
|
||||||
DeviceCommunicationIF>(newChannelId);
|
// DeviceCommunicationIF>(newChannelId);
|
||||||
|
//
|
||||||
if (newCommunication != NULL) {
|
// if (newCommunication != NULL) {
|
||||||
ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress,
|
// ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress,
|
||||||
maxDeviceReplyLen);
|
// maxDeviceReplyLen);
|
||||||
if (result != RETURN_OK) {
|
// if (result != RETURN_OK) {
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
return RETURN_OK;
|
// return RETURN_OK;
|
||||||
}
|
// }
|
||||||
return RETURN_FAILED;
|
// return RETURN_FAILED;
|
||||||
}
|
//}
|
||||||
|
|
||||||
void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
|
void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
|
||||||
storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage);
|
storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage);
|
||||||
@ -1022,7 +1036,6 @@ void DeviceHandlerBase::replyRawReplyIfnotWiretapped(const uint8_t* data,
|
|||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
|
ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
|
||||||
CommandMessage * message) {
|
CommandMessage * message) {
|
||||||
ReturnValue_t result;
|
|
||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
case DeviceHandlerMessage::CMD_WIRETAPPING:
|
case DeviceHandlerMessage::CMD_WIRETAPPING:
|
||||||
switch (DeviceHandlerMessage::getWiretappingMode(message)) {
|
switch (DeviceHandlerMessage::getWiretappingMode(message)) {
|
||||||
@ -1044,19 +1057,19 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
|
|||||||
}
|
}
|
||||||
replyReturnvalueToCommand(RETURN_OK);
|
replyReturnvalueToCommand(RETURN_OK);
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
case DeviceHandlerMessage::CMD_SWITCH_IOBOARD:
|
// case DeviceHandlerMessage::CMD_SWITCH_IOBOARD:
|
||||||
if (mode != MODE_OFF) {
|
// if (mode != MODE_OFF) {
|
||||||
replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND);
|
// replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND);
|
||||||
} else {
|
// } else {
|
||||||
result = switchCookieChannel(
|
// result = switchCookieChannel(
|
||||||
DeviceHandlerMessage::getIoBoardObjectId(message));
|
// DeviceHandlerMessage::getIoBoardObjectId(message));
|
||||||
if (result == RETURN_OK) {
|
// if (result == RETURN_OK) {
|
||||||
replyReturnvalueToCommand(RETURN_OK);
|
// replyReturnvalueToCommand(RETURN_OK);
|
||||||
} else {
|
// } else {
|
||||||
replyReturnvalueToCommand(CANT_SWITCH_IOBOARD);
|
// replyReturnvalueToCommand(CANT_SWITCH_IO_ADDRESS);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return RETURN_OK;
|
// return RETURN_OK;
|
||||||
case DeviceHandlerMessage::CMD_RAW:
|
case DeviceHandlerMessage::CMD_RAW:
|
||||||
if ((mode != MODE_RAW)) {
|
if ((mode != MODE_RAW)) {
|
||||||
DeviceHandlerMessage::clear(message);
|
DeviceHandlerMessage::clear(message);
|
||||||
@ -1270,3 +1283,9 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
|
|||||||
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){
|
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){
|
||||||
executingTask = task_;
|
executingTask = task_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default implementations empty.
|
||||||
|
void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
|
||||||
|
object_id_t objectId, uint32_t parameter) {}
|
||||||
|
|
||||||
|
void DeviceHandlerBase::performOperationHook() {}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,8 @@
|
|||||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the Interface used to communicate with a device handler.
|
* @brief This is the Interface used to communicate with a device handler.
|
||||||
|
* @details Includes all expected return values, events and modes.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class DeviceHandlerIF {
|
class DeviceHandlerIF {
|
||||||
@ -22,22 +23,62 @@ public:
|
|||||||
*
|
*
|
||||||
* @details The mode of the device handler must not be confused with the mode the device is in.
|
* @details The mode of the device handler must not be confused with the mode the device is in.
|
||||||
* The mode of the device itself is transparent to the user but related to the mode of the handler.
|
* The mode of the device itself is transparent to the user but related to the mode of the handler.
|
||||||
|
* MODE_ON and MODE_OFF are included in hasModesIF.h
|
||||||
*/
|
*/
|
||||||
// MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted
|
|
||||||
// MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on.
|
// MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted
|
||||||
static const Mode_t MODE_NORMAL = 2; //!< The device is powered on and the device handler periodically sends commands. The commands to be sent are selected by the handler according to the submode.
|
// MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on.
|
||||||
static const Mode_t MODE_RAW = 3; //!< The device is powered on and ready to perform operations. In this mode, raw commands can be sent. The device handler will send all replies received from the command back to the commanding object.
|
//! The device is powered on and the device handler periodically sends
|
||||||
static const Mode_t MODE_ERROR_ON = 4; //!4< The device is shut down but the switch could not be turned off, so the device still is powered. In this mode, only a mode change to @c MODE_OFF can be commanded, which tries to switch off the device again.
|
//! commands. The commands to be sent are selected by the handler
|
||||||
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The device handler performs all commands to get the device in a state ready to perform commands. When this is completed, the mode changes to @c MODE_ON.
|
//! according to the submode.
|
||||||
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6; //!< This is a transitional state which can not be commanded. The device handler performs all actions and commands to get the device shut down. When the device is off, the mode changes to @c MODE_OFF.
|
static const Mode_t MODE_NORMAL = 2;
|
||||||
|
//! The device is powered on and ready to perform operations. In this mode,
|
||||||
|
//! raw commands can be sent. The device handler will send all replies
|
||||||
|
//! received from the command back to the commanding object.
|
||||||
|
static const Mode_t MODE_RAW = 3;
|
||||||
|
//! The device is shut down but the switch could not be turned off, so the
|
||||||
|
//! device still is powered. In this mode, only a mode change to @c MODE_OFF
|
||||||
|
//! can be commanded, which tries to switch off the device again.
|
||||||
|
static const Mode_t MODE_ERROR_ON = 4;
|
||||||
|
//! This is a transitional state which can not be commanded. The device
|
||||||
|
//! handler performs all commands to get the device in a state ready to
|
||||||
|
//! perform commands. When this is completed, the mode changes to @c MODE_ON.
|
||||||
|
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5;
|
||||||
|
//! This is a transitional state which can not be commanded.
|
||||||
|
//! The device handler performs all actions and commands to get the device
|
||||||
|
//! shut down. When the device is off, the mode changes to @c MODE_OFF.
|
||||||
|
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_ON to use the to on
|
||||||
|
//! transition if available.
|
||||||
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
|
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_RAW to use the to raw
|
||||||
|
//! transition if available.
|
||||||
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
|
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal
|
||||||
|
//! transition if available.
|
||||||
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
|
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
|
||||||
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1; //!< This is a transitional state which can not be commanded. The device is shut down and ready to be switched off. After the command to set the switch off has been sent, the mode changes to @c MODE_WAIT_OFF
|
//! This is a transitional state which can not be commanded.
|
||||||
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2; //!< This is a transitional state which can not be commanded. The device will be switched on in this state. After the command to set the switch on has been sent, the mode changes to @c MODE_WAIT_ON
|
//! The device is shut down and ready to be switched off.
|
||||||
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3; //!< This is a transitional state which can not be commanded. The switch has been commanded off and the handler waits for it to be off. When the switch is off, the mode changes to @c MODE_OFF.
|
//! After the command to set the switch off has been sent,
|
||||||
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4; //!< This is a transitional state which can not be commanded. The switch has been commanded on and the handler waits for it to be on. When the switch is on, the mode changes to @c MODE_TO_ON.
|
//! the mode changes to @c MODE_WAIT_OFF
|
||||||
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The switch has been commanded off and is off now. This state is only to do an RMAP cycle once more where the doSendRead() function will set the mode to MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board
|
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1;
|
||||||
|
//! This is a transitional state which can not be commanded. The device
|
||||||
|
//! will be switched on in this state. After the command to set the switch
|
||||||
|
//! on has been sent, the mode changes to @c MODE_WAIT_ON.
|
||||||
|
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch has
|
||||||
|
//! been commanded off and the handler waits for it to be off.
|
||||||
|
//! When the switch is off, the mode changes to @c MODE_OFF.
|
||||||
|
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch
|
||||||
|
//! has been commanded on and the handler waits for it to be on.
|
||||||
|
//! When the switch is on, the mode changes to @c MODE_TO_ON.
|
||||||
|
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch has
|
||||||
|
//! been commanded off and is off now. This state is only to do an RMAP
|
||||||
|
//! cycle once more where the doSendRead() function will set the mode to
|
||||||
|
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
|
||||||
|
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
|
||||||
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW);
|
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW);
|
||||||
@ -53,11 +94,13 @@ public:
|
|||||||
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH);
|
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH);
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
||||||
static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0);
|
|
||||||
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1);
|
// Standard codes used when building commands.
|
||||||
static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2);
|
static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If the command size is 0. Checked in DHB
|
||||||
|
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); //!< Command ID not in commandMap. Checked in DHB
|
||||||
|
static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); //!< Command was already executed. Checked in DHB
|
||||||
static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3);
|
static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3);
|
||||||
static const ReturnValue_t CANT_SWITCH_IOBOARD = MAKE_RETURN_CODE(0xA4);
|
static const ReturnValue_t CANT_SWITCH_ADDRESS = MAKE_RETURN_CODE(0xA4);
|
||||||
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
|
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
|
||||||
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6);
|
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6);
|
||||||
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7);
|
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7);
|
||||||
@ -65,50 +108,42 @@ public:
|
|||||||
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
|
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
|
||||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
|
||||||
|
|
||||||
//standard codes used in scan for reply
|
// Standard codes used in scanForReply
|
||||||
// static const ReturnValue_t TOO_SHORT = MAKE_RETURN_CODE(0xB1);
|
static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB0);
|
||||||
static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB2);
|
static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB1);
|
||||||
static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB3);
|
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB2);
|
||||||
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB4);
|
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB3);
|
||||||
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB5);
|
|
||||||
|
|
||||||
//standard codes used in interpret device reply
|
// Standard codes used in interpretDeviceReply
|
||||||
static const ReturnValue_t DEVICE_DID_NOT_EXECUTE = MAKE_RETURN_CODE(0xC1); //the device reported, that it did not execute the command
|
static const ReturnValue_t DEVICE_DID_NOT_EXECUTE = MAKE_RETURN_CODE(0xC0); //the device reported, that it did not execute the command
|
||||||
static const ReturnValue_t DEVICE_REPORTED_ERROR = MAKE_RETURN_CODE(0xC2);
|
static const ReturnValue_t DEVICE_REPORTED_ERROR = MAKE_RETURN_CODE(0xC1);
|
||||||
static const ReturnValue_t UNKNOW_DEVICE_REPLY = MAKE_RETURN_CODE(0xC3); //the deviceCommandId reported by scanforReply is unknown
|
static const ReturnValue_t UNKNOW_DEVICE_REPLY = MAKE_RETURN_CODE(0xC2); //the deviceCommandId reported by scanforReply is unknown
|
||||||
static const ReturnValue_t DEVICE_REPLY_INVALID = MAKE_RETURN_CODE(0xC4); //syntax etc is correct but still not ok, eg parameters where none are expected
|
static const ReturnValue_t DEVICE_REPLY_INVALID = MAKE_RETURN_CODE(0xC3); //syntax etc is correct but still not ok, eg parameters where none are expected
|
||||||
|
|
||||||
//Standard codes used in buildCommandFromCommand
|
// Standard codes used in buildCommandFromCommand
|
||||||
static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE(
|
static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE(0xD0);
|
||||||
0xD0);
|
static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS = MAKE_RETURN_CODE(0xD1);
|
||||||
static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS =
|
|
||||||
MAKE_RETURN_CODE(0xD1);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RMAP Action that will be executed.
|
* Communication action that will be executed.
|
||||||
*
|
*
|
||||||
* This is used by the child class to tell the base class what to do.
|
* This is used by the child class to tell the base class what to do.
|
||||||
*/
|
*/
|
||||||
enum RmapAction_t {
|
enum CommunicationAction_t: uint8_t {
|
||||||
SEND_WRITE,//!< RMAP send write
|
SEND_WRITE,//!< Send write
|
||||||
GET_WRITE, //!< RMAP get write
|
GET_WRITE, //!< Get write
|
||||||
SEND_READ, //!< RMAP send read
|
SEND_READ, //!< Send read
|
||||||
GET_READ, //!< RMAP get read
|
GET_READ, //!< Get read
|
||||||
NOTHING //!< Do nothing.
|
NOTHING //!< Do nothing.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Destructor
|
* Default Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~DeviceHandlerIF() {
|
virtual ~DeviceHandlerIF() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This MessageQueue is used to command the device handler.
|
* This MessageQueue is used to command the device handler.
|
||||||
*
|
|
||||||
* To command a device handler, a DeviceHandlerCommandMessage can be sent to this Queue.
|
|
||||||
* The handler replies with a DeviceHandlerCommandMessage containing the DeviceHandlerCommand_t reply.
|
|
||||||
*
|
|
||||||
* @return the id of the MessageQueue
|
* @return the id of the MessageQueue
|
||||||
*/
|
*/
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
@ -16,6 +16,5 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime,
|
|||||||
handler->setTaskIF(executingTask);
|
handler->setTaskIF(executingTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedSequenceSlot::~FixedSequenceSlot() {
|
FixedSequenceSlot::~FixedSequenceSlot() {}
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -13,35 +13,47 @@
|
|||||||
class PeriodicTaskIF;
|
class PeriodicTaskIF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This class is the representation of a single polling sequence table entry.
|
* @brief This class is the representation of a single polling sequence table entry.
|
||||||
*
|
*
|
||||||
* \details The PollingSlot class is the representation of a single polling sequence table entry.
|
* @details The PollingSlot class is the representation of a single polling
|
||||||
|
* sequence table entry.
|
||||||
*/
|
*/
|
||||||
class FixedSequenceSlot {
|
class FixedSequenceSlot {
|
||||||
public:
|
public:
|
||||||
FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, int8_t setSequenceId, PeriodicTaskIF* executingTask );
|
FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs,
|
||||||
|
int8_t setSequenceId, PeriodicTaskIF* executingTask );
|
||||||
virtual ~FixedSequenceSlot();
|
virtual ~FixedSequenceSlot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief \c handler identifies which device handler object is executed in this slot.
|
* @brief Handler identifies which device handler object is executed in this slot.
|
||||||
*/
|
*/
|
||||||
ExecutableObjectIF* handler;
|
ExecutableObjectIF* handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This attribute defines when a device handler object is executed.
|
* @brief This attribute defines when a device handler object is executed.
|
||||||
*
|
*
|
||||||
* \details The pollingTime attribute identifies the time the handler is executed in ms. It must be
|
* @details The pollingTime attribute identifies the time the handler is executed in ms.
|
||||||
* smaller than the period length of the polling sequence, what is ensured by automated calculation
|
* It must be smaller than the period length of the polling sequence.
|
||||||
* from a database.
|
|
||||||
*/
|
*/
|
||||||
uint32_t pollingTimeMs;
|
uint32_t pollingTimeMs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This value defines the type of device communication.
|
* @brief This value defines the type of device communication.
|
||||||
*
|
*
|
||||||
* \details The state of this value decides what communication routine is called in the PST executable or the device handler object.
|
* @details The state of this value decides what communication routine is
|
||||||
|
* called in the PST executable or the device handler object.
|
||||||
*/
|
*/
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Operator overload for the comparison operator to
|
||||||
|
* allow sorting by polling time.
|
||||||
|
* @param fixedSequenceSlot
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const {
|
||||||
|
return pollingTimeMs < fixedSequenceSlot.pollingTimeMs;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,17 +7,12 @@ FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
FixedSlotSequence::~FixedSlotSequence() {
|
FixedSlotSequence::~FixedSlotSequence() {
|
||||||
std::list<FixedSequenceSlot*>::iterator slotIt;
|
// Call the destructor on each list entry.
|
||||||
//Iterate through slotList and delete all entries.
|
slotList.clear();
|
||||||
slotIt = this->slotList.begin();
|
|
||||||
while (slotIt != this->slotList.end()) {
|
|
||||||
delete (*slotIt);
|
|
||||||
slotIt++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedSlotSequence::executeAndAdvance() {
|
void FixedSlotSequence::executeAndAdvance() {
|
||||||
(*this->current)->handler->performOperation((*this->current)->opcode);
|
current->handler->performOperation(current->opcode);
|
||||||
// if (returnValue != RETURN_OK) {
|
// if (returnValue != RETURN_OK) {
|
||||||
// this->sendErrorMessage( returnValue );
|
// this->sendErrorMessage( returnValue );
|
||||||
// }
|
// }
|
||||||
@ -31,53 +26,50 @@ void FixedSlotSequence::executeAndAdvance() {
|
|||||||
|
|
||||||
uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
|
uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
|
||||||
uint32_t oldTime;
|
uint32_t oldTime;
|
||||||
std::list<FixedSequenceSlot*>::iterator it;
|
SlotListIter slotListIter = current;
|
||||||
it = current;
|
|
||||||
// Get the pollingTimeMs of the current slot object.
|
// Get the pollingTimeMs of the current slot object.
|
||||||
oldTime = (*it)->pollingTimeMs;
|
oldTime = slotListIter->pollingTimeMs;
|
||||||
// Advance to the next object.
|
// Advance to the next object.
|
||||||
it++;
|
slotListIter++;
|
||||||
// Find the next interval which is not 0.
|
// Find the next interval which is not 0.
|
||||||
while (it != slotList.end()) {
|
while (slotListIter != slotList.end()) {
|
||||||
if (oldTime != (*it)->pollingTimeMs) {
|
if (oldTime != slotListIter->pollingTimeMs) {
|
||||||
return (*it)->pollingTimeMs - oldTime;
|
return slotListIter->pollingTimeMs - oldTime;
|
||||||
} else {
|
} else {
|
||||||
it++;
|
slotListIter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the list end is reached (this is definitely an interval != 0),
|
// If the list end is reached (this is definitely an interval != 0),
|
||||||
// the interval is calculated by subtracting the remaining time of the PST
|
// the interval is calculated by subtracting the remaining time of the PST
|
||||||
// and adding the start time of the first handler in the list.
|
// and adding the start time of the first handler in the list.
|
||||||
it = slotList.begin();
|
slotListIter = slotList.begin();
|
||||||
return lengthMs - oldTime + (*it)->pollingTimeMs;
|
return lengthMs - oldTime + slotListIter->pollingTimeMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
|
uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
|
||||||
uint32_t currentTime;
|
uint32_t currentTime;
|
||||||
std::list<FixedSequenceSlot*>::iterator it;
|
SlotListIter slotListIter = current;
|
||||||
it = current;
|
|
||||||
// Get the pollingTimeMs of the current slot object.
|
// Get the pollingTimeMs of the current slot object.
|
||||||
currentTime = (*it)->pollingTimeMs;
|
currentTime = slotListIter->pollingTimeMs;
|
||||||
|
|
||||||
//if it is the first slot, calculate difference to last slot
|
//if it is the first slot, calculate difference to last slot
|
||||||
if (it == slotList.begin()){
|
if (slotListIter == slotList.begin()){
|
||||||
return lengthMs - (*(--slotList.end()))->pollingTimeMs + currentTime;
|
return lengthMs - (--slotList.end())->pollingTimeMs + currentTime;
|
||||||
}
|
}
|
||||||
// get previous slot
|
// get previous slot
|
||||||
it--;
|
slotListIter--;
|
||||||
|
|
||||||
return currentTime - (*it)->pollingTimeMs;
|
return currentTime - slotListIter->pollingTimeMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FixedSlotSequence::slotFollowsImmediately() {
|
bool FixedSlotSequence::slotFollowsImmediately() {
|
||||||
uint32_t currentTime = (*current)->pollingTimeMs;
|
uint32_t currentTime = current->pollingTimeMs;
|
||||||
std::list<FixedSequenceSlot*>::iterator it;
|
SlotListIter fixedSequenceIter = this->current;
|
||||||
it = this->current;
|
|
||||||
// Get the pollingTimeMs of the current slot object.
|
// Get the pollingTimeMs of the current slot object.
|
||||||
if (it == slotList.begin())
|
if (fixedSequenceIter == slotList.begin())
|
||||||
return false;
|
return false;
|
||||||
it--;
|
fixedSequenceIter--;
|
||||||
if ((*it)->pollingTimeMs == currentTime) {
|
if (fixedSequenceIter->pollingTimeMs == currentTime) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -93,26 +85,30 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
|
|||||||
sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl;
|
sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto slotIt = slotList.begin();
|
auto slotIt = slotList.begin();
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
uint32_t time = 0;
|
uint32_t time = 0;
|
||||||
while (slotIt != slotList.end()) {
|
while (slotIt != slotList.end()) {
|
||||||
if ((*slotIt)->handler == NULL) {
|
if (slotIt->handler == nullptr) {
|
||||||
sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!"
|
sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
count++;
|
count++;
|
||||||
} else if ((*slotIt)->pollingTimeMs < time) {
|
} else if (slotIt->pollingTimeMs < time) {
|
||||||
sif::error << "FixedSlotSequence::initialize: Time: "
|
sif::error << "FixedSlotSequence::initialize: Time: "
|
||||||
<< (*slotIt)->pollingTimeMs
|
<< slotIt->pollingTimeMs
|
||||||
<< " is smaller than previous with " << time << std::endl;
|
<< " is smaller than previous with " << time << std::endl;
|
||||||
count++;
|
count++;
|
||||||
} else {
|
} else {
|
||||||
//All ok, print slot.
|
// All ok, print slot.
|
||||||
// (*slotIt)->print();
|
//info << "Current slot polling time: " << std::endl;
|
||||||
|
//info << std::dec << slotIt->pollingTimeMs << std::endl;
|
||||||
}
|
}
|
||||||
time = (*slotIt)->pollingTimeMs;
|
time = slotIt->pollingTimeMs;
|
||||||
slotIt++;
|
slotIt++;
|
||||||
}
|
}
|
||||||
|
//info << "Number of elements in slot list: "
|
||||||
|
// << slotList.size() << std::endl;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -121,8 +117,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
|
|||||||
|
|
||||||
void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
|
void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
|
||||||
int8_t executionStep, PeriodicTaskIF* executingTask) {
|
int8_t executionStep, PeriodicTaskIF* executingTask) {
|
||||||
this->slotList.push_back(
|
this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep,
|
||||||
new FixedSequenceSlot(componentId, slotTimeMs, executionStep,
|
|
||||||
executingTask));
|
executingTask));
|
||||||
this->current = slotList.begin();
|
this->current = slotList.begin();
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef FIXEDSLOTSEQUENCE_H_
|
#ifndef FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
|
||||||
#define FIXEDSLOTSEQUENCE_H_
|
#define FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
|
||||||
|
|
||||||
#include <framework/devicehandlers/FixedSequenceSlot.h>
|
#include <framework/devicehandlers/FixedSequenceSlot.h>
|
||||||
#include <framework/objectmanager/SystemObject.h>
|
#include <framework/objectmanager/SystemObject.h>
|
||||||
#include <list>
|
#include <set>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class is the representation of a Polling Sequence Table in software.
|
* @brief This class is the representation of a Polling Sequence Table in software.
|
||||||
@ -24,30 +24,39 @@
|
|||||||
*/
|
*/
|
||||||
class FixedSlotSequence {
|
class FixedSlotSequence {
|
||||||
public:
|
public:
|
||||||
|
using SlotList = std::multiset<FixedSequenceSlot>;
|
||||||
|
using SlotListIter = std::multiset<FixedSequenceSlot>::iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The constructor of the FixedSlotSequence object.
|
* @brief The constructor of the FixedSlotSequence object.
|
||||||
*
|
*
|
||||||
* \details The constructor takes two arguments, the period length and the init function.
|
* @details The constructor takes two arguments, the period length and the init function.
|
||||||
*
|
*
|
||||||
* \param setLength The period length, expressed in ms.
|
* @param setLength The period length, expressed in ms.
|
||||||
*/
|
*/
|
||||||
FixedSlotSequence(uint32_t setLengthMs);
|
FixedSlotSequence(uint32_t setLengthMs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The destructor of the FixedSlotSequence object.
|
* @brief The destructor of the FixedSlotSequence object.
|
||||||
*
|
*
|
||||||
* \details The destructor frees all allocated memory by iterating through the slotList
|
* @details The destructor frees all allocated memory by iterating through the slotList
|
||||||
* and deleting all allocated resources.
|
* and deleting all allocated resources.
|
||||||
*/
|
*/
|
||||||
virtual ~FixedSlotSequence();
|
virtual ~FixedSlotSequence();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This is a method to add an PollingSlot object to slotList.
|
* @brief This is a method to add an PollingSlot object to slotList.
|
||||||
*
|
*
|
||||||
* \details Here, a polling slot object is added to the slot list. It is appended
|
* @details Here, a polling slot object is added to the slot list. It is appended
|
||||||
* to the end of the list. The list is currently NOT reordered.
|
* to the end of the list. The list is currently NOT reordered.
|
||||||
* Afterwards, the iterator current is set to the beginning of the list.
|
* Afterwards, the iterator current is set to the beginning of the list.
|
||||||
|
* @param Object ID of the object to add
|
||||||
|
* @param setTime Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask
|
||||||
|
* will be called inside the slot period.
|
||||||
|
* @param setSequenceId ID which can be used to distinguish
|
||||||
|
* different task operations
|
||||||
|
* @param
|
||||||
|
* @param
|
||||||
*/
|
*/
|
||||||
void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId,
|
void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId,
|
||||||
PeriodicTaskIF* executingTask);
|
PeriodicTaskIF* executingTask);
|
||||||
@ -61,47 +70,59 @@ public:
|
|||||||
bool slotFollowsImmediately();
|
bool slotFollowsImmediately();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This method returns the time until the next software component is invoked.
|
* @brief This method returns the time until the next software
|
||||||
|
* component is invoked.
|
||||||
*
|
*
|
||||||
* \details This method is vitally important for the operation of the PST. By fetching the polling time
|
* @details
|
||||||
* of the current slot and that of the next one (or the first one, if the list end is reached)
|
* This method is vitally important for the operation of the PST.
|
||||||
* it calculates and returns the interval in milliseconds within which the handler execution
|
* By fetching the polling time of the current slot and that of the
|
||||||
* shall take place. If the next slot has the same time as the current one, it is ignored until
|
* next one (or the first one, if the list end is reached)
|
||||||
* a slot with different time or the end of the PST is found.
|
* it calculates and returns the interval in milliseconds within
|
||||||
|
* which the handler execution shall take place.
|
||||||
|
* If the next slot has the same time as the current one, it is ignored
|
||||||
|
* until a slot with different time or the end of the PST is found.
|
||||||
*/
|
*/
|
||||||
uint32_t getIntervalToNextSlotMs();
|
uint32_t getIntervalToNextSlotMs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This method returns the time difference between the current slot and the previous slot
|
* @brief This method returns the time difference between the current
|
||||||
|
* slot and the previous slot
|
||||||
*
|
*
|
||||||
* \details This method is vitally important for the operation of the PST. By fetching the polling time
|
* @details
|
||||||
* of the current slot and that of the prevous one (or the last one, if the slot is the first one)
|
* This method is vitally important for the operation of the PST.
|
||||||
* it calculates and returns the interval in milliseconds that the handler execution shall be delayed.
|
* By fetching the polling time of the current slot and that of the previous
|
||||||
|
* one (or the last one, if the slot is the first one) it calculates and
|
||||||
|
* returns the interval in milliseconds that the handler execution shall
|
||||||
|
* be delayed.
|
||||||
*/
|
*/
|
||||||
uint32_t getIntervalToPreviousSlotMs();
|
uint32_t getIntervalToPreviousSlotMs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This method returns the length of this FixedSlotSequence instance.
|
* @brief This method returns the length of this FixedSlotSequence instance.
|
||||||
*/
|
*/
|
||||||
uint32_t getLengthMs() const;
|
uint32_t getLengthMs() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The method to execute the device handler entered in the current OPUSPollingSlot object.
|
* @brief The method to execute the device handler entered in the current
|
||||||
|
* PollingSlot object.
|
||||||
*
|
*
|
||||||
* \details Within this method the device handler object to be executed is chosen by looking up the
|
* @details
|
||||||
* handler address of the current slot in the handlerMap. Either the device handler's
|
* Within this method the device handler object to be executed is chosen by
|
||||||
* talkToInterface or its listenToInterface method is invoked, depending on the isTalking flag
|
* looking up the handler address of the current slot in the handlerMap.
|
||||||
* of the polling slot. After execution the iterator current is increased or, by reaching the
|
* Either the device handler's talkToInterface or its listenToInterface
|
||||||
|
* method is invoked, depending on the isTalking flag of the polling slot.
|
||||||
|
* After execution the iterator current is increased or, by reaching the
|
||||||
* end of slotList, reset to the beginning.
|
* end of slotList, reset to the beginning.
|
||||||
*/
|
*/
|
||||||
void executeAndAdvance();
|
void executeAndAdvance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief An iterator that indicates the current polling slot to execute.
|
* @brief An iterator that indicates the current polling slot to execute.
|
||||||
*
|
*
|
||||||
* \details This is an iterator for slotList and always points to the polling slot which is executed next.
|
* @details This is an iterator for slotList and always points to the
|
||||||
|
* polling slot which is executed next.
|
||||||
*/
|
*/
|
||||||
std::list<FixedSequenceSlot*>::iterator current;
|
SlotListIter current;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate through slotList and check successful creation.
|
* Iterate through slotList and check successful creation.
|
||||||
@ -109,18 +130,21 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t checkSequence() const;
|
ReturnValue_t checkSequence() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This list contains all OPUSPollingSlot objects, defining order and execution time of the
|
* @brief This list contains all PollingSlot objects, defining order and
|
||||||
* device handler objects.
|
* execution time of the device handler objects.
|
||||||
*
|
*
|
||||||
* \details The slot list is a std:list object that contains all created OPUSPollingSlot instances.
|
* @details
|
||||||
* They are NOT ordered automatically, so by adding entries, the correct order needs to be ensured.
|
* The slot list is a std:list object that contains all created
|
||||||
* By iterating through this list the polling sequence is executed. Two entries with identical
|
* PollingSlot instances. They are NOT ordered automatically, so by
|
||||||
* polling times are executed immediately one after another.
|
* adding entries, the correct order needs to be ensured. By iterating
|
||||||
|
* through this list the polling sequence is executed. Two entries with
|
||||||
|
* identical polling times are executed immediately one after another.
|
||||||
*/
|
*/
|
||||||
std::list<FixedSequenceSlot*> slotList;
|
SlotList slotList;
|
||||||
|
|
||||||
uint32_t lengthMs;
|
uint32_t lengthMs;
|
||||||
};
|
};
|
||||||
|
61
globalfunctions/arrayprinter.cpp
Normal file
61
globalfunctions/arrayprinter.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include <framework/globalfunctions/arrayprinter.h>
|
||||||
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
void arrayprinter::print(const uint8_t *data, size_t size, OutputType type,
|
||||||
|
bool printInfo, size_t maxCharPerLine) {
|
||||||
|
if(printInfo) {
|
||||||
|
sif::info << "Printing data with size " << size << ": ";
|
||||||
|
}
|
||||||
|
sif::info << "[";
|
||||||
|
if(type == OutputType::HEX) {
|
||||||
|
arrayprinter::printHex(data, size, maxCharPerLine);
|
||||||
|
}
|
||||||
|
else if (type == OutputType::DEC) {
|
||||||
|
arrayprinter::printDec(data, size, maxCharPerLine);
|
||||||
|
}
|
||||||
|
else if(type == OutputType::BIN) {
|
||||||
|
arrayprinter::printBin(data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void arrayprinter::printHex(const uint8_t *data, size_t size,
|
||||||
|
size_t maxCharPerLine) {
|
||||||
|
sif::info << std::hex;
|
||||||
|
for(size_t i = 0; i < size; i++) {
|
||||||
|
sif::info << "0x" << static_cast<int>(data[i]);
|
||||||
|
if(i < size - 1){
|
||||||
|
sif::info << " , ";
|
||||||
|
if(i > 0 and i % maxCharPerLine == 0) {
|
||||||
|
sif::info << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
sif::info << std::dec;
|
||||||
|
sif::info << "]" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void arrayprinter::printDec(const uint8_t *data, size_t size,
|
||||||
|
size_t maxCharPerLine) {
|
||||||
|
sif::info << std::dec;
|
||||||
|
for(size_t i = 0; i < size; i++) {
|
||||||
|
sif::info << static_cast<int>(data[i]);
|
||||||
|
if(i < size - 1){
|
||||||
|
sif::info << " , ";
|
||||||
|
if(i > 0 and i % maxCharPerLine == 0) {
|
||||||
|
sif::info << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sif::info << "]" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void arrayprinter::printBin(const uint8_t *data, size_t size) {
|
||||||
|
sif::info << "\n" << std::flush;
|
||||||
|
for(size_t i = 0; i < size; i++) {
|
||||||
|
sif::info << "Byte " << i + 1 << ": 0b"<<
|
||||||
|
std::bitset<8>(data[i]) << ",\n" << std::flush;
|
||||||
|
}
|
||||||
|
sif::info << "]" << std::endl;
|
||||||
|
}
|
20
globalfunctions/arrayprinter.h
Normal file
20
globalfunctions/arrayprinter.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_
|
||||||
|
#define FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
enum class OutputType {
|
||||||
|
DEC,
|
||||||
|
HEX,
|
||||||
|
BIN
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace arrayprinter {
|
||||||
|
void print(const uint8_t* data, size_t size, OutputType type = OutputType::HEX,
|
||||||
|
bool printInfo = true, size_t maxCharPerLine = 12);
|
||||||
|
void printHex(const uint8_t* data, size_t size, size_t maxCharPerLine = 12);
|
||||||
|
void printDec(const uint8_t* data, size_t size, size_t maxCharPerLine = 12);
|
||||||
|
void printBin(const uint8_t* data, size_t size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ */
|
@ -18,8 +18,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
static QueueFactory* instance();
|
static QueueFactory* instance();
|
||||||
|
|
||||||
MessageQueueIF* createMessageQueue(uint32_t message_depth = 3,
|
MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3,
|
||||||
uint32_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE);
|
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
|
|
||||||
void deleteMessageQueue(MessageQueueIF* queue);
|
void deleteMessageQueue(MessageQueueIF* queue);
|
||||||
private:
|
private:
|
||||||
|
@ -152,7 +152,7 @@ void MemoryHelper::handleMemoryLoad(CommandMessage* message) {
|
|||||||
ipcAddress = MemoryMessage::getStoreID(message);
|
ipcAddress = MemoryMessage::getStoreID(message);
|
||||||
const uint8_t* p_data = NULL;
|
const uint8_t* p_data = NULL;
|
||||||
uint8_t* dataPointer = NULL;
|
uint8_t* dataPointer = NULL;
|
||||||
uint32_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t returnCode = ipcStore->getData(ipcAddress, &p_data, &size);
|
ReturnValue_t returnCode = ipcStore->getData(ipcAddress, &p_data, &size);
|
||||||
if (returnCode == RETURN_OK) {
|
if (returnCode == RETURN_OK) {
|
||||||
returnCode = workOnThis->handleMemoryLoad(address, p_data, size,
|
returnCode = workOnThis->handleMemoryLoad(address, p_data, size,
|
||||||
|
@ -16,6 +16,10 @@ ReturnValue_t ModeMessage::setModeMessage(CommandMessage* message, Command_t com
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t ModeMessage::getCantReachModeReason(const CommandMessage* message) {
|
||||||
|
return message->getParameter();
|
||||||
|
}
|
||||||
|
|
||||||
void ModeMessage::clear(CommandMessage* message) {
|
void ModeMessage::clear(CommandMessage* message) {
|
||||||
message->setCommand(CommandMessage::CMD_NONE);
|
message->setCommand(CommandMessage::CMD_NONE);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ public:
|
|||||||
static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);//!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);//!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
||||||
static const Command_t REPLY_MODE_INFO = MAKE_COMMAND_ID(0x03); //!> Unrequested info about the current mode (used for composites to inform their container of a changed mode)
|
static const Command_t REPLY_MODE_INFO = MAKE_COMMAND_ID(0x03); //!> Unrequested info about the current mode (used for composites to inform their container of a changed mode)
|
||||||
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(0x04); //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(0x04); //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
||||||
//SHOULDDO is there a way we can transmit a returnvalue when responding that the mode is wrong, so we can give a nice failure code when commanded by PUS?
|
|
||||||
static const Command_t REPLY_WRONG_MODE_REPLY = MAKE_COMMAND_ID(0x05);//!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded and a transition started but was aborted; the parameters contain the mode that was reached
|
static const Command_t REPLY_WRONG_MODE_REPLY = MAKE_COMMAND_ID(0x05);//!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded and a transition started but was aborted; the parameters contain the mode that was reached
|
||||||
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(0x06);//!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(0x06);//!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
||||||
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(0x07);//!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(0x07);//!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
||||||
@ -34,6 +33,7 @@ public:
|
|||||||
static ReturnValue_t setModeMessage(CommandMessage* message,
|
static ReturnValue_t setModeMessage(CommandMessage* message,
|
||||||
Command_t command, Mode_t mode, Submode_t submode);
|
Command_t command, Mode_t mode, Submode_t submode);
|
||||||
static void cantReachMode(CommandMessage* message, ReturnValue_t reason);
|
static void cantReachMode(CommandMessage* message, ReturnValue_t reason);
|
||||||
|
static ReturnValue_t getCantReachModeReason(const CommandMessage* message);
|
||||||
static void clear(CommandMessage* message);
|
static void clear(CommandMessage* message);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,38 +1,40 @@
|
|||||||
#include <framework/objectmanager/ObjectManager.h>
|
#include <framework/objectmanager/ObjectManager.h>
|
||||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
#include <iomanip>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
ObjectManager::ObjectManager( void (*setProducer)() ) : produceObjects(setProducer) {
|
ObjectManager::ObjectManager( void (*setProducer)() ):
|
||||||
|
produceObjects(setProducer) {
|
||||||
//There's nothing special to do in the constructor.
|
//There's nothing special to do in the constructor.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectManager::~ObjectManager() {
|
ObjectManager::~ObjectManager() {
|
||||||
std::map<object_id_t, SystemObjectIF*>::iterator it;
|
for (auto const& iter : objectList) {
|
||||||
for (it = this->objectList.begin(); it != this->objectList.end(); it++) {
|
delete iter.second;
|
||||||
delete it->second;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) {
|
ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) {
|
||||||
bool insert_return = this->objectList.insert( std::pair< object_id_t, SystemObjectIF* >( id, object ) ).second;
|
auto returnPair = objectList.emplace(id, object);
|
||||||
if (insert_return == true) {
|
if (returnPair.second) {
|
||||||
// sif::debug << "ObjectManager::insert: Object " << std::hex
|
// sif::debug << "ObjectManager::insert: Object " << std::hex
|
||||||
// << (int)id << std::dec << " inserted." << std::endl;
|
// << (int)id << std::dec << " inserted." << std::endl;
|
||||||
return this->RETURN_OK;
|
return this->RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
sif::error << "ObjectManager::insert: Object id " << std::hex
|
sif::error << "ObjectManager::insert: Object id " << std::hex
|
||||||
<< (int)id << std::dec << " is already in use!" << std::endl;
|
<< (int)id << std::dec << " is already in use!" << std::endl;
|
||||||
exit(0); //This is very severe and difficult to handle in other places.
|
sif::error << "Terminating program." << std::endl;
|
||||||
return this->INSERTION_FAILED;
|
//This is very severe and difficult to handle in other places.
|
||||||
|
std::exit(INSERTION_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ObjectManager::remove( object_id_t id ) {
|
ReturnValue_t ObjectManager::remove( object_id_t id ) {
|
||||||
if ( this->getSystemObject(id) != NULL ) {
|
if ( this->getSystemObject(id) != NULL ) {
|
||||||
this->objectList.erase( id );
|
this->objectList.erase( id );
|
||||||
sif::debug << "ObjectManager::removeObject: Object " << std::hex
|
//sif::debug << "ObjectManager::removeObject: Object " << std::hex
|
||||||
<< (int)id << std::dec << " removed." << std::endl;
|
// << (int)id << std::dec << " removed." << std::endl;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
} else {
|
} else {
|
||||||
sif::error << "ObjectManager::removeObject: Requested object "
|
sif::error << "ObjectManager::removeObject: Requested object "
|
||||||
@ -44,61 +46,63 @@ ReturnValue_t ObjectManager::remove( object_id_t id ) {
|
|||||||
|
|
||||||
|
|
||||||
SystemObjectIF* ObjectManager::getSystemObject( object_id_t id ) {
|
SystemObjectIF* ObjectManager::getSystemObject( object_id_t id ) {
|
||||||
std::map<object_id_t, SystemObjectIF*>::iterator it = this->objectList.find( id );
|
auto listIter = this->objectList.find( id );
|
||||||
if (it == this->objectList.end() ) {
|
if (listIter == this->objectList.end() ) {
|
||||||
//Changed for testing different method.
|
return nullptr;
|
||||||
// SystemObjectIF* object = this->produceObjects( id );
|
|
||||||
// return object;
|
|
||||||
return NULL;
|
|
||||||
} else {
|
} else {
|
||||||
return it->second;
|
return listIter->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectManager::ObjectManager( ) : produceObjects(NULL) {
|
ObjectManager::ObjectManager() : produceObjects(nullptr) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::initialize() {
|
void ObjectManager::initialize() {
|
||||||
|
if(produceObjects == nullptr) {
|
||||||
|
sif::error << "ObjectManager::initialize: Passed produceObjects "
|
||||||
|
"functions is nullptr!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
this->produceObjects();
|
this->produceObjects();
|
||||||
ReturnValue_t return_value = RETURN_FAILED;
|
ReturnValue_t result = RETURN_FAILED;
|
||||||
uint32_t error_count = 0;
|
uint32_t errorCount = 0;
|
||||||
for (std::map<object_id_t, SystemObjectIF*>::iterator it = this->objectList.begin(); it != objectList.end(); it++ ) {
|
for (auto const& it : objectList) {
|
||||||
return_value = it->second->initialize();
|
result = it.second->initialize();
|
||||||
if ( return_value != RETURN_OK ) {
|
if ( result != RETURN_OK ) {
|
||||||
object_id_t var = it->first;
|
object_id_t var = it.first;
|
||||||
sif::error << "Object " << std::hex << (int) var
|
sif::error << "ObjectManager::initialize: Object 0x" << std::hex <<
|
||||||
<< " failed to initialize with code 0x" << return_value
|
std::setw(8) << std::setfill('0')<< var << " failed to "
|
||||||
<< std::dec << std::endl;
|
"initialize with code 0x" << result << std::dec <<
|
||||||
error_count++;
|
std::setfill(' ') << std::endl;
|
||||||
|
errorCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error_count > 0) {
|
if (errorCount > 0) {
|
||||||
sif::error << "ObjectManager::ObjectManager: Counted " << error_count
|
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
||||||
<< " failed initializations." << std::endl;
|
<< " failed initializations." << std::endl;
|
||||||
}
|
}
|
||||||
//Init was successful. Now check successful interconnections.
|
//Init was successful. Now check successful interconnections.
|
||||||
error_count = 0;
|
errorCount = 0;
|
||||||
for (std::map<object_id_t, SystemObjectIF*>::iterator it = this->objectList.begin(); it != objectList.end(); it++ ) {
|
for (auto const& it : objectList) {
|
||||||
return_value = it->second->checkObjectConnections();
|
result = it.second->checkObjectConnections();
|
||||||
if ( return_value != RETURN_OK ) {
|
if ( result != RETURN_OK ) {
|
||||||
sif::error << "Object " << std::hex << (int) it->first
|
sif::error << "ObjectManager::ObjectManager: Object " << std::hex <<
|
||||||
<< " connection check failed with code 0x" << return_value
|
(int) it.first << " connection check failed with code 0x"
|
||||||
<< std::dec << std::endl;
|
<< result << std::dec << std::endl;
|
||||||
error_count++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error_count > 0) {
|
if (errorCount > 0) {
|
||||||
sif::error << "ObjectManager::ObjectManager: Counted " << error_count
|
sif::error << "ObjectManager::ObjectManager: Counted " << errorCount
|
||||||
<< " failed connection checks." << std::endl;
|
<< " failed connection checks." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::printList() {
|
void ObjectManager::printList() {
|
||||||
std::map<object_id_t, SystemObjectIF*>::iterator it;
|
std::map<object_id_t, SystemObjectIF*>::iterator it;
|
||||||
sif::debug << "ObjectManager: Object List contains:" << std::endl;
|
sif::debug << "ObjectManager: Object List contains:" << std::endl;
|
||||||
for (it = this->objectList.begin(); it != this->objectList.end(); it++) {
|
for (auto const& it : objectList) {
|
||||||
sif::debug << std::hex << it->first << " | " << it->second << std::endl;
|
sif::debug << std::hex << it.first << " | " << it.second << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,10 @@
|
|||||||
/**
|
#ifndef FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_
|
||||||
* @file ObjectManagerIF.h
|
#define FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_
|
||||||
* @brief This file contains the implementation of the ObjectManagerIF interface
|
|
||||||
* @date 19.09.2012
|
|
||||||
* @author Bastian Baetz
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef OBJECTMANAGERIF_H_
|
|
||||||
#define OBJECTMANAGERIF_H_
|
|
||||||
|
|
||||||
#include <framework/objectmanager/frameworkObjects.h>
|
#include <framework/objectmanager/frameworkObjects.h>
|
||||||
#include <config/objects/systemObjectList.h>
|
|
||||||
#include <framework/objectmanager/SystemObjectIF.h>
|
#include <framework/objectmanager/SystemObjectIF.h>
|
||||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class provides an interface to the global object manager.
|
* @brief This class provides an interface to the global object manager.
|
||||||
@ -20,13 +13,17 @@
|
|||||||
* inserted, removed and retrieved from the list. On getting the
|
* inserted, removed and retrieved from the list. On getting the
|
||||||
* object, the call checks if the object implements the requested
|
* object, the call checks if the object implements the requested
|
||||||
* interface.
|
* interface.
|
||||||
* \ingroup system_objects
|
* @author Bastian Baetz
|
||||||
|
* @ingroup system_objects
|
||||||
*/
|
*/
|
||||||
class ObjectManagerIF : public HasReturnvaluesIF {
|
class ObjectManagerIF : public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::OBJECT_MANAGER_IF;
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::OBJECT_MANAGER_IF;
|
||||||
static const ReturnValue_t INSERTION_FAILED = MAKE_RETURN_CODE( 1 );
|
static constexpr ReturnValue_t INSERTION_FAILED = MAKE_RETURN_CODE( 1 );
|
||||||
static const ReturnValue_t NOT_FOUND = MAKE_RETURN_CODE( 2 );
|
static constexpr ReturnValue_t NOT_FOUND = MAKE_RETURN_CODE( 2 );
|
||||||
|
static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 );
|
||||||
|
static constexpr ReturnValue_t INTERNAL_ERR_REPORTER_UNINIT = MAKE_RETURN_CODE( 4 );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief This method is used to hide the template-based get call from
|
* @brief This method is used to hide the template-based get call from
|
||||||
@ -78,15 +75,21 @@ public:
|
|||||||
virtual void printList() = 0;
|
virtual void printList() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T* ObjectManagerIF::get( object_id_t id ) {
|
|
||||||
SystemObjectIF* temp = this->getSystemObject(id);
|
|
||||||
return dynamic_cast<T*>(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the forward declaration of the global objectManager instance.
|
* @brief This is the forward declaration of the global objectManager instance.
|
||||||
*/
|
*/
|
||||||
extern ObjectManagerIF *objectManager;
|
extern ObjectManagerIF *objectManager;
|
||||||
|
|
||||||
|
/*Documentation can be found in the class method declaration above.*/
|
||||||
|
template <typename T>
|
||||||
|
T* ObjectManagerIF::get( object_id_t id ) {
|
||||||
|
if(objectManager == nullptr) {
|
||||||
|
sif::error << "ObjectManagerIF: Global object manager has not "
|
||||||
|
"been initialized yet!" << std::endl;
|
||||||
|
}
|
||||||
|
SystemObjectIF* temp = this->getSystemObject(id);
|
||||||
|
return dynamic_cast<T*>(temp);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* OBJECTMANAGERIF_H_ */
|
#endif /* OBJECTMANAGERIF_H_ */
|
||||||
|
@ -82,10 +82,10 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const {
|
|||||||
|
|
||||||
void FixedTimeslotTask::taskFunctionality() {
|
void FixedTimeslotTask::taskFunctionality() {
|
||||||
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
||||||
std::list<FixedSequenceSlot*>::iterator it = pst.current;
|
auto slotListIter = pst.current;
|
||||||
|
|
||||||
//The start time for the first entry is read.
|
//The start time for the first entry is read.
|
||||||
uint32_t intervalMs = (*it)->pollingTimeMs;
|
uint32_t intervalMs = slotListIter->pollingTimeMs;
|
||||||
TickType_t interval = pdMS_TO_TICKS(intervalMs);
|
TickType_t interval = pdMS_TO_TICKS(intervalMs);
|
||||||
|
|
||||||
TickType_t xLastWakeTime;
|
TickType_t xLastWakeTime;
|
||||||
@ -120,4 +120,3 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
|
|||||||
vTaskDelay(pdMS_TO_TICKS(ms));
|
vTaskDelay(pdMS_TO_TICKS(ms));
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
#include <framework/tasks/FixedTimeslotTaskIF.h>
|
#include <framework/tasks/FixedTimeslotTaskIF.h>
|
||||||
#include <framework/tasks/Typedef.h>
|
#include <framework/tasks/Typedef.h>
|
||||||
|
|
||||||
#include <FreeRTOS.h>
|
extern "C" {
|
||||||
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
}
|
||||||
|
|
||||||
class FixedTimeslotTask: public FixedTimeslotTaskIF {
|
class FixedTimeslotTask: public FixedTimeslotTaskIF {
|
||||||
public:
|
public:
|
||||||
|
@ -97,7 +97,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
bool ignoreFault) {
|
bool ignoreFault) {
|
||||||
message->setSender(sentFrom);
|
message->setSender(sentFrom);
|
||||||
|
|
||||||
BaseType_t result = xQueueSendToBack(reinterpret_cast<void*>(sendTo),reinterpret_cast<const void*>(message->getBuffer()), 0);
|
BaseType_t result = xQueueSendToBack(reinterpret_cast<QueueHandle_t>(sendTo),
|
||||||
|
reinterpret_cast<const void*>(message->getBuffer()), 0);
|
||||||
if (result != pdPASS) {
|
if (result != pdPASS) {
|
||||||
if (!ignoreFault) {
|
if (!ignoreFault) {
|
||||||
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||||
|
@ -25,8 +25,8 @@ QueueFactory::~QueueFactory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth,
|
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth,
|
||||||
uint32_t max_message_size) {
|
size_t maxMessageSize) {
|
||||||
return new MessageQueue(message_depth, max_message_size);
|
return new MessageQueue(message_depth, maxMessageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {
|
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <framework/osal/linux/FixedTimeslotTask.h>
|
#include <framework/osal/linux/FixedTimeslotTask.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
|
uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
|
||||||
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
|
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
|
||||||
@ -23,7 +20,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) {
|
|||||||
FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(arg));
|
FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(arg));
|
||||||
//The task's functionality is called.
|
//The task's functionality is called.
|
||||||
originalTask->taskFunctionality();
|
originalTask->taskFunctionality();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t FixedTimeslotTask::startTask() {
|
ReturnValue_t FixedTimeslotTask::startTask() {
|
||||||
|
@ -8,7 +8,20 @@
|
|||||||
|
|
||||||
class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread {
|
class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread {
|
||||||
public:
|
public:
|
||||||
FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_);
|
/**
|
||||||
|
* Create a generic periodic task.
|
||||||
|
* @param name_
|
||||||
|
* Name, maximum allowed size of linux is 16 chars, everything else will
|
||||||
|
* be truncated.
|
||||||
|
* @param priority_
|
||||||
|
* Real-time priority, ranges from 1 to 99 for Linux.
|
||||||
|
* See: https://man7.org/linux/man-pages/man7/sched.7.html
|
||||||
|
* @param stackSize_
|
||||||
|
* @param period_
|
||||||
|
* @param deadlineMissedFunc_
|
||||||
|
*/
|
||||||
|
FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_,
|
||||||
|
uint32_t periodMs_);
|
||||||
virtual ~FixedTimeslotTask();
|
virtual ~FixedTimeslotTask();
|
||||||
|
|
||||||
virtual ReturnValue_t startTask();
|
virtual ReturnValue_t startTask();
|
||||||
@ -17,7 +30,9 @@ public:
|
|||||||
|
|
||||||
virtual uint32_t getPeriodMs() const;
|
virtual uint32_t getPeriodMs() const;
|
||||||
|
|
||||||
virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep);
|
virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
|
||||||
|
int8_t executionStep);
|
||||||
|
|
||||||
virtual ReturnValue_t checkSequence() const;
|
virtual ReturnValue_t checkSequence() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,11 +49,10 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief This function holds the main functionality of the thread.
|
* @brief This function holds the main functionality of the thread.
|
||||||
*
|
* @details
|
||||||
*
|
* Holding the main functionality of the task, this method is most important.
|
||||||
* @details Holding the main functionality of the task, this method is most important.
|
* It links the functionalities provided by FixedSlotSequence with the
|
||||||
* It links the functionalities provided by FixedSlotSequence with the OS's System Calls
|
* OS's System Calls to keep the timing of the periods.
|
||||||
* to keep the timing of the periods.
|
|
||||||
*/
|
*/
|
||||||
virtual void taskFunctionality();
|
virtual void taskFunctionality();
|
||||||
|
|
||||||
@ -46,8 +60,13 @@ private:
|
|||||||
/**
|
/**
|
||||||
* @brief This is the entry point in a new thread.
|
* @brief This is the entry point in a new thread.
|
||||||
*
|
*
|
||||||
* @details This method, that is the entry point in the new thread and calls taskFunctionality of the child class.
|
* @details
|
||||||
* Needs a valid pointer to the derived class.
|
* This method, that is the entry point in the new thread and calls
|
||||||
|
* taskFunctionality of the child class. Needs a valid pointer to the
|
||||||
|
* derived class.
|
||||||
|
*
|
||||||
|
* The void* returnvalue is not used yet but could be used to return
|
||||||
|
* arbitrary data.
|
||||||
*/
|
*/
|
||||||
static void* taskEntryPoint(void* arg);
|
static void* taskEntryPoint(void* arg);
|
||||||
FixedSlotSequence pst;
|
FixedSlotSequence pst;
|
||||||
|
@ -1,56 +1,37 @@
|
|||||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
#include <fcntl.h> /* For O_* constants */
|
|
||||||
#include <sys/stat.h> /* For mode constants */
|
|
||||||
#include <mqueue.h>
|
|
||||||
#include <cstring>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <framework/osal/linux/MessageQueue.h>
|
#include <framework/osal/linux/MessageQueue.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
|
#include <fcntl.h> /* For O_* constants */
|
||||||
id(0), lastPartner(0), defaultDestination(NO_QUEUE) {
|
#include <sys/stat.h> /* For mode constants */
|
||||||
|
#include <cstring>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
|
||||||
mq_attr attributes;
|
mq_attr attributes;
|
||||||
this->id = 0;
|
this->id = 0;
|
||||||
//Set attributes
|
//Set attributes
|
||||||
attributes.mq_curmsgs = 0;
|
attributes.mq_curmsgs = 0;
|
||||||
attributes.mq_maxmsg = message_depth;
|
attributes.mq_maxmsg = messageDepth;
|
||||||
attributes.mq_msgsize = max_message_size;
|
attributes.mq_msgsize = maxMessageSize;
|
||||||
attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open
|
attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open
|
||||||
//Set the name of the queue
|
//Set the name of the queue. The slash is mandatory!
|
||||||
sprintf(name, "/Q%u\n", queueCounter++);
|
sprintf(name, "/FSFW_MQ%u\n", queueCounter++);
|
||||||
|
|
||||||
//Create a nonblocking queue if the name is available (the queue is Read and
|
// Create a nonblocking queue if the name is available (the queue is read
|
||||||
// writable for the owner as well as the group)
|
// and writable for the owner as well as the group)
|
||||||
mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL,
|
int oflag = O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL;
|
||||||
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes);
|
mode_t mode = S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH;
|
||||||
|
mqd_t tempId = mq_open(name, oflag, mode, &attributes);
|
||||||
if (tempId == -1) {
|
if (tempId == -1) {
|
||||||
//An error occured during open
|
handleError(&attributes, messageDepth);
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
|
||||||
//Failed either the first time or the second time
|
|
||||||
sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
|
|
||||||
<< name << std::dec << " failed with status: "
|
|
||||||
<< strerror(errno) << std::endl;
|
|
||||||
} else {
|
|
||||||
//Successful mq_open call
|
//Successful mq_open call
|
||||||
this->id = tempId;
|
this->id = tempId;
|
||||||
}
|
}
|
||||||
@ -69,6 +50,73 @@ MessageQueue::~MessageQueue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
|
||||||
|
uint32_t messageDepth) {
|
||||||
|
switch(errno) {
|
||||||
|
case(EINVAL): {
|
||||||
|
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 manually by using:
|
||||||
|
// sudo setcap 'CAP_SYS_RESOURCE=+ep' <pathToBinary>
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(EEXIST): {
|
||||||
|
// An error occured during open
|
||||||
|
// We need to distinguish if it is caused by an already created queue
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Failed either the first time or the second time
|
||||||
|
sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
|
||||||
|
<< name << std::dec << " failed with status: "
|
||||||
|
<< strerror(errno) << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessage* message, bool ignoreFault) {
|
MessageQueueMessage* message, bool ignoreFault) {
|
||||||
return sendMessageFrom(sendTo, message, this->getId(), false);
|
return sendMessageFrom(sendTo, message, this->getId(), false);
|
||||||
@ -108,12 +156,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
|
|||||||
//Success but no message received
|
//Success but no message received
|
||||||
return MessageQueueIF::EMPTY;
|
return MessageQueueIF::EMPTY;
|
||||||
} else {
|
} else {
|
||||||
//No message was received. Keep lastPartner anyway, I might send something later.
|
//No message was received. Keep lastPartner anyway, I might send
|
||||||
//But still, delete packet content.
|
//something later. But still, delete packet content.
|
||||||
memset(message->getData(), 0, message->MAX_DATA_SIZE);
|
memset(message->getData(), 0, message->MAX_DATA_SIZE);
|
||||||
switch(errno){
|
switch(errno){
|
||||||
case EAGAIN:
|
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;
|
return MessageQueueIF::EMPTY;
|
||||||
case EBADF:
|
case EBADF:
|
||||||
//mqdes doesn't represent a valid queue open for reading.
|
//mqdes doesn't represent a valid queue open for reading.
|
||||||
@ -123,9 +172,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
|
|||||||
case EINVAL:
|
case EINVAL:
|
||||||
/*
|
/*
|
||||||
* This value indicates one of the following:
|
* This value indicates one of the following:
|
||||||
* * The pointer to the buffer for storing the received message, msg_ptr, is NULL.
|
* - The pointer to the buffer for storing the received message,
|
||||||
* * The number of bytes requested, msg_len is less than zero.
|
* msg_ptr, is NULL.
|
||||||
* * 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 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 "
|
sif::error << "MessageQueue::receive: configuration error "
|
||||||
<< strerror(errno) << std::endl;
|
<< strerror(errno) << std::endl;
|
||||||
@ -133,8 +185,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
|
|||||||
case EMSGSIZE:
|
case EMSGSIZE:
|
||||||
/*
|
/*
|
||||||
* This value indicates one of the following:
|
* 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 QNX extended option MQ_READBUF_DYNAMIC hasn't been set,
|
||||||
* * 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.
|
* 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 "
|
sif::error << "MessageQueue::receive: configuration error "
|
||||||
<< strerror(errno) << std::endl;
|
<< strerror(errno) << std::endl;
|
||||||
@ -182,9 +238,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
|||||||
case EINVAL:
|
case EINVAL:
|
||||||
/*
|
/*
|
||||||
* This value indicates one of the following:
|
* This value indicates one of the following:
|
||||||
* * mq_attr is NULL.
|
* - 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_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:
|
default:
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
@ -233,7 +290,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
//TODO: Check if we're in ISR.
|
//TODO: Check if we're in ISR.
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
if(!ignoreFault){
|
if(!ignoreFault){
|
||||||
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
InternalErrorReporterIF* internalErrorReporter =
|
||||||
|
objectManager->get<InternalErrorReporterIF>(
|
||||||
objects::INTERNAL_ERROR_REPORTER);
|
objects::INTERNAL_ERROR_REPORTER);
|
||||||
if (internalErrorReporter != NULL) {
|
if (internalErrorReporter != NULL) {
|
||||||
internalErrorReporter->queueMessageNotSent();
|
internalErrorReporter->queueMessageNotSent();
|
||||||
@ -241,10 +299,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
}
|
}
|
||||||
switch(errno){
|
switch(errno){
|
||||||
case EAGAIN:
|
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;
|
return MessageQueueIF::FULL;
|
||||||
case EBADF:
|
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 "
|
sif::error << "MessageQueue::sendMessage: Configuration error "
|
||||||
<< strerror(errno) << " in mq_send mqSendTo: " << sendTo
|
<< strerror(errno) << " in mq_send mqSendTo: " << sendTo
|
||||||
<< " sent from " << sentFrom << std::endl;
|
<< " sent from " << sentFrom << std::endl;
|
||||||
@ -254,18 +315,22 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
case EINVAL:
|
case EINVAL:
|
||||||
/*
|
/*
|
||||||
* This value indicates one of the following:
|
* This value indicates one of the following:
|
||||||
* * msg_ptr is NULL.
|
* - msg_ptr is NULL.
|
||||||
* * msg_len is negative.
|
* - msg_len is negative.
|
||||||
* * msg_prio is greater than MQ_PRIO_MAX.
|
* - msg_prio is greater than MQ_PRIO_MAX.
|
||||||
* * msg_prio is less than 0.
|
* - msg_prio is less than 0.
|
||||||
* * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des,
|
* - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and
|
||||||
* and msg_prio is greater than the priority of the calling process.
|
* msg_prio is greater than the priority of the calling process.
|
||||||
* */
|
*/
|
||||||
sif::error << "MessageQueue::sendMessage: Configuration error "
|
sif::error << "MessageQueue::sendMessage: Configuration error "
|
||||||
<< strerror(errno) << " in mq_send" << std::endl;
|
<< strerror(errno) << " in mq_send" << std::endl;
|
||||||
/*NO BREAK*/
|
/*NO BREAK*/
|
||||||
case EMSGSIZE:
|
case EMSGSIZE:
|
||||||
//The msg_len is greater than the msgsize associated with the specified queue.
|
// The msg_len is greater than the msgsize associated with
|
||||||
|
//the specified queue.
|
||||||
|
sif::error << "MessageQueue::sendMessage: Size error [" <<
|
||||||
|
strerror(errno) << "] in mq_send" << std::endl;
|
||||||
|
/*NO BREAK*/
|
||||||
default:
|
default:
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -4,21 +4,26 @@
|
|||||||
#include <framework/internalError/InternalErrorReporterIF.h>
|
#include <framework/internalError/InternalErrorReporterIF.h>
|
||||||
#include <framework/ipc/MessageQueueIF.h>
|
#include <framework/ipc/MessageQueueIF.h>
|
||||||
#include <framework/ipc/MessageQueueMessage.h>
|
#include <framework/ipc/MessageQueueMessage.h>
|
||||||
|
|
||||||
|
#include <mqueue.h>
|
||||||
/**
|
/**
|
||||||
* @brief This class manages sending and receiving of message queue messages.
|
* @brief This class manages sending and receiving of message queue messages.
|
||||||
*
|
*
|
||||||
* @details Message queues are used to pass asynchronous messages between processes.
|
* @details
|
||||||
|
* Message queues are used to pass asynchronous messages between processes.
|
||||||
* They work like post boxes, where all incoming messages are stored in FIFO
|
* They work like post boxes, where all incoming messages are stored in FIFO
|
||||||
* order. This class creates a new receiving queue and provides methods to fetch
|
* order. This class creates a new receiving queue and provides methods to fetch
|
||||||
* received messages. Being a child of MessageQueueSender, this class also provides
|
* received messages. Being a child of MessageQueueSender, this class also
|
||||||
* methods to send a message to a user-defined or a default destination. In addition
|
* provides methods to send a message to a user-defined or a default destination.
|
||||||
* it also provides a reply method to answer to the queue it received its last message
|
* In addition it also provides a reply method to answer to the queue it
|
||||||
* from.
|
* received its last message from.
|
||||||
* The MessageQueue should be used as "post box" for a single owning object. So all
|
*
|
||||||
* message queue communication is "n-to-one".
|
* The MessageQueue should be used as "post box" for a single owning object.
|
||||||
* For creating the queue, as well as sending and receiving messages, the class makes
|
* So all message queue communication is "n-to-one".
|
||||||
* use of the operating system calls provided.
|
*
|
||||||
* \ingroup message_queue
|
* The creation of message queues, as well as sending and receiving messages,
|
||||||
|
* makes use of the operating system calls provided.
|
||||||
|
* @ingroup message_queue
|
||||||
*/
|
*/
|
||||||
class MessageQueue : public MessageQueueIF {
|
class MessageQueue : public MessageQueueIF {
|
||||||
friend class MessageQueueSenderIF;
|
friend class MessageQueueSenderIF;
|
||||||
@ -35,7 +40,8 @@ public:
|
|||||||
* @param max_message_size With this parameter, the maximum message size can be adjusted.
|
* @param max_message_size With this parameter, the maximum message size can be adjusted.
|
||||||
* This should be left default.
|
* This should be left default.
|
||||||
*/
|
*/
|
||||||
MessageQueue( size_t message_depth = 3, size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE );
|
MessageQueue(uint32_t messageDepth = 3,
|
||||||
|
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE );
|
||||||
/**
|
/**
|
||||||
* @brief The destructor deletes the formerly created message queue.
|
* @brief The destructor deletes the formerly created message queue.
|
||||||
* @details This is accomplished by using the delete call provided by the operating system.
|
* @details This is accomplished by using the delete call provided by the operating system.
|
||||||
@ -168,6 +174,8 @@ private:
|
|||||||
char name[5];
|
char name[5];
|
||||||
|
|
||||||
static uint16_t queueCounter;
|
static uint16_t queueCounter;
|
||||||
|
|
||||||
|
ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MESSAGEQUEUE_H_ */
|
#endif /* MESSAGEQUEUE_H_ */
|
||||||
|
@ -3,9 +3,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <framework/osal/linux/PeriodicPosixTask.h>
|
#include <framework/osal/linux/PeriodicPosixTask.h>
|
||||||
|
|
||||||
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):PosixThread(name_,priority_,stackSize_),objectList(),started(false),periodMs(period_),deadlineMissedFunc(
|
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_,
|
||||||
deadlineMissedFunc_) {
|
size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):
|
||||||
|
PosixThread(name_,priority_,stackSize_),objectList(),started(false),
|
||||||
|
periodMs(period_),deadlineMissedFunc(deadlineMissedFunc_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicPosixTask::~PeriodicPosixTask() {
|
PeriodicPosixTask::~PeriodicPosixTask() {
|
||||||
@ -37,7 +38,8 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
|
|||||||
|
|
||||||
ReturnValue_t PeriodicPosixTask::startTask(void){
|
ReturnValue_t PeriodicPosixTask::startTask(void){
|
||||||
started = true;
|
started = true;
|
||||||
createTask(&taskEntryPoint,this);
|
//sif::info << stackSize << std::endl;
|
||||||
|
PosixThread::createTask(&taskEntryPoint,this);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,9 +58,11 @@ void PeriodicPosixTask::taskFunctionality(void){
|
|||||||
char name[20] = {0};
|
char name[20] = {0};
|
||||||
int status = pthread_getname_np(pthread_self(),name,sizeof(name));
|
int status = pthread_getname_np(pthread_self(),name,sizeof(name));
|
||||||
if(status==0){
|
if(status==0){
|
||||||
sif::error << "ObjectTask: " << name << " Deadline missed." << std::endl;
|
sif::error << "PeriodicPosixTask " << name << ": Deadline "
|
||||||
|
"missed." << std::endl;
|
||||||
}else{
|
}else{
|
||||||
sif::error << "ObjectTask: X Deadline missed. " << status << std::endl;
|
sif::error << "PeriodicPosixTask X: Deadline missed. " <<
|
||||||
|
status << std::endl;
|
||||||
}
|
}
|
||||||
if (this->deadlineMissedFunc != NULL) {
|
if (this->deadlineMissedFunc != NULL) {
|
||||||
this->deadlineMissedFunc();
|
this->deadlineMissedFunc();
|
||||||
|
@ -9,9 +9,22 @@
|
|||||||
|
|
||||||
class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF {
|
class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Create a generic periodic task.
|
||||||
|
* @param name_
|
||||||
|
* Name, maximum allowed size of linux is 16 chars, everything else will
|
||||||
|
* be truncated.
|
||||||
|
* @param priority_
|
||||||
|
* Real-time priority, ranges from 1 to 99 for Linux.
|
||||||
|
* See: https://man7.org/linux/man-pages/man7/sched.7.html
|
||||||
|
* @param stackSize_
|
||||||
|
* @param period_
|
||||||
|
* @param deadlineMissedFunc_
|
||||||
|
*/
|
||||||
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
|
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
|
||||||
uint32_t period_, void(*deadlineMissedFunc_)());
|
uint32_t period_, void(*deadlineMissedFunc_)());
|
||||||
virtual ~PeriodicPosixTask();
|
virtual ~PeriodicPosixTask();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The method to start the task.
|
* @brief The method to start the task.
|
||||||
* @details The method starts the task with the respective system call.
|
* @details The method starts the task with the respective system call.
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
#include <framework/osal/linux/PosixThread.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <framework/osal/linux/PosixThread.h>
|
|
||||||
|
|
||||||
|
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
|
||||||
|
thread(0),priority(priority_),stackSize(stackSize_) {
|
||||||
|
name[0] = '\0';
|
||||||
|
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
|
||||||
|
}
|
||||||
|
|
||||||
PosixThread::~PosixThread() {
|
PosixThread::~PosixThread() {
|
||||||
//No deletion and no free of Stack Pointer
|
//No deletion and no free of Stack Pointer
|
||||||
@ -55,10 +60,6 @@ void PosixThread::resume(){
|
|||||||
pthread_kill(thread,SIGUSR1);
|
pthread_kill(thread,SIGUSR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
|
bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
|
||||||
const uint64_t delayTime_ms) {
|
const uint64_t delayTime_ms) {
|
||||||
uint64_t nextTimeToWake_ms;
|
uint64_t nextTimeToWake_ms;
|
||||||
@ -113,12 +114,6 @@ uint64_t PosixThread::getCurrentMonotonicTimeMs(){
|
|||||||
return currentTime_ms;
|
return currentTime_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
|
|
||||||
thread(0),priority(priority_),stackSize(stackSize_) {
|
|
||||||
strcpy(name,name_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
||||||
//sif::debug << "PosixThread::createTask" << std::endl;
|
//sif::debug << "PosixThread::createTask" << std::endl;
|
||||||
@ -135,14 +130,24 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
|||||||
sif::error << "Posix Thread attribute init failed with: " <<
|
sif::error << "Posix Thread attribute init failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
}
|
}
|
||||||
void* sp;
|
void* stackPointer;
|
||||||
status = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stackSize);
|
status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
sif::error << "Posix Thread stack init failed with: " <<
|
sif::error << "PosixThread::createTask: Stack init failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
|
if(errno == ENOMEM) {
|
||||||
|
uint64_t stackMb = stackSize/10e6;
|
||||||
|
sif::error << "PosixThread::createTask: Insufficient memory for"
|
||||||
|
" the requested " << stackMb << " MB" << std::endl;
|
||||||
|
}
|
||||||
|
else if(errno == EINVAL) {
|
||||||
|
sif::error << "PosixThread::createTask: Wrong alignment argument!"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pthread_attr_setstack(&attributes, sp, stackSize);
|
status = pthread_attr_setstack(&attributes, stackPointer, stackSize);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
sif::error << "Posix Thread attribute setStack failed with: " <<
|
sif::error << "Posix Thread attribute setStack failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
@ -154,7 +159,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
|||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO FIFO -> This needs root privileges for the process
|
// TODO FIFO -> This needs root privileges for the process
|
||||||
status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO);
|
status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
sif::error << "Posix Thread attribute schedule policy failed with: " <<
|
sif::error << "Posix Thread attribute schedule policy failed with: " <<
|
||||||
@ -188,8 +193,18 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
|||||||
|
|
||||||
status = pthread_setname_np(thread,name);
|
status = pthread_setname_np(thread,name);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
sif::error << "Posix Thread setname failed with: " <<
|
sif::error << "PosixThread::createTask: setname failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
|
if(status == ERANGE) {
|
||||||
|
sif::error << "PosixThread::createTask: Task name length longer"
|
||||||
|
" than 16 chars. Truncating.." << std::endl;
|
||||||
|
name[15] = '\0';
|
||||||
|
status = pthread_setname_np(thread,name);
|
||||||
|
if(status != 0){
|
||||||
|
sif::error << "PosixThread::createTask: Setting name"
|
||||||
|
" did not work.." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pthread_attr_destroy(&attributes);
|
status = pthread_attr_destroy(&attributes);
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
|
#ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
|
||||||
#define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
|
#define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
class PosixThread {
|
class PosixThread {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
|
||||||
PosixThread(const char* name_, int priority_, size_t stackSize_);
|
PosixThread(const char* name_, int priority_, size_t stackSize_);
|
||||||
virtual ~PosixThread();
|
virtual ~PosixThread();
|
||||||
/**
|
/**
|
||||||
@ -54,21 +54,24 @@ protected:
|
|||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function that has to be called by derived class because the derived class pointer has to be valid as argument
|
* @brief Function that has to be called by derived class because the
|
||||||
* @details This function creates a pthread with the given parameters. As the function requires a pointer to the derived object
|
* derived class pointer has to be valid as argument.
|
||||||
* it has to be called after the this pointer of the derived object is valid. Sets the taskEntryPoint as
|
* @details
|
||||||
* function to be called by new a thread.
|
* This function creates a pthread with the given parameters. As the
|
||||||
* @param name_ Name of the task
|
* function requires a pointer to the derived object it has to be called
|
||||||
* @param priority_ Priority of the task according to POSIX
|
* after the this pointer of the derived object is valid.
|
||||||
* @param stackSize_ Size of the stack attached to that task
|
* Sets the taskEntryPoint as function to be called by new a thread.
|
||||||
* @param arg_ argument of the taskEntryPoint function, needs to be this pointer of derived class
|
* @param fnc_ Function which will be executed by the thread.
|
||||||
|
* @param arg_
|
||||||
|
* argument of the taskEntryPoint function, needs to be this pointer
|
||||||
|
* of derived class
|
||||||
*/
|
*/
|
||||||
void createTask(void* (*fnc_)(void*),void* arg_);
|
void createTask(void* (*fnc_)(void*),void* arg_);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char name[10];
|
char name[PTHREAD_MAX_NAMELEN];
|
||||||
int priority;
|
int priority;
|
||||||
size_t stackSize;
|
size_t stackSize = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */
|
#endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */
|
||||||
|
@ -5,16 +5,18 @@
|
|||||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
QueueFactory* QueueFactory::factoryInstance = NULL;
|
QueueFactory* QueueFactory::factoryInstance = nullptr;
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) {
|
MessageQueueMessage* message, MessageQueueId_t sentFrom,
|
||||||
return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault);
|
bool ignoreFault) {
|
||||||
|
return MessageQueue::sendMessageFromMessageQueue(sendTo,message,
|
||||||
|
sentFrom,ignoreFault);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueFactory* QueueFactory::instance() {
|
QueueFactory* QueueFactory::instance() {
|
||||||
if (factoryInstance == NULL) {
|
if (factoryInstance == nullptr) {
|
||||||
factoryInstance = new QueueFactory;
|
factoryInstance = new QueueFactory;
|
||||||
}
|
}
|
||||||
return factoryInstance;
|
return factoryInstance;
|
||||||
@ -26,9 +28,9 @@ QueueFactory::QueueFactory() {
|
|||||||
QueueFactory::~QueueFactory() {
|
QueueFactory::~QueueFactory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth,
|
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth,
|
||||||
uint32_t max_message_size) {
|
size_t maxMessageSize) {
|
||||||
return new MessageQueue(message_depth, max_message_size);
|
return new MessageQueue(messageDepth, maxMessageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {
|
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {
|
||||||
|
@ -13,12 +13,20 @@ TaskFactory* TaskFactory::instance() {
|
|||||||
return TaskFactory::factoryInstance;
|
return TaskFactory::factoryInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,
|
||||||
return static_cast<PeriodicTaskIF*>(new PeriodicPosixTask(name_, taskPriority_,stackSize_,periodInSeconds_ * 1000,deadLineMissedFunction_));
|
TaskPriority taskPriority_,TaskStackSize stackSize_,
|
||||||
|
TaskPeriod periodInSeconds_,
|
||||||
|
TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
||||||
|
return new PeriodicPosixTask(name_, taskPriority_,stackSize_,
|
||||||
|
periodInSeconds_ * 1000, deadLineMissedFunction_);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,
|
||||||
return static_cast<FixedTimeslotTaskIF*>(new FixedTimeslotTask(name_, taskPriority_,stackSize_,periodInSeconds_*1000));
|
TaskPriority taskPriority_,TaskStackSize stackSize_,
|
||||||
|
TaskPeriod periodInSeconds_,
|
||||||
|
TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
||||||
|
return new FixedTimeslotTask(name_, taskPriority_,stackSize_,
|
||||||
|
periodInSeconds_*1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
|
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
|
||||||
|
@ -49,9 +49,9 @@ QueueFactory::QueueFactory() {
|
|||||||
QueueFactory::~QueueFactory() {
|
QueueFactory::~QueueFactory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth,
|
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth,
|
||||||
uint32_t max_message_size) {
|
size_t maxMessageSize) {
|
||||||
return new MessageQueue(message_depth, max_message_size);
|
return new MessageQueue(messageDepth, maxMessageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {
|
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {
|
||||||
|
@ -37,7 +37,7 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) {
|
|||||||
ParameterMessage::getParameterId(message));
|
ParameterMessage::getParameterId(message));
|
||||||
|
|
||||||
const uint8_t *storedStream;
|
const uint8_t *storedStream;
|
||||||
uint32_t storedStreamSize;
|
size_t storedStreamSize;
|
||||||
result = storage->getData(
|
result = storage->getData(
|
||||||
ParameterMessage::getStoreId(message), &storedStream,
|
ParameterMessage::getStoreId(message), &storedStream,
|
||||||
&storedStreamSize);
|
&storedStreamSize);
|
||||||
|
@ -24,6 +24,7 @@ enum {
|
|||||||
MEMORY_HELPER, //MH
|
MEMORY_HELPER, //MH
|
||||||
SERIALIZE_IF, //SE
|
SERIALIZE_IF, //SE
|
||||||
FIXED_MAP, //FM
|
FIXED_MAP, //FM
|
||||||
|
FIXED_MULTIMAP, //FMM
|
||||||
HAS_HEALTH_IF, //HHI
|
HAS_HEALTH_IF, //HHI
|
||||||
FIFO_CLASS, //FF
|
FIFO_CLASS, //FF
|
||||||
MESSAGE_PROXY, //MQP
|
MESSAGE_PROXY, //MQP
|
||||||
@ -54,11 +55,15 @@ enum {
|
|||||||
HAS_ACTIONS_IF, //HF
|
HAS_ACTIONS_IF, //HF
|
||||||
DEVICE_COMMUNICATION_IF, //DC
|
DEVICE_COMMUNICATION_IF, //DC
|
||||||
BSP, //BSP
|
BSP, //BSP
|
||||||
TIME_STAMPER_IF, //TSI 52
|
TIME_STAMPER_IF, //TSI 53
|
||||||
//TODO This will shift all IDs for FLP
|
//TODO This will shift all IDs for FLP
|
||||||
SGP4PROPAGATOR_CLASS, //SGP4 53
|
SGP4PROPAGATOR_CLASS, //SGP4 54
|
||||||
MUTEX_IF, //MUX 54
|
MUTEX_IF, //MUX 55
|
||||||
MESSAGE_QUEUE_IF,//MQI 55
|
MESSAGE_QUEUE_IF,//MQI 56
|
||||||
|
SEMAPHORE_IF, //SPH 57
|
||||||
|
LOCAL_POOL_OWNER_IF, //LPIF 58
|
||||||
|
POOL_VARIABLE_IF, //PVA 59
|
||||||
|
HOUSEKEEPING_MANAGER, //HKM 60
|
||||||
FW_CLASS_ID_COUNT //is actually count + 1 !
|
FW_CLASS_ID_COUNT //is actually count + 1 !
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,27 +1,23 @@
|
|||||||
#ifndef HASRETURNVALUESIF_H_
|
#ifndef FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
|
||||||
#define HASRETURNVALUESIF_H_
|
#define FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <framework/returnvalues/FwClassIds.h>
|
#include <framework/returnvalues/FwClassIds.h>
|
||||||
#include <config/returnvalues/classIds.h>
|
#include <config/returnvalues/classIds.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#define MAKE_RETURN_CODE( number ) ((INTERFACE_ID << 8) + (number))
|
#define MAKE_RETURN_CODE( number ) ((INTERFACE_ID << 8) + (number))
|
||||||
typedef uint16_t ReturnValue_t;
|
typedef uint16_t ReturnValue_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HasReturnvaluesIF {
|
class HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
static const ReturnValue_t RETURN_OK = 0;
|
static const ReturnValue_t RETURN_OK = 0;
|
||||||
static const ReturnValue_t RETURN_FAILED = 1;
|
static const ReturnValue_t RETURN_FAILED = 1;
|
||||||
virtual ~HasReturnvaluesIF() {
|
virtual ~HasReturnvaluesIF() {}
|
||||||
}
|
|
||||||
|
|
||||||
|
static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) {
|
||||||
|
return (interfaceId << 8) + number;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ */
|
||||||
|
|
||||||
#endif /* HASRETURNVALUESIF_H_ */
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#ifndef RMAPCOOKIE_H_
|
#ifndef RMAPCOOKIE_H_
|
||||||
#define RMAPCOOKIE_H_
|
#define RMAPCOOKIE_H_
|
||||||
|
|
||||||
#include <framework/devicehandlers/Cookie.h>
|
#include <framework/devicehandlers/CookieIF.h>
|
||||||
#include <framework/rmap/rmapStructs.h>
|
#include <framework/rmap/rmapStructs.h>
|
||||||
|
|
||||||
class RMAPChannelIF;
|
class RMAPChannelIF;
|
||||||
|
|
||||||
class RMAPCookie : public Cookie{
|
class RMAPCookie : public CookieIF {
|
||||||
public:
|
public:
|
||||||
//To Uli: Sorry, I need an empty ctor to initialize an array of cookies.
|
//To Uli: Sorry, I need an empty ctor to initialize an array of cookies.
|
||||||
RMAPCookie();
|
RMAPCookie();
|
||||||
|
@ -5,43 +5,43 @@
|
|||||||
RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() {
|
RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RmapDeviceCommunicationIF::sendMessage(Cookie* cookie,
|
ReturnValue_t RmapDeviceCommunicationIF::sendMessage(CookieIF* cookie,
|
||||||
uint8_t* data, uint32_t len) {
|
uint8_t* data, uint32_t len) {
|
||||||
return RMAP::sendWriteCommand((RMAPCookie *) cookie, data, len);
|
return RMAP::sendWriteCommand((RMAPCookie *) cookie, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(Cookie* cookie) {
|
ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(CookieIF* cookie) {
|
||||||
return RMAP::getWriteReply((RMAPCookie *) cookie);
|
return RMAP::getWriteReply((RMAPCookie *) cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage(
|
ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage(
|
||||||
Cookie* cookie) {
|
CookieIF* cookie) {
|
||||||
return RMAP::sendReadCommand((RMAPCookie *) cookie,
|
return RMAP::sendReadCommand((RMAPCookie *) cookie,
|
||||||
((RMAPCookie *) cookie)->getMaxReplyLen());
|
((RMAPCookie *) cookie)->getMaxReplyLen());
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(Cookie* cookie,
|
ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(CookieIF* cookie,
|
||||||
uint8_t** buffer, uint32_t* size) {
|
uint8_t** buffer, uint32_t* size) {
|
||||||
return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size);
|
return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RmapDeviceCommunicationIF::setAddress(Cookie* cookie,
|
ReturnValue_t RmapDeviceCommunicationIF::setAddress(CookieIF* cookie,
|
||||||
uint32_t address) {
|
uint32_t address) {
|
||||||
|
|
||||||
((RMAPCookie *) cookie)->setAddress(address);
|
((RMAPCookie *) cookie)->setAddress(address);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RmapDeviceCommunicationIF::getAddress(Cookie* cookie) {
|
uint32_t RmapDeviceCommunicationIF::getAddress(CookieIF* cookie) {
|
||||||
return ((RMAPCookie *) cookie)->getAddress();
|
return ((RMAPCookie *) cookie)->getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RmapDeviceCommunicationIF::setParameter(Cookie* cookie,
|
ReturnValue_t RmapDeviceCommunicationIF::setParameter(CookieIF* cookie,
|
||||||
uint32_t parameter) {
|
uint32_t parameter) {
|
||||||
//TODO Empty?
|
//TODO Empty?
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RmapDeviceCommunicationIF::getParameter(Cookie* cookie) {
|
uint32_t RmapDeviceCommunicationIF::getParameter(CookieIF* cookie) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
* @param maxReplyLen Maximum length of expected reply
|
* @param maxReplyLen Maximum length of expected reply
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
|
virtual ReturnValue_t open(CookieIF **cookie, uint32_t address,
|
||||||
uint32_t maxReplyLen) = 0;
|
uint32_t maxReplyLen) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,7 +39,7 @@ public:
|
|||||||
* @param maxReplyLen
|
* @param maxReplyLen
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
|
virtual ReturnValue_t reOpen(CookieIF *cookie, uint32_t address,
|
||||||
uint32_t maxReplyLen) = 0;
|
uint32_t maxReplyLen) = 0;
|
||||||
|
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ public:
|
|||||||
* Closing call of connection and memory free of cookie. Mission dependent call
|
* Closing call of connection and memory free of cookie. Mission dependent call
|
||||||
* @param cookie
|
* @param cookie
|
||||||
*/
|
*/
|
||||||
virtual void close(Cookie *cookie) = 0;
|
virtual void close(CookieIF *cookie) = 0;
|
||||||
|
|
||||||
//SHOULDDO can data be const?
|
//SHOULDDO can data be const?
|
||||||
/**
|
/**
|
||||||
@ -58,23 +58,23 @@ public:
|
|||||||
* @param len Length of the data to be send
|
* @param len Length of the data to be send
|
||||||
* @return - Return codes of RMAP::sendWriteCommand()
|
* @return - Return codes of RMAP::sendWriteCommand()
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
|
virtual ReturnValue_t sendMessage(CookieIF *cookie, uint8_t *data,
|
||||||
uint32_t len);
|
uint32_t len);
|
||||||
|
|
||||||
virtual ReturnValue_t getSendSuccess(Cookie *cookie);
|
virtual ReturnValue_t getSendSuccess(CookieIF *cookie);
|
||||||
|
|
||||||
virtual ReturnValue_t requestReceiveMessage(Cookie *cookie);
|
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie);
|
||||||
|
|
||||||
virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
|
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
|
||||||
uint32_t *size);
|
uint32_t *size);
|
||||||
|
|
||||||
virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address);
|
virtual ReturnValue_t setAddress(CookieIF *cookie, uint32_t address);
|
||||||
|
|
||||||
virtual uint32_t getAddress(Cookie *cookie);
|
virtual uint32_t getAddress(CookieIF *cookie);
|
||||||
|
|
||||||
virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter);
|
virtual ReturnValue_t setParameter(CookieIF *cookie, uint32_t parameter);
|
||||||
|
|
||||||
virtual uint32_t getParameter(Cookie *cookie);
|
virtual uint32_t getParameter(CookieIF *cookie);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ */
|
#endif /* MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ */
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_
|
|
||||||
#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file LocalPool
|
* @file LocalPool
|
||||||
*
|
|
||||||
* @date 02.02.2012
|
* @date 02.02.2012
|
||||||
* @author Bastian Baetz
|
* @author Bastian Baetz
|
||||||
*
|
|
||||||
* @brief This file contains the definition of the LocalPool class.
|
* @brief This file contains the definition of the LocalPool class.
|
||||||
*/
|
*/
|
||||||
|
#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_
|
||||||
|
#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_
|
||||||
|
|
||||||
#include <framework/objectmanager/SystemObject.h>
|
#include <framework/objectmanager/SystemObject.h>
|
||||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
@ -20,7 +17,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief The LocalPool class provides an intermediate data storage with
|
* @brief The LocalPool class provides an intermediate data storage with
|
||||||
* a fixed pool size policy.
|
* a fixed pool size policy.
|
||||||
* \details The class implements the StorageManagerIF interface. While the
|
* @details The class implements the StorageManagerIF interface. While the
|
||||||
* total number of pools is fixed, the element sizes in one pool and
|
* 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 number of pool elements per pool are set on construction.
|
||||||
* The full amount of memory is allocated on construction.
|
* The full amount of memory is allocated on construction.
|
||||||
@ -31,7 +28,6 @@
|
|||||||
* It is possible to store empty packets in the pool.
|
* It is possible to store empty packets in the pool.
|
||||||
* The local pool is NOT thread-safe.
|
* The local pool is NOT thread-safe.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS = 5>
|
template<uint8_t NUMBER_OF_POOLS = 5>
|
||||||
class LocalPool: public SystemObject, public StorageManagerIF {
|
class LocalPool: public SystemObject, public StorageManagerIF {
|
||||||
public:
|
public:
|
||||||
@ -39,7 +35,65 @@ public:
|
|||||||
* @brief This definition generally sets the number of different sized pools.
|
* @brief This definition generally sets the number of different sized pools.
|
||||||
* @details This must be less than the maximum number of pools (currently 0xff).
|
* @details This must be less than the maximum number of pools (currently 0xff).
|
||||||
*/
|
*/
|
||||||
// static const uint32_t NUMBER_OF_POOLS;
|
// 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.
|
||||||
|
* <b>The sizes must be provided in ascending order.
|
||||||
|
* </b>
|
||||||
|
* @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);
|
||||||
|
/**
|
||||||
|
* @brief In the LocalPool's destructor all allocated memory is freed.
|
||||||
|
*/
|
||||||
|
virtual ~LocalPool(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Documentation: See StorageManagerIF.h
|
||||||
|
*/
|
||||||
|
ReturnValue_t addData(store_address_t* storageId, 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 getData(store_address_t packet_id, const uint8_t** packet_ptr,
|
||||||
|
size_t * size) 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(uint8_t* ptr, size_t size,
|
||||||
|
store_address_t* storeId = NULL) override;
|
||||||
|
void clearStore() override;
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* With this helper method, a free element of \c size is reserved.
|
||||||
|
* @param size The minimum packet size that shall be reserved.
|
||||||
|
* @param[out] address Storage ID of the reserved data.
|
||||||
|
* @return - #RETURN_OK on success,
|
||||||
|
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t reserveSpace(const uint32_t size,
|
||||||
|
store_address_t* address, bool ignoreFault);
|
||||||
|
|
||||||
|
InternalErrorReporterIF *internalErrorReporter;
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Indicates that this element is free.
|
* Indicates that this element is free.
|
||||||
@ -60,7 +114,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* @brief store represents the actual memory pool.
|
* @brief store represents the actual memory pool.
|
||||||
* @details It is an array of pointers to memory, which was allocated with
|
* @details It is an array of pointers to memory, which was allocated with
|
||||||
* a \c new call on construction.
|
* a @c new call on construction.
|
||||||
*/
|
*/
|
||||||
uint8_t* store[NUMBER_OF_POOLS];
|
uint8_t* store[NUMBER_OF_POOLS];
|
||||||
/**
|
/**
|
||||||
@ -78,7 +132,7 @@ private:
|
|||||||
* @param data The data to be stored.
|
* @param data The data to be stored.
|
||||||
* @param size The size of 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, uint32_t size);
|
void write(store_address_t packet_id, const uint8_t* data, size_t size);
|
||||||
/**
|
/**
|
||||||
* @brief A helper method to read the element size of a certain pool.
|
* @brief A helper method to read the element size of a certain pool.
|
||||||
* @param pool_index The pool in which to look.
|
* @param pool_index The pool in which to look.
|
||||||
@ -101,7 +155,8 @@ private:
|
|||||||
* @return - #RETURN_OK on success,
|
* @return - #RETURN_OK on success,
|
||||||
* - #DATA_TOO_LARGE otherwise.
|
* - #DATA_TOO_LARGE otherwise.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t getPoolIndex(uint32_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex = 0);
|
ReturnValue_t getPoolIndex(size_t packet_size, uint16_t* poolIndex,
|
||||||
|
uint16_t startAtIndex = 0);
|
||||||
/**
|
/**
|
||||||
* @brief This helper method calculates the true array position in store
|
* @brief This helper method calculates the true array position in store
|
||||||
* of a given packet id.
|
* of a given packet id.
|
||||||
@ -121,310 +176,8 @@ private:
|
|||||||
* - #DATA_STORAGE_FULL if the store is full
|
* - #DATA_STORAGE_FULL if the store is full
|
||||||
*/
|
*/
|
||||||
ReturnValue_t findEmpty(uint16_t pool_index, uint16_t* element);
|
ReturnValue_t findEmpty(uint16_t pool_index, uint16_t* element);
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* With this helper method, a free element of \c size is reserved.
|
|
||||||
* @param size The minimum packet size that shall be reserved.
|
|
||||||
* @param[out] address Storage ID of the reserved data.
|
|
||||||
* @return - #RETURN_OK on success,
|
|
||||||
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault);
|
|
||||||
|
|
||||||
InternalErrorReporterIF *internalErrorReporter;
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @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.
|
|
||||||
* <b>The sizes must be provided in ascending order.
|
|
||||||
* </b>
|
|
||||||
* @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).
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
/**
|
|
||||||
* @brief In the LocalPool's destructor all allocated memory is freed.
|
|
||||||
*/
|
|
||||||
virtual ~LocalPool(void);
|
|
||||||
ReturnValue_t addData(store_address_t* storageId, const uint8_t * data,
|
|
||||||
uint32_t size, bool ignoreFault = false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* With this helper method, a free element of \c size is reserved.
|
|
||||||
*
|
|
||||||
* @param size The minimum packet size that shall be reserved.
|
|
||||||
* @return Returns the storage identifier within the storage or
|
|
||||||
* StorageManagerIF::INVALID_ADDRESS (in raw).
|
|
||||||
*/
|
|
||||||
ReturnValue_t getFreeElement(store_address_t* storageId,
|
|
||||||
const uint32_t size, uint8_t** p_data, bool ignoreFault = false);
|
|
||||||
ReturnValue_t getData(store_address_t packet_id, const uint8_t** packet_ptr,
|
|
||||||
uint32_t* size);
|
|
||||||
ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr,
|
|
||||||
uint32_t* size);
|
|
||||||
virtual ReturnValue_t deleteData(store_address_t);
|
|
||||||
virtual ReturnValue_t deleteData(uint8_t* ptr, uint32_t size,
|
|
||||||
store_address_t* storeId = NULL);
|
|
||||||
void clearStore();
|
|
||||||
ReturnValue_t initialize();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
#include <framework/storagemanager/LocalPool.tpp>
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::findEmpty(uint16_t pool_index,
|
|
||||||
uint16_t* element) {
|
|
||||||
ReturnValue_t status = DATA_STORAGE_FULL;
|
|
||||||
for (uint16_t foundElement = 0; foundElement < n_elements[pool_index];
|
|
||||||
foundElement++) {
|
|
||||||
if (size_list[pool_index][foundElement] == STORAGE_FREE) {
|
|
||||||
*element = foundElement;
|
|
||||||
status = RETURN_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline void LocalPool<NUMBER_OF_POOLS>::write(store_address_t packet_id,
|
|
||||||
const uint8_t* data, uint32_t size) {
|
|
||||||
uint8_t* ptr;
|
|
||||||
uint32_t packet_position = getRawPosition(packet_id);
|
|
||||||
|
|
||||||
//check size? -> Not necessary, because size is checked before calling this function.
|
|
||||||
ptr = &store[packet_id.pool_index][packet_position];
|
|
||||||
memcpy(ptr, data, size);
|
|
||||||
size_list[packet_id.pool_index][packet_id.packet_index] = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns page size of 0 in case store_index is illegal
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline uint32_t LocalPool<NUMBER_OF_POOLS>::getPageSize(uint16_t pool_index) {
|
|
||||||
if (pool_index < NUMBER_OF_POOLS) {
|
|
||||||
return element_sizes[pool_index];
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::getPoolIndex(
|
|
||||||
uint32_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex) {
|
|
||||||
for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) {
|
|
||||||
// debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << n << ", Element Size: " << element_sizes[n] << std::endl;
|
|
||||||
if (element_sizes[n] >= packet_size) {
|
|
||||||
*poolIndex = n;
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DATA_TOO_LARGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline uint32_t LocalPool<NUMBER_OF_POOLS>::getRawPosition(
|
|
||||||
store_address_t packet_id) {
|
|
||||||
return packet_id.packet_index * element_sizes[packet_id.pool_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::reserveSpace(
|
|
||||||
const uint32_t size, store_address_t* address, bool ignoreFault) {
|
|
||||||
ReturnValue_t status = getPoolIndex(size, &address->pool_index);
|
|
||||||
if (status != RETURN_OK) {
|
|
||||||
sif::error << "LocalPool( " << std::hex << getObjectId() << std::dec
|
|
||||||
<< " )::reserveSpace: Packet too large." << std::endl;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
status = findEmpty(address->pool_index, &address->packet_index);
|
|
||||||
while (status != RETURN_OK && spillsToHigherPools) {
|
|
||||||
status = getPoolIndex(size, &address->pool_index, address->pool_index + 1);
|
|
||||||
if (status != RETURN_OK) {
|
|
||||||
//We don't find any fitting pool anymore.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
status = findEmpty(address->pool_index, &address->packet_index);
|
|
||||||
}
|
|
||||||
if (status == RETURN_OK) {
|
|
||||||
// if (getObjectId() == objects::IPC_STORE && address->pool_index >= 3) {
|
|
||||||
// debug << "Reserve: Pool: " << std::dec << address->pool_index << " Index: " << address->packet_index << std::endl;
|
|
||||||
// }
|
|
||||||
|
|
||||||
size_list[address->pool_index][address->packet_index] = size;
|
|
||||||
} else {
|
|
||||||
if (!ignoreFault) {
|
|
||||||
internalErrorReporter->storeFull();
|
|
||||||
}
|
|
||||||
// error << "LocalPool( " << std::hex << getObjectId() << std::dec
|
|
||||||
// << " )::reserveSpace: Packet store is full." << std::endl;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline LocalPool<NUMBER_OF_POOLS>::LocalPool(object_id_t setObjectId,
|
|
||||||
const uint16_t element_sizes[NUMBER_OF_POOLS],
|
|
||||||
const uint16_t n_elements[NUMBER_OF_POOLS], bool registered, bool spillsToHigherPools) :
|
|
||||||
SystemObject(setObjectId, registered), spillsToHigherPools(spillsToHigherPools), internalErrorReporter(NULL) {
|
|
||||||
for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) {
|
|
||||||
this->element_sizes[n] = element_sizes[n];
|
|
||||||
this->n_elements[n] = n_elements[n];
|
|
||||||
store[n] = new uint8_t[n_elements[n] * element_sizes[n]];
|
|
||||||
size_list[n] = new uint32_t[n_elements[n]];
|
|
||||||
memset(store[n], 0x00, (n_elements[n] * element_sizes[n]));
|
|
||||||
memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); //TODO checkme
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline LocalPool<NUMBER_OF_POOLS>::~LocalPool(void) {
|
|
||||||
for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) {
|
|
||||||
delete[] store[n];
|
|
||||||
delete[] size_list[n];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::addData(
|
|
||||||
store_address_t* storageId, const uint8_t* data, uint32_t size, bool ignoreFault) {
|
|
||||||
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
|
||||||
if (status == RETURN_OK) {
|
|
||||||
write(*storageId, data, size);
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::getFreeElement(
|
|
||||||
store_address_t* storageId, const uint32_t size, uint8_t** p_data, bool ignoreFault) {
|
|
||||||
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
|
||||||
if (status == RETURN_OK) {
|
|
||||||
*p_data = &store[storageId->pool_index][getRawPosition(*storageId)];
|
|
||||||
} else {
|
|
||||||
*p_data = NULL;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::getData(
|
|
||||||
store_address_t packet_id, const uint8_t** packet_ptr, uint32_t* size) {
|
|
||||||
uint8_t* tempData = NULL;
|
|
||||||
ReturnValue_t status = modifyData(packet_id, &tempData, size);
|
|
||||||
*packet_ptr = tempData;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::modifyData(store_address_t packet_id,
|
|
||||||
uint8_t** packet_ptr, uint32_t* size) {
|
|
||||||
ReturnValue_t status = RETURN_FAILED;
|
|
||||||
if (packet_id.pool_index >= NUMBER_OF_POOLS) {
|
|
||||||
return ILLEGAL_STORAGE_ID;
|
|
||||||
}
|
|
||||||
if ((packet_id.packet_index >= n_elements[packet_id.pool_index])) {
|
|
||||||
return ILLEGAL_STORAGE_ID;
|
|
||||||
}
|
|
||||||
if (size_list[packet_id.pool_index][packet_id.packet_index]
|
|
||||||
!= STORAGE_FREE) {
|
|
||||||
uint32_t packet_position = getRawPosition(packet_id);
|
|
||||||
*packet_ptr = &store[packet_id.pool_index][packet_position];
|
|
||||||
*size = size_list[packet_id.pool_index][packet_id.packet_index];
|
|
||||||
status = RETURN_OK;
|
|
||||||
} else {
|
|
||||||
status = DATA_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::deleteData(
|
|
||||||
store_address_t packet_id) {
|
|
||||||
|
|
||||||
// if (getObjectId() == objects::IPC_STORE && packet_id.pool_index >= 3) {
|
|
||||||
// debug << "Delete: Pool: " << std::dec << packet_id.pool_index << " Index: " << packet_id.packet_index << std::endl;
|
|
||||||
// }
|
|
||||||
ReturnValue_t status = RETURN_OK;
|
|
||||||
uint32_t page_size = getPageSize(packet_id.pool_index);
|
|
||||||
if ((page_size != 0)
|
|
||||||
&& (packet_id.packet_index < n_elements[packet_id.pool_index])) {
|
|
||||||
uint16_t packet_position = getRawPosition(packet_id);
|
|
||||||
uint8_t* ptr = &store[packet_id.pool_index][packet_position];
|
|
||||||
memset(ptr, 0, page_size);
|
|
||||||
//Set free list
|
|
||||||
size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE;
|
|
||||||
} else {
|
|
||||||
//pool_index or packet_index is too large
|
|
||||||
sif::error << "LocalPool:deleteData failed." << std::endl;
|
|
||||||
status = ILLEGAL_STORAGE_ID;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline void LocalPool<NUMBER_OF_POOLS>::clearStore() {
|
|
||||||
for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) {
|
|
||||||
memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list)));//TODO checkme
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::deleteData(uint8_t* ptr,
|
|
||||||
uint32_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] <= ptr) && (&store[n][n_elements[n]*element_sizes[n]]) > ptr) {
|
|
||||||
localId.pool_index = n;
|
|
||||||
uint32_t deltaAddress = ptr - store[n];
|
|
||||||
//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.packet_index = deltaAddress / element_sizes[n];
|
|
||||||
result = deleteData(localId);
|
|
||||||
// if (deltaAddress % element_sizes[n] != 0) {
|
|
||||||
// error << "Pool::deleteData: address not aligned!" << std::endl;
|
|
||||||
// }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (storeId != NULL) {
|
|
||||||
*storeId = localId;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::initialize() {
|
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
|
|
||||||
if (internalErrorReporter == NULL){
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check if any pool size is large than the maximum allowed.
|
|
||||||
for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) {
|
|
||||||
if (element_sizes[count] >= STORAGE_FREE) {
|
|
||||||
sif::error
|
|
||||||
<< "LocalPool::initialize: Pool is too large! Max. allowed size is: "
|
|
||||||
<< (STORAGE_FREE - 1) << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ */
|
#endif /* FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ */
|
||||||
|
260
storagemanager/LocalPool.tpp
Normal file
260
storagemanager/LocalPool.tpp
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_
|
||||||
|
#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline LocalPool<NUMBER_OF_POOLS>::LocalPool(object_id_t setObjectId,
|
||||||
|
const uint16_t element_sizes[NUMBER_OF_POOLS],
|
||||||
|
const uint16_t n_elements[NUMBER_OF_POOLS], bool registered,
|
||||||
|
bool spillsToHigherPools) :
|
||||||
|
SystemObject(setObjectId, registered), internalErrorReporter(nullptr),
|
||||||
|
spillsToHigherPools(spillsToHigherPools)
|
||||||
|
{
|
||||||
|
for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) {
|
||||||
|
this->element_sizes[n] = element_sizes[n];
|
||||||
|
this->n_elements[n] = n_elements[n];
|
||||||
|
store[n] = new uint8_t[n_elements[n] * element_sizes[n]];
|
||||||
|
size_list[n] = new uint32_t[n_elements[n]];
|
||||||
|
memset(store[n], 0x00, (n_elements[n] * element_sizes[n]));
|
||||||
|
//TODO checkme
|
||||||
|
memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::findEmpty(uint16_t pool_index,
|
||||||
|
uint16_t* element) {
|
||||||
|
ReturnValue_t status = DATA_STORAGE_FULL;
|
||||||
|
for (uint16_t foundElement = 0; foundElement < n_elements[pool_index];
|
||||||
|
foundElement++) {
|
||||||
|
if (size_list[pool_index][foundElement] == STORAGE_FREE) {
|
||||||
|
*element = foundElement;
|
||||||
|
status = RETURN_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline void LocalPool<NUMBER_OF_POOLS>::write(store_address_t packet_id,
|
||||||
|
const uint8_t* data, size_t size) {
|
||||||
|
uint8_t* ptr;
|
||||||
|
uint32_t packet_position = getRawPosition(packet_id);
|
||||||
|
|
||||||
|
//check size? -> Not necessary, because size is checked before calling this function.
|
||||||
|
ptr = &store[packet_id.pool_index][packet_position];
|
||||||
|
memcpy(ptr, data, size);
|
||||||
|
size_list[packet_id.pool_index][packet_id.packet_index] = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns page size of 0 in case store_index is illegal
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline uint32_t LocalPool<NUMBER_OF_POOLS>::getPageSize(uint16_t pool_index) {
|
||||||
|
if (pool_index < NUMBER_OF_POOLS) {
|
||||||
|
return element_sizes[pool_index];
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::getPoolIndex(
|
||||||
|
size_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex) {
|
||||||
|
for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) {
|
||||||
|
//debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " <<
|
||||||
|
// n << ", Element Size: " << element_sizes[n] << std::endl;
|
||||||
|
if (element_sizes[n] >= packet_size) {
|
||||||
|
*poolIndex = n;
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DATA_TOO_LARGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline uint32_t LocalPool<NUMBER_OF_POOLS>::getRawPosition(
|
||||||
|
store_address_t packet_id) {
|
||||||
|
return packet_id.packet_index * element_sizes[packet_id.pool_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::reserveSpace(
|
||||||
|
const uint32_t size, store_address_t* address, bool ignoreFault) {
|
||||||
|
ReturnValue_t status = getPoolIndex(size, &address->pool_index);
|
||||||
|
if (status != RETURN_OK) {
|
||||||
|
sif::error << "LocalPool( " << std::hex << getObjectId() << std::dec
|
||||||
|
<< " )::reserveSpace: Packet too large." << std::endl;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
status = findEmpty(address->pool_index, &address->packet_index);
|
||||||
|
while (status != RETURN_OK && spillsToHigherPools) {
|
||||||
|
status = getPoolIndex(size, &address->pool_index, address->pool_index + 1);
|
||||||
|
if (status != RETURN_OK) {
|
||||||
|
//We don't find any fitting pool anymore.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
status = findEmpty(address->pool_index, &address->packet_index);
|
||||||
|
}
|
||||||
|
if (status == RETURN_OK) {
|
||||||
|
// if (getObjectId() == objects::IPC_STORE && address->pool_index >= 3) {
|
||||||
|
// debug << "Reserve: Pool: " << std::dec << address->pool_index <<
|
||||||
|
// " Index: " << address->packet_index << std::endl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
size_list[address->pool_index][address->packet_index] = size;
|
||||||
|
} else {
|
||||||
|
if (!ignoreFault and internalErrorReporter != nullptr) {
|
||||||
|
internalErrorReporter->storeFull();
|
||||||
|
}
|
||||||
|
// error << "LocalPool( " << std::hex << getObjectId() << std::dec
|
||||||
|
// << " )::reserveSpace: Packet store is full." << std::endl;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline LocalPool<NUMBER_OF_POOLS>::~LocalPool(void) {
|
||||||
|
for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) {
|
||||||
|
delete[] store[n];
|
||||||
|
delete[] size_list[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::getFreeElement(
|
||||||
|
store_address_t* storageId, const size_t size,
|
||||||
|
uint8_t** p_data, bool ignoreFault) {
|
||||||
|
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
||||||
|
if (status == RETURN_OK) {
|
||||||
|
*p_data = &store[storageId->pool_index][getRawPosition(*storageId)];
|
||||||
|
} else {
|
||||||
|
*p_data = NULL;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::getData(
|
||||||
|
store_address_t packet_id, const uint8_t** packet_ptr, size_t* size) {
|
||||||
|
uint8_t* tempData = NULL;
|
||||||
|
ReturnValue_t status = modifyData(packet_id, &tempData, size);
|
||||||
|
*packet_ptr = tempData;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::modifyData(
|
||||||
|
store_address_t packet_id, uint8_t** packet_ptr, size_t* size) {
|
||||||
|
ReturnValue_t status = RETURN_FAILED;
|
||||||
|
if (packet_id.pool_index >= NUMBER_OF_POOLS) {
|
||||||
|
return ILLEGAL_STORAGE_ID;
|
||||||
|
}
|
||||||
|
if ((packet_id.packet_index >= n_elements[packet_id.pool_index])) {
|
||||||
|
return ILLEGAL_STORAGE_ID;
|
||||||
|
}
|
||||||
|
if (size_list[packet_id.pool_index][packet_id.packet_index]
|
||||||
|
!= STORAGE_FREE) {
|
||||||
|
uint32_t packet_position = getRawPosition(packet_id);
|
||||||
|
*packet_ptr = &store[packet_id.pool_index][packet_position];
|
||||||
|
*size = size_list[packet_id.pool_index][packet_id.packet_index];
|
||||||
|
status = RETURN_OK;
|
||||||
|
} else {
|
||||||
|
status = DATA_DOES_NOT_EXIST;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::deleteData(
|
||||||
|
store_address_t packet_id) {
|
||||||
|
//if (getObjectId() == objects::IPC_STORE && packet_id.pool_index >= 3) {
|
||||||
|
// debug << "Delete: Pool: " << std::dec << packet_id.pool_index << " Index: "
|
||||||
|
// << packet_id.packet_index << std::endl;
|
||||||
|
//}
|
||||||
|
ReturnValue_t status = RETURN_OK;
|
||||||
|
uint32_t page_size = getPageSize(packet_id.pool_index);
|
||||||
|
if ((page_size != 0)
|
||||||
|
&& (packet_id.packet_index < n_elements[packet_id.pool_index])) {
|
||||||
|
uint16_t packet_position = getRawPosition(packet_id);
|
||||||
|
uint8_t* ptr = &store[packet_id.pool_index][packet_position];
|
||||||
|
memset(ptr, 0, page_size);
|
||||||
|
//Set free list
|
||||||
|
size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE;
|
||||||
|
} else {
|
||||||
|
//pool_index or packet_index is too large
|
||||||
|
sif::error << "LocalPool:deleteData failed." << std::endl;
|
||||||
|
status = ILLEGAL_STORAGE_ID;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline void LocalPool<NUMBER_OF_POOLS>::clearStore() {
|
||||||
|
for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) {
|
||||||
|
//TODO checkme
|
||||||
|
memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::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] <= ptr) && (&store[n][n_elements[n]*element_sizes[n]]) > ptr) {
|
||||||
|
localId.pool_index = n;
|
||||||
|
uint32_t deltaAddress = ptr - store[n];
|
||||||
|
// 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.packet_index = deltaAddress / element_sizes[n];
|
||||||
|
result = deleteData(localId);
|
||||||
|
//if (deltaAddress % element_sizes[n] != 0) {
|
||||||
|
// error << "Pool::deleteData: address not aligned!" << std::endl;
|
||||||
|
//}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (storeId != NULL) {
|
||||||
|
*storeId = localId;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t LocalPool<NUMBER_OF_POOLS>::initialize() {
|
||||||
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||||
|
objects::INTERNAL_ERROR_REPORTER);
|
||||||
|
if (internalErrorReporter == NULL){
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if any pool size is large than the maximum allowed.
|
||||||
|
for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) {
|
||||||
|
if (element_sizes[count] >= STORAGE_FREE) {
|
||||||
|
sif::error << "LocalPool::initialize: Pool is too large! "
|
||||||
|
"Max. allowed size is: " << (STORAGE_FREE - 1) << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,12 +1,3 @@
|
|||||||
/**
|
|
||||||
* @file PoolManager
|
|
||||||
*
|
|
||||||
* @date 02.02.2012
|
|
||||||
* @author Bastian Baetz
|
|
||||||
*
|
|
||||||
* @brief This file contains the definition of the PoolManager class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef POOLMANAGER_H_
|
#ifndef POOLMANAGER_H_
|
||||||
#define POOLMANAGER_H_
|
#define POOLMANAGER_H_
|
||||||
|
|
||||||
@ -17,70 +8,39 @@
|
|||||||
/**
|
/**
|
||||||
* @brief The PoolManager class provides an intermediate data storage with
|
* @brief The PoolManager class provides an intermediate data storage with
|
||||||
* a fixed pool size policy for inter-process communication.
|
* a fixed pool size policy for inter-process communication.
|
||||||
* \details Uses local pool, but is thread-safe.
|
* @details Uses local pool calls but is thread safe by protecting the call
|
||||||
|
* with a lock.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <uint8_t NUMBER_OF_POOLS = 5>
|
template <uint8_t NUMBER_OF_POOLS = 5>
|
||||||
class PoolManager : public LocalPool<NUMBER_OF_POOLS> {
|
class PoolManager : public LocalPool<NUMBER_OF_POOLS> {
|
||||||
|
public:
|
||||||
|
PoolManager(object_id_t setObjectId,
|
||||||
|
const uint16_t element_sizes[NUMBER_OF_POOLS],
|
||||||
|
const uint16_t n_elements[NUMBER_OF_POOLS]);
|
||||||
|
|
||||||
|
//! @brief In the PoolManager's destructor all allocated memory is freed.
|
||||||
|
virtual ~PoolManager();
|
||||||
|
|
||||||
|
//! @brief LocalPool overrides for thread-safety.
|
||||||
|
ReturnValue_t deleteData(store_address_t) override;
|
||||||
|
ReturnValue_t deleteData(uint8_t* buffer, size_t size,
|
||||||
|
store_address_t* storeId = NULL) override;
|
||||||
|
ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr,
|
||||||
|
size_t* size) override;
|
||||||
protected:
|
protected:
|
||||||
/**
|
ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address,
|
||||||
* Overwritten for thread safety.
|
bool ignoreFault) override;
|
||||||
* Locks during execution.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The mutex is created in the constructor and makes access mutual exclusive.
|
* @brief The mutex is created in the constructor and makes
|
||||||
* \details Locking and unlocking is done during searching for free slots and deleting existing slots.
|
* access mutual exclusive.
|
||||||
|
* @details Locking and unlocking is done during searching for free slots
|
||||||
|
* and deleting existing slots.
|
||||||
*/
|
*/
|
||||||
MutexIF* mutex;
|
MutexIF* mutex;
|
||||||
public:
|
|
||||||
PoolManager( object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], const uint16_t n_elements[NUMBER_OF_POOLS] );
|
|
||||||
/**
|
|
||||||
* @brief In the PoolManager's destructor all allocated memory is freed.
|
|
||||||
*/
|
|
||||||
virtual ~PoolManager( void );
|
|
||||||
/**
|
|
||||||
* Overwritten for thread safety.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t deleteData(store_address_t);
|
|
||||||
virtual ReturnValue_t deleteData(uint8_t* buffer, uint32_t size, store_address_t* storeId = NULL);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
#include "PoolManager.tpp"
|
||||||
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault) {
|
|
||||||
MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT);
|
|
||||||
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::reserveSpace(size,address,ignoreFault);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline PoolManager<NUMBER_OF_POOLS>::PoolManager(object_id_t setObjectId,
|
|
||||||
const uint16_t element_sizes[NUMBER_OF_POOLS],
|
|
||||||
const uint16_t n_elements[NUMBER_OF_POOLS]) : LocalPool<NUMBER_OF_POOLS>(setObjectId, element_sizes, n_elements, true) {
|
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline PoolManager<NUMBER_OF_POOLS>::~PoolManager(void) {
|
|
||||||
MutexFactory::instance()->deleteMutex(mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(
|
|
||||||
store_address_t packet_id) {
|
|
||||||
// debug << "PoolManager( " << translateObject(getObjectId()) << " )::deleteData from store " << packet_id.pool_index << ". id is " << packet_id.packet_index << std::endl;
|
|
||||||
MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT);
|
|
||||||
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(packet_id);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<uint8_t NUMBER_OF_POOLS>
|
|
||||||
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(uint8_t* buffer, uint32_t size,
|
|
||||||
store_address_t* storeId) {
|
|
||||||
MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT);
|
|
||||||
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(buffer, size, storeId);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* POOLMANAGER_H_ */
|
#endif /* POOLMANAGER_H_ */
|
||||||
|
55
storagemanager/PoolManager.tpp
Normal file
55
storagemanager/PoolManager.tpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_
|
||||||
|
#define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline PoolManager<NUMBER_OF_POOLS>::PoolManager(object_id_t setObjectId,
|
||||||
|
const uint16_t element_sizes[NUMBER_OF_POOLS],
|
||||||
|
const uint16_t n_elements[NUMBER_OF_POOLS]) :
|
||||||
|
LocalPool<NUMBER_OF_POOLS>(setObjectId, element_sizes, n_elements, true) {
|
||||||
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline PoolManager<NUMBER_OF_POOLS>::~PoolManager(void) {
|
||||||
|
MutexFactory::instance()->deleteMutex(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::reserveSpace(
|
||||||
|
const uint32_t size, store_address_t* address, bool ignoreFault) {
|
||||||
|
MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT);
|
||||||
|
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::reserveSpace(size,
|
||||||
|
address,ignoreFault);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(
|
||||||
|
store_address_t packet_id) {
|
||||||
|
// debug << "PoolManager( " << translateObject(getObjectId()) <<
|
||||||
|
// " )::deleteData from store " << packet_id.pool_index <<
|
||||||
|
// ". id is "<< packet_id.packet_index << std::endl;
|
||||||
|
MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT);
|
||||||
|
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(packet_id);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(uint8_t* buffer,
|
||||||
|
size_t size, store_address_t* storeId) {
|
||||||
|
MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT);
|
||||||
|
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(buffer,
|
||||||
|
size, storeId);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<uint8_t NUMBER_OF_POOLS>
|
||||||
|
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::modifyData(
|
||||||
|
store_address_t packet_id, uint8_t** packet_ptr, size_t* size) {
|
||||||
|
MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT);
|
||||||
|
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::modifyData(packet_id,
|
||||||
|
packet_ptr, size);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -6,18 +6,19 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This union defines the type that identifies where a data packet is stored in the store.
|
* @brief This union defines the type that identifies where a data packet is
|
||||||
* It comprises of a raw part to read it as raw value and a structured part to use it in
|
* stored in the store.
|
||||||
* pool-like stores.
|
* It consists 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 {
|
union store_address_t {
|
||||||
/**
|
/**
|
||||||
* Default Constructor, initializing to INVALID_ADDRESS
|
* Default Constructor, initializing to INVALID_ADDRESS
|
||||||
*/
|
*/
|
||||||
store_address_t():raw(0xFFFFFFFF){}
|
store_address_t():raw(0xFFFFFFFF){}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to create an address object using the raw address
|
* Constructor to create an address object using the raw address
|
||||||
*
|
|
||||||
* @param rawAddress
|
* @param rawAddress
|
||||||
*/
|
*/
|
||||||
store_address_t(uint32_t rawAddress):raw(rawAddress){}
|
store_address_t(uint32_t rawAddress):raw(rawAddress){}
|
||||||
@ -30,7 +31,8 @@ union store_address_t {
|
|||||||
* @param packetIndex
|
* @param packetIndex
|
||||||
*/
|
*/
|
||||||
store_address_t(uint16_t poolIndex, uint16_t packetIndex):
|
store_address_t(uint16_t poolIndex, uint16_t packetIndex):
|
||||||
pool_index(poolIndex),packet_index(packetIndex){}
|
pool_index(poolIndex),packet_index(packetIndex) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A structure with two elements to access the store address pool-like.
|
* A structure with two elements to access the store address pool-like.
|
||||||
*/
|
*/
|
||||||
@ -48,6 +50,10 @@ union store_address_t {
|
|||||||
* Alternative access to the raw value.
|
* Alternative access to the raw value.
|
||||||
*/
|
*/
|
||||||
uint32_t raw;
|
uint32_t raw;
|
||||||
|
|
||||||
|
bool operator==(const store_address_t& other) const {
|
||||||
|
return raw == other.raw;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +100,8 @@ public:
|
|||||||
* @li RETURN_FAILED if data could not be added.
|
* @li RETURN_FAILED if data could not be added.
|
||||||
* storageId is unchanged then.
|
* storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, uint32_t size, bool ignoreFault = false) = 0;
|
virtual ReturnValue_t addData(store_address_t* storageId,
|
||||||
|
const uint8_t * data, size_t size, bool ignoreFault = false) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief With deleteData, the storageManager frees the memory region
|
* @brief With deleteData, the storageManager frees the memory region
|
||||||
* identified by packet_id.
|
* identified by packet_id.
|
||||||
@ -105,14 +112,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t deleteData(store_address_t packet_id) = 0;
|
virtual ReturnValue_t deleteData(store_address_t packet_id) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Another deleteData which uses the pointer and size of the stored data to delete the content.
|
* @brief Another deleteData which uses the pointer and size of the
|
||||||
|
* stored data to delete the content.
|
||||||
* @param buffer Pointer to the data.
|
* @param buffer Pointer to the data.
|
||||||
* @param size Size of data to be stored.
|
* @param size Size of data to be stored.
|
||||||
* @param storeId Store id of the deleted element (optional)
|
* @param storeId Store id of the deleted element (optional)
|
||||||
* @return @li RETURN_OK on success.
|
* @return @li RETURN_OK on success.
|
||||||
* @li failure code if deletion did not work
|
* @li failure code if deletion did not work
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t deleteData(uint8_t* buffer, uint32_t size, store_address_t* storeId = NULL) = 0;
|
virtual ReturnValue_t deleteData(uint8_t* buffer, size_t size,
|
||||||
|
store_address_t* storeId = nullptr) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief getData returns an address to data and the size of the data
|
* @brief getData returns an address to data and the size of the data
|
||||||
* for a given packet_id.
|
* for a given packet_id.
|
||||||
@ -125,12 +134,12 @@ public:
|
|||||||
* (e.g. an illegal packet_id was passed).
|
* (e.g. an illegal packet_id was passed).
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getData(store_address_t packet_id,
|
virtual ReturnValue_t getData(store_address_t packet_id,
|
||||||
const uint8_t** packet_ptr, uint32_t* size) = 0;
|
const uint8_t** packet_ptr, size_t* size) = 0;
|
||||||
/**
|
/**
|
||||||
* Same as above, but not const and therefore modifiable.
|
* Same as above, but not const and therefore modifiable.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t modifyData(store_address_t packet_id,
|
virtual ReturnValue_t modifyData(store_address_t packet_id,
|
||||||
uint8_t** packet_ptr, uint32_t* size) = 0;
|
uint8_t** packet_ptr, size_t* size) = 0;
|
||||||
/**
|
/**
|
||||||
* This method reserves an element of \c size.
|
* This method reserves an element of \c size.
|
||||||
*
|
*
|
||||||
@ -144,13 +153,13 @@ public:
|
|||||||
* @li RETURN_FAILED if data could not be added.
|
* @li RETURN_FAILED if data could not be added.
|
||||||
* storageId is unchanged then.
|
* storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getFreeElement(store_address_t* storageId, const uint32_t size, uint8_t** p_data, bool ignoreFault = false ) = 0;
|
virtual ReturnValue_t getFreeElement(store_address_t* storageId,
|
||||||
|
const size_t size, uint8_t** p_data, bool ignoreFault = false ) = 0;
|
||||||
/**
|
/**
|
||||||
* Clears the whole store.
|
* Clears the whole store.
|
||||||
* Use with care!
|
* Use with care!
|
||||||
*/
|
*/
|
||||||
virtual void clearStore() = 0;
|
virtual void clearStore() = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* STORAGEMANAGERIF_H_ */
|
#endif /* STORAGEMANAGERIF_H_ */
|
||||||
|
@ -162,7 +162,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) {
|
|||||||
case ModeSequenceMessage::ADD_SEQUENCE: {
|
case ModeSequenceMessage::ADD_SEQUENCE: {
|
||||||
FixedArrayList<ModeListEntry, MAX_LENGTH_OF_TABLE_OR_SEQUENCE> sequence;
|
FixedArrayList<ModeListEntry, MAX_LENGTH_OF_TABLE_OR_SEQUENCE> sequence;
|
||||||
const uint8_t *pointer;
|
const uint8_t *pointer;
|
||||||
uint32_t sizeRead;
|
size_t sizeRead;
|
||||||
result = IPCStore->getData(
|
result = IPCStore->getData(
|
||||||
ModeSequenceMessage::getStoreAddress(message), &pointer,
|
ModeSequenceMessage::getStoreAddress(message), &pointer,
|
||||||
&sizeRead);
|
&sizeRead);
|
||||||
@ -188,7 +188,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) {
|
|||||||
case ModeSequenceMessage::ADD_TABLE: {
|
case ModeSequenceMessage::ADD_TABLE: {
|
||||||
FixedArrayList<ModeListEntry, MAX_LENGTH_OF_TABLE_OR_SEQUENCE> table;
|
FixedArrayList<ModeListEntry, MAX_LENGTH_OF_TABLE_OR_SEQUENCE> table;
|
||||||
const uint8_t *pointer;
|
const uint8_t *pointer;
|
||||||
uint32_t sizeRead;
|
size_t sizeRead;
|
||||||
result = IPCStore->getData(
|
result = IPCStore->getData(
|
||||||
ModeSequenceMessage::getStoreAddress(message), &pointer,
|
ModeSequenceMessage::getStoreAddress(message), &pointer,
|
||||||
&sizeRead);
|
&sizeRead);
|
||||||
|
@ -13,7 +13,7 @@ CCSDSDistributor::~CCSDSDistributor() {
|
|||||||
iterator_t CCSDSDistributor::selectDestination() {
|
iterator_t CCSDSDistributor::selectDestination() {
|
||||||
// debug << "CCSDSDistributor::selectDestination received: " << this->currentMessage.getStorageId().pool_index << ", " << this->currentMessage.getStorageId().packet_index << std::endl;
|
// debug << "CCSDSDistributor::selectDestination received: " << this->currentMessage.getStorageId().pool_index << ", " << this->currentMessage.getStorageId().packet_index << std::endl;
|
||||||
const uint8_t* p_packet = NULL;
|
const uint8_t* p_packet = NULL;
|
||||||
uint32_t size = 0;
|
size_t size = 0;
|
||||||
//TODO check returncode?
|
//TODO check returncode?
|
||||||
this->tcStore->getData( this->currentMessage.getStorageId(), &p_packet, &size );
|
this->tcStore->getData( this->currentMessage.getStorageId(), &p_packet, &size );
|
||||||
SpacePacketBase current_packet( p_packet );
|
SpacePacketBase current_packet( p_packet );
|
||||||
|
@ -81,7 +81,7 @@ void TmPacketStored::deletePacket() {
|
|||||||
void TmPacketStored::setStoreAddress(store_address_t setAddress) {
|
void TmPacketStored::setStoreAddress(store_address_t setAddress) {
|
||||||
storeAddress = setAddress;
|
storeAddress = setAddress;
|
||||||
const uint8_t* temp_data = NULL;
|
const uint8_t* temp_data = NULL;
|
||||||
uint32_t temp_size;
|
size_t temp_size;
|
||||||
if (!checkAndSetStore()) {
|
if (!checkAndSetStore()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user