Merge remote-tracking branch 'upstram/master' into mueller_FixedTimeslotTaskImprovements

This commit is contained in:
Robin Müller 2020-07-06 12:27:12 +02:00
commit 05393b900b
19 changed files with 1108 additions and 794 deletions

View File

@ -2,15 +2,16 @@
#include <framework/devicehandlers/ChildHandlerBase.h>
#include <framework/subsystem/SubsystemBase.h>
ChildHandlerBase::ChildHandlerBase(uint32_t ioBoardAddress,
object_id_t setObjectId, object_id_t deviceCommunication,
uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch,
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
uint32_t parent, FailureIsolationBase* customFdir, uint32_t cmdQueueSize) :
DeviceHandlerBase(ioBoardAddress, setObjectId, maxDeviceReplyLen,
setDeviceSwitch, deviceCommunication, thermalStatePoolId,
thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), cmdQueueSize), parentId(
parent), childHandlerFdir(setObjectId) {
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * comCookie,
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
uint32_t thermalRequestPoolId, uint32_t parent,
FailureIsolationBase* customFdir, size_t cmdQueueSize) :
DeviceHandlerBase(setObjectId, deviceCommunication, comCookie,
setDeviceSwitch, thermalStatePoolId,thermalRequestPoolId,
(customFdir == nullptr? &childHandlerFdir : customFdir),
cmdQueueSize),
parentId(parent), childHandlerFdir(setObjectId) {
}
ChildHandlerBase::~ChildHandlerBase() {

View File

@ -6,12 +6,12 @@
class ChildHandlerBase: public DeviceHandlerBase {
public:
ChildHandlerBase(uint32_t ioBoardAddress, object_id_t setObjectId,
object_id_t deviceCommunication, uint32_t maxDeviceReplyLen,
ChildHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * comCookie,
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
uint32_t thermalRequestPoolId, uint32_t parent,
FailureIsolationBase* customFdir = NULL,
uint32_t cmdQueueSize = 20);
FailureIsolationBase* customFdir = nullptr,
size_t cmdQueueSize = 20);
virtual ~ChildHandlerBase();
virtual ReturnValue_t initialize();

View File

@ -1,10 +0,0 @@
#ifndef COOKIE_H_
#define COOKIE_H_
class Cookie{
public:
virtual ~Cookie(){}
};
#endif /* COOKIE_H_ */

34
devicehandlers/CookieIF.h Normal file
View 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_ */

View File

@ -1,63 +1,131 @@
#ifndef DEVICECOMMUNICATIONIF_H_
#define DEVICECOMMUNICATIONIF_H_
#include <framework/devicehandlers/Cookie.h>
#include <framework/devicehandlers/CookieIF.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 {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF;
static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x03);
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x04);
static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x05);
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x06);
static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x07);
//! Standard Error Codes
//! General protocol error. Define more concrete errors in child handler
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x01);
//! If cookie is a null pointer
static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x03);
// 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.
* The previous connection must not be closed.
* If the returnvalue is not RETURN_OK, the cookie is unchanged and
* can be used with the previous connection.
* @brief Device specific initialization, using the cookie.
* @details
* The cookie is already prepared in the factory. If the communication
* 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 address
* @param maxReplyLen
* @return
* @param requestLen Size of data to read
* @return - @c RETURN_OK to confirm the request for data has been sent.
* - Everything else triggers failure event with
* returnvalue as parameter 1
*/
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
uint32_t maxReplyLen) = 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;
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
size_t requestLen) = 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_ */

View File

