updating code from Flying Laptop
This is the framework of Flying Laptop OBSW version A.13.0.
This commit is contained in:
23
devicehandlers/AcceptsDeviceResponsesIF.h
Normal file
23
devicehandlers/AcceptsDeviceResponsesIF.h
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @file AcceptsDeviceResponsesIF.h
|
||||
* @brief This file defines the AcceptsDeviceResponsesIF class.
|
||||
* @date 15.05.2013
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#ifndef ACCEPTSDEVICERESPONSESIF_H_
|
||||
#define ACCEPTSDEVICERESPONSESIF_H_
|
||||
|
||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||
|
||||
class AcceptsDeviceResponsesIF {
|
||||
public:
|
||||
/**
|
||||
* Default empty virtual destructor.
|
||||
*/
|
||||
virtual ~AcceptsDeviceResponsesIF() {
|
||||
}
|
||||
virtual MessageQueueId_t getDeviceQueue() = 0;
|
||||
};
|
||||
|
||||
#endif /* ACCEPTSDEVICERESPONSESIF_H_ */
|
@ -40,11 +40,6 @@ void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = commandChildren(mode, submode);
|
||||
if (result == NEED_SECOND_STEP) {
|
||||
internalState = STATE_NEED_SECOND_STEP;
|
||||
} else if (result != RETURN_OK) {
|
||||
//TODO: Debug
|
||||
debug << std::hex << getObjectId()
|
||||
<< ": AssemblyBase::commandChildren returned: " << result
|
||||
<< std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +135,6 @@ void AssemblyBase::handleModeTransitionFailed(ReturnValue_t result) {
|
||||
if (targetMode == MODE_OFF) {
|
||||
triggerEvent(CHILD_PROBLEMS, result);
|
||||
internalState = STATE_NONE;
|
||||
//TODO: Maybe go to ERROR_ON here. Does this cause problems in subsystem?
|
||||
setMode(targetMode, targetSubmode);
|
||||
} else {
|
||||
if (handleChildrenChangedHealth()) {
|
||||
@ -157,7 +151,7 @@ void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo,
|
||||
CommandMessage command;
|
||||
HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET,
|
||||
health);
|
||||
if (commandQueue.sendMessage(sendTo, &command) == RETURN_OK) {
|
||||
if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) {
|
||||
commandsOutstanding++;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
class AssemblyBase: public SubsystemBase {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = ASSEMBLY_BASE;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ASSEMBLY_BASE;
|
||||
static const ReturnValue_t NEED_SECOND_STEP = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t NEED_TO_RECONFIGURE = MAKE_RETURN_CODE(0x02);
|
||||
static const ReturnValue_t MODE_FALLBACK = MAKE_RETURN_CODE(0x03);
|
||||
|
@ -6,7 +6,7 @@ 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, FDIRBase* customFdir, uint32_t cmdQueueSize) :
|
||||
uint32_t parent, FailureIsolationBase* customFdir, uint32_t cmdQueueSize) :
|
||||
DeviceHandlerBase(ioBoardAddress, setObjectId, maxDeviceReplyLen,
|
||||
setDeviceSwitch, deviceCommunication, thermalStatePoolId,
|
||||
thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), cmdQueueSize), parentId(
|
||||
|
@ -10,7 +10,7 @@ public:
|
||||
object_id_t deviceCommunication, uint32_t maxDeviceReplyLen,
|
||||
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
|
||||
uint32_t thermalRequestPoolId, uint32_t parent,
|
||||
FDIRBase* customFdir = NULL,
|
||||
FailureIsolationBase* customFdir = NULL,
|
||||
uint32_t cmdQueueSize = 20);
|
||||
virtual ~ChildHandlerBase();
|
||||
|
||||
|
@ -1,14 +1,7 @@
|
||||
/*
|
||||
* ChildHandlerFDIR.cpp
|
||||
*
|
||||
* Created on: 08.02.2016
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/devicehandlers/ChildHandlerFDIR.h>
|
||||
|
||||
ChildHandlerFDIR::ChildHandlerFDIR(object_id_t owner, object_id_t faultTreeParent, uint32_t recoveryCount) :
|
||||
DeviceHandlerFDIR(owner, faultTreeParent) {
|
||||
DeviceHandlerFailureIsolation(owner, faultTreeParent) {
|
||||
recoveryCounter.setFailureThreshold(recoveryCount);
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,18 @@
|
||||
/*
|
||||
* ChildHandlerFDIR.h
|
||||
*
|
||||
* Created on: 08.02.2016
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_DEVICEHANDLERS_CHILDHANDLERFDIR_H_
|
||||
#define FRAMEWORK_DEVICEHANDLERS_CHILDHANDLERFDIR_H_
|
||||
|
||||
#include <framework/devicehandlers/DeviceHandlerFDIR.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerFailureIsolation.h>
|
||||
|
||||
/**
|
||||
* Very simple extension to normal FDIR.
|
||||
* Does not have a default fault tree parent and
|
||||
* allows to make the recovery count settable to 0.
|
||||
*/
|
||||
class ChildHandlerFDIR: public DeviceHandlerFDIR {
|
||||
class ChildHandlerFDIR: public DeviceHandlerFailureIsolation {
|
||||
public:
|
||||
ChildHandlerFDIR(object_id_t owner, object_id_t faultTreeParent =
|
||||
NO_FAULT_TREE_PARENT, uint32_t recoveryCount = 0);
|
||||
~ChildHandlerFDIR();
|
||||
virtual ~ChildHandlerFDIR();
|
||||
protected:
|
||||
static const object_id_t NO_FAULT_TREE_PARENT = 0;
|
||||
};
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
class DeviceCommunicationIF: public HasReturnvaluesIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_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);
|
||||
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x02);
|
||||
@ -39,7 +39,7 @@ public:
|
||||
|
||||
virtual void close(Cookie *cookie) = 0;
|
||||
|
||||
//TODO can data be const?
|
||||
//SHOULDDO can data be const?
|
||||
virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
|
||||
uint32_t len) = 0;
|
||||
|
||||
|
@ -1,52 +1,58 @@
|
||||
/*
|
||||
* DeviceHandlerBase.cpp
|
||||
*
|
||||
* Created on: 30.10.2012
|
||||
* Author: mohr
|
||||
*/
|
||||
|
||||
#include <config/datapool/dataPoolInit.h>
|
||||
#include <mission/devices/PCDUHandler.h>
|
||||
#include <config/hardware/IoBoardAddresses.h>
|
||||
#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_ccitt.h>
|
||||
#include <framework/objectmanager/ObjectManager.h>
|
||||
#include <framework/rmap/RMAP.h>
|
||||
#include <framework/rmap/RMAPChannelIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include <framework/subsystem/SubsystemBase.h>
|
||||
#include <mission/tmtcservices/AcceptsDeviceResponsesIF.h>
|
||||
#include <mission/controllers/tcs/ThermalComponentIF.h>
|
||||
#include <framework/thermal/ThermalComponentIF.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
|
||||
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,
|
||||
FDIRBase* fdirInstance, uint32_t cmdQueueSize) :
|
||||
FailureIsolationBase* fdirInstance, uint32_t cmdQueueSize) :
|
||||
SystemObject(setObjectId), rawPacket(0), rawPacketLen(0), mode(
|
||||
MODE_OFF), submode(SUBMODE_NONE), pstStep(0), maxDeviceReplyLen(
|
||||
maxDeviceReplyLen), wiretappingMode(OFF), theOneWhoReceivesRawTraffic(
|
||||
0), storedRawData(StorageManagerIF::INVALID_ADDRESS), theOneWhoWantsToReadRawTraffic(
|
||||
0), powerSwitcher(NULL), IPCStore(NULL), deviceCommunicationId(
|
||||
deviceCommunication), communicationInterface(NULL), cookie(
|
||||
NULL), commandQueue(cmdQueueSize, CommandMessage::MAX_MESSAGE_SIZE), deviceThermalStatePoolId(
|
||||
thermalStatePoolId), deviceThermalRequestPoolId(
|
||||
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), defaultFDIRUsed(
|
||||
fdirInstance == NULL), switchOffWasReported(
|
||||
false), cookieInfo(), ioBoardAddress(ioBoardAddress), timeoutStart(0), childTransitionDelay(
|
||||
5000), transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode(
|
||||
SUBMODE_NONE), deviceSwitch(setDeviceSwitch), actionHelper(
|
||||
this, &commandQueue) {
|
||||
0), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(
|
||||
fdirInstance == NULL), switchOffWasReported(false), executingTask(
|
||||
NULL), actionHelper(this, commandQueue), cookieInfo(), ioBoardAddress(
|
||||
//=======
|
||||
// NULL), IPCStore(NULL), deviceCommunicationId(deviceCommunication), communicationInterface(
|
||||
// NULL), cookie(
|
||||
// NULL), commandQueue(cmdQueueSize, CommandMessage::MAX_MESSAGE_SIZE), deviceThermalStatePoolId(
|
||||
// thermalStatePoolId), deviceThermalRequestPoolId(
|
||||
// thermalRequestPoolId), healthHelper(this, setObjectId), modeHelper(
|
||||
// this), parameterHelper(this), childTransitionFailure(RETURN_OK), ignoreMissedRepliesCount(
|
||||
// 0), fdirInstance(fdirInstance), defaultFDIRUsed(
|
||||
// fdirInstance == NULL), switchOffWasReported(false), actionHelper(
|
||||
// this, &commandQueue), cookieInfo(), ioBoardAddress(
|
||||
//>>>>>>> makefile
|
||||
ioBoardAddress), timeoutStart(0), 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) {
|
||||
this->fdirInstance = new DeviceHandlerFDIR(setObjectId);
|
||||
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
|
||||
defaultFDIRParentId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,10 +61,10 @@ DeviceHandlerBase::~DeviceHandlerBase() {
|
||||
if (defaultFDIRUsed) {
|
||||
delete fdirInstance;
|
||||
}
|
||||
|
||||
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::performInPST(uint8_t counter) {
|
||||
ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
|
||||
this->pstStep = counter;
|
||||
|
||||
if (counter == 0) {
|
||||
@ -68,9 +74,10 @@ void DeviceHandlerBase::performInPST(uint8_t counter) {
|
||||
checkSwitchState();
|
||||
decrementDeviceReplyMap();
|
||||
fdirInstance->checkForFailures();
|
||||
hkSwitcher.performOperation();
|
||||
}
|
||||
if (mode == MODE_OFF) {
|
||||
return;
|
||||
return RETURN_OK;
|
||||
}
|
||||
switch (getRmapAction()) {
|
||||
case SEND_WRITE:
|
||||
@ -92,7 +99,7 @@ void DeviceHandlerBase::performInPST(uint8_t counter) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::decrementDeviceReplyMap() {
|
||||
@ -118,7 +125,7 @@ void DeviceHandlerBase::readCommandQueue() {
|
||||
}
|
||||
|
||||
CommandMessage message;
|
||||
ReturnValue_t result = commandQueue.receiveMessage(&message);
|
||||
ReturnValue_t result = commandQueue->receiveMessage(&message);
|
||||
if (result != RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
@ -171,7 +178,7 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
break;
|
||||
}
|
||||
uint32_t currentUptime;
|
||||
OSAL::getUptime(¤tUptime);
|
||||
Clock::getUptime(¤tUptime);
|
||||
if (currentUptime - timeoutStart >= childTransitionDelay) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, childTransitionFailure, 0);
|
||||
setMode(transitionSourceMode, transitionSourceSubMode);
|
||||
@ -189,7 +196,7 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
break;
|
||||
case _MODE_WAIT_ON: {
|
||||
uint32_t currentUptime;
|
||||
OSAL::getUptime(¤tUptime);
|
||||
Clock::getUptime(¤tUptime);
|
||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT,
|
||||
0);
|
||||
@ -209,7 +216,7 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
break;
|
||||
case _MODE_WAIT_OFF: {
|
||||
uint32_t currentUptime;
|
||||
OSAL::getUptime(¤tUptime);
|
||||
Clock::getUptime(¤tUptime);
|
||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT,
|
||||
0);
|
||||
@ -347,6 +354,7 @@ void DeviceHandlerBase::setTransition(Mode_t modeTo, Submode_t submodeTo) {
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
changeHK(mode, submode, false);
|
||||
submode = newSubmode;
|
||||
mode = newMode;
|
||||
modeChanged();
|
||||
@ -355,7 +363,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
modeHelper.modeChanged(newMode, newSubmode);
|
||||
announceMode(false);
|
||||
}
|
||||
OSAL::getUptime(&timeoutStart);
|
||||
Clock::getUptime(&timeoutStart);
|
||||
|
||||
if (mode == MODE_OFF) {
|
||||
DataSet mySet;
|
||||
@ -367,6 +375,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
}
|
||||
mySet.commit(PoolVariableIF::VALID);
|
||||
}
|
||||
changeHK(mode, submode, true);
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setMode(Mode_t newMode) {
|
||||
@ -378,10 +387,10 @@ void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status,
|
||||
//This is actually the reply protocol for raw and misc dh commands.
|
||||
if (status == RETURN_OK) {
|
||||
CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, parameter);
|
||||
commandQueue.reply(&reply);
|
||||
commandQueue->reply(&reply);
|
||||
} else {
|
||||
CommandMessage reply(CommandMessage::REPLY_REJECTED, status, parameter);
|
||||
commandQueue.reply(&reply);
|
||||
commandQueue->reply(&reply);
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,8 +464,7 @@ void DeviceHandlerBase::doGetWrite() {
|
||||
ReturnValue_t result = communicationInterface->getSendSuccess(cookie);
|
||||
if (result == RETURN_OK) {
|
||||
if (wiretappingMode == RAW) {
|
||||
replyRawData(rawPacket, rawPacketLen,
|
||||
theOneWhoWantsToReadRawTraffic, 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.
|
||||
result = enableReplyInReplyMap(cookieInfo.pendingCommand);
|
||||
@ -515,19 +523,11 @@ void DeviceHandlerBase::doGetRead() {
|
||||
return;
|
||||
|
||||
if (wiretappingMode == RAW) {
|
||||
replyRawData(receivedData, receivedDataLen,
|
||||
theOneWhoWantsToReadRawTraffic);
|
||||
replyRawData(receivedData, receivedDataLen, requestedRawTraffic);
|
||||
}
|
||||
|
||||
if (mode == MODE_RAW) {
|
||||
if ((wiretappingMode == RAW)
|
||||
&& (theOneWhoReceivesRawTraffic
|
||||
== theOneWhoWantsToReadRawTraffic)) {
|
||||
//The raw packet was already sent by the wiretapping service
|
||||
} else {
|
||||
replyRawData(receivedData, receivedDataLen,
|
||||
theOneWhoReceivesRawTraffic);
|
||||
}
|
||||
replyRawReplyIfnotWiretapped(receivedData, receivedDataLen);
|
||||
} else {
|
||||
//The loop may not execute more often than the number of received bytes (worst case).
|
||||
//This approach avoids infinite loops due to buggy scanForReply routines (seen in bug 1077).
|
||||
@ -537,12 +537,12 @@ void DeviceHandlerBase::doGetRead() {
|
||||
&foundLen);
|
||||
switch (result) {
|
||||
case RETURN_OK:
|
||||
handleReply(receivedData, foundId);
|
||||
handleReply(receivedData, foundId, foundLen);
|
||||
break;
|
||||
case APERIODIC_REPLY: {
|
||||
DataSet dataSet;
|
||||
result = interpretDeviceReply(foundId, receivedData);
|
||||
if (result != RETURN_OK) {
|
||||
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
||||
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result,
|
||||
foundId);
|
||||
}
|
||||
@ -552,6 +552,7 @@ void DeviceHandlerBase::doGetRead() {
|
||||
break;
|
||||
default:
|
||||
//We need to wait for timeout.. don't know what command failed and who sent it.
|
||||
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
||||
triggerEvent(DEVICE_READING_REPLY_FAILED, result, foundLen);
|
||||
break;
|
||||
}
|
||||
@ -613,15 +614,15 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
}
|
||||
|
||||
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
|
||||
AcceptsDeviceResponsesIF>(objects::PUS_DEVICE_COMMAND_SERVICE);
|
||||
AcceptsDeviceResponsesIF>(rawDataReceiverId);
|
||||
|
||||
if (rawReceiver == NULL) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
theOneWhoReceivesRawTraffic = rawReceiver->getDeviceQueue();
|
||||
defaultRawReceiver = rawReceiver->getDeviceQueue();
|
||||
|
||||
powerSwitcher = objectManager->get<PowerSwitchIF>(objects::PCDU_HANDLER);
|
||||
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
|
||||
if (powerSwitcher == NULL) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
@ -649,6 +650,11 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = hkSwitcher.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fillCommandAndReplyMap();
|
||||
|
||||
//Set temperature target state to NON_OP.
|
||||
@ -676,12 +682,6 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
|
||||
return;
|
||||
}
|
||||
|
||||
Command_t handlerCommand = DeviceHandlerMessage::REPLY_RAW_REPLY;
|
||||
|
||||
if (isCommand) {
|
||||
handlerCommand = DeviceHandlerMessage::REPLY_RAW_COMMAND;
|
||||
}
|
||||
|
||||
CommandMessage message;
|
||||
|
||||
DeviceHandlerMessage::setDeviceHandlerRawReplayMessage(&message,
|
||||
@ -689,11 +689,11 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
|
||||
|
||||
// this->DeviceHandlerCommand = CommandMessage::CMD_NONE;
|
||||
|
||||
result = commandQueue.sendMessage(sendTo, &message);
|
||||
result = commandQueue->sendMessage(sendTo, &message);
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
IPCStore->deleteData(address);
|
||||
triggerEvent(MessageQueue::SEND_MSG_FAILED, result, sendTo);
|
||||
//Silently discard data, this indicates heavy TM traffic which should not be increased by additional events.
|
||||
}
|
||||
}
|
||||
|
||||
@ -714,23 +714,22 @@ DeviceHandlerBase::RmapAction_t DeviceHandlerBase::getRmapAction() {
|
||||
return GET_READ;
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
return NOTHING;
|
||||
}
|
||||
|
||||
MessageQueueId_t DeviceHandlerBase::getCommandQueue() const {
|
||||
return commandQueue.getId();
|
||||
return commandQueue->getId();
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
|
||||
DeviceCommandId_t foundId) {
|
||||
DeviceCommandId_t foundId, uint32_t foundLen) {
|
||||
ReturnValue_t result;
|
||||
DataSet dataSet;
|
||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(foundId);
|
||||
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
||||
triggerEvent(DEVICE_UNKNOWN_REPLY, foundId);
|
||||
return;
|
||||
}
|
||||
@ -747,12 +746,13 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
|
||||
result = interpretDeviceReply(foundId, receivedData);
|
||||
if (result != RETURN_OK) {
|
||||
//Report failed interpretation to FDIR.
|
||||
replyRawReplyIfnotWiretapped(receivedData, foundLen);
|
||||
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, foundId);
|
||||
}
|
||||
replyToReply(iter, result);
|
||||
} else {
|
||||
//Other completion failure messages are created by timeout.
|
||||
//Powering down the device might take some time during which periodic replys may still come in.
|
||||
//Powering down the device might take some time during which periodic replies may still come in.
|
||||
if (mode != _MODE_WAIT_OFF) {
|
||||
triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId);
|
||||
}
|
||||
@ -899,7 +899,8 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode,
|
||||
mySet.read();
|
||||
if (thermalRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||
if (!ThermalComponentIF::isOperational(thermalState)) {
|
||||
triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE, thermalState);
|
||||
triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE,
|
||||
thermalState);
|
||||
return NON_OP_TEMPERATURE;
|
||||
}
|
||||
}
|
||||
@ -1020,6 +1021,20 @@ ReturnValue_t DeviceHandlerBase::acceptExternalDeviceCommands() {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* interface) {
|
||||
executingTask = interface;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::replyRawReplyIfnotWiretapped(const uint8_t* data,
|
||||
size_t len) {
|
||||
if ((wiretappingMode == RAW)
|
||||
&& (defaultRawReceiver == requestedRawTraffic)) {
|
||||
//The raw packet was already sent by the wiretapping service
|
||||
} else {
|
||||
replyRawData(data, len, defaultRawReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
|
||||
CommandMessage * message) {
|
||||
ReturnValue_t result;
|
||||
@ -1028,11 +1043,11 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
|
||||
switch (DeviceHandlerMessage::getWiretappingMode(message)) {
|
||||
case RAW:
|
||||
wiretappingMode = RAW;
|
||||
theOneWhoWantsToReadRawTraffic = commandQueue.getLastPartner();
|
||||
requestedRawTraffic = commandQueue->getLastPartner();
|
||||
break;
|
||||
case TM:
|
||||
wiretappingMode = TM;
|
||||
theOneWhoWantsToReadRawTraffic = commandQueue.getLastPartner();
|
||||
requestedRawTraffic = commandQueue->getLastPartner();
|
||||
break;
|
||||
case OFF:
|
||||
wiretappingMode = OFF;
|
||||
@ -1091,23 +1106,39 @@ ReturnValue_t DeviceHandlerBase::letChildHandleMessage(
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::handleDeviceTM(SerializeIF* data,
|
||||
DeviceCommandId_t replyId, bool neverInDataPool) {
|
||||
DeviceCommandId_t replyId, bool neverInDataPool, bool forceDirectTm) {
|
||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
triggerEvent(DEVICE_UNKNOWN_REPLY, replyId);
|
||||
return;
|
||||
}
|
||||
if (iter->second.command != deviceCommandMap.end()) {
|
||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, data);
|
||||
if (iter->second.command != deviceCommandMap.end()) {//replies to a command
|
||||
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
||||
DeviceTmReportingWrapper wrapper(getObjectId(), replyId, data);
|
||||
|
||||
if (queueId != NO_COMMANDER) {
|
||||
//This may fail, but we'll ignore the fault.
|
||||
actionHelper.reportData(queueId, replyId, data);
|
||||
}
|
||||
//This check should make sure we get any TM but don't get anything doubled.
|
||||
if (wiretappingMode == TM
|
||||
&& (theOneWhoWantsToReadRawTraffic != queueId)) {
|
||||
actionHelper.reportData(theOneWhoWantsToReadRawTraffic,
|
||||
replyId, &wrapper);
|
||||
if (wiretappingMode == TM && (requestedRawTraffic != queueId)) {
|
||||
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
||||
} else if (forceDirectTm && (defaultRawReceiver != queueId)) {
|
||||
|
||||
// hiding of sender needed so the service will handle it as unexpected Data, no matter what state
|
||||
//(progress or completed) it is in
|
||||
actionHelper.reportData(defaultRawReceiver, replyId, &wrapper,
|
||||
true);
|
||||
|
||||
}
|
||||
} else { //unrequested/aperiodic replies
|
||||
if (wiretappingMode == TM) {
|
||||
actionHelper.reportData(requestedRawTraffic, replyId, &wrapper);
|
||||
} else if (forceDirectTm) {
|
||||
// hiding of sender needed so the service will handle it as unexpected Data, no matter what state
|
||||
//(progress or completed) it is in
|
||||
actionHelper.reportData(defaultRawReceiver, replyId, &wrapper,
|
||||
true);
|
||||
}
|
||||
}
|
||||
//Try to cast to DataSet and commit data.
|
||||
@ -1171,7 +1202,8 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
||||
result = COMMAND_NOT_SUPPORTED;
|
||||
} else if (iter->second.isExecuting) {
|
||||
debug << std::hex << getObjectId()
|
||||
<< ": DHB::buildInternalCommand: Command " << deviceCommandId << " isExecuting" << std::endl; //so we can track misconfigurations
|
||||
<< ": DHB::buildInternalCommand: Command "
|
||||
<< deviceCommandId << " isExecuting" << std::endl; //so we can track misconfigurations
|
||||
return; //this is an internal command, no need to report a failure here, missed reply will track if a reply is too late, otherwise, it's ok
|
||||
} else {
|
||||
iter->second.sendReplyTo = NO_COMMANDER;
|
||||
@ -1232,7 +1264,9 @@ ReturnValue_t DeviceHandlerBase::getParameter(uint8_t domainId,
|
||||
}
|
||||
|
||||
bool DeviceHandlerBase::isTransitionalMode() {
|
||||
return ((mode & (TRANSITION_MODE_BASE_ACTION_MASK | TRANSITION_MODE_CHILD_ACTION_MASK)) != 0);
|
||||
return ((mode
|
||||
& (TRANSITION_MODE_BASE_ACTION_MASK
|
||||
| TRANSITION_MODE_CHILD_ACTION_MASK)) != 0);
|
||||
}
|
||||
|
||||
bool DeviceHandlerBase::commandIsExecuting(DeviceCommandId_t commandId) {
|
||||
@ -1244,3 +1278,6 @@ bool DeviceHandlerBase::commandIsExecuting(DeviceCommandId_t commandId) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
|
||||
}
|
||||
|
@ -6,9 +6,7 @@
|
||||
#include <framework/datapool/DataSet.h>
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/devicehandlers/DeviceCommunicationIF.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerFDIR.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <framework/devicehandlers/PollingSequenceExecutableIF.h>
|
||||
#include <framework/health/HealthHelper.h>
|
||||
#include <framework/modes/HasModesIF.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
@ -16,7 +14,17 @@
|
||||
#include <framework/parameters/ParameterHelper.h>
|
||||
#include <framework/power/PowerSwitchIF.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerFailureIsolation.h>
|
||||
#include <framework/datapool/HkSwitchHelper.h>
|
||||
#include <framework/serialize/SerialFixedArrayListAdapter.h>
|
||||
#include <map>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include <framework/tasks/PeriodicTaskIF.h>
|
||||
|
||||
namespace Factory{
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
class StorageManagerIF;
|
||||
|
||||
@ -27,7 +35,7 @@ class StorageManagerIF;
|
||||
* communication with commanding objects.
|
||||
* It inherits SystemObject and thus can be created by the ObjectManagerIF.
|
||||
*
|
||||
* This class is called by the PollingSequenceTable periodically. Thus, the execution is divided into PST cycles and steps within a cycle.
|
||||
* This class uses the opcode of ExecutableObjectIF to perform a step-wise execution.
|
||||
* For each step an RMAP action is selected and executed. If data has been received (eg in case of an RMAP Read), the data will be interpreted.
|
||||
* The action for each step can be defined by the child class but as most device handlers share a 4-call (Read-getRead-write-getWrite) structure,
|
||||
* a default implementation is provided.
|
||||
@ -36,12 +44,13 @@ class StorageManagerIF;
|
||||
*/
|
||||
class DeviceHandlerBase: public DeviceHandlerIF,
|
||||
public HasReturnvaluesIF,
|
||||
public PollingSequenceExecutableIF,
|
||||
public ExecutableObjectIF,
|
||||
public SystemObject,
|
||||
public HasModesIF,
|
||||
public HasHealthIF,
|
||||
public HasActionsIF,
|
||||
public ReceivesParameterMessagesIF {
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
public:
|
||||
/**
|
||||
* The constructor passes the objectId to the SystemObject().
|
||||
@ -54,16 +63,16 @@ public:
|
||||
uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch,
|
||||
object_id_t deviceCommunication, uint32_t thermalStatePoolId =
|
||||
PoolVariableIF::NO_PARAMETER,
|
||||
uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER, FDIRBase* fdirInstance = NULL, uint32_t cmdQueueSize = 20);
|
||||
uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER,
|
||||
FailureIsolationBase* fdirInstance = NULL, uint32_t cmdQueueSize = 20);
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue(void) const;
|
||||
|
||||
virtual void performInPST(uint8_t counter);
|
||||
virtual ReturnValue_t performOperation(uint8_t counter);
|
||||
|
||||
virtual ReturnValue_t initialize();
|
||||
|
||||
/**
|
||||
* MUST be called after initialize(), not before! TODO: Is this statement still valid?
|
||||
*
|
||||
* @param parentQueueId
|
||||
*/
|
||||
@ -81,13 +90,15 @@ public:
|
||||
HealthState getHealth();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
|
||||
void setTaskIF(PeriodicTaskIF* interface);
|
||||
protected:
|
||||
/**
|
||||
* The Returnvalues id of this class, required by HasReturnvaluesIF
|
||||
*/
|
||||
static const uint8_t INTERFACE_ID = DEVICE_HANDLER_BASE;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
||||
|
||||
static const ReturnValue_t INVALID_CHANNEL = MAKE_RETURN_CODE(4);
|
||||
static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(5);
|
||||
@ -106,19 +117,6 @@ protected:
|
||||
static const DeviceCommandId_t NO_COMMAND_ID = -2;
|
||||
static const MessageQueueId_t NO_COMMANDER = 0;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
};
|
||||
|
||||
/**
|
||||
* Pointer to the raw packet that will be sent.
|
||||
*/
|
||||
@ -143,7 +141,7 @@ protected:
|
||||
Submode_t submode;
|
||||
|
||||
/**
|
||||
* This is the counter value from performInPST().
|
||||
* This is the counter value from performOperation().
|
||||
*/
|
||||
uint8_t pstStep;
|
||||
|
||||
@ -163,11 +161,12 @@ protected:
|
||||
} wiretappingMode;
|
||||
|
||||
/**
|
||||
* the message queue which commanded raw mode
|
||||
* A message queue that accepts raw replies
|
||||
*
|
||||
* This is the one to receive raw replies
|
||||
* Statically initialized in initialize() to a configurable object. Used when there is no method
|
||||
* of finding a recipient, ie raw mode and reporting erreonous replies
|
||||
*/
|
||||
MessageQueueId_t theOneWhoReceivesRawTraffic;
|
||||
MessageQueueId_t defaultRawReceiver;
|
||||
|
||||
store_address_t storedRawData;
|
||||
|
||||
@ -176,7 +175,7 @@ protected:
|
||||
*
|
||||
* if #isWiretappingActive all raw communication from and to the device will be sent to this queue
|
||||
*/
|
||||
MessageQueueId_t theOneWhoWantsToReadRawTraffic;
|
||||
MessageQueueId_t requestedRawTraffic;
|
||||
|
||||
/**
|
||||
* the object used to set power switches
|
||||
@ -208,7 +207,7 @@ protected:
|
||||
/**
|
||||
* The MessageQueue used to receive device handler commands and to send replies.
|
||||
*/
|
||||
MessageQueue commandQueue;
|
||||
MessageQueueIF* commandQueue;
|
||||
|
||||
/**
|
||||
* this is the datapool variable with the thermal state of the device
|
||||
@ -241,12 +240,21 @@ protected:
|
||||
|
||||
uint32_t ignoreMissedRepliesCount; //!< Counts if communication channel lost a reply, so some missed replys can be ignored.
|
||||
|
||||
FDIRBase* fdirInstance; //!< Pointer to the used FDIR instance. If not provided by child, default class is instantiated.
|
||||
FailureIsolationBase* fdirInstance; //!< Pointer to the used FDIR instance. If not provided by child, default class is instantiated.
|
||||
|
||||
HkSwitchHelper hkSwitcher;
|
||||
|
||||
bool defaultFDIRUsed; //!< To correctly delete the default instance.
|
||||
|
||||
bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown.
|
||||
|
||||
static object_id_t powerSwitcherId; //!< Object which switches power on and off.
|
||||
|
||||
static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default.
|
||||
|
||||
static object_id_t defaultFDIRParentId; //!< Object which may be the root cause of an identified fault.
|
||||
|
||||
PeriodicTaskIF* executingTask;
|
||||
/**
|
||||
* Helper function to report a missed reply
|
||||
*
|
||||
@ -593,6 +601,12 @@ protected:
|
||||
virtual void replyRawData(const uint8_t *data, size_t len,
|
||||
MessageQueueId_t sendTo, bool isCommand = false);
|
||||
|
||||
/**
|
||||
* Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping is active and if so,
|
||||
* does not send the Data as the wiretapping will have sent it already
|
||||
*/
|
||||
void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len);
|
||||
|
||||
/**
|
||||
* Return the switches connected to the device.
|
||||
*
|
||||
@ -663,6 +677,11 @@ protected:
|
||||
*/
|
||||
virtual void setNormalDatapoolEntriesInvalid() = 0;
|
||||
|
||||
/**
|
||||
* build a list of sids and pass it to the #hkSwitcher
|
||||
*/
|
||||
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
||||
|
||||
/**
|
||||
* Children can overwrite this function to suppress checking of the command Queue
|
||||
*
|
||||
@ -679,7 +698,7 @@ protected:
|
||||
bool isAwaitingReply();
|
||||
|
||||
void handleDeviceTM(SerializeIF *dataSet, DeviceCommandId_t commandId,
|
||||
bool neverInDataPool = false);
|
||||
bool neverInDataPool = false, bool forceDirectTm = false);
|
||||
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode);
|
||||
@ -732,12 +751,6 @@ protected:
|
||||
virtual ReturnValue_t acceptExternalDeviceCommands();
|
||||
|
||||
bool commandIsExecuting(DeviceCommandId_t commandId);
|
||||
private:
|
||||
|
||||
/**
|
||||
* Information about commands
|
||||
*/
|
||||
DeviceCommandMap deviceCommandMap;
|
||||
|
||||
/**
|
||||
* Information about expected replies
|
||||
@ -750,6 +763,7 @@ private:
|
||||
uint8_t periodic; //!< if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles
|
||||
DeviceCommandMap::iterator command; //!< The command that expects this reply.
|
||||
};
|
||||
|
||||
/**
|
||||
* Definition for the important reply Map.
|
||||
*/
|
||||
@ -767,6 +781,15 @@ private:
|
||||
*/
|
||||
DeviceReplyMap deviceReplyMap;
|
||||
|
||||
/**
|
||||
* Information about commands
|
||||
*/
|
||||
DeviceCommandMap deviceCommandMap;
|
||||
|
||||
ActionHelper actionHelper;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* State a cookie is in.
|
||||
*
|
||||
@ -837,8 +860,6 @@ private:
|
||||
*/
|
||||
const uint8_t deviceSwitch;
|
||||
|
||||
ActionHelper actionHelper;
|
||||
|
||||
/**
|
||||
* read the command queue
|
||||
*/
|
||||
@ -880,8 +901,9 @@ private:
|
||||
*
|
||||
* @param data the found packet
|
||||
* @param id the found id
|
||||
* @foundLen the length of the packet
|
||||
*/
|
||||
void handleReply(const uint8_t *data, DeviceCommandId_t id);
|
||||
void handleReply(const uint8_t *data, DeviceCommandId_t id, uint32_t foundLen);
|
||||
|
||||
void replyToReply(DeviceReplyMap::iterator iter, ReturnValue_t status);
|
||||
/**
|
||||
|
@ -1,20 +1,14 @@
|
||||
/*
|
||||
* DeviceHandlerFDIR.cpp
|
||||
*
|
||||
* Created on: 09.09.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerFDIR.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerFailureIsolation.h>
|
||||
#include <framework/health/HealthTableIF.h>
|
||||
#include <framework/power/Fuse.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <mission/controllers/power/Fuse.h>
|
||||
#include <mission/controllers/tcs/ThermalComponentIF.h>
|
||||
#include <framework/thermal/ThermalComponentIF.h>
|
||||
|
||||
//TODO: Mechanisms have no power FDIR..
|
||||
DeviceHandlerFDIR::DeviceHandlerFDIR(object_id_t owner, object_id_t parent) :
|
||||
FDIRBase(owner, parent), strangeReplyCount(MAX_STRANGE_REPLIES,
|
||||
object_id_t DeviceHandlerFailureIsolation::powerConfirmationId = 0;
|
||||
|
||||
DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent) :
|
||||
FailureIsolationBase(owner, parent), strangeReplyCount(MAX_STRANGE_REPLIES,
|
||||
STRANGE_REPLIES_TIME_MS, parameterDomainBase++), missedReplyCount(
|
||||
MAX_MISSED_REPLY_COUNT, MISSED_REPLY_TIME_MS,
|
||||
parameterDomainBase++), recoveryCounter(MAX_REBOOT,
|
||||
@ -22,25 +16,11 @@ DeviceHandlerFDIR::DeviceHandlerFDIR(object_id_t owner, object_id_t parent) :
|
||||
0) {
|
||||
}
|
||||
|
||||
DeviceHandlerFDIR::~DeviceHandlerFDIR() {
|
||||
DeviceHandlerFailureIsolation::~DeviceHandlerFailureIsolation() {
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerFDIR::eventReceived(EventMessage* event) {
|
||||
if (fdirState != NONE) {
|
||||
//Only wait for those events, ignore all others.
|
||||
if (event->getParameter1() == HasHealthIF::HEALTHY
|
||||
&& event->getEvent() == HasHealthIF::HEALTH_INFO) {
|
||||
setFdirState(NONE);
|
||||
}
|
||||
if (event->getEvent() == HasModesIF::MODE_INFO
|
||||
&& fdirState != RECOVERY_ONGOING) {
|
||||
setFdirState(NONE);
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (owner->getHealth() == HasHealthIF::FAULTY
|
||||
|| owner->getHealth() == HasHealthIF::PERMANENT_FAULTY) {
|
||||
//Ignore all events in case device is already faulty.
|
||||
ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event) {
|
||||
if(isFdirInActionOrAreWeFaulty(event)) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
@ -76,13 +56,11 @@ ReturnValue_t DeviceHandlerFDIR::eventReceived(EventMessage* event) {
|
||||
break;
|
||||
case StorageManagerIF::GET_DATA_FAILED:
|
||||
case StorageManagerIF::STORE_DATA_FAILED:
|
||||
case MessageQueue::SEND_MSG_FAILED:
|
||||
//Rather strange bugs, occur in RAW mode only. TODO:? By now: Ignore.
|
||||
//Rather strange bugs, occur in RAW mode only. Ignore.
|
||||
break;
|
||||
case DeviceHandlerIF::INVALID_DEVICE_COMMAND:
|
||||
//Ignore, is bad configuration. We can't do anything in flight.
|
||||
break;
|
||||
case DeviceHandlerIF::MONITORING_AMBIGUOUS:
|
||||
case HasHealthIF::HEALTH_INFO:
|
||||
case HasModesIF::MODE_INFO:
|
||||
case HasModesIF::CHANGING_MODE:
|
||||
@ -111,13 +89,17 @@ ReturnValue_t DeviceHandlerFDIR::eventReceived(EventMessage* event) {
|
||||
case ThermalComponentIF::COMPONENT_TEMP_OOL_LOW:
|
||||
case ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH:
|
||||
//Well, the device is not really faulty, but it is required to stay off as long as possible.
|
||||
//*******ACS*****
|
||||
case DeviceHandlerIF::MONITORING_LIMIT_EXCEEDED:
|
||||
setFaulty(event->getEvent());
|
||||
break;
|
||||
case ThermalComponentIF::TEMP_NOT_IN_OP_RANGE:
|
||||
//Ignore, is information only.
|
||||
break;
|
||||
//*******Default monitoring variables. Are currently not used.*****
|
||||
// case DeviceHandlerIF::MONITORING_LIMIT_EXCEEDED:
|
||||
// setFaulty(event->getEvent());
|
||||
// break;
|
||||
// case DeviceHandlerIF::MONITORING_AMBIGUOUS:
|
||||
// break;
|
||||
default:
|
||||
//We don't know the event, someone else should handle it.
|
||||
return RETURN_FAILED;
|
||||
@ -125,7 +107,7 @@ ReturnValue_t DeviceHandlerFDIR::eventReceived(EventMessage* event) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::eventConfirmed(EventMessage* event) {
|
||||
void DeviceHandlerFailureIsolation::eventConfirmed(EventMessage* event) {
|
||||
switch (event->getEvent()) {
|
||||
case DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED:
|
||||
case DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED:
|
||||
@ -143,13 +125,13 @@ void DeviceHandlerFDIR::eventConfirmed(EventMessage* event) {
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::decrementFaultCounters() {
|
||||
void DeviceHandlerFailureIsolation::decrementFaultCounters() {
|
||||
strangeReplyCount.checkForDecrement();
|
||||
missedReplyCount.checkForDecrement();
|
||||
recoveryCounter.checkForDecrement();
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::handleRecovery(Event reason) {
|
||||
void DeviceHandlerFailureIsolation::handleRecovery(Event reason) {
|
||||
clearFaultCounters();
|
||||
if (!recoveryCounter.incrementAndCheck()) {
|
||||
startRecovery(reason);
|
||||
@ -158,7 +140,7 @@ void DeviceHandlerFDIR::handleRecovery(Event reason) {
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::wasParentsFault(EventMessage* event) {
|
||||
void DeviceHandlerFailureIsolation::wasParentsFault(EventMessage* event) {
|
||||
//We'll better ignore the SWITCH_WENT_OFF event and await a system-wide reset.
|
||||
//This means, no fault message will come through until a MODE_ or HEALTH_INFO message comes through -> Is that ok?
|
||||
//Same issue in TxFailureIsolation!
|
||||
@ -168,18 +150,18 @@ void DeviceHandlerFDIR::wasParentsFault(EventMessage* event) {
|
||||
// }
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::clearFaultCounters() {
|
||||
void DeviceHandlerFailureIsolation::clearFaultCounters() {
|
||||
strangeReplyCount.clear();
|
||||
missedReplyCount.clear();
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerFDIR::initialize() {
|
||||
ReturnValue_t result = FDIRBase::initialize();
|
||||
ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
|
||||
ReturnValue_t result = FailureIsolationBase::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
ConfirmsFailuresIF* power = objectManager->get<ConfirmsFailuresIF>(
|
||||
objects::PCDU_HANDLER);
|
||||
powerConfirmationId);
|
||||
if (power == NULL) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
@ -187,31 +169,31 @@ ReturnValue_t DeviceHandlerFDIR::initialize() {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::setFdirState(FDIRState state) {
|
||||
FDIRBase::throwFdirEvent(FDIR_CHANGED_STATE, state, fdirState);
|
||||
void DeviceHandlerFailureIsolation::setFdirState(FDIRState state) {
|
||||
FailureIsolationBase::throwFdirEvent(FDIR_CHANGED_STATE, state, fdirState);
|
||||
fdirState = state;
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::triggerEvent(Event event, uint32_t parameter1,
|
||||
void DeviceHandlerFailureIsolation::triggerEvent(Event event, uint32_t parameter1,
|
||||
uint32_t parameter2) {
|
||||
//Do not throw error events if fdirState != none.
|
||||
//This will still forward MODE and HEALTH INFO events in any case.
|
||||
if (fdirState == NONE || EVENT::getSeverity(event) == SEVERITY::INFO) {
|
||||
FDIRBase::triggerEvent(event, parameter1, parameter2);
|
||||
FailureIsolationBase::triggerEvent(event, parameter1, parameter2);
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceHandlerFDIR::isFdirActionInProgress() {
|
||||
bool DeviceHandlerFailureIsolation::isFdirActionInProgress() {
|
||||
return (fdirState != NONE);
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::startRecovery(Event reason) {
|
||||
void DeviceHandlerFailureIsolation::startRecovery(Event reason) {
|
||||
throwFdirEvent(FDIR_STARTS_RECOVERY, EVENT::getEventId(reason));
|
||||
setOwnerHealth(HasHealthIF::NEEDS_RECOVERY);
|
||||
setFdirState(RECOVERY_ONGOING);
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerFDIR::getParameter(uint8_t domainId,
|
||||
ReturnValue_t DeviceHandlerFailureIsolation::getParameter(uint8_t domainId,
|
||||
uint16_t parameterId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t result = strangeReplyCount.getParameter(domainId, parameterId,
|
||||
@ -232,8 +214,30 @@ ReturnValue_t DeviceHandlerFDIR::getParameter(uint8_t domainId,
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
|
||||
void DeviceHandlerFDIR::setFaulty(Event reason) {
|
||||
void DeviceHandlerFailureIsolation::setFaulty(Event reason) {
|
||||
throwFdirEvent(FDIR_TURNS_OFF_DEVICE, EVENT::getEventId(reason));
|
||||
setOwnerHealth(HasHealthIF::FAULTY);
|
||||
setFdirState(AWAIT_SHUTDOWN);
|
||||
}
|
||||
|
||||
bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty(
|
||||
EventMessage* event) {
|
||||
if (fdirState != NONE) {
|
||||
//Only wait for those events, ignore all others.
|
||||
if (event->getParameter1() == HasHealthIF::HEALTHY
|
||||
&& event->getEvent() == HasHealthIF::HEALTH_INFO) {
|
||||
setFdirState(NONE);
|
||||
}
|
||||
if (event->getEvent() == HasModesIF::MODE_INFO
|
||||
&& fdirState != RECOVERY_ONGOING) {
|
||||
setFdirState(NONE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (owner->getHealth() == HasHealthIF::FAULTY
|
||||
|| owner->getHealth() == HasHealthIF::PERMANENT_FAULTY) {
|
||||
//Ignore all events in case device is already faulty.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,27 +1,22 @@
|
||||
/*
|
||||
* DeviceHandlerFDIR.h
|
||||
*
|
||||
* Created on: 09.09.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFDIR_H_
|
||||
#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFDIR_H_
|
||||
#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_
|
||||
#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_
|
||||
|
||||
#include <framework/fdir/FaultCounter.h>
|
||||
#include <framework/fdir/FDIRBase.h>
|
||||
#include <framework/fdir/FailureIsolationBase.h>
|
||||
namespace Factory{
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
class DeviceHandlerFDIR: public FDIRBase {
|
||||
|
||||
class DeviceHandlerFailureIsolation: public FailureIsolationBase {
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
friend class Heater;
|
||||
public:
|
||||
DeviceHandlerFDIR(object_id_t owner, object_id_t parent = objects::IO_ASSEMBLY);
|
||||
~DeviceHandlerFDIR();
|
||||
virtual ReturnValue_t eventReceived(EventMessage* event);
|
||||
void eventConfirmed(EventMessage* event);
|
||||
void wasParentsFault(EventMessage* event);
|
||||
void decrementFaultCounters();
|
||||
DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent);
|
||||
~DeviceHandlerFailureIsolation();
|
||||
ReturnValue_t initialize();
|
||||
void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
||||
bool isFdirActionInProgress();
|
||||
void triggerEvent(Event event, uint32_t parameter1 = 0,
|
||||
uint32_t parameter2 = 0);bool isFdirActionInProgress();
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
@ -30,25 +25,28 @@ protected:
|
||||
FaultCounter missedReplyCount;
|
||||
FaultCounter recoveryCounter;
|
||||
enum FDIRState {
|
||||
NONE,
|
||||
RECOVERY_ONGOING,
|
||||
DEVICE_MIGHT_BE_OFF,
|
||||
AWAIT_SHUTDOWN
|
||||
NONE, RECOVERY_ONGOING, DEVICE_MIGHT_BE_OFF, AWAIT_SHUTDOWN
|
||||
};
|
||||
FDIRState fdirState;
|
||||
MessageQueueId_t powerConfirmation;
|
||||
//TODO: Arbitrary numbers! Adjust!
|
||||
static object_id_t powerConfirmationId;
|
||||
static const uint32_t MAX_REBOOT = 1;
|
||||
static const uint32_t REBOOT_TIME_MS = 180000;
|
||||
static const uint32_t MAX_STRANGE_REPLIES = 10;
|
||||
static const uint32_t STRANGE_REPLIES_TIME_MS = 10000;
|
||||
static const uint32_t MAX_MISSED_REPLY_COUNT = 5;
|
||||
static const uint32_t MISSED_REPLY_TIME_MS = 10000;
|
||||
virtual ReturnValue_t eventReceived(EventMessage* event);
|
||||
virtual void eventConfirmed(EventMessage* event);
|
||||
void wasParentsFault(EventMessage* event);
|
||||
void decrementFaultCounters();
|
||||
void handleRecovery(Event reason);
|
||||
virtual void clearFaultCounters();
|
||||
void setFdirState(FDIRState state);
|
||||
void startRecovery(Event reason);
|
||||
void setFaulty(Event reason);
|
||||
|
||||
bool isFdirInActionOrAreWeFaulty(EventMessage* event);
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFDIR_H_ */
|
||||
#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERFAILUREISOLATION_H_ */
|
@ -4,8 +4,8 @@
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerMessage.h>
|
||||
#include <framework/events/Event.h>
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
#include <framework/modes/HasModesIF.h>
|
||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||
|
||||
/**
|
||||
* This is the Interface used to communicate with a device handler.
|
||||
@ -52,7 +52,7 @@ public:
|
||||
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW);
|
||||
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH);
|
||||
|
||||
static const uint8_t INTERFACE_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);
|
||||
static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2);
|
||||
@ -63,6 +63,7 @@ public:
|
||||
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 scan for reply
|
||||
// static const ReturnValue_t TOO_SHORT = MAKE_RETURN_CODE(0xB1);
|
||||
@ -82,6 +83,19 @@ public:
|
||||
0xD0);
|
||||
static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS =
|
||||
MAKE_RETURN_CODE(0xD1);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
@ -89,7 +89,7 @@ void DeviceHandlerMessage::clear(CommandMessage* message) {
|
||||
ipcStore->deleteData(getStoreAddress(message));
|
||||
}
|
||||
}
|
||||
/* NO BREAK*/
|
||||
/* NO BREAK falls through*/
|
||||
case CMD_SWITCH_IOBOARD:
|
||||
case CMD_WIRETAPPING:
|
||||
message->setCommand(CommandMessage::CMD_NONE);
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <framework/ipc/CommandMessage.h>
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
//TODO: rework the static constructors to name the type of command they are building, maybe even hide setting the commandID.
|
||||
//SHOULDDO: rework the static constructors to name the type of command they are building, maybe even hide setting the commandID.
|
||||
|
||||
/**
|
||||
* This is used to uniquely identify commands that are sent to a device
|
||||
@ -25,7 +25,7 @@ public:
|
||||
/**
|
||||
* These are the commands that can be sent to a DeviceHandlerBase
|
||||
*/
|
||||
static const uint8_t MESSAGE_ID = DEVICE_HANDLER_COMMAND_MESSAGE_ID;
|
||||
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::DEVICE_HANDLER_COMMAND;
|
||||
static const Command_t CMD_RAW = MAKE_COMMAND_ID( 1 ); //!< Sends a raw command, setParameter is a ::store_id_t containing the raw packet to send
|
||||
// static const Command_t CMD_DIRECT = MAKE_COMMAND_ID( 2 ); //!< Sends a direct command, setParameter is a ::DeviceCommandId_t, setParameter2 is a ::store_id_t containing the data needed for the command
|
||||
static const Command_t CMD_SWITCH_IOBOARD = MAKE_COMMAND_ID( 3 ); //!< Requests a IO-Board switch, setParameter() is the IO-Board identifier
|
||||
|
21
devicehandlers/FixedSequenceSlot.cpp
Normal file
21
devicehandlers/FixedSequenceSlot.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @file PollingSlot.cpp
|
||||
* @brief This file defines the PollingSlot class.
|
||||
* @date 19.12.2012
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/devicehandlers/FixedSequenceSlot.h>
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
#include <cstddef>
|
||||
|
||||
FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime,
|
||||
int8_t setSequenceId, PeriodicTaskIF* executingTask) :
|
||||
handler(NULL), pollingTimeMs(setTime), opcode(setSequenceId) {
|
||||
handler = objectManager->get<ExecutableObjectIF>(handlerId);
|
||||
handler->setTaskIF(executingTask);
|
||||
}
|
||||
|
||||
FixedSequenceSlot::~FixedSequenceSlot() {
|
||||
}
|
||||
|
@ -1,44 +1,40 @@
|
||||
/**
|
||||
* @file PollingSlot.h
|
||||
* @file FixedSequenceSlot.h
|
||||
* @brief This file defines the PollingSlot class.
|
||||
* @date 19.12.2012
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#ifndef POLLINGSLOT_H_
|
||||
#define POLLINGSLOT_H_
|
||||
#ifndef FIXEDSEQUENCESLOT_H_
|
||||
#define FIXEDSEQUENCESLOT_H_
|
||||
|
||||
#include <framework/devicehandlers/PollingSequenceExecutableIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/osal/OSAL.h>
|
||||
|
||||
class PollingSequence;
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
class PeriodicTaskIF;
|
||||
|
||||
/**
|
||||
* \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.
|
||||
* It contains three attributes and a debug method to print its content.
|
||||
*/
|
||||
class PollingSlot {
|
||||
friend class PollingSequence;
|
||||
friend class PollingTask;
|
||||
friend ReturnValue_t pollingSequenceInitFunction(PollingSequence *thisSequence);
|
||||
friend ReturnValue_t payloadSequenceInitFunction(PollingSequence *thisSequence);
|
||||
protected:
|
||||
class FixedSequenceSlot {
|
||||
public:
|
||||
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.
|
||||
*/
|
||||
PollingSequenceExecutableIF* handler;
|
||||
ExecutableObjectIF* handler;
|
||||
|
||||
/**
|
||||
* \brief This attribute defines when a device handler object is executed.
|
||||
*
|
||||
* \details The pollingTime attribute identifies the time the handler is executed in clock ticks. It must be
|
||||
* \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.
|
||||
*/
|
||||
Interval_t pollingTime;
|
||||
uint32_t pollingTimeMs;
|
||||
|
||||
/**
|
||||
* \brief This value defines the type of device communication.
|
||||
@ -46,16 +42,7 @@ protected:
|
||||
* \details The state of this value decides what communication routine is called in the PST executable or the device handler object.
|
||||
*/
|
||||
uint8_t opcode;
|
||||
|
||||
public:
|
||||
PollingSlot( object_id_t handlerId, Interval_t setTime, int8_t setSequenceId );
|
||||
virtual ~PollingSlot();
|
||||
|
||||
/**
|
||||
* \brief This is a small debug method to print the PollingSlot's content to a debug interface.
|
||||
*/
|
||||
void print() const;
|
||||
};
|
||||
|
||||
|
||||
#endif /* POLLINGSLOT_H_ */
|
||||
#endif /* FIXEDSEQUENCESLOT_H_ */
|
109
devicehandlers/FixedSlotSequence.cpp
Normal file
109
devicehandlers/FixedSlotSequence.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include <framework/devicehandlers/FixedSlotSequence.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) :
|
||||
lengthMs(setLengthMs) {
|
||||
current = slotList.begin();
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
void FixedSlotSequence::executeAndAdvance() {
|
||||
// (*this->current)->print();
|
||||
(*this->current)->handler->performOperation((*this->current)->opcode);
|
||||
// if (returnValue != RETURN_OK) {
|
||||
// this->sendErrorMessage( returnValue );
|
||||
// }
|
||||
//Increment the polling Sequence iterator
|
||||
this->current++;
|
||||
//Set it to the beginning, if the list's end is reached.
|
||||
if (this->current == this->slotList.end()) {
|
||||
this->current = this->slotList.begin();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t FixedSlotSequence::getIntervalMs() {
|
||||
uint32_t oldTime;
|
||||
std::list<FixedSequenceSlot*>::iterator it;
|
||||
it = current;
|
||||
// Get the pollingTimeMs of the current slot object.
|
||||
oldTime = (*it)->pollingTimeMs;
|
||||
// Advance to the next object.
|
||||
it++;
|
||||
// Find the next interval which is not 0.
|
||||
while (it != slotList.end()) {
|
||||
if (oldTime != (*it)->pollingTimeMs) {
|
||||
return (*it)->pollingTimeMs - oldTime;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
bool FixedSlotSequence::slotFollowsImmediately() {
|
||||
uint32_t currentTime = (*current)->pollingTimeMs;
|
||||
std::list<FixedSequenceSlot*>::iterator it;
|
||||
it = this->current;
|
||||
// Get the pollingTimeMs of the current slot object.
|
||||
if (it == slotList.begin())
|
||||
return false;
|
||||
it--;
|
||||
if ((*it)->pollingTimeMs == currentTime) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t FixedSlotSequence::getLengthMs() const {
|
||||
return this->lengthMs;
|
||||
}
|
||||
|
||||
ReturnValue_t FixedSlotSequence::checkSequence() const {
|
||||
//Iterate through slotList and check successful creation. Checks if timing is ok (must be ascending) and if all handlers were found.
|
||||
auto slotIt = slotList.begin();
|
||||
uint32_t count = 0;
|
||||
uint32_t time = 0;
|
||||
while (slotIt != slotList.end()) {
|
||||
if ((*slotIt)->handler == NULL) {
|
||||
error << "FixedSlotSequene::initialize: ObjectId does not exist!"
|
||||
<< std::endl;
|
||||
count++;
|
||||
} else if ((*slotIt)->pollingTimeMs < time) {
|
||||
error << "FixedSlotSequence::initialize: Time: "
|
||||
<< (*slotIt)->pollingTimeMs
|
||||
<< " is smaller than previous with " << time << std::endl;
|
||||
count++;
|
||||
} else {
|
||||
//All ok, print slot.
|
||||
// (*slotIt)->print();
|
||||
}
|
||||
time = (*slotIt)->pollingTimeMs;
|
||||
slotIt++;
|
||||
}
|
||||
if (count > 0) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
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->current = slotList.begin();
|
||||
}
|
@ -1,24 +1,14 @@
|
||||
/**
|
||||
* @file PollingSequence.h
|
||||
* @brief This file defines the PollingSequence class.
|
||||
* @date 19.12.2012
|
||||
* @author baetz
|
||||
*/
|
||||
#ifndef FIXEDSLOTSEQUENCE_H_
|
||||
#define FIXEDSLOTSEQUENCE_H_
|
||||
|
||||
#ifndef POLLINGSEQUENCE_H_
|
||||
#define POLLINGSEQUENCE_H_
|
||||
|
||||
#include <framework/devicehandlers/PollingSequenceExecutableIF.h>
|
||||
#include <framework/devicehandlers/PollingSlot.h>
|
||||
#include <framework/devicehandlers/FixedSequenceSlot.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/osal/OSAL.h>
|
||||
#include<list>
|
||||
|
||||
#include <list>
|
||||
|
||||
/**
|
||||
* \brief This class is the representation of a Polling Sequence Table in software.
|
||||
*
|
||||
* \details The PollingSequence object maintains the dynamic execution of device handler objects.
|
||||
* \details The FixedSlotSequence object maintains the dynamic execution of device handler objects.
|
||||
* The main idea is to create a list of device handlers, to announce all handlers to the
|
||||
* polling sequence and to maintain a list of polling slot objects. This slot list represents the
|
||||
* Polling Sequence Table in software. Each polling slot contains information to indicate when and
|
||||
@ -26,10 +16,78 @@
|
||||
* The sequence is then executed by iterating through this slot list.
|
||||
* Handlers are invoking by calling a certain function stored in the handler list.
|
||||
*/
|
||||
class PollingSequence : public SystemObject {
|
||||
friend class PollingTask;
|
||||
friend ReturnValue_t pollingSequenceInitFunction(PollingSequence *thisSequence);
|
||||
friend ReturnValue_t payloadSequenceInitFunction(PollingSequence *thisSequence);
|
||||
class FixedSlotSequence {
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief The constructor of the FixedSlotSequence object.
|
||||
*
|
||||
* \details The constructor takes two arguments, the period length and the init function.
|
||||
*
|
||||
* \param setLength The period length, expressed in ms.
|
||||
*/
|
||||
FixedSlotSequence(uint32_t setLengthMs);
|
||||
|
||||
/**
|
||||
* \brief The destructor of the FixedSlotSequence object.
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId,
|
||||
PeriodicTaskIF* executingTask);
|
||||
|
||||
/**
|
||||
* Checks if the current slot shall be executed immediately after the one before.
|
||||
* This allows to distinguish between grouped and not grouped handlers.
|
||||
* @return - @c true if the slot has the same polling time as the previous
|
||||
* - @c false else
|
||||
*/
|
||||
bool slotFollowsImmediately();
|
||||
|
||||
/**
|
||||
* \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 clock ticks within which the handler execution
|
||||
* shall take place.
|
||||
*/
|
||||
uint32_t getIntervalMs();
|
||||
|
||||
/**
|
||||
* \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.
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* \details This is an iterator for slotList and always points to the polling slot which is executed next.
|
||||
*/
|
||||
std::list<FixedSequenceSlot*>::iterator current;
|
||||
|
||||
ReturnValue_t checkSequence() const;
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -41,109 +99,9 @@ protected:
|
||||
* By iterating through this list the polling sequence is executed. Two entries with identical
|
||||
* polling times are executed immediately one after another.
|
||||
*/
|
||||
std::list<PollingSlot*> slotList;
|
||||
std::list<FixedSequenceSlot*> slotList;
|
||||
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
std::list<PollingSlot*>::iterator current;
|
||||
|
||||
/**
|
||||
* \brief The period of the Polling Sequence Table in clock ticks.
|
||||
*
|
||||
* \details This attribute is set within the constructor, defining the main period length of the
|
||||
* Polling Sequence Table. The length is expressed in clock ticks.
|
||||
*
|
||||
*/
|
||||
Interval_t length;
|
||||
|
||||
/**
|
||||
* \brief The init function passed by the ctor
|
||||
*
|
||||
* \details This function will be called during initialize()
|
||||
*
|
||||
*/
|
||||
ReturnValue_t (*initFunction)(PollingSequence *thisSequence);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief The constructor of the PollingSequence object.
|
||||
*
|
||||
* \details The constructor takes two arguments, the period length and the init function.
|
||||
*
|
||||
* \param setLength The period length, expressed in clock ticks.
|
||||
*/
|
||||
PollingSequence( object_id_t setObjectId, Interval_t setLength, ReturnValue_t (*initFunction)(PollingSequence *thisSequence) );
|
||||
|
||||
/**
|
||||
* \brief The destructor of the PollingSequence object.
|
||||
*
|
||||
* \details The destructor frees all allocated memory by iterating through
|
||||
* handlerMap and slotList and deleting all allocated resources.
|
||||
*/
|
||||
virtual ~PollingSequence();
|
||||
|
||||
/**
|
||||
* \brief This is a method to add an OPUSPollingSlot object to slotList.
|
||||
*
|
||||
* \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 setSlot This is a pointer to a OPUSPollingSlot object.
|
||||
*/
|
||||
void addSlot( PollingSlot* setSlot );
|
||||
|
||||
/**
|
||||
* Checks if the current slot shall be executed immediately after the one before.
|
||||
* This allows to distinguish between grouped and not grouped handlers.
|
||||
* @return - @c true if the slot has the same polling time as the previous
|
||||
* - @c false else
|
||||
*/
|
||||
bool slotFollowsImmediately();
|
||||
|
||||
/**
|
||||
* \brief This method returns the time until the next device handler object 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 clock ticks within which the handler execution
|
||||
* shall take place.
|
||||
*/
|
||||
Interval_t getInterval();
|
||||
|
||||
/**
|
||||
* \brief This method returns the length of this PollingSequence instance.
|
||||
*/
|
||||
Interval_t getLength();
|
||||
|
||||
/**
|
||||
* \brief The method to execute the device handler entered in the current OPUSPollingSlot 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.
|
||||
*/
|
||||
void pollAndAdvance();
|
||||
|
||||
/**
|
||||
* \brief This is a method to print debug output.
|
||||
*
|
||||
* \details print is a simple debug method to print the whole polling sequence to the debug interface.
|
||||
* It iterates through slotList and calls all print()} functions of the announced polling slot
|
||||
* instances.
|
||||
*
|
||||
*/
|
||||
void print();
|
||||
|
||||
ReturnValue_t initialize();
|
||||
//std::string getObjectTypeAsString();
|
||||
uint32_t lengthMs;
|
||||
};
|
||||
|
||||
|
||||
#endif /* POLLINGSEQUENCE_H_ */
|
||||
#endif /* FIXEDSLOTSEQUENCE_H_ */
|
@ -1,18 +1,20 @@
|
||||
#include <framework/devicehandlers/HealthDevice.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
|
||||
HealthDevice::HealthDevice(object_id_t setObjectId,
|
||||
MessageQueueId_t parentQueue) :
|
||||
SystemObject(setObjectId), lastHealth(HEALTHY), parentQueue(
|
||||
parentQueue), commandQueue(3,
|
||||
CommandMessage::COMMAND_MESSAGE_SIZE), healthHelper(this, setObjectId) {
|
||||
parentQueue), commandQueue(), healthHelper(this, setObjectId) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(3, CommandMessage::COMMAND_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
HealthDevice::~HealthDevice() {
|
||||
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
||||
}
|
||||
|
||||
ReturnValue_t HealthDevice::performOperation() {
|
||||
ReturnValue_t HealthDevice::performOperation(uint8_t opCode) {
|
||||
CommandMessage message;
|
||||
ReturnValue_t result = commandQueue.receiveMessage(&message);
|
||||
ReturnValue_t result = commandQueue->receiveMessage(&message);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
healthHelper.handleHealthCommand(&message);
|
||||
}
|
||||
@ -32,7 +34,7 @@ ReturnValue_t HealthDevice::initialize() {
|
||||
}
|
||||
|
||||
MessageQueueId_t HealthDevice::getCommandQueue() const {
|
||||
return commandQueue.getId();
|
||||
return commandQueue->getId();
|
||||
}
|
||||
|
||||
void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <framework/health/HealthHelper.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
|
||||
class HealthDevice: public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
@ -13,7 +14,7 @@ public:
|
||||
HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue);
|
||||
virtual ~HealthDevice();
|
||||
|
||||
ReturnValue_t performOperation();
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
|
||||
ReturnValue_t initialize();
|
||||
|
||||
@ -31,7 +32,7 @@ protected:
|
||||
HealthState lastHealth;
|
||||
|
||||
MessageQueueId_t parentQueue;
|
||||
MessageQueue commandQueue;
|
||||
MessageQueueIF* commandQueue;
|
||||
public:
|
||||
HealthHelper healthHelper;
|
||||
};
|
||||
|
@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# OPUS makefile
|
||||
#
|
||||
# Created on: Mar 04, 2010
|
||||
# Author: ziemke
|
||||
# Author: Claas Ziemke
|
||||
# Copyright 2010, Claas Ziemke <claas.ziemke@gmx.net>
|
||||
#
|
||||
|
||||
BASEDIR=../../
|
||||
include $(BASEDIR)options.mk
|
||||
|
||||
OBJ = $(BUILDDIR)/ChannelResetHandler.o \
|
||||
$(BUILDDIR)/RawCommandHandler.o \
|
||||
$(BUILDDIR)/RawDataHandler.o \
|
||||
$(BUILDDIR)/OPUSPollingSequence.o \
|
||||
$(BUILDDIR)/PollingTask.o \
|
||||
$(BUILDDIR)/Device.o \
|
||||
$(BUILDDIR)/RmapCookie.o \
|
||||
|
||||
all: $(OBJ)
|
||||
|
||||
$(BUILDDIR)/%.o: %.cpp %.h
|
||||
$(CPP) $(CFLAGS) $(DEFINES) $(CCOPT) ${INCLUDE} -c $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.gcno *.gcda
|
@ -1,115 +0,0 @@
|
||||
/**
|
||||
* @file PollingSequence.cpp
|
||||
* @brief This file defines the PollingSequence class.
|
||||
* @date 19.12.2012
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/devicehandlers/PollingSequence.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
|
||||
uint32_t PollingSequenceExecutableIF::pollingSequenceLengthMs = 0;
|
||||
uint32_t PollingSequenceExecutableIF::payloadSequenceLengthMs = 0;
|
||||
|
||||
PollingSequence::PollingSequence(object_id_t setObjectId, Interval_t setLength, ReturnValue_t (*initFunction)(PollingSequence *thisSequence)) : SystemObject( setObjectId ),
|
||||
initFunction(initFunction){
|
||||
this->length = setLength;
|
||||
// PollingSequenceExecutableIF::pollingSequenceLengthMs = (setLength * 1000)
|
||||
// / OSAL::getTicksPerSecond();
|
||||
current = slotList.begin();
|
||||
}
|
||||
|
||||
PollingSequence::~PollingSequence() {
|
||||
std::list<PollingSlot*>::iterator slotIt;
|
||||
//Iterate through slotList and delete all entries.
|
||||
slotIt = this->slotList.begin();
|
||||
while (slotIt != this->slotList.end()) {
|
||||
delete (*slotIt);
|
||||
slotIt++;
|
||||
}
|
||||
}
|
||||
|
||||
void PollingSequence::addSlot(PollingSlot* setSlot) {
|
||||
//The slot is added to the end of the list.
|
||||
this->slotList.push_back(setSlot);
|
||||
this->current = slotList.begin();
|
||||
}
|
||||
|
||||
void PollingSequence::pollAndAdvance() {
|
||||
// (*this->current)->print();
|
||||
(*this->current)->handler->performInPST( (*this->current)->opcode );
|
||||
// if (returnValue != RETURN_OK) {
|
||||
// this->sendErrorMessage( returnValue );
|
||||
// }
|
||||
//Increment the polling Sequence iterator
|
||||
this->current++;
|
||||
//Set it to the beginning, if the list's end is reached.
|
||||
if (this->current == this->slotList.end()) {
|
||||
this->current = this->slotList.begin();
|
||||
}
|
||||
}
|
||||
|
||||
Interval_t PollingSequence::getInterval() {
|
||||
Interval_t oldTime;
|
||||
std::list<PollingSlot*>::iterator it;
|
||||
it = this->current;
|
||||
// Get the pollingTime of the current slot object.
|
||||
oldTime = (*it)->pollingTime;
|
||||
// Advance to the next object.
|
||||
it++;
|
||||
// Find the next interval which is not 0.
|
||||
while ( it != slotList.end() ) {
|
||||
if ( oldTime != (*it)->pollingTime ) {
|
||||
return (*it)->pollingTime - oldTime;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
// 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 this->length - oldTime + (*it)->pollingTime;
|
||||
}
|
||||
|
||||
bool PollingSequence::slotFollowsImmediately() {
|
||||
Interval_t currentTime = (*current)->pollingTime;
|
||||
std::list<PollingSlot*>::iterator it;
|
||||
it = this->current;
|
||||
// Get the pollingTime of the current slot object.
|
||||
if ( it == slotList.begin() ) return false;
|
||||
it--;
|
||||
if ( (*it)->pollingTime == currentTime ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Interval_t PollingSequence::getLength() {
|
||||
return this->length;
|
||||
}
|
||||
|
||||
void PollingSequence::print() {
|
||||
debug << "Polling sequence contains:" << std::endl;
|
||||
|
||||
//Iterate through slotList and start all PollingSlot::print() methods.
|
||||
do {
|
||||
(*current)->print();
|
||||
current++;
|
||||
} while (current != slotList.end());
|
||||
current = slotList.begin();
|
||||
}
|
||||
|
||||
//std::string PollingSequence::getObjectTypeAsString() {
|
||||
// return "PollingSequence";
|
||||
//}
|
||||
|
||||
ReturnValue_t PollingSequence::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
return initFunction(this);
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* PollingSequenceExecutableIF.h
|
||||
*
|
||||
* Created on: Mar 30, 2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef POLLINGSEQUENCEEXECUTABLE_H_
|
||||
#define POLLINGSEQUENCEEXECUTABLE_H_
|
||||
|
||||
//TODO clean this whole file up
|
||||
|
||||
//TODO maybe define a type to make it look cleaner and use it in the PST
|
||||
#define SEND_WRITE_CMD 0
|
||||
#define GET_WRITE_REPLY 1
|
||||
#define SEND_READ_CMD 2
|
||||
#define GET_READ_REPLY 3
|
||||
|
||||
|
||||
#include <framework/osal/OSAL.h>
|
||||
|
||||
class PollingSequenceExecutableIF {
|
||||
public:
|
||||
static uint32_t pollingSequenceLengthMs;
|
||||
static uint32_t payloadSequenceLengthMs;
|
||||
virtual void performInPST( uint8_t ) = 0;
|
||||
virtual ~PollingSequenceExecutableIF() { }
|
||||
};
|
||||
|
||||
#endif /* POLLINGSEQUENCEEXECUTABLE_H_ */
|
@ -1,29 +0,0 @@
|
||||
/**
|
||||
* @file PollingSlot.cpp
|
||||
* @brief This file defines the PollingSlot class.
|
||||
* @date 19.12.2012
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/devicehandlers/PollingSlot.h>
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
PollingSlot::PollingSlot( object_id_t handlerId, Interval_t setTime, int8_t setSequenceId ) {
|
||||
//Set all attributes directly on object creation.
|
||||
this->handler = objectManager->get<PollingSequenceExecutableIF>( handlerId );
|
||||
this->pollingTime = setTime;
|
||||
this->opcode = setSequenceId;
|
||||
}
|
||||
|
||||
PollingSlot::~PollingSlot() {
|
||||
}
|
||||
|
||||
void PollingSlot::print() const {
|
||||
SystemObjectIF * systemObject = dynamic_cast<SystemObjectIF *>(handler);
|
||||
object_id_t id = (systemObject == NULL) ? 0xffffffff : systemObject->getObjectId();
|
||||
debug << "HandlerID: " << std::hex << id << std::dec << "; Polling Time: "
|
||||
<< this->pollingTime << "; Opcode: " << (uint16_t) this->opcode
|
||||
<< std::endl;
|
||||
}
|
||||
|
@ -1,103 +0,0 @@
|
||||
/**
|
||||
* \file OPUSPollingTask.cpp
|
||||
*
|
||||
* \brief This file contains the implementation for the OPUSPollingTask class.
|
||||
*
|
||||
* \author Bastian Baetz
|
||||
*
|
||||
* \date 17.03.2011
|
||||
*
|
||||
*/
|
||||
|
||||
#include <framework/devicehandlers/PollingTask.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
uint32_t PollingTask::deadlineMissedCount = 0;
|
||||
|
||||
PollingTask::PollingTask( const char *name, TaskPriority_t setPriority, size_t setStack, void (*setDeadlineMissedFunc)(), object_id_t getPst ) :
|
||||
TaskBase( setPriority, setStack, name ), periodId(0) {
|
||||
// All additional attributes are applied to the object.
|
||||
this->deadlineMissedFunc = setDeadlineMissedFunc;
|
||||
this->pst = objectManager->get<PollingSequence>( getPst );
|
||||
}
|
||||
|
||||
PollingTask::~PollingTask() {
|
||||
// The PollingSequence destructor is called, if a sequence is announced.
|
||||
if ( this->pst != NULL ) {
|
||||
this->pst->~PollingSequence();
|
||||
} else {
|
||||
// There was no memory allocation, so there's nothing to do.
|
||||
}
|
||||
}
|
||||
|
||||
TaskReturn_t PollingTask::taskEntryPoint( TaskArgument_t argument ) {
|
||||
|
||||
//The argument is re-interpreted as PollingTask.
|
||||
PollingTask *originalTask( reinterpret_cast<PollingTask*>( argument ) );
|
||||
if ( originalTask->pst != NULL ) {
|
||||
//The task's functionality is called.
|
||||
originalTask->taskFunctionality();
|
||||
} else {
|
||||
|
||||
}
|
||||
debug << "Polling task " << originalTask->getId() << " returned from taskFunctionality." << std::endl;
|
||||
}
|
||||
|
||||
void PollingTask::missedDeadlineCounter() {
|
||||
PollingTask::deadlineMissedCount++;
|
||||
if (PollingTask::deadlineMissedCount%10 == 0) {
|
||||
error << "PST missed " << PollingTask::deadlineMissedCount << " deadlines." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PollingTask::startTask() {
|
||||
this->setRunning( true );
|
||||
ReturnValue_t status;
|
||||
status = OSAL::startTask( &( this->id ), PollingTask::taskEntryPoint, TaskArgument_t( ( void *)this ) );
|
||||
if( status != RETURN_OK ) {
|
||||
//TODO: Call any FDIR routine?
|
||||
error << "PollingTask::startTask for " << std::hex << this->getId() << std::dec << " failed." << std::endl;
|
||||
} else {
|
||||
// debug << "PollingTask::startTask for " << std::hex << this->getId() << std::dec << " successful" << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void PollingTask::taskFunctionality() {
|
||||
ReturnValue_t status = OSAL::TIMEOUT;
|
||||
Interval_t interval;
|
||||
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
||||
std::list<PollingSlot*>::iterator it;
|
||||
|
||||
it = this->pst->current;
|
||||
//The start time for the first entry is read.
|
||||
interval = ( *it )->pollingTime;
|
||||
//The period is set up and started with the system call.
|
||||
status = OSAL::setAndStartPeriod( interval, &( this->periodId ) );
|
||||
if( status == RETURN_OK ) {
|
||||
//The task's "infinite" inner loop is entered.
|
||||
while( this->isRunning ) {
|
||||
if ( pst->slotFollowsImmediately() ) {
|
||||
//Do nothing
|
||||
} else {
|
||||
//The interval for the next polling slot is selected.
|
||||
interval = this->pst->getInterval();
|
||||
//The period is checked and restarted with the new interval.
|
||||
//If the deadline was missed, the deadlineMissedFunc is called.
|
||||
status = OSAL::checkAndRestartPeriod( this->periodId, interval );
|
||||
if( status == OSAL::TIMEOUT ) {
|
||||
if( this->deadlineMissedFunc != NULL ) {
|
||||
this->deadlineMissedFunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
//The device handler for this slot is executed and the next one is chosen.
|
||||
this->pst->pollAndAdvance();
|
||||
}
|
||||
} else {
|
||||
error << "PollingTask::setAndStartPeriod failed with status "<< status << std::endl;
|
||||
}
|
||||
//Any operating system object for periodic execution is deleted.
|
||||
debug << "Deleting the PollingTask's period." << std::endl;
|
||||
OSAL::deletePeriod( &(this->id) );
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
/**
|
||||
* @file PollingTask.h
|
||||
*
|
||||
* @brief This file contains the definition for the PollingTask class.
|
||||
*
|
||||
* @author Claas Ziemke, Bastian Baetz
|
||||
*
|
||||
* @date 17.03.2011
|
||||
*
|
||||
* Copyright 2009,2010, Claas Ziemke <claas.ziemke@gmx.net>
|
||||
* All rights reserved
|
||||
*
|
||||
*/
|
||||
#ifndef POLLINGTASK_H_
|
||||
#define POLLINGTASK_H_
|
||||
|
||||
#include <framework/devicehandlers/PollingSequence.h>
|
||||
#include <framework/tasks/TaskBase.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This class represents a specialized thread to execute polling sequences.
|
||||
*
|
||||
* @image latex seq_PST_dynamic.eps "Sequence diagram of polling sequence operation" width=1@textwidth
|
||||
* @image html seq_PST_dynamic.png "Sequence diagram of polling sequence operation"
|
||||
*
|
||||
* @details The Polling Sequence Table is executed in a task of special type, called PollingTask.
|
||||
* After creation the polling task initializes the PST and starts taskFunctionality.
|
||||
* An infinite loop is entered within which the iteration through the PST is done by repetitive calls of
|
||||
* getInterval() and pollAndAdvance().
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
class PollingTask: public TaskBase {
|
||||
protected:
|
||||
/**
|
||||
* @brief id of the associated OS period
|
||||
*/
|
||||
PeriodId_t periodId;
|
||||
|
||||
/**
|
||||
* @brief This attribute is the pointer to the complete polling sequence table object.
|
||||
*
|
||||
* @details The most important attribute of the thread object.
|
||||
* It holds a pointer to the complete polling sequence table object.
|
||||
*/
|
||||
PollingSequence* pst;
|
||||
|
||||
/**
|
||||
* @brief This attribute holds a function pointer that is executed when a deadline was missed.
|
||||
*
|
||||
* @details Another function may be announced to determine the actions to perform when a deadline was missed.
|
||||
* Currently, only one function for missing any deadline is allowed.
|
||||
* If not used, it shall be declared NULL.
|
||||
*/
|
||||
void ( *deadlineMissedFunc )( void );
|
||||
/**
|
||||
* @brief This is the entry point in a new polling thread.
|
||||
*
|
||||
* @details This method, that is the general entry point in the new thread, is here set to generate
|
||||
* and link the Polling Sequence Table to the thread object and start taskFunctionality()
|
||||
* on success. If operation of the task is ended for some reason,
|
||||
* the destructor is called to free allocated memory.
|
||||
*/
|
||||
static TaskReturn_t taskEntryPoint( TaskArgument_t argument );
|
||||
|
||||
/**
|
||||
* @brief This function holds the main functionality of the thread.
|
||||
*
|
||||
*
|
||||
* @details Holding the main functionality of the task, this method is most important.
|
||||
* It links the functionalities provided by PollingSequence with the OS's System Calls
|
||||
* to keep the timing of the periods.
|
||||
*/
|
||||
void taskFunctionality( void );
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The standard constructor of the class.
|
||||
*
|
||||
* @details This is the general constructor of the class. In addition to the TaskBase parameters,
|
||||
* the following variables are passed:
|
||||
*
|
||||
* @param (*setDeadlineMissedFunc)() The function pointer to the deadline missed function that shall be assigned.
|
||||
*
|
||||
* @param getPst The object id of the completely initialized polling sequence.
|
||||
*/
|
||||
PollingTask( const char *name, TaskPriority_t setPriority, size_t setStack, void (*setDeadlineMissedFunc)(), object_id_t getPst );
|
||||
|
||||
/**
|
||||
* @brief The destructor of the class.
|
||||
*
|
||||
* @details The destructor frees all heap memory that was allocated on thread initialization for the PST and
|
||||
* the device handlers. This is done by calling the PST's destructor.
|
||||
*/
|
||||
virtual ~PollingTask( void );
|
||||
|
||||
/**
|
||||
* @brief The function to actually start a new task.
|
||||
*
|
||||
* @details As described in TaskBase this method invokes the operating systems method to start a new task.
|
||||
* Entry point is taskEntryPoint().
|
||||
*/
|
||||
ReturnValue_t startTask( void );
|
||||
/**
|
||||
* This static function can be used as #deadlineMissedFunc.
|
||||
* It counts missedDeadlines and prints the number of missed deadlines every 10th time.
|
||||
*/
|
||||
static void missedDeadlineCounter();
|
||||
/**
|
||||
* A helper variable to count missed deadlines.
|
||||
*/
|
||||
static uint32_t deadlineMissedCount;
|
||||
};
|
||||
|
||||
#endif /* POLLINGTASK_H_ */
|
Reference in New Issue
Block a user