@ -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/DeviceTmReportingWrapper.h>
#include <framework/globalfunctions/CRC.h>
#include <framework/objectmanager/ObjectManager.h>
#include <framework/storagemanager/StorageManagerIF.h>
#include <framework/subsystem/SubsystemBase.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/serviceinterface/ServiceInterfaceStream.h>
#include <iomanip>
object_id_t DeviceHandlerBase::powerSwitcherId = 0;
object_id_t DeviceHandlerBase::rawDataReceiverId = 0;
object_id_t DeviceHandlerBase::defaultFDIRParentId = 0;
DeviceHandlerBase::DeviceHandlerBase(uint32_t ioBoardAddress,
object_id_t setObjectId, uint32_t maxDeviceReplyLen,
uint8_t setDeviceSwitch, object_id_t deviceCommunication,
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
FailureIsolationBase* fdirInstance, uint32_t cmdQueueSize) :
SystemObject(setObjectId), rawPacket(0), rawPacketLen(0), mode(
MODE_OFF), submode(SUBMODE_NONE), pstStep(0), maxDeviceReplyLen(
maxDeviceReplyLen), wiretappingMode(OFF), defaultRawReceiver(0), storedRawData(
StorageManagerIF::INVALID_ADDRESS), requestedRawTraffic(0), powerSwitcher(
NULL), IPCStore(NULL), deviceCommunicationId(deviceCommunication), communicationInterface(
NULL), cookie(
NULL), commandQueue(NULL), deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId(
thermalRequestPoolId), healthHelper(this, setObjectId), modeHelper(
this), parameterHelper(this), childTransitionFailure(RETURN_OK), ignoreMissedRepliesCount(
0), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(
fdirInstance == NULL), switchOffWasReported(false),executingTask(NULL), actionHelper(this, NULL), cookieInfo(), ioBoardAddress(
ioBoardAddress), timeoutStart(0), childTransitionDelay(5000), transitionSourceMode(
_MODE_POWER_DOWN), transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(
setDeviceSwitch) {
DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * comCookie,
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance,
size_t cmdQueueSize) :
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
deviceCommunicationId(deviceCommunication), comCookie(comCookie),
deviceThermalStatePoolId(thermalStatePoolId),
deviceThermalRequestPoolId(thermalRequestPoolId),
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
switchOffWasReported(false), actionHelper(this, nullptr),
childTransitionDelay(5000),
transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode(
SUBMODE_NONE), deviceSwitch(setDeviceSwitch) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
CommandMessage::MAX_MESSAGE_SIZE);
cookieInfo.state = COOKIE_UNUSED;
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,
defaultFDIRParentId);
}
}
DeviceHandlerBase::~DeviceHandlerBase() {
communicationInterface->close(cookie);
delete comCookie;
if (defaultFDIRUsed) {
delete fdirInstance;
}
@ -56,7 +64,7 @@ DeviceHandlerBase::~DeviceHandlerBase() {
ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
this->pstStep = counter;
if (counter == 0) {
if (getComAction() == SEND_WRITE) {
cookieInfo.state = COOKIE_UNUSED;
readCommandQueue();
doStateMachine();
@ -64,11 +72,12 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
decrementDeviceReplyMap();
fdirInstance->checkForFailures();
hkSwitcher.performOperation();
performOperationHook();
}
if (mode == MODE_OFF) {
return RETURN_OK;
}
switch (getRmapAction()) {
switch (getComAction()) {
case SEND_WRITE:
if ((cookieInfo.state == COOKIE_UNUSED)) {
buildInternalCommand();
@ -91,13 +100,91 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
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() {
for (std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) {
if (iter->second.delayCycles != 0) {
iter->second.delayCycles--;
if (iter->second.delayCycles == 0) {
if (iter->second.periodic != 0) {
if (iter->second.periodic) {
iter->second.delayCycles = iter->second.maxDelayCycles;
}
replyToReply(iter, TIMEOUT);
@ -256,55 +343,49 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
}
}
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
uint8_t periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
//No need to check, as we may try to insert multiple times.
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand,
uint16_t maxDelayCycles, size_t replyLen, bool periodic,
bool hasDifferentReplyId, DeviceCommandId_t replyId) {
//No need to check, as we may try to insert multiple times.
insertInCommandMap(deviceCommand);
if (hasDifferentReplyId) {
return insertInReplyMap(replyId, maxDelayCycles, periodic);
return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic);
} else {
return insertInReplyMap(deviceCommand, maxDelayCycles, periodic);
return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic);
}
}
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
uint16_t maxDelayCycles, uint8_t periodic) {
uint16_t maxDelayCycles, size_t replyLen, bool periodic) {
DeviceReplyInfo info;
info.maxDelayCycles = maxDelayCycles;
info.periodic = periodic;
info.delayCycles = 0;
info.replyLen = replyLen;
info.command = deviceCommandMap.end();
std::pair<std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator, bool> returnValue;
returnValue = deviceReplyMap.insert(
std::pair<DeviceCommandId_t, DeviceReplyInfo>(replyId, info));
if (returnValue.second) {
auto resultPair = deviceReplyMap.emplace(replyId, info);
if (resultPair.second) {
return RETURN_OK;
} else {
return RETURN_FAILED;
}
}
ReturnValue_t DeviceHandlerBase::insertInCommandMap(
DeviceCommandId_t deviceCommand) {
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
DeviceCommandInfo info;
info.expectedReplies = 0;
info.isExecuting = false;
info.sendReplyTo = NO_COMMANDER;
std::pair<std::map<DeviceCommandId_t, DeviceCommandInfo>::iterator, bool> returnValue;
returnValue = deviceCommandMap.insert(
std::pair<DeviceCommandId_t, DeviceCommandInfo>(deviceCommand,
info));
if (returnValue.second) {
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
if (resultPair.second) {
return RETURN_OK;
} else {
return RETURN_FAILED;
}
}
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(
DeviceCommandId_t deviceReply, uint16_t delayCycles,
uint16_t maxDelayCycles, uint8_t periodic) {
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) {
std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
deviceReplyMap.find(deviceReply);
if (iter == deviceReplyMap.end()) {
@ -429,7 +510,7 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
void DeviceHandlerBase::doSendWrite() {
if (cookieInfo.state == COOKIE_WRITE_READY) {
ReturnValue_t result = communicationInterface->sendMessage(cookie,
ReturnValue_t result = communicationInterface->sendMessage(comCookie,
rawPacket, rawPacketLen);
if (result == RETURN_OK) {
@ -450,12 +531,14 @@ void DeviceHandlerBase::doGetWrite() {
return;
}
cookieInfo.state = COOKIE_UNUSED;
ReturnValue_t result = communicationInterface->getSendSuccess(cookie);
ReturnValue_t result = communicationInterface->getSendSuccess(comCookie);
if (result == RETURN_OK) {
if (wiretappingMode == RAW) {
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);
} else {
//always generate a failure event, so that FDIR knows what's up
@ -471,7 +554,17 @@ void DeviceHandlerBase::doGetWrite() {
void DeviceHandlerBase::doSendRead() {
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) {
cookieInfo.state = COOKIE_READ_SENT;
} else {
@ -485,10 +578,10 @@ void DeviceHandlerBase::doSendRead() {
}
void DeviceHandlerBase::doGetRead() {
uint32_t receivedDataLen;
size_t receivedDataLen;
uint8_t *receivedData;
DeviceCommandId_t foundId = 0xFFFFFFFF;
uint32_t foundLen = 0;
size_t foundLen = 0;
ReturnValue_t result;
if (cookieInfo.state != COOKIE_READ_SENT) {
@ -498,8 +591,8 @@ void DeviceHandlerBase::doGetRead() {
cookieInfo.state = COOKIE_UNUSED;
result = communicationInterface->readReceivedMessage(cookie, &receivedData,
&receivedDataLen);
result = communicationInterface->readReceivedMessage(comCookie,
&receivedData, &receivedDataLen);
if (result != RETURN_OK) {
triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result);
@ -508,7 +601,7 @@ void DeviceHandlerBase::doGetRead() {
return;
}
if (receivedDataLen == 0)
if (receivedDataLen == 0 or result == DeviceCommunicationIF::NO_REPLY_RECEIVED)
return;
if (wiretappingMode == RAW) {
@ -539,6 +632,8 @@ void DeviceHandlerBase::doGetRead() {
break;
case IGNORE_REPLY_DATA:
break;
case IGNORE_FULL_PACKET:
return;
default:
//We need to wait for timeout.. don't know what command failed and who sent it.
replyRawReplyIfnotWiretapped(receivedData, foundLen);
@ -560,8 +655,8 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
uint8_t * *data, uint32_t * len) {
size_t lenTmp;
if (IPCStore == NULL) {
*data = NULL;
if (IPCStore == nullptr) {
*data = nullptr;
*len = 0;
return RETURN_FAILED;
}
@ -572,90 +667,10 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
} else {
triggerEvent(StorageManagerIF::GET_DATA_FAILED, result,
storageAddress.raw);
*data = NULL;
*data = nullptr;
*len = 0;
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,
@ -687,8 +702,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
}
//Default child implementations
DeviceHandlerBase::RmapAction_t DeviceHandlerBase::getRmapAction() {
DeviceHandlerIF::CommunicationAction_t DeviceHandlerBase::getComAction() {
switch (pstStep) {
case 0:
return SEND_WRITE;
@ -727,7 +741,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
if (info->delayCycles != 0) {
if (info->periodic != 0) {
if (info->periodic) {
info->delayCycles = info->maxDelayCycles;
} else {
info->delayCycles = 0;
@ -748,20 +762,20 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
}
}
ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) {
DeviceCommunicationIF *newCommunication = objectManager->get<
DeviceCommunicationIF>(newChannelId);
if (newCommunication != NULL) {
ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress,
maxDeviceReplyLen);
if (result != RETURN_OK) {
return result;
}
return RETURN_OK;
}
return RETURN_FAILED;
}
//ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) {
// DeviceCommunicationIF *newCommunication = objectManager->get<
// DeviceCommunicationIF>(newChannelId);
//
// if (newCommunication != NULL) {
// ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress,
// maxDeviceReplyLen);
// if (result != RETURN_OK) {
// return result;
// }
// return RETURN_OK;
// }
// return RETURN_FAILED;
//}
void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage);
@ -1022,7 +1036,6 @@ void DeviceHandlerBase::replyRawReplyIfnotWiretapped(const uint8_t* data,
ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
CommandMessage * message) {
ReturnValue_t result;
switch (message->getCommand()) {
case DeviceHandlerMessage::CMD_WIRETAPPING:
switch (DeviceHandlerMessage::getWiretappingMode(message)) {
@ -1044,19 +1057,19 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
}
replyReturnvalueToCommand(RETURN_OK);
return RETURN_OK;
case DeviceHandlerMessage::CMD_SWITCH_IOBOARD:
if (mode != MODE_OFF) {
replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND);
} else {
result = switchCookieChannel(
DeviceHandlerMessage::getIoBoardObjectId(message));
if (result == RETURN_OK) {
replyReturnvalueToCommand(RETURN_OK);
} else {
replyReturnvalueToCommand(CANT_SWITCH_IOBOARD);
}
}
return RETURN_OK;
// case DeviceHandlerMessage::CMD_SWITCH_IOBOARD:
// if (mode != MODE_OFF) {
// replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND);
// } else {
// result = switchCookieChannel(
// DeviceHandlerMessage::getIoBoardObjectId(message));
// if (result == RETURN_OK) {
// replyReturnvalueToCommand(RETURN_OK);
// } else {
// replyReturnvalueToCommand(CANT_SWITCH_IO_ADDRESS);
// }
// }
// return RETURN_OK;
case DeviceHandlerMessage::CMD_RAW:
if ((mode != MODE_RAW)) {
DeviceHandlerMessage::clear(message);
@ -1270,3 +1283,9 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* 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

View File

@ -8,7 +8,8 @@
#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 {
@ -22,93 +23,127 @@ public:
*
* @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.
* 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.
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.
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.
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.
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.
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_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
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
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
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.
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.
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 uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW);
static const Event DEVICE_SENDING_COMMAND_FAILED = MAKE_EVENT(1, SEVERITY::LOW);
static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, SEVERITY::LOW);
static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, SEVERITY::LOW);
static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, SEVERITY::LOW);
static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, SEVERITY::LOW);
static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, SEVERITY::LOW);
static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, SEVERITY::LOW);
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, SEVERITY::LOW); //!< Indicates a SW bug in child class.
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW);
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH);
// 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.
//! 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.
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;
//! 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;
//! 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;
//! 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
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 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);
static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2);
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 WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6);
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7);
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command.
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
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_SENDING_COMMAND_FAILED = MAKE_EVENT(1, SEVERITY::LOW);
static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, SEVERITY::LOW);
static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, SEVERITY::LOW);
static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, SEVERITY::LOW);
static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, SEVERITY::LOW);
static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, SEVERITY::LOW);
static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, SEVERITY::LOW);
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, SEVERITY::LOW); //!< Indicates a SW bug in child class.
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW);
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH);
//standard codes used in scan for reply
// static const ReturnValue_t TOO_SHORT = MAKE_RETURN_CODE(0xB1);
static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB2);
static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB3);
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB4);
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB5);
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
//standard codes used in interpret device reply
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_REPORTED_ERROR = MAKE_RETURN_CODE(0xC2);
static const ReturnValue_t UNKNOW_DEVICE_REPLY = MAKE_RETURN_CODE(0xC3); //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
// Standard codes used when building commands.
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 CANT_SWITCH_ADDRESS = MAKE_RETURN_CODE(0xA4);
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 BUSY = MAKE_RETURN_CODE(0xA7);
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command.
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
//Standard codes used in buildCommandFromCommand
static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE(
0xD0);
static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS =
MAKE_RETURN_CODE(0xD1);
// Standard codes used in scanForReply
static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB0);
static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB1);
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB2);
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB3);
// Standard codes used in interpretDeviceReply
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(0xC1);
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(0xC3); //syntax etc is correct but still not ok, eg parameters where none are expected
// Standard codes used in buildCommandFromCommand
static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE(0xD0);
static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS = MAKE_RETURN_CODE(0xD1);
/**
* Communication action that will be executed.
*
* This is used by the child class to tell the base class what to do.
*/
enum CommunicationAction_t: uint8_t {
SEND_WRITE,//!< Send write
GET_WRITE, //!< Get write
SEND_READ, //!< Send read
GET_READ, //!< Get read
NOTHING //!< Do nothing.
};
/**
* RMAP Action that will be executed.
*
* This is used by the child class to tell the base class what to do.
*/
enum RmapAction_t {
SEND_WRITE,//!< RMAP send write
GET_WRITE, //!< RMAP get write
SEND_READ, //!< RMAP send read
GET_READ, //!< RMAP get read
NOTHING //!< Do nothing.
};
/**
* Default Destructor
*/
virtual ~DeviceHandlerIF() {
}
virtual ~DeviceHandlerIF() {}
/**
* 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
*/
virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@ -16,6 +16,5 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime,
handler->setTaskIF(executingTask);
}
FixedSequenceSlot::~FixedSequenceSlot() {
}
FixedSequenceSlot::~FixedSequenceSlot() {}

View File

@ -13,35 +13,47 @@
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 {
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();
/**
* \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;
/**
* \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
* smaller than the period length of the polling sequence, what is ensured by automated calculation
* from a database.
* @details The pollingTime attribute identifies the time the handler is executed in ms.
* It must be smaller than the period length of the polling sequence.
*/
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;
/**
* @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;
}
};

View File

@ -7,17 +7,12 @@ FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) :
}
FixedSlotSequence::~FixedSlotSequence() {
std::list<FixedSequenceSlot*>::iterator slotIt;
//Iterate through slotList and delete all entries.
slotIt = this->slotList.begin();
while (slotIt != this->slotList.end()) {
delete (*slotIt);
slotIt++;
}
// Call the destructor on each list entry.
slotList.clear();
}
void FixedSlotSequence::executeAndAdvance() {
(*this->current)->handler->performOperation((*this->current)->opcode);
current->handler->performOperation(current->opcode);
// if (returnValue != RETURN_OK) {
// this->sendErrorMessage( returnValue );
// }
@ -31,53 +26,50 @@ void FixedSlotSequence::executeAndAdvance() {
uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
uint32_t oldTime;
std::list<FixedSequenceSlot*>::iterator it;
it = current;
SlotListIter slotListIter = current;
// Get the pollingTimeMs of the current slot object.
oldTime = (*it)->pollingTimeMs;
oldTime = slotListIter->pollingTimeMs;
// Advance to the next object.
it++;
slotListIter++;
// Find the next interval which is not 0.
while (it != slotList.end()) {
if (oldTime != (*it)->pollingTimeMs) {
return (*it)->pollingTimeMs - oldTime;
while (slotListIter != slotList.end()) {
if (oldTime != slotListIter->pollingTimeMs) {
return slotListIter->pollingTimeMs - oldTime;
} else {
it++;
slotListIter++;
}
}
// If the list end is reached (this is definitely an interval != 0),
// the interval is calculated by subtracting the remaining time of the PST
// and adding the start time of the first handler in the list.
it = slotList.begin();
return lengthMs - oldTime + (*it)->pollingTimeMs;
slotListIter = slotList.begin();
return lengthMs - oldTime + slotListIter->pollingTimeMs;
}
uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
uint32_t currentTime;
std::list<FixedSequenceSlot*>::iterator it;
it = current;
SlotListIter slotListIter = current;
// 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 == slotList.begin()){
return lengthMs - (*(--slotList.end()))->pollingTimeMs + currentTime;
if (slotListIter == slotList.begin()){
return lengthMs - (--slotList.end())->pollingTimeMs + currentTime;
}
// get previous slot
it--;
slotListIter--;
return currentTime - (*it)->pollingTimeMs;
return currentTime - slotListIter->pollingTimeMs;
}
bool FixedSlotSequence::slotFollowsImmediately() {
uint32_t currentTime = (*current)->pollingTimeMs;
std::list<FixedSequenceSlot*>::iterator it;
it = this->current;
uint32_t currentTime = current->pollingTimeMs;
SlotListIter fixedSequenceIter = this->current;
// Get the pollingTimeMs of the current slot object.
if (it == slotList.begin())
if (fixedSequenceIter == slotList.begin())
return false;
it--;
if ((*it)->pollingTimeMs == currentTime) {
fixedSequenceIter--;
if (fixedSequenceIter->pollingTimeMs == currentTime) {
return true;
} else {
return false;
@ -93,26 +85,30 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
auto slotIt = slotList.begin();
uint32_t count = 0;
uint32_t time = 0;
while (slotIt != slotList.end()) {
if ((*slotIt)->handler == NULL) {
if (slotIt->handler == nullptr) {
sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!"
<< std::endl;
count++;
} else if ((*slotIt)->pollingTimeMs < time) {
} else if (slotIt->pollingTimeMs < time) {
sif::error << "FixedSlotSequence::initialize: Time: "
<< (*slotIt)->pollingTimeMs
<< slotIt->pollingTimeMs
<< " is smaller than previous with " << time << std::endl;
count++;
} else {
//All ok, print slot.
// (*slotIt)->print();
// All ok, print slot.
//info << "Current slot polling time: " << std::endl;
//info << std::dec << slotIt->pollingTimeMs << std::endl;
}
time = (*slotIt)->pollingTimeMs;
time = slotIt->pollingTimeMs;
slotIt++;
}
//info << "Number of elements in slot list: "
// << slotList.size() << std::endl;
if (count > 0) {
return HasReturnvaluesIF::RETURN_FAILED;
}
@ -121,8 +117,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep, PeriodicTaskIF* executingTask) {
this->slotList.push_back(
new FixedSequenceSlot(componentId, slotTimeMs, executionStep,
executingTask));
this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep,
executingTask));
this->current = slotList.begin();
}

View File

@ -1,9 +1,9 @@
#ifndef FIXEDSLOTSEQUENCE_H_
#define FIXEDSLOTSEQUENCE_H_
#ifndef FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
#define FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
#include <framework/devicehandlers/FixedSequenceSlot.h>
#include <framework/objectmanager/SystemObject.h>
#include <list>
#include <set>
/**
* @brief This class is the representation of a Polling Sequence Table in software.
@ -24,30 +24,39 @@
*/
class FixedSlotSequence {
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);
/**
* \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.
*/
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.
* 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,
PeriodicTaskIF* executingTask);
@ -61,47 +70,59 @@ public:
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
* of the current slot and that of the next one (or the first one, if the list end is reached)
* 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.
* @details
* This method is vitally important for the operation of the PST.
* By fetching the polling time of the current slot and that of the
* next one (or the first one, if the list end is reached)
* 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();
/**
* \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
* of the current slot and that of the prevous 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.
* @details
* This method is vitally important for the operation of the PST.
* 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();
/**
* \brief This method returns the length of this FixedSlotSequence instance.
* @brief This method returns the length of this FixedSlotSequence instance.
*/
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
* handler address of the current slot in the handlerMap. 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.
* @details
* Within this method the device handler object to be executed is chosen by
* looking up the handler address of the current slot in the handlerMap.
* 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.
*/
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.
@ -109,18 +130,21 @@ public:
* @return
*/
ReturnValue_t checkSequence() const;
protected:
/**
* \brief This list contains all OPUSPollingSlot objects, defining order and execution time of the
* device handler objects.
* @brief This list contains all PollingSlot objects, defining order and
* execution time of the device handler objects.
*
* \details The slot list is a std:list object that contains all created OPUSPollingSlot instances.
* They are NOT ordered automatically, so by 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.
* @details
* The slot list is a std:list object that contains all created
* PollingSlot instances. They are NOT ordered automatically, so by
* 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;
};

View File

@ -156,4 +156,3 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
vTaskDelay(pdMS_TO_TICKS(ms));
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -95,4 +95,4 @@ protected:
void handleMissedDeadline();
};
#endif /* POLLINGTASK_H_ */
#endif /* FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ */

View File

@ -24,6 +24,7 @@ enum {
MEMORY_HELPER, //MH
SERIALIZE_IF, //SE
FIXED_MAP, //FM
FIXED_MULTIMAP, //FMM
HAS_HEALTH_IF, //HHI
FIFO_CLASS, //FF
MESSAGE_PROXY, //MQP
@ -54,11 +55,15 @@ enum {
HAS_ACTIONS_IF, //HF
DEVICE_COMMUNICATION_IF, //DC
BSP, //BSP
TIME_STAMPER_IF, //TSI 52
TIME_STAMPER_IF, //TSI 53
//TODO This will shift all IDs for FLP
SGP4PROPAGATOR_CLASS, //SGP4 53
MUTEX_IF, //MUX 54
MESSAGE_QUEUE_IF,//MQI 55
SGP4PROPAGATOR_CLASS, //SGP4 54
MUTEX_IF, //MUX 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 !
};

View File

@ -1,27 +1,23 @@
#ifndef HASRETURNVALUESIF_H_
#define HASRETURNVALUESIF_H_
#ifndef FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
#define FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
#include <stdint.h>
#include <framework/returnvalues/FwClassIds.h>
#include <config/returnvalues/classIds.h>
#include <cstdint>
#define MAKE_RETURN_CODE( number ) ((INTERFACE_ID << 8) + (number))
typedef uint16_t ReturnValue_t;
class HasReturnvaluesIF {
public:
static const ReturnValue_t RETURN_OK = 0;
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 /* HASRETURNVALUESIF_H_ */
#endif /* FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ */

View File

@ -1,12 +1,12 @@
#ifndef RMAPCOOKIE_H_
#define RMAPCOOKIE_H_
#include <framework/devicehandlers/Cookie.h>
#include <framework/devicehandlers/CookieIF.h>
#include <framework/rmap/rmapStructs.h>
class RMAPChannelIF;
class RMAPCookie : public Cookie{
class RMAPCookie : public CookieIF {
public:
//To Uli: Sorry, I need an empty ctor to initialize an array of cookies.
RMAPCookie();

View File

@ -5,43 +5,43 @@
RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() {
}
ReturnValue_t RmapDeviceCommunicationIF::sendMessage(Cookie* cookie,
ReturnValue_t RmapDeviceCommunicationIF::sendMessage(CookieIF* cookie,
uint8_t* data, uint32_t 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);
}
ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage(
Cookie* cookie) {
CookieIF* cookie) {
return RMAP::sendReadCommand((RMAPCookie *) cookie,
((RMAPCookie *) cookie)->getMaxReplyLen());
}
ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(Cookie* cookie,
ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(CookieIF* cookie,
uint8_t** buffer, uint32_t* size) {
return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size);
}
ReturnValue_t RmapDeviceCommunicationIF::setAddress(Cookie* cookie,
ReturnValue_t RmapDeviceCommunicationIF::setAddress(CookieIF* cookie,
uint32_t address) {
((RMAPCookie *) cookie)->setAddress(address);
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t RmapDeviceCommunicationIF::getAddress(Cookie* cookie) {
uint32_t RmapDeviceCommunicationIF::getAddress(CookieIF* cookie) {
return ((RMAPCookie *) cookie)->getAddress();
}
ReturnValue_t RmapDeviceCommunicationIF::setParameter(Cookie* cookie,
ReturnValue_t RmapDeviceCommunicationIF::setParameter(CookieIF* cookie,
uint32_t parameter) {
//TODO Empty?
return HasReturnvaluesIF::RETURN_FAILED;
}
uint32_t RmapDeviceCommunicationIF::getParameter(Cookie* cookie) {
uint32_t RmapDeviceCommunicationIF::getParameter(CookieIF* cookie) {
return 0;
}

View File

@ -25,7 +25,7 @@ public:
* @param maxReplyLen Maximum length of expected reply
* @return
*/
virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
virtual ReturnValue_t open(CookieIF **cookie, uint32_t address,
uint32_t maxReplyLen) = 0;
/**
@ -39,7 +39,7 @@ public:
* @param maxReplyLen
* @return
*/
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address,
virtual ReturnValue_t reOpen(CookieIF *cookie, uint32_t address,
uint32_t maxReplyLen) = 0;
@ -47,7 +47,7 @@ public:
* Closing call of connection and memory free of cookie. Mission dependent call
* @param cookie
*/
virtual void close(Cookie *cookie) = 0;
virtual void close(CookieIF *cookie) = 0;
//SHOULDDO can data be const?
/**
@ -58,23 +58,23 @@ public:
* @param len Length of the data to be send
* @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);
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);
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_ */