Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
#include "../returnvalues/returnvalue.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "definitions.h"
|
||||
|
||||
/**
|
||||
* @brief A List that stores its values in an array.
|
||||
@ -19,9 +20,6 @@ class ArrayList {
|
||||
friend class SerialArrayListAdapter;
|
||||
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
/**
|
||||
* This is the allocating constructor.
|
||||
* It allocates an array of the specified size.
|
||||
@ -187,7 +185,7 @@ class ArrayList {
|
||||
*/
|
||||
ReturnValue_t insert(T entry) {
|
||||
if (size >= maxSize_) {
|
||||
return FULL;
|
||||
return containers::LIST_FULL;
|
||||
}
|
||||
entries[size] = entry;
|
||||
++size;
|
||||
|
@ -20,9 +20,11 @@ class FixedArrayList : public ArrayList<T, count_t> {
|
||||
FixedArrayList() : ArrayList<T, count_t>(data, MAX_SIZE) {}
|
||||
|
||||
FixedArrayList(const FixedArrayList& other) : ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||
memcpy(this->data, other.data, sizeof(this->data));
|
||||
this->entries = data;
|
||||
this->size = other.size;
|
||||
for (size_t idx = 0; idx < this->size; idx++) {
|
||||
data[idx] = other.data[idx];
|
||||
}
|
||||
}
|
||||
|
||||
FixedArrayList& operator=(FixedArrayList other) {
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "../returnvalues/returnvalue.h"
|
||||
#include "ArrayList.h"
|
||||
#include "definitions.h"
|
||||
|
||||
/**
|
||||
* @brief Map implementation for maps with a pre-defined size.
|
||||
@ -24,11 +24,6 @@ class FixedMap : public SerializeIF {
|
||||
"derived class from SerializeIF to be serialize-able");
|
||||
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
||||
|
||||
private:
|
||||
static const key_t EMPTY_SLOT = -1;
|
||||
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
||||
@ -76,10 +71,10 @@ class FixedMap : public SerializeIF {
|
||||
|
||||
ReturnValue_t insert(key_t key, T value, Iterator* storedValue = nullptr) {
|
||||
if (exists(key) == returnvalue::OK) {
|
||||
return KEY_ALREADY_EXISTS;
|
||||
return containers::KEY_ALREADY_EXISTS;
|
||||
}
|
||||
if (_size == theMap.maxSize()) {
|
||||
return MAP_FULL;
|
||||
return containers::MAP_FULL;
|
||||
}
|
||||
theMap[_size].first = key;
|
||||
theMap[_size].second = value;
|
||||
@ -93,7 +88,7 @@ class FixedMap : public SerializeIF {
|
||||
ReturnValue_t insert(std::pair<key_t, T> pair) { return insert(pair.first, pair.second); }
|
||||
|
||||
ReturnValue_t exists(key_t key) const {
|
||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
||||
ReturnValue_t result = containers::KEY_DOES_NOT_EXIST;
|
||||
if (findIndex(key) < _size) {
|
||||
result = returnvalue::OK;
|
||||
}
|
||||
@ -103,7 +98,7 @@ class FixedMap : public SerializeIF {
|
||||
ReturnValue_t erase(Iterator* iter) {
|
||||
uint32_t i;
|
||||
if ((i = findIndex((*iter).value->first)) >= _size) {
|
||||
return KEY_DOES_NOT_EXIST;
|
||||
return containers::KEY_DOES_NOT_EXIST;
|
||||
}
|
||||
theMap[i] = theMap[_size - 1];
|
||||
--_size;
|
||||
@ -114,7 +109,7 @@ class FixedMap : public SerializeIF {
|
||||
ReturnValue_t erase(key_t key) {
|
||||
uint32_t i;
|
||||
if ((i = findIndex(key)) >= _size) {
|
||||
return KEY_DOES_NOT_EXIST;
|
||||
return containers::KEY_DOES_NOT_EXIST;
|
||||
}
|
||||
theMap[i] = theMap[_size - 1];
|
||||
--_size;
|
||||
|
14
src/fsfw/container/definitions.h
Normal file
14
src/fsfw/container/definitions.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef FSFW_CONTAINER_DEFINITIONS_H_
|
||||
#define FSFW_CONTAINER_DEFINITIONS_H_
|
||||
|
||||
#include "fsfw/retval.h"
|
||||
|
||||
namespace containers {
|
||||
static const ReturnValue_t KEY_ALREADY_EXISTS = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x01);
|
||||
static const ReturnValue_t MAP_FULL = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x02);
|
||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x03);
|
||||
|
||||
static const ReturnValue_t LIST_FULL = returnvalue::makeCode(CLASS_ID::ARRAY_LIST, 0x01);
|
||||
} // namespace containers
|
||||
|
||||
#endif /* FSFW_CONTAINER_DEFINITIONS_H_ */
|
@ -4,11 +4,10 @@
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/subsystem/SubsystemBase.h"
|
||||
#include "fsfw/subsystem/helper.h"
|
||||
|
||||
ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||
size_t commandQueueDepth)
|
||||
ControllerBase::ControllerBase(object_id_t setObjectId, size_t commandQueueDepth)
|
||||
: SystemObject(setObjectId),
|
||||
parentId(parentId),
|
||||
mode(MODE_OFF),
|
||||
submode(SUBMODE_NONE),
|
||||
modeHelper(this),
|
||||
@ -21,33 +20,15 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
|
||||
ReturnValue_t ControllerBase::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
ReturnValue_t result = modeHelper.initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t parentQueue = 0;
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
auto* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
parentQueue = parent->getCommandQueue();
|
||||
|
||||
parent->registerChild(getObjectId());
|
||||
}
|
||||
|
||||
result = healthHelper.initialize(parentQueue);
|
||||
result = healthHelper.initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = modeHelper.initialize(parentQueue);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
return SystemObject::initialize();
|
||||
}
|
||||
|
||||
MessageQueueId_t ControllerBase::getCommandQueue() const { return commandQueue->getId(); }
|
||||
@ -120,3 +101,13 @@ void ControllerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
||||
void ControllerBase::changeHK(Mode_t mode_, Submode_t submode_, bool enable) {}
|
||||
|
||||
ReturnValue_t ControllerBase::initializeAfterTaskCreation() { return returnvalue::OK; }
|
||||
|
||||
const HasHealthIF* ControllerBase::getOptHealthIF() const { return this; }
|
||||
|
||||
const HasModesIF& ControllerBase::getModeIF() const { return *this; }
|
||||
|
||||
ModeTreeChildIF& ControllerBase::getModeTreeChildIF() { return *this; }
|
||||
|
||||
ReturnValue_t ControllerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||
return modetree::connectModeTreeParent(parent, *this, healthHelper, modeHelper);
|
||||
}
|
||||
|
@ -6,6 +6,9 @@
|
||||
#include "fsfw/modes/HasModesIF.h"
|
||||
#include "fsfw/modes/ModeHelper.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/subsystem/HasModeTreeChildrenIF.h"
|
||||
#include "fsfw/subsystem/ModeTreeChildIF.h"
|
||||
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||
|
||||
@ -18,13 +21,18 @@
|
||||
class ControllerBase : public HasModesIF,
|
||||
public HasHealthIF,
|
||||
public ExecutableObjectIF,
|
||||
public ModeTreeChildIF,
|
||||
public ModeTreeConnectionIF,
|
||||
public SystemObject {
|
||||
public:
|
||||
static const Mode_t MODE_NORMAL = 2;
|
||||
|
||||
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||
ControllerBase(object_id_t setObjectId, size_t commandQueueDepth = 3);
|
||||
~ControllerBase() override;
|
||||
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||
|
||||
/** SystemObject override */
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
@ -38,6 +46,8 @@ class ControllerBase : public HasModesIF,
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
void setTaskIF(PeriodicTaskIF *task) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
const HasHealthIF *getOptHealthIF() const override;
|
||||
const HasModesIF &getModeIF() const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -56,8 +66,6 @@ class ControllerBase : public HasModesIF,
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) override = 0;
|
||||
|
||||
const object_id_t parentId;
|
||||
|
||||
Mode_t mode;
|
||||
|
||||
Submode_t submode;
|
||||
|
@ -1,8 +1,7 @@
|
||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||
|
||||
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, object_id_t parentId,
|
||||
size_t commandQueueDepth)
|
||||
: ControllerBase(objectId, parentId, commandQueueDepth),
|
||||
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth)
|
||||
: ControllerBase(objectId, commandQueueDepth),
|
||||
poolManager(this, commandQueue),
|
||||
actionHelper(this, commandQueue) {}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
public HasActionsIF,
|
||||
public HasLocalDataPoolIF {
|
||||
public:
|
||||
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||
ExtendedControllerBase(object_id_t objectId, size_t commandQueueDepth = 3);
|
||||
~ExtendedControllerBase() override;
|
||||
|
||||
/* SystemObjectIF overrides */
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "fsfw/devicehandlers/AssemblyBase.h"
|
||||
|
||||
AssemblyBase::AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth)
|
||||
: SubsystemBase(objectId, parentId, MODE_OFF, commandQueueDepth),
|
||||
AssemblyBase::AssemblyBase(object_id_t objectId, uint16_t commandQueueDepth)
|
||||
: SubsystemBase(objectId, MODE_OFF, commandQueueDepth),
|
||||
internalState(STATE_NONE),
|
||||
recoveryState(RECOVERY_IDLE),
|
||||
recoveringDevice(childrenMap.end()),
|
||||
|
@ -41,7 +41,7 @@ class AssemblyBase : public SubsystemBase {
|
||||
static const ReturnValue_t NEED_TO_CHANGE_HEALTH = MAKE_RETURN_CODE(0x05);
|
||||
static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE = MAKE_RETURN_CODE(0xa1);
|
||||
|
||||
AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth = 8);
|
||||
AssemblyBase(object_id_t objectId, uint16_t commandQueueDepth = 8);
|
||||
virtual ~AssemblyBase();
|
||||
|
||||
protected:
|
||||
|
@ -3,17 +3,12 @@
|
||||
#include "fsfw/subsystem/SubsystemBase.h"
|
||||
|
||||
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
|
||||
CookieIF* cookie, object_id_t hkDestination,
|
||||
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
|
||||
object_id_t parent, FailureIsolationBase* customFdir,
|
||||
size_t cmdQueueSize)
|
||||
CookieIF* cookie, HasModeTreeChildrenIF& parent,
|
||||
FailureIsolationBase* customFdir, size_t cmdQueueSize)
|
||||
: DeviceHandlerBase(setObjectId, deviceCommunication, cookie,
|
||||
(customFdir == nullptr ? &childHandlerFdir : customFdir), cmdQueueSize),
|
||||
parentId(parent),
|
||||
childHandlerFdir(setObjectId) {
|
||||
this->setHkDestination(hkDestination);
|
||||
this->setThermalStateRequestPoolIds(thermalStatePoolId, thermalRequestPoolId);
|
||||
}
|
||||
parent(parent),
|
||||
childHandlerFdir(setObjectId) {}
|
||||
|
||||
ChildHandlerBase::~ChildHandlerBase() {}
|
||||
|
||||
@ -23,21 +18,5 @@ ReturnValue_t ChildHandlerBase::initialize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t parentQueue = 0;
|
||||
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == NULL) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
parentQueue = parent->getCommandQueue();
|
||||
|
||||
parent->registerChild(getObjectId());
|
||||
}
|
||||
|
||||
healthHelper.setParentQueue(parentQueue);
|
||||
|
||||
modeHelper.setParentQueue(parentQueue);
|
||||
|
||||
return returnvalue::OK;
|
||||
return DeviceHandlerBase::connectModeTreeParent(parent);
|
||||
}
|
||||
|
@ -1,22 +1,23 @@
|
||||
#ifndef FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_
|
||||
#define FSFW_DEVICEHANDLER_CHILDHANDLERBASE_H_
|
||||
|
||||
#include <fsfw/subsystem/HasModeTreeChildrenIF.h>
|
||||
|
||||
#include "ChildHandlerFDIR.h"
|
||||
#include "DeviceHandlerBase.h"
|
||||
|
||||
class ChildHandlerBase : public DeviceHandlerBase {
|
||||
public:
|
||||
ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF* cookie,
|
||||
object_id_t hkDestination, uint32_t thermalStatePoolId,
|
||||
uint32_t thermalRequestPoolId, object_id_t parent = objects::NO_OBJECT,
|
||||
FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20);
|
||||
HasModeTreeChildrenIF& parent, FailureIsolationBase* customFdir = nullptr,
|
||||
size_t cmdQueueSize = 20);
|
||||
|
||||
virtual ~ChildHandlerBase();
|
||||
|
||||
virtual ReturnValue_t initialize();
|
||||
|
||||
protected:
|
||||
const uint32_t parentId;
|
||||
HasModeTreeChildrenIF& parent;
|
||||
ChildHandlerFDIR childHandlerFdir;
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "DeviceHandlerBase.h"
|
||||
|
||||
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
||||
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
||||
@ -12,6 +12,7 @@
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/subsystem/SubsystemBase.h"
|
||||
#include "fsfw/subsystem/helper.h"
|
||||
#include "fsfw/thermal/ThermalComponentIF.h"
|
||||
|
||||
object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||
@ -22,8 +23,6 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
CookieIF* comCookie, FailureIsolationBase* fdirInstance,
|
||||
size_t cmdQueueSize)
|
||||
: SystemObject(setObjectId),
|
||||
mode(MODE_OFF),
|
||||
submode(SUBMODE_NONE),
|
||||
wiretappingMode(OFF),
|
||||
storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
||||
deviceCommunicationId(deviceCommunication),
|
||||
@ -38,6 +37,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
defaultFDIRUsed(fdirInstance == nullptr),
|
||||
switchOffWasReported(false),
|
||||
childTransitionDelay(5000),
|
||||
mode(MODE_OFF),
|
||||
submode(SUBMODE_NONE),
|
||||
transitionSourceMode(_MODE_POWER_DOWN),
|
||||
transitionSourceSubMode(SUBMODE_NONE) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
@ -132,14 +133,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
||||
}
|
||||
|
||||
if (this->parent != objects::NO_OBJECT) {
|
||||
HasModesIF* modeIF = ObjectManager::instance()->get<HasModesIF>(this->parent);
|
||||
HasHealthIF* healthIF = ObjectManager::instance()->get<HasHealthIF>(this->parent);
|
||||
if (modeIF != nullptr and healthIF != nullptr) {
|
||||
setParentQueue(modeIF->getCommandQueue());
|
||||
}
|
||||
}
|
||||
|
||||
communicationInterface =
|
||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||
if (communicationInterface == nullptr) {
|
||||
@ -362,7 +355,6 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
callChildStatemachine();
|
||||
break;
|
||||
}
|
||||
ReturnValue_t switchState = getStateOfSwitches();
|
||||
@ -574,8 +566,15 @@ void DeviceHandlerBase::setTransition(Mode_t modeTo, Submode_t submodeTo) {
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
||||
// changeHK(mode, submode, false);
|
||||
/**
|
||||
* handle transition from OFF to NORMAL by continuing towards normal when ON is reached
|
||||
*/
|
||||
if (newMode == MODE_ON and continueToNormal) {
|
||||
continueToNormal = false;
|
||||
mode = _MODE_TO_NORMAL;
|
||||
return;
|
||||
}
|
||||
|
||||
submode = newSubmode;
|
||||
mode = newMode;
|
||||
modeChanged();
|
||||
@ -584,6 +583,8 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
disableCommandsAndReplies();
|
||||
}
|
||||
if (!isTransitionalMode()) {
|
||||
// clear this flag when a non-transitional Mode is reached to be safe
|
||||
continueToNormal = false;
|
||||
modeHelper.modeChanged(newMode, newSubmode);
|
||||
announceMode(false);
|
||||
}
|
||||
@ -1068,8 +1069,7 @@ Mode_t DeviceHandlerBase::getBaseMode(Mode_t transitionMode) {
|
||||
return transitionMode & ~(TRANSITION_MODE_BASE_ACTION_MASK | TRANSITION_MODE_CHILD_ACTION_MASK);
|
||||
}
|
||||
|
||||
// SHOULDDO: Allow transition from OFF to NORMAL to reduce complexity in assemblies. And, by the
|
||||
// way, throw away DHB and write a new one:
|
||||
// SHOULDDO: throw away DHB and write a new one:
|
||||
// - Include power and thermal completely, but more modular :-)
|
||||
// - Don't use modes for state transitions, reduce FSM (Finte State Machine) complexity.
|
||||
// - Modularization?
|
||||
@ -1081,11 +1081,10 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
||||
if ((mode == MODE_ERROR_ON) && (commandedMode != MODE_OFF)) {
|
||||
return TRANS_NOT_ALLOWED;
|
||||
}
|
||||
if ((commandedMode == MODE_NORMAL) && (mode == MODE_OFF)) {
|
||||
return TRANS_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
if ((commandedMode == MODE_ON) && (mode == MODE_OFF) and (thermalSet != nullptr)) {
|
||||
// Do not check thermal state for MODE_RAW
|
||||
if ((mode == MODE_OFF) and ((commandedMode == MODE_ON) or (commandedMode == MODE_NORMAL)) and
|
||||
(thermalSet != nullptr)) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
||||
@ -1100,6 +1099,7 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commandedSubmode) {
|
||||
continueToNormal = false;
|
||||
switch (commandedMode) {
|
||||
case MODE_ON:
|
||||
handleTransitionToOnMode(commandedMode, commandedSubmode);
|
||||
@ -1129,8 +1129,9 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commande
|
||||
case MODE_NORMAL:
|
||||
if (mode != MODE_OFF) {
|
||||
setTransition(MODE_NORMAL, commandedSubmode);
|
||||
} else {
|
||||
replyReturnvalueToCommand(HasModesIF::TRANS_NOT_ALLOWED);
|
||||
} else { // mode is off
|
||||
continueToNormal = true;
|
||||
handleTransitionToOnMode(MODE_NORMAL, commandedSubmode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1578,12 +1579,14 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
||||
|
||||
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
||||
|
||||
void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; }
|
||||
|
||||
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) {
|
||||
this->powerSwitcher = switcher;
|
||||
}
|
||||
|
||||
Mode_t DeviceHandlerBase::getMode() { return mode; }
|
||||
|
||||
Submode_t DeviceHandlerBase::getSubmode() { return submode; }
|
||||
|
||||
void DeviceHandlerBase::disableCommandsAndReplies() {
|
||||
for (auto& command : deviceCommandMap) {
|
||||
if (command.second.isExecuting) {
|
||||
@ -1602,6 +1605,16 @@ void DeviceHandlerBase::disableCommandsAndReplies() {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||
return modetree::connectModeTreeParent(parent, *this, healthHelper, modeHelper);
|
||||
}
|
||||
|
||||
const HasHealthIF* DeviceHandlerBase::getOptHealthIF() const { return this; }
|
||||
|
||||
const HasModesIF& DeviceHandlerBase::getModeIF() const { return *this; }
|
||||
|
||||
ModeTreeChildIF& DeviceHandlerBase::getModeTreeChildIF() { return *this; }
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::finishAction(bool success, DeviceCommandId_t action,
|
||||
ReturnValue_t result) {
|
||||
auto commandIter = deviceCommandMap.find(action);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||
#include "fsfw/util/dataWrapper.h"
|
||||
@ -84,6 +85,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
public HasModesIF,
|
||||
public HasHealthIF,
|
||||
public HasActionsIF,
|
||||
public ModeTreeChildIF,
|
||||
public ModeTreeConnectionIF,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public HasLocalDataPoolIF {
|
||||
friend void(Factory::setStaticFrameworkObjectIds)();
|
||||
@ -104,8 +107,55 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||
|
||||
void setCustomFdir(FailureIsolationBase *fdir);
|
||||
void setParent(object_id_t parent);
|
||||
void setPowerSwitcher(PowerSwitchIF *switcher);
|
||||
|
||||
/**
|
||||
* extending the modes of DeviceHandler IF for internal state machine
|
||||
*/
|
||||
static constexpr uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
||||
static constexpr uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
||||
//! 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.
|
||||
//! It is possible to set the mode to _MODE_SHUT_DOWN to use the to off
|
||||
//! transition if available.
|
||||
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;
|
||||
|
||||
void setHkDestination(object_id_t hkDestination);
|
||||
|
||||
/**
|
||||
@ -121,6 +171,10 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID,
|
||||
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID);
|
||||
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||
|
||||
/**
|
||||
* @brief Helper function to ease device handler development.
|
||||
* This will instruct the transition to MODE_ON immediately
|
||||
@ -166,7 +220,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* @param counter Specifies which Action to perform
|
||||
* @return returnvalue::OK for successful execution
|
||||
*/
|
||||
virtual ReturnValue_t performOperation(uint8_t counter) override;
|
||||
ReturnValue_t performOperation(uint8_t counter) override;
|
||||
|
||||
/**
|
||||
* @brief Initializes the device handler
|
||||
@ -176,14 +230,14 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* Calls fillCommandAndReplyMap().
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t initialize() override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
/**
|
||||
* @brief Intialization steps performed after all tasks have been created.
|
||||
* This function will be called by the executing task.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~DeviceHandlerBase();
|
||||
@ -200,6 +254,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
virtual object_id_t getObjectId() const override;
|
||||
|
||||
/**
|
||||
* This is a helper method for classes which are parent nodes in the mode tree.
|
||||
* It registers the passed queue as the destination for mode and health messages.
|
||||
* @param parentQueueId
|
||||
*/
|
||||
virtual void setParentQueue(MessageQueueId_t parentQueueId);
|
||||
@ -696,15 +752,18 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
size_t rawPacketLen = 0;
|
||||
|
||||
/**
|
||||
* The mode the device handler is currently in.
|
||||
* This should never be changed directly but only with setMode()
|
||||
* Get the current mode
|
||||
*
|
||||
* set via setMode()
|
||||
*/
|
||||
Mode_t mode;
|
||||
Mode_t getMode();
|
||||
|
||||
/**
|
||||
* The submode the device handler is currently in.
|
||||
* This should never be changed directly but only with setMode()
|
||||
* Get the current Submode
|
||||
*
|
||||
* set via setMode()
|
||||
*/
|
||||
Submode_t submode;
|
||||
Submode_t getSubmode();
|
||||
|
||||
/** This is the counter value from performOperation(). */
|
||||
uint8_t pstStep = 0;
|
||||
@ -893,8 +952,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
|
||||
*
|
||||
* If the transition is complete, the mode should be set to the target mode,
|
||||
* which can be deduced from the current mode which is
|
||||
* [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]
|
||||
* which can be deduced from the current mode (which is
|
||||
* [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]) using getBaseMode()
|
||||
*
|
||||
* The intended target submode is already set.
|
||||
* The origin submode can be read in subModeFrom.
|
||||
@ -961,6 +1020,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
*/
|
||||
LocalDataPoolManager *getHkManagerHandle() override;
|
||||
|
||||
const HasHealthIF *getOptHealthIF() const override;
|
||||
const HasModesIF &getModeIF() const override;
|
||||
|
||||
/**
|
||||
* Returns the delay cycle count of a reply.
|
||||
* A count != 0 indicates that the command is already executed.
|
||||
@ -1206,6 +1268,18 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
*/
|
||||
uint32_t childTransitionDelay;
|
||||
|
||||
/**
|
||||
* The mode the device handler is currently in.
|
||||
* This should not be changed directly but only with setMode()
|
||||
*/
|
||||
Mode_t mode;
|
||||
|
||||
/**
|
||||
* The submode the device handler is currently in.
|
||||
* This should not be changed directly but only with setMode()
|
||||
*/
|
||||
Submode_t submode;
|
||||
|
||||
/**
|
||||
* @brief The mode the current transition originated from
|
||||
*
|
||||
@ -1223,6 +1297,15 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
*/
|
||||
Submode_t transitionSourceSubMode;
|
||||
|
||||
/**
|
||||
* used to make the state machine continue from ON to NOMAL when
|
||||
* a Device is commanded to NORMAL in OFF mode
|
||||
*
|
||||
* set in startTransition()
|
||||
* evaluated in setMode() to continue to NORMAL when ON is reached
|
||||
*/
|
||||
bool continueToNormal;
|
||||
|
||||
/**
|
||||
* read the command queue
|
||||
*/
|
||||
|
@ -24,9 +24,6 @@ class DeviceHandlerIF {
|
||||
static const DeviceCommandId_t RAW_COMMAND_ID = -1;
|
||||
static const DeviceCommandId_t NO_COMMAND_ID = -2;
|
||||
|
||||
static constexpr uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
||||
static constexpr uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
||||
|
||||
using dh_heater_request_t = uint8_t;
|
||||
using dh_thermal_state_t = int8_t;
|
||||
|
||||
@ -54,47 +51,6 @@ class DeviceHandlerIF {
|
||||
//! 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.
|
||||
//! It is possible to set the mode to _MODE_SHUT_DOWN to use the to off
|
||||
//! transition if available.
|
||||
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 SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
|
||||
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||
|
@ -40,6 +40,7 @@ class HasFileSystemIF {
|
||||
//! [EXPORT] : P1: Can be file system specific error code
|
||||
static constexpr ReturnValue_t GENERIC_FILE_ERROR = MAKE_RETURN_CODE(0);
|
||||
static constexpr ReturnValue_t GENERIC_DIR_ERROR = MAKE_RETURN_CODE(1);
|
||||
static constexpr ReturnValue_t FILESYSTEM_INACTIVE = MAKE_RETURN_CODE(2);
|
||||
static constexpr ReturnValue_t GENERIC_RENAME_ERROR = MAKE_RETURN_CODE(3);
|
||||
|
||||
//! [EXPORT] : File system is currently busy
|
||||
|
@ -5,7 +5,11 @@
|
||||
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
||||
: objectId(objectId), owner(owner) {}
|
||||
|
||||
HealthHelper::~HealthHelper() { healthTable->removeObject(objectId); }
|
||||
HealthHelper::~HealthHelper() {
|
||||
if (healthTable != nullptr) {
|
||||
healthTable->removeObject(objectId);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
||||
switch (message->getCommand()) {
|
||||
|
@ -24,3 +24,13 @@ void ModeMessage::setCantReachMode(CommandMessage* message, ReturnValue_t reason
|
||||
message->setParameter(reason);
|
||||
message->setParameter2(0);
|
||||
}
|
||||
|
||||
void ModeMessage::setModeAnnounceMessage(CommandMessage& message, bool recursive) {
|
||||
Command_t cmd;
|
||||
if (recursive) {
|
||||
cmd = CMD_MODE_ANNOUNCE_RECURSIVELY;
|
||||
} else {
|
||||
cmd = CMD_MODE_ANNOUNCE;
|
||||
}
|
||||
message.setCommand(cmd);
|
||||
}
|
||||
|
@ -1,43 +1,42 @@
|
||||
#ifndef FSFW_MODES_MODEMESSAGE_H_
|
||||
#define FSFW_MODES_MODEMESSAGE_H_
|
||||
|
||||
#include "../ipc/CommandMessage.h"
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
|
||||
typedef uint32_t Mode_t;
|
||||
typedef uint8_t Submode_t;
|
||||
|
||||
class ModeMessage {
|
||||
private:
|
||||
ModeMessage();
|
||||
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND;
|
||||
static const Command_t CMD_MODE_COMMAND =
|
||||
MAKE_COMMAND_ID(0x01); //!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY,
|
||||
//! REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies,
|
||||
//! as this will break the subsystem mode machine!!
|
||||
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(
|
||||
0xF1); //!> Command to set the specified Mode, regardless of external control flag, replies
|
||||
//! are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any
|
||||
//! replies, as this will break the subsystem mode machine!!
|
||||
static const Command_t REPLY_MODE_REPLY =
|
||||
MAKE_COMMAND_ID(0x02); //!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
||||
static const Command_t REPLY_MODE_INFO =
|
||||
MAKE_COMMAND_ID(0x03); //!> Unrequested info about the current mode (used for composites to
|
||||
//! inform their container of a changed mode)
|
||||
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(
|
||||
0x04); //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
||||
static const Command_t REPLY_WRONG_MODE_REPLY =
|
||||
MAKE_COMMAND_ID(0x05); //!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded
|
||||
//! and a transition started but was aborted; the parameters contain
|
||||
//! the mode that was reached
|
||||
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(
|
||||
0x06); //!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
||||
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(
|
||||
0x07); //!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
||||
static const Command_t CMD_MODE_ANNOUNCE_RECURSIVELY =
|
||||
MAKE_COMMAND_ID(0x08); //!> Command to trigger an ModeInfo Event and to send this command to
|
||||
//! every child. This command does NOT have a reply.
|
||||
//!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY,
|
||||
//! REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies,
|
||||
//! as this will break the subsystem mode machine!!
|
||||
static const Command_t CMD_MODE_COMMAND = MAKE_COMMAND_ID(0x01);
|
||||
//!> Command to set the specified Mode, regardless of external control flag, replies
|
||||
//! are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any
|
||||
//! replies, as this will break the subsystem mode machine!!
|
||||
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(0xF1);
|
||||
//!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
||||
static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);
|
||||
//!> Unrequested info about the current mode (used for composites to
|
||||
//! inform their container of a changed mode)
|
||||
static const Command_t REPLY_MODE_INFO = MAKE_COMMAND_ID(0x03);
|
||||
//!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
||||
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(0x04);
|
||||
//!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded
|
||||
//! and a transition started but was aborted; the parameters contain
|
||||
//! the mode that was reached
|
||||
static const Command_t REPLY_WRONG_MODE_REPLY = MAKE_COMMAND_ID(0x05);
|
||||
//!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
||||
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(0x06);
|
||||
//!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
||||
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(0x07);
|
||||
//!> Command to trigger an ModeInfo Event and to send this command to
|
||||
//! every child. This command does NOT have a reply.
|
||||
static const Command_t CMD_MODE_ANNOUNCE_RECURSIVELY = MAKE_COMMAND_ID(0x08);
|
||||
|
||||
ModeMessage() = delete;
|
||||
|
||||
static Mode_t getMode(const CommandMessage* message);
|
||||
static Submode_t getSubmode(const CommandMessage* message);
|
||||
@ -45,6 +44,7 @@ class ModeMessage {
|
||||
|
||||
static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode,
|
||||
Submode_t submode);
|
||||
static void setModeAnnounceMessage(CommandMessage& message, bool recursive);
|
||||
static void setCantReachMode(CommandMessage* message, ReturnValue_t reason);
|
||||
static void clear(CommandMessage* message);
|
||||
};
|
||||
|
@ -274,6 +274,8 @@ ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket, bool& tmSent)
|
||||
ConstStorageAccessor storeAccessor(storeId);
|
||||
ReturnValue_t result = tmStore->getData(storeId, storeAccessor);
|
||||
if (result != returnvalue::OK) {
|
||||
// Invalid entry, pop FIFO
|
||||
tmtcBridge->tmFifo->pop();
|
||||
return result;
|
||||
}
|
||||
if (wiretappingEnabled) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
|
||||
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
|
||||
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||
power::Switch_t pwrSwitch)
|
||||
: SystemObject(objectId),
|
||||
switcher(pwrSwitcher, pwrSwitch),
|
||||
@ -54,7 +54,7 @@ ReturnValue_t PowerSwitcherComponent::initialize() {
|
||||
|
||||
MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const { return queue->getId(); }
|
||||
|
||||
void PowerSwitcherComponent::getMode(Mode_t *mode, Submode_t *submode) {
|
||||
void PowerSwitcherComponent::getMode(Mode_t* mode, Submode_t* submode) {
|
||||
*mode = this->mode;
|
||||
*submode = this->submode;
|
||||
}
|
||||
@ -65,7 +65,7 @@ ReturnValue_t PowerSwitcherComponent::setHealth(HealthState health) {
|
||||
}
|
||||
|
||||
ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
uint32_t* msToReachTheMode) {
|
||||
*msToReachTheMode = 5000;
|
||||
if (mode != MODE_ON and mode != MODE_OFF) {
|
||||
return TRANS_NOT_ALLOWED;
|
||||
@ -105,3 +105,15 @@ void PowerSwitcherComponent::setMode(Mode_t newMode, Submode_t newSubmode) {
|
||||
}
|
||||
|
||||
HasHealthIF::HealthState PowerSwitcherComponent::getHealth() { return healthHelper.getHealth(); }
|
||||
|
||||
const HasHealthIF* PowerSwitcherComponent::getOptHealthIF() const { return this; }
|
||||
|
||||
const HasModesIF& PowerSwitcherComponent::getModeIF() const { return *this; }
|
||||
|
||||
ReturnValue_t PowerSwitcherComponent::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||
return parent.registerChild(*this);
|
||||
}
|
||||
|
||||
object_id_t PowerSwitcherComponent::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
||||
ModeTreeChildIF& PowerSwitcherComponent::getModeTreeChildIF() { return *this; }
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/power/PowerSwitcher.h>
|
||||
#include <fsfw/power/definitions.h>
|
||||
#include <fsfw/subsystem/ModeTreeChildIF.h>
|
||||
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
|
||||
class PowerSwitchIF;
|
||||
@ -24,12 +26,17 @@ class PowerSwitchIF;
|
||||
*/
|
||||
class PowerSwitcherComponent : public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public ModeTreeChildIF,
|
||||
public ModeTreeConnectionIF,
|
||||
public HasModesIF,
|
||||
public HasHealthIF {
|
||||
public:
|
||||
PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF *pwrSwitcher,
|
||||
power::Switch_t pwrSwitch);
|
||||
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||
|
||||
private:
|
||||
MessageQueueIF *queue = nullptr;
|
||||
PowerSwitcher switcher;
|
||||
@ -56,6 +63,10 @@ class PowerSwitcherComponent : public SystemObject,
|
||||
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
HasHealthIF::HealthState getHealth() override;
|
||||
|
||||
object_id_t getObjectId() const override;
|
||||
const HasHealthIF *getOptHealthIF() const override;
|
||||
const HasModesIF &getModeIF() const override;
|
||||
};
|
||||
|
||||
#endif /* _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ */
|
||||
|
@ -20,6 +20,7 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
|
||||
case (Subservice::COMMAND_MODE_COMMAND):
|
||||
case (Subservice::COMMAND_MODE_READ):
|
||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||
return returnvalue::OK;
|
||||
default:
|
||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||
@ -53,15 +54,26 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
|
||||
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen,
|
||||
uint32_t *state, object_id_t objectId) {
|
||||
ModePacket modeCommandPacket;
|
||||
ReturnValue_t result =
|
||||
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE or
|
||||
subservice == Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY) {
|
||||
bool recursive = true;
|
||||
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
|
||||
recursive = false;
|
||||
}
|
||||
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
||||
} else {
|
||||
ModePacket modeCommandPacket;
|
||||
ReturnValue_t result =
|
||||
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
|
||||
modeCommandPacket.getSubmode());
|
||||
}
|
||||
|
||||
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
|
||||
modeCommandPacket.getSubmode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "fsfw/pus/Service17Test.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeElement.h>
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
@ -31,6 +33,15 @@ ReturnValue_t Service17Test::handleRequest(uint8_t subservice) {
|
||||
}
|
||||
return tmHelper.storeAndSendTmPacket();
|
||||
}
|
||||
case Subservice::PING_WITH_DATA: {
|
||||
SerializeElement<uint32_t> receivedDataLen = currentPacket.getUserDataLen();
|
||||
ReturnValue_t result =
|
||||
tmHelper.prepareTmPacket(Subservice::PING_WITH_DATA_REPORT_WITH_SIZE, receivedDataLen);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return tmHelper.storeAndSendTmPacket();
|
||||
}
|
||||
default:
|
||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||
}
|
||||
|
@ -32,6 +32,9 @@ class Service17Test : public PusServiceBase {
|
||||
CONNECTION_TEST_REPORT = 2,
|
||||
//! [EXPORT] : [COMMAND] Trigger test reply and test event
|
||||
EVENT_TRIGGER_TEST = 128,
|
||||
PING_WITH_DATA = 129,
|
||||
//! [EXPORT] : [COMMAND] Report which reports the sent user data size
|
||||
PING_WITH_DATA_REPORT_WITH_SIZE = 130
|
||||
};
|
||||
|
||||
explicit Service17Test(PsbParams params);
|
||||
|
@ -42,7 +42,7 @@
|
||||
class Service5EventReporting : public PusServiceBase {
|
||||
public:
|
||||
Service5EventReporting(PsbParams params, size_t maxNumberReportsPerCycle = 10,
|
||||
uint32_t messageQueueDepth = 10);
|
||||
uint32_t messageQueueDepth = 20);
|
||||
~Service5EventReporting() override;
|
||||
|
||||
/***
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
||||
#define FSFW_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
||||
|
||||
#include "../../modes/ModeMessage.h"
|
||||
#include "../../serialize/SerialLinkedListAdapter.h"
|
||||
#include "../../serialize/SerializeIF.h"
|
||||
#include "fsfw/modes/ModeMessage.h"
|
||||
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
/**
|
||||
* @brief Subservice 1, 2, 3, 4, 5
|
||||
|
@ -1,3 +1,4 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE Subsystem.cpp SubsystemBase.cpp)
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE Subsystem.cpp SubsystemBase.cpp
|
||||
helper.cpp)
|
||||
|
||||
add_subdirectory(modes)
|
||||
|
13
src/fsfw/subsystem/HasModeTreeChildrenIF.h
Normal file
13
src/fsfw/subsystem/HasModeTreeChildrenIF.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef FSFW_SUBSYSTEM_HASMODETREECHILDRENIF_H_
|
||||
#define FSFW_SUBSYSTEM_HASMODETREECHILDRENIF_H_
|
||||
|
||||
#include "ModeTreeChildIF.h"
|
||||
|
||||
class HasModeTreeChildrenIF {
|
||||
public:
|
||||
virtual ~HasModeTreeChildrenIF() = default;
|
||||
virtual ReturnValue_t registerChild(const ModeTreeChildIF& child) = 0;
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
};
|
||||
|
||||
#endif // FSFW_SUBSYSTEM_HASMODETREECHILDRENIF_H_
|
15
src/fsfw/subsystem/ModeTreeChildIF.h
Normal file
15
src/fsfw/subsystem/ModeTreeChildIF.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef FSFW_SUBSYSTEM_MODETREECHILDIF_H_
|
||||
#define FSFW_SUBSYSTEM_MODETREECHILDIF_H_
|
||||
|
||||
#include <fsfw/health/HasHealthIF.h>
|
||||
#include <fsfw/modes/HasModesIF.h>
|
||||
|
||||
class ModeTreeChildIF {
|
||||
public:
|
||||
virtual ~ModeTreeChildIF() = default;
|
||||
virtual object_id_t getObjectId() const = 0;
|
||||
virtual const HasHealthIF* getOptHealthIF() const = 0;
|
||||
virtual const HasModesIF& getModeIF() const = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SUBSYSTEM_MODETREECHILDIF_H_ */
|
13
src/fsfw/subsystem/ModeTreeConnectionIF.h
Normal file
13
src/fsfw/subsystem/ModeTreeConnectionIF.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef FSFW_SUBSYSTEM_MODES_MODETREECONNECTIONIF_H_
|
||||
#define FSFW_SUBSYSTEM_MODES_MODETREECONNECTIONIF_H_
|
||||
|
||||
#include "fsfw/subsystem/HasModeTreeChildrenIF.h"
|
||||
|
||||
class ModeTreeConnectionIF {
|
||||
public:
|
||||
virtual ~ModeTreeConnectionIF() = default;
|
||||
virtual ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) = 0;
|
||||
virtual ModeTreeChildIF& getModeTreeChildIF() = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_SUBSYSTEM_MODES_MODETREECONNECTIONIF_H_ */
|
@ -9,9 +9,9 @@
|
||||
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||
#include "fsfw/serialize/SerializeElement.h"
|
||||
|
||||
Subsystem::Subsystem(object_id_t setObjectId, object_id_t parent, uint32_t maxNumberOfSequences,
|
||||
Subsystem::Subsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
|
||||
uint32_t maxNumberOfTables)
|
||||
: SubsystemBase(setObjectId, parent, 0),
|
||||
: SubsystemBase(setObjectId, 0),
|
||||
isInTransition(false),
|
||||
childrenChangedHealth(false),
|
||||
currentTargetTable(),
|
||||
@ -36,6 +36,13 @@ ReturnValue_t Subsystem::checkSequence(HybridIterator<ModeListEntry> iter,
|
||||
|
||||
for (; iter.value != nullptr; ++iter) {
|
||||
if (!existsModeTable(iter->getTableId())) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
using namespace std;
|
||||
sif::warning << "Subsystem::checkSequence: "
|
||||
<< "Object " << setfill('0') << hex << "0x" << setw(8) << getObjectId()
|
||||
<< setw(0) << ": Mode table for mode ID "
|
||||
<< "0x" << setw(8) << iter->getTableId() << " does not exist" << dec << endl;
|
||||
#endif
|
||||
return TABLE_DOES_NOT_EXIST;
|
||||
} else {
|
||||
ReturnValue_t result = checkTable(getTable(iter->getTableId()));
|
||||
|
@ -66,8 +66,7 @@ class Subsystem : public SubsystemBase, public HasModeSequenceIF {
|
||||
* @param maxNumberOfSequences
|
||||
* @param maxNumberOfTables
|
||||
*/
|
||||
Subsystem(object_id_t setObjectId, object_id_t parent, uint32_t maxNumberOfSequences,
|
||||
uint32_t maxNumberOfTables);
|
||||
Subsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
|
||||
virtual ~Subsystem();
|
||||
|
||||
ReturnValue_t addSequence(SequenceEntry sequence);
|
||||
|
@ -1,16 +1,17 @@
|
||||
#include "fsfw/subsystem/SubsystemBase.h"
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "fsfw/subsystem/helper.h"
|
||||
|
||||
SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t initialMode,
|
||||
SubsystemBase::SubsystemBase(object_id_t setObjectId, Mode_t initialMode,
|
||||
uint16_t commandQueueDepth)
|
||||
: SystemObject(setObjectId),
|
||||
mode(initialMode),
|
||||
healthHelper(this, setObjectId),
|
||||
modeHelper(this),
|
||||
parentId(parent) {
|
||||
modeHelper(this) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
@ -18,36 +19,6 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t
|
||||
|
||||
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
|
||||
ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
|
||||
ChildInfo info;
|
||||
|
||||
HasModesIF* child = ObjectManager::instance()->get<HasModesIF>(objectId);
|
||||
// This is a rather ugly hack to have the changedHealth info for all
|
||||
// children available.
|
||||
HasHealthIF* healthChild = ObjectManager::instance()->get<HasHealthIF>(objectId);
|
||||
if (child == nullptr) {
|
||||
if (healthChild == nullptr) {
|
||||
return CHILD_DOESNT_HAVE_MODES;
|
||||
} else {
|
||||
info.commandQueue = healthChild->getCommandQueue();
|
||||
info.mode = MODE_OFF;
|
||||
}
|
||||
} else {
|
||||
// intentional to force an initial command during system startup
|
||||
info.commandQueue = child->getCommandQueue();
|
||||
info.mode = HasModesIF::MODE_UNDEFINED;
|
||||
}
|
||||
|
||||
info.submode = SUBMODE_NONE;
|
||||
info.healthChanged = false;
|
||||
|
||||
auto resultPair = childrenMap.emplace(objectId, info);
|
||||
if (not resultPair.second) {
|
||||
return COULD_NOT_INSERT_CHILD;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SubsystemBase::checkStateAgainstTable(HybridIterator<ModeListEntry> tableIter,
|
||||
Submode_t targetSubmode) {
|
||||
std::map<object_id_t, ChildInfo>::iterator childIter;
|
||||
@ -87,7 +58,8 @@ void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submod
|
||||
if ((iter = childrenMap.find(object)) == childrenMap.end()) {
|
||||
// illegal table entry, should only happen due to misconfigured mode table
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << std::hex << getObjectId() << ": invalid mode table entry" << std::endl;
|
||||
sif::debug << std::hex << SystemObject::getObjectId() << ": invalid mode table entry"
|
||||
<< std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
@ -158,36 +130,15 @@ ReturnValue_t SubsystemBase::updateChildChangedHealth(MessageQueueId_t queue, bo
|
||||
MessageQueueId_t SubsystemBase::getCommandQueue() const { return commandQueue->getId(); }
|
||||
|
||||
ReturnValue_t SubsystemBase::initialize() {
|
||||
MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE;
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
|
||||
ReturnValue_t result = modeHelper.initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
parentQueue = parent->getCommandQueue();
|
||||
|
||||
parent->registerChild(getObjectId());
|
||||
}
|
||||
|
||||
result = healthHelper.initialize(parentQueue);
|
||||
|
||||
result = healthHelper.initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = modeHelper.initialize(parentQueue);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
return SystemObject::initialize();
|
||||
}
|
||||
|
||||
ReturnValue_t SubsystemBase::performOperation(uint8_t opCode) {
|
||||
@ -240,8 +191,14 @@ ReturnValue_t SubsystemBase::handleModeReply(CommandMessage* message) {
|
||||
}
|
||||
|
||||
ReturnValue_t SubsystemBase::checkTable(HybridIterator<ModeListEntry> tableIter) {
|
||||
for (; tableIter.value != NULL; ++tableIter) {
|
||||
for (; tableIter.value != nullptr; ++tableIter) {
|
||||
if (childrenMap.find(tableIter.value->getObject()) == childrenMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
using namespace std;
|
||||
sif::warning << "SubsystemBase::checkTable: Could not find Object " << setfill('0') << hex
|
||||
<< "0x" << setw(8) << tableIter.value->getObject() << " in object " << setw(8)
|
||||
<< setw(0) << "0x" << setw(8) << SystemObject::getObjectId() << dec << std::endl;
|
||||
#endif
|
||||
return TABLE_CONTAINS_INVALID_OBJECT_ID;
|
||||
}
|
||||
}
|
||||
@ -326,4 +283,33 @@ ReturnValue_t SubsystemBase::setHealth(HealthState health) {
|
||||
|
||||
HasHealthIF::HealthState SubsystemBase::getHealth() { return healthHelper.getHealth(); }
|
||||
|
||||
ReturnValue_t SubsystemBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||
return modetree::connectModeTreeParent(parent, *this, healthHelper, modeHelper);
|
||||
}
|
||||
|
||||
object_id_t SubsystemBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||
|
||||
void SubsystemBase::modeChanged() {}
|
||||
|
||||
ReturnValue_t SubsystemBase::registerChild(const ModeTreeChildIF& child) {
|
||||
ChildInfo info;
|
||||
|
||||
const HasModesIF& modeChild = child.getModeIF();
|
||||
// intentional to force an initial command during system startup
|
||||
info.commandQueue = modeChild.getCommandQueue();
|
||||
info.mode = HasModesIF::MODE_UNDEFINED;
|
||||
info.submode = SUBMODE_NONE;
|
||||
info.healthChanged = false;
|
||||
|
||||
auto resultPair = childrenMap.emplace(child.getObjectId(), info);
|
||||
if (not resultPair.second) {
|
||||
return COULD_NOT_INSERT_CHILD;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
const HasHealthIF* SubsystemBase::getOptHealthIF() const { return this; }
|
||||
|
||||
const HasModesIF& SubsystemBase::getModeIF() const { return *this; }
|
||||
|
||||
ModeTreeChildIF& SubsystemBase::getModeTreeChildIF() { return *this; }
|
||||
|
@ -3,14 +3,16 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../container/HybridIterator.h"
|
||||
#include "../health/HasHealthIF.h"
|
||||
#include "../health/HealthHelper.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../modes/HasModesIF.h"
|
||||
#include "../objectmanager/SystemObject.h"
|
||||
#include "../returnvalues/returnvalue.h"
|
||||
#include "../tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/container/HybridIterator.h"
|
||||
#include "fsfw/health/HasHealthIF.h"
|
||||
#include "fsfw/health/HealthHelper.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/modes/HasModesIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw/subsystem/HasModeTreeChildrenIF.h"
|
||||
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "modes/HasModeSequenceIF.h"
|
||||
|
||||
/**
|
||||
@ -27,6 +29,9 @@
|
||||
class SubsystemBase : public SystemObject,
|
||||
public HasModesIF,
|
||||
public HasHealthIF,
|
||||
public HasModeTreeChildrenIF,
|
||||
public ModeTreeConnectionIF,
|
||||
public ModeTreeChildIF,
|
||||
public ExecutableObjectIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SUBSYSTEM_BASE;
|
||||
@ -36,32 +41,34 @@ class SubsystemBase : public SystemObject,
|
||||
static const ReturnValue_t COULD_NOT_INSERT_CHILD = MAKE_RETURN_CODE(0x04);
|
||||
static const ReturnValue_t TABLE_CONTAINS_INVALID_OBJECT_ID = MAKE_RETURN_CODE(0x05);
|
||||
|
||||
SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t initialMode = 0,
|
||||
uint16_t commandQueueDepth = 8);
|
||||
SubsystemBase(object_id_t setObjectId, Mode_t initialMode = 0, uint16_t commandQueueDepth = 8);
|
||||
virtual ~SubsystemBase();
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue() const override;
|
||||
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||
|
||||
/**
|
||||
* Function to register the child objects.
|
||||
* Performs a checks if the child does implement HasHealthIF and/or HasModesIF
|
||||
*
|
||||
* Also adds them to the internal childrenMap.
|
||||
* Also adds them to the internal childrenMap.
|
||||
*
|
||||
* @param objectId
|
||||
* @return returnvalue::OK if successful
|
||||
* CHILD_DOESNT_HAVE_MODES if Child is no HasHealthIF and no HasModesIF
|
||||
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
|
||||
* CHILD_DOESNT_HAVE_MODES if Child is no HasHealthIF and no HasModesIF
|
||||
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
|
||||
*/
|
||||
ReturnValue_t registerChild(object_id_t objectId);
|
||||
ReturnValue_t registerChild(const ModeTreeChildIF &child) override;
|
||||
|
||||
virtual ReturnValue_t initialize() override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
|
||||
virtual ReturnValue_t setHealth(HealthState health) override;
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
|
||||
virtual HasHealthIF::HealthState getHealth() override;
|
||||
HasHealthIF::HealthState getHealth() override;
|
||||
|
||||
protected:
|
||||
struct ChildInfo {
|
||||
@ -88,8 +95,6 @@ class SubsystemBase : public SystemObject,
|
||||
|
||||
ModeHelper modeHelper;
|
||||
|
||||
const object_id_t parentId;
|
||||
|
||||
typedef std::map<object_id_t, ChildInfo> ChildrenMap;
|
||||
ChildrenMap childrenMap;
|
||||
|
||||
@ -136,6 +141,10 @@ class SubsystemBase : public SystemObject,
|
||||
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
|
||||
object_id_t getObjectId() const override;
|
||||
const HasHealthIF *getOptHealthIF() const override;
|
||||
const HasModesIF &getModeIF() const override;
|
||||
|
||||
virtual void setToExternalControl() override;
|
||||
|
||||
virtual void announceMode(bool recursive) override;
|
||||
|
13
src/fsfw/subsystem/helper.cpp
Normal file
13
src/fsfw/subsystem/helper.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "helper.h"
|
||||
|
||||
ReturnValue_t modetree::connectModeTreeParent(HasModeTreeChildrenIF& parent,
|
||||
const ModeTreeChildIF& child,
|
||||
HealthHelper& healthHelper, ModeHelper& modeHelper) {
|
||||
ReturnValue_t result = parent.registerChild(child);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
healthHelper.setParentQueue(parent.getCommandQueue());
|
||||
modeHelper.setParentQueue(parent.getCommandQueue());
|
||||
return returnvalue::OK;
|
||||
}
|
14
src/fsfw/subsystem/helper.h
Normal file
14
src/fsfw/subsystem/helper.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef FSFW_SUBSYSTEM_HELPER_H_
|
||||
#define FSFW_SUBSYSTEM_HELPER_H_
|
||||
|
||||
#include "HasModeTreeChildrenIF.h"
|
||||
#include "fsfw/health/HealthHelper.h"
|
||||
|
||||
namespace modetree {
|
||||
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent, const ModeTreeChildIF& child,
|
||||
HealthHelper& healthHelper, ModeHelper& modeHelper);
|
||||
|
||||
}
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_SUBSYSTEM_HELPER_H_ */
|
@ -21,7 +21,7 @@ SpacePacketReader::~SpacePacketReader() = default;
|
||||
|
||||
inline uint16_t SpacePacketReader::getPacketIdRaw() const { return ccsds::getPacketId(*spHeader); }
|
||||
|
||||
const uint8_t* SpacePacketReader::getPacketData() { return packetDataField; }
|
||||
const uint8_t* SpacePacketReader::getPacketData() const { return packetDataField; }
|
||||
|
||||
ReturnValue_t SpacePacketReader::setData(uint8_t* data, size_t maxSize_, void* args) {
|
||||
return setInternalFields(data, maxSize_);
|
||||
|
@ -71,7 +71,7 @@ class SpacePacketReader : public SpacePacketIF,
|
||||
// Helper methods:
|
||||
[[nodiscard]] ReturnValue_t checkSize() const;
|
||||
|
||||
const uint8_t* getPacketData();
|
||||
const uint8_t* getPacketData() const;
|
||||
|
||||
ReturnValue_t setReadOnlyData(const uint8_t* data, size_t maxSize);
|
||||
|
||||
|
@ -27,8 +27,8 @@ ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) {
|
||||
ReturnValue_t result = performService();
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PusService " << psbParams.serviceId << ": performService returned with "
|
||||
<< static_cast<uint16_t>(result) << std::endl;
|
||||
sif::error << "PusService " << static_cast<int>(psbParams.serviceId)
|
||||
<< ": performService returned with " << static_cast<uint16_t>(result) << std::endl;
|
||||
#endif
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, size_t len,
|
||||
#endif
|
||||
return DeviceHandlerIF::INVALID_DATA;
|
||||
}
|
||||
if (mode == _MODE_START_UP) {
|
||||
if (getMode() == _MODE_START_UP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, size_t len,
|
||||
return DeviceHandlerIF::INVALID_DATA;
|
||||
}
|
||||
|
||||
if (mode == _MODE_START_UP) {
|
||||
if (getMode() == _MODE_START_UP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
||||
case (RM3100::CONFIGURE_CYCLE_COUNT):
|
||||
case (RM3100::CONFIGURE_TMRC): {
|
||||
// We can only check whether write was successful with read operation
|
||||
if (mode == _MODE_START_UP) {
|
||||
if (getMode() == _MODE_START_UP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
break;
|
||||
@ -192,7 +192,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
||||
if (packet[1] == tmrcRegValue) {
|
||||
commandExecuted = true;
|
||||
// Reading TMRC was commanded. Trigger event to inform ground
|
||||
if (mode != _MODE_START_UP) {
|
||||
if (getMode() != _MODE_START_UP) {
|
||||
triggerEvent(tmrcSet, tmrcRegValue, 0);
|
||||
}
|
||||
} else {
|
||||
@ -211,7 +211,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
||||
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
|
||||
}
|
||||
// Reading TMRC was commanded. Trigger event to inform ground
|
||||
if (mode != _MODE_START_UP) {
|
||||
if (getMode() != _MODE_START_UP) {
|
||||
uint32_t eventParam1 = (cycleCountX << 16) | cycleCountY;
|
||||
triggerEvent(cycleCountersSet, eventParam1, cycleCountZ);
|
||||
}
|
||||
|
@ -5,11 +5,14 @@ endif()
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp
|
||||
utility.cpp)
|
||||
|
||||
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
||||
add_subdirectory(gpio)
|
||||
endif()
|
||||
if(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS)
|
||||
add_subdirectory(serial)
|
||||
endif()
|
||||
|
||||
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
||||
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
||||
add_subdirectory(gpio)
|
||||
endif()
|
||||
add_subdirectory(uart)
|
||||
# Adding those does not really make sense on Apple systems which are generally
|
||||
# host systems. It won't even compile as the headers are missing
|
||||
if(NOT APPLE)
|
||||
|
@ -214,7 +214,7 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
auto gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LinuxLibgpioIF::pullHigh: Unknown GPIO ID " << gpioId << std::endl;
|
||||
@ -244,7 +244,7 @@ ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
auto gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LinuxLibgpioIF::pullLow: Unknown GPIO ID " << gpioId << std::endl;
|
||||
@ -295,7 +295,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegularBase& regul
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState) {
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
auto gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||
@ -377,7 +377,7 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsById(gpioId_t gpioIdToCheck,
|
||||
gpio::GpioTypes expectedType,
|
||||
GpioMap& mapToAdd) {
|
||||
// Cross check with private map
|
||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||
auto gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||
if (gpioMapIter != gpioMap.end()) {
|
||||
auto& gpioType = gpioMapIter->second->gpioType;
|
||||
bool eraseDuplicateDifferentType = false;
|
||||
|
@ -44,7 +44,6 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
||||
|
||||
// Holds the information and configuration of all used GPIOs
|
||||
GpioUnorderedMap gpioMap;
|
||||
GpioUnorderedMapIter gpioMapIter;
|
||||
|
||||
/**
|
||||
* @brief This functions drives line of a GPIO specified by the GPIO ID.
|
||||
|
@ -41,7 +41,7 @@ ReturnValue_t I2cComIF::initializeInterface(CookieIF* cookie) {
|
||||
|
||||
i2cAddress = i2cCookie->getAddress();
|
||||
|
||||
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
auto i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
|
||||
size_t maxReplyLen = i2cCookie->getMaxReplyLen();
|
||||
I2cInstance i2cInstance = {std::vector<uint8_t>(maxReplyLen), 0};
|
||||
@ -89,7 +89,7 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
||||
}
|
||||
|
||||
address_t i2cAddress = i2cCookie->getAddress();
|
||||
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
auto i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not "
|
||||
@ -140,20 +140,19 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" << std::endl;
|
||||
#endif
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
address_t i2cAddress = i2cCookie->getAddress();
|
||||
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
auto i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::requestReceiveMessage: i2cAddress of Cookie not "
|
||||
<< "registered in i2cDeviceMap" << std::endl;
|
||||
#endif
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
|
||||
deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::requestReceiveMessage");
|
||||
@ -162,7 +161,6 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
}
|
||||
result = openDevice(deviceFile, i2cAddress, &fd);
|
||||
if (result != returnvalue::OK) {
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -183,7 +181,10 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
#else
|
||||
#endif
|
||||
#endif
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
|
||||
<< " bytes" << std::endl;
|
||||
#endif
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
@ -206,7 +207,7 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
}
|
||||
|
||||
address_t i2cAddress = i2cCookie->getAddress();
|
||||
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
auto i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
|
||||
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::readReceivedMessage: i2cAddress of Cookie not "
|
||||
|
@ -36,12 +36,10 @@ class I2cComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
};
|
||||
|
||||
using I2cDeviceMap = std::unordered_map<address_t, I2cInstance>;
|
||||
using I2cDeviceMapIter = I2cDeviceMap::iterator;
|
||||
|
||||
/* In this map all i2c devices will be registered with their address and
|
||||
* the appropriate file descriptor will be stored */
|
||||
I2cDeviceMap i2cDeviceMap;
|
||||
I2cDeviceMapIter i2cDeviceMapIter;
|
||||
|
||||
/**
|
||||
* @brief This function opens an I2C device and binds the opened file
|
||||
|
2
src/fsfw_hal/linux/serial/CMakeLists.txt
Normal file
2
src/fsfw_hal/linux/serial/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
target_sources(${LIB_FSFW_NAME} PUBLIC SerialComIF.cpp SerialCookie.cpp
|
||||
helper.cpp)
|
@ -1,4 +1,4 @@
|
||||
#include "UartComIF.h"
|
||||
#include "SerialComIF.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -11,13 +11,12 @@
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "fsfw_hal/linux/utility.h"
|
||||
|
||||
UartComIF::UartComIF(object_id_t objectId) : SystemObject(objectId) {}
|
||||
SerialComIF::SerialComIF(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
UartComIF::~UartComIF() {}
|
||||
SerialComIF::~SerialComIF() {}
|
||||
|
||||
ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
|
||||
ReturnValue_t SerialComIF::initializeInterface(CookieIF* cookie) {
|
||||
std::string deviceFile;
|
||||
UartDeviceMapIter uartDeviceMapIter;
|
||||
|
||||
if (cookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
@ -33,7 +32,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
|
||||
|
||||
deviceFile = uartCookie->getDeviceFile();
|
||||
|
||||
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
if (uartDeviceMapIter == uartDeviceMap.end()) {
|
||||
int fileDescriptor = configureUartPort(uartCookie);
|
||||
if (fileDescriptor < 0) {
|
||||
@ -60,7 +59,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
||||
int SerialComIF::configureUartPort(UartCookie* uartCookie) {
|
||||
struct termios options = {};
|
||||
|
||||
std::string deviceFile = uartCookie->getDeviceFile();
|
||||
@ -89,7 +88,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
setParityOptions(&options, uartCookie);
|
||||
uart::setParity(options, uartCookie->getParity());
|
||||
setStopBitOptions(&options, uartCookie);
|
||||
setDatasizeOptions(&options, uartCookie);
|
||||
setFixedOptions(&options);
|
||||
@ -115,24 +114,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
void UartComIF::setParityOptions(struct termios* options, UartCookie* uartCookie) {
|
||||
/* Clear parity bit */
|
||||
options->c_cflag &= ~PARENB;
|
||||
switch (uartCookie->getParity()) {
|
||||
case Parity::EVEN:
|
||||
options->c_cflag |= PARENB;
|
||||
options->c_cflag &= ~PARODD;
|
||||
break;
|
||||
case Parity::ODD:
|
||||
options->c_cflag |= PARENB;
|
||||
options->c_cflag |= PARODD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCookie) {
|
||||
void SerialComIF::setStopBitOptions(struct termios* options, UartCookie* uartCookie) {
|
||||
/* Clear stop field. Sets stop bit to one bit */
|
||||
options->c_cflag &= ~CSTOPB;
|
||||
switch (uartCookie->getStopBits()) {
|
||||
@ -144,7 +126,7 @@ void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCooki
|
||||
}
|
||||
}
|
||||
|
||||
void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCookie) {
|
||||
void SerialComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCookie) {
|
||||
/* Clear size bits */
|
||||
options->c_cflag &= ~CSIZE;
|
||||
switch (uartCookie->getBitsPerWord()) {
|
||||
@ -168,7 +150,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook
|
||||
}
|
||||
}
|
||||
|
||||
void UartComIF::setFixedOptions(struct termios* options) {
|
||||
void SerialComIF::setFixedOptions(struct termios* options) {
|
||||
/* Disable RTS/CTS hardware flow control */
|
||||
options->c_cflag &= ~CRTSCTS;
|
||||
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
|
||||
@ -191,10 +173,9 @@ void UartComIF::setFixedOptions(struct termios* options) {
|
||||
options->c_oflag &= ~ONLCR;
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
||||
ReturnValue_t SerialComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
||||
int fd = 0;
|
||||
std::string deviceFile;
|
||||
UartDeviceMapIter uartDeviceMapIter;
|
||||
|
||||
if (sendLen == 0) {
|
||||
return returnvalue::OK;
|
||||
@ -216,7 +197,7 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||
}
|
||||
|
||||
deviceFile = uartCookie->getDeviceFile();
|
||||
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
if (uartDeviceMapIter == uartDeviceMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "UartComIF::sendMessage: Device file " << deviceFile << "not in UART map"
|
||||
@ -238,11 +219,10 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
||||
ReturnValue_t SerialComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
||||
|
||||
ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||
ReturnValue_t SerialComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||
std::string deviceFile;
|
||||
UartDeviceMapIter uartDeviceMapIter;
|
||||
|
||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
||||
if (uartCookie == nullptr) {
|
||||
@ -254,7 +234,7 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL
|
||||
|
||||
UartModes uartMode = uartCookie->getUartMode();
|
||||
deviceFile = uartCookie->getDeviceFile();
|
||||
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
|
||||
if (uartMode == UartModes::NON_CANONICAL and requestLen == 0) {
|
||||
return returnvalue::OK;
|
||||
@ -277,8 +257,8 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
|
||||
size_t requestLen) {
|
||||
ReturnValue_t SerialComIF::handleCanonicalRead(UartCookie& uartCookie,
|
||||
UartDeviceMap::iterator& iter, size_t requestLen) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t maxReadCycles = uartCookie.getReadCycles();
|
||||
uint8_t currentReadCycles = 0;
|
||||
@ -335,8 +315,9 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
|
||||
size_t requestLen) {
|
||||
ReturnValue_t SerialComIF::handleNoncanonicalRead(UartCookie& uartCookie,
|
||||
UartDeviceMap::iterator& iter,
|
||||
size_t requestLen) {
|
||||
int fd = iter->second.fileDescriptor;
|
||||
auto bufferPtr = iter->second.replyBuffer.data();
|
||||
// Size check to prevent buffer overflow
|
||||
@ -369,9 +350,8 @@ ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie, UartDevi
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
||||
ReturnValue_t SerialComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
||||
std::string deviceFile;
|
||||
UartDeviceMapIter uartDeviceMapIter;
|
||||
|
||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
||||
if (uartCookie == nullptr) {
|
||||
@ -382,7 +362,7 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
}
|
||||
|
||||
deviceFile = uartCookie->getDeviceFile();
|
||||
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
if (uartDeviceMapIter == uartDeviceMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile << " not in uart map"
|
||||
@ -400,9 +380,8 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
|
||||
ReturnValue_t SerialComIF::flushUartRxBuffer(CookieIF* cookie) {
|
||||
std::string deviceFile;
|
||||
UartDeviceMapIter uartDeviceMapIter;
|
||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
||||
if (uartCookie == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -411,7 +390,7 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
deviceFile = uartCookie->getDeviceFile();
|
||||
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
if (uartDeviceMapIter != uartDeviceMap.end()) {
|
||||
int fd = uartDeviceMapIter->second.fileDescriptor;
|
||||
tcflush(fd, TCIFLUSH);
|
||||
@ -420,9 +399,8 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
|
||||
ReturnValue_t SerialComIF::flushUartTxBuffer(CookieIF* cookie) {
|
||||
std::string deviceFile;
|
||||
UartDeviceMapIter uartDeviceMapIter;
|
||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
||||
if (uartCookie == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -431,7 +409,7 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
deviceFile = uartCookie->getDeviceFile();
|
||||
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
if (uartDeviceMapIter != uartDeviceMap.end()) {
|
||||
int fd = uartDeviceMapIter->second.fileDescriptor;
|
||||
tcflush(fd, TCOFLUSH);
|
||||
@ -440,9 +418,8 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
|
||||
ReturnValue_t SerialComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
|
||||
std::string deviceFile;
|
||||
UartDeviceMapIter uartDeviceMapIter;
|
||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
||||
if (uartCookie == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -451,7 +428,7 @@ ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
deviceFile = uartCookie->getDeviceFile();
|
||||
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
||||
if (uartDeviceMapIter != uartDeviceMap.end()) {
|
||||
int fd = uartDeviceMapIter->second.fileDescriptor;
|
||||
tcflush(fd, TCIOFLUSH);
|
@ -3,13 +3,12 @@
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw_hal/linux/serial/SerialCookie.h>
|
||||
#include <fsfw_hal/linux/serial/helper.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "UartCookie.h"
|
||||
#include "helper.h"
|
||||
|
||||
/**
|
||||
* @brief This is the communication interface to access serial ports on linux based operating
|
||||
* systems.
|
||||
@ -19,7 +18,7 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
class SerialComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
public:
|
||||
static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART;
|
||||
|
||||
@ -27,9 +26,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2);
|
||||
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3);
|
||||
|
||||
UartComIF(object_id_t objectId);
|
||||
SerialComIF(object_id_t objectId);
|
||||
|
||||
virtual ~UartComIF();
|
||||
virtual ~SerialComIF();
|
||||
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
@ -63,7 +62,6 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
};
|
||||
|
||||
using UartDeviceMap = std::unordered_map<UartDeviceFile_t, UartElements>;
|
||||
using UartDeviceMapIter = UartDeviceMap::iterator;
|
||||
|
||||
/**
|
||||
* The uart devie map stores informations of initialized uart ports.
|
||||
@ -79,17 +77,6 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
*/
|
||||
int configureUartPort(UartCookie* uartCookie);
|
||||
|
||||
/**
|
||||
* @brief This function adds the parity settings to the termios options struct.
|
||||
*
|
||||
* @param options Pointer to termios options struct which will be modified to enable or disable
|
||||
* parity checking.
|
||||
* @param uartCookie Pointer to uart cookie containing the information about the desired
|
||||
* parity settings.
|
||||
*
|
||||
*/
|
||||
void setParityOptions(struct termios* options, UartCookie* uartCookie);
|
||||
|
||||
void setStopBitOptions(struct termios* options, UartCookie* uartCookie);
|
||||
|
||||
/**
|
||||
@ -102,9 +89,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
*/
|
||||
void setDatasizeOptions(struct termios* options, UartCookie* uartCookie);
|
||||
|
||||
ReturnValue_t handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
|
||||
ReturnValue_t handleCanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
||||
size_t requestLen);
|
||||
ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
|
||||
ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
||||
size_t requestLen);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "UartCookie.h"
|
||||
#include "SerialCookie.h"
|
||||
|
||||
#include <fsfw/serviceinterface.h>
|
||||
|
@ -3,11 +3,10 @@
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||
#include <fsfw_hal/linux/serial/helper.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "helper.h"
|
||||
|
||||
/**
|
||||
* @brief Cookie for the UartComIF. There are many options available to configure the UART driver.
|
||||
* The constructor only requests for common options like the baudrate. Other options can
|
163
src/fsfw_hal/linux/serial/helper.cpp
Normal file
163
src/fsfw_hal/linux/serial/helper.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
#include <fsfw_hal/linux/serial/helper.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
void uart::setMode(struct termios& options, UartModes mode) {
|
||||
if (mode == UartModes::NON_CANONICAL) {
|
||||
/* Disable canonical mode */
|
||||
options.c_lflag &= ~ICANON;
|
||||
} else if (mode == UartModes::CANONICAL) {
|
||||
options.c_lflag |= ICANON;
|
||||
}
|
||||
}
|
||||
|
||||
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
||||
switch (baud) {
|
||||
case UartBaudRate::RATE_50:
|
||||
cfsetspeed(&options, B50);
|
||||
break;
|
||||
case UartBaudRate::RATE_75:
|
||||
cfsetspeed(&options, B75);
|
||||
break;
|
||||
case UartBaudRate::RATE_110:
|
||||
cfsetspeed(&options, B110);
|
||||
break;
|
||||
case UartBaudRate::RATE_134:
|
||||
cfsetspeed(&options, B134);
|
||||
break;
|
||||
case UartBaudRate::RATE_150:
|
||||
cfsetspeed(&options, B150);
|
||||
break;
|
||||
case UartBaudRate::RATE_200:
|
||||
cfsetspeed(&options, B200);
|
||||
break;
|
||||
case UartBaudRate::RATE_300:
|
||||
cfsetspeed(&options, B300);
|
||||
break;
|
||||
case UartBaudRate::RATE_600:
|
||||
cfsetspeed(&options, B600);
|
||||
break;
|
||||
case UartBaudRate::RATE_1200:
|
||||
cfsetspeed(&options, B1200);
|
||||
break;
|
||||
case UartBaudRate::RATE_1800:
|
||||
cfsetspeed(&options, B1800);
|
||||
break;
|
||||
case UartBaudRate::RATE_2400:
|
||||
cfsetspeed(&options, B2400);
|
||||
break;
|
||||
case UartBaudRate::RATE_4800:
|
||||
cfsetspeed(&options, B4800);
|
||||
break;
|
||||
case UartBaudRate::RATE_9600:
|
||||
cfsetspeed(&options, B9600);
|
||||
break;
|
||||
case UartBaudRate::RATE_19200:
|
||||
cfsetspeed(&options, B19200);
|
||||
break;
|
||||
case UartBaudRate::RATE_38400:
|
||||
cfsetspeed(&options, B38400);
|
||||
break;
|
||||
case UartBaudRate::RATE_57600:
|
||||
cfsetspeed(&options, B57600);
|
||||
break;
|
||||
case UartBaudRate::RATE_115200:
|
||||
cfsetspeed(&options, B115200);
|
||||
break;
|
||||
case UartBaudRate::RATE_230400:
|
||||
cfsetspeed(&options, B230400);
|
||||
break;
|
||||
#ifndef __APPLE__
|
||||
case UartBaudRate::RATE_460800:
|
||||
cfsetspeed(&options, B460800);
|
||||
break;
|
||||
case UartBaudRate::RATE_500000:
|
||||
cfsetspeed(&options, B500000);
|
||||
break;
|
||||
case UartBaudRate::RATE_576000:
|
||||
cfsetspeed(&options, B576000);
|
||||
break;
|
||||
case UartBaudRate::RATE_921600:
|
||||
cfsetspeed(&options, B921600);
|
||||
break;
|
||||
case UartBaudRate::RATE_1000000:
|
||||
cfsetspeed(&options, B1000000);
|
||||
break;
|
||||
case UartBaudRate::RATE_1152000:
|
||||
cfsetspeed(&options, B1152000);
|
||||
break;
|
||||
case UartBaudRate::RATE_1500000:
|
||||
cfsetspeed(&options, B1500000);
|
||||
break;
|
||||
case UartBaudRate::RATE_2000000:
|
||||
cfsetspeed(&options, B2000000);
|
||||
break;
|
||||
case UartBaudRate::RATE_2500000:
|
||||
cfsetspeed(&options, B2500000);
|
||||
break;
|
||||
case UartBaudRate::RATE_3000000:
|
||||
cfsetspeed(&options, B3000000);
|
||||
break;
|
||||
case UartBaudRate::RATE_3500000:
|
||||
cfsetspeed(&options, B3500000);
|
||||
break;
|
||||
case UartBaudRate::RATE_4000000:
|
||||
cfsetspeed(&options, B4000000);
|
||||
break;
|
||||
#endif // ! __APPLE__
|
||||
default:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
||||
options.c_cflag &= ~CSIZE; // Clear all the size bits
|
||||
if (bits == BitsPerWord::BITS_5) {
|
||||
options.c_cflag |= CS5;
|
||||
} else if (bits == BitsPerWord::BITS_6) {
|
||||
options.c_cflag |= CS6;
|
||||
} else if (bits == BitsPerWord::BITS_7) {
|
||||
options.c_cflag |= CS7;
|
||||
} else if (bits == BitsPerWord::BITS_8) {
|
||||
options.c_cflag |= CS8;
|
||||
}
|
||||
}
|
||||
|
||||
void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
|
||||
|
||||
void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
|
||||
|
||||
void uart::setParity(struct termios& options, Parity parity) {
|
||||
/* Clear parity bit */
|
||||
options.c_cflag &= ~PARENB;
|
||||
switch (parity) {
|
||||
case Parity::EVEN:
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag &= ~PARODD;
|
||||
break;
|
||||
case Parity::ODD:
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag |= PARODD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
||||
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
||||
}
|
||||
|
||||
void uart::setStopbits(struct termios& options, StopBits bits) {
|
||||
if (bits == StopBits::TWO_STOP_BITS) {
|
||||
// Use two stop bits
|
||||
options.c_cflag |= CSTOPB;
|
||||
} else {
|
||||
// Clear stop field, only one stop bit used in communication
|
||||
options.c_cflag &= ~CSTOPB;
|
||||
}
|
||||
}
|
@ -54,6 +54,16 @@ void setMode(struct termios& options, UartModes mode);
|
||||
*/
|
||||
void setBaudrate(struct termios& options, UartBaudRate baud);
|
||||
|
||||
void setStopbits(struct termios& options, StopBits bits);
|
||||
|
||||
void setBitsPerWord(struct termios& options, BitsPerWord bits);
|
||||
|
||||
void enableRead(struct termios& options);
|
||||
|
||||
void setParity(struct termios& options, Parity parity);
|
||||
|
||||
void ignoreCtrlLines(struct termios& options);
|
||||
|
||||
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
||||
|
||||
} // namespace uart
|
@ -15,18 +15,8 @@
|
||||
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
||||
#include "fsfw_hal/linux/utility.h"
|
||||
|
||||
SpiComIF::SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF)
|
||||
SpiComIF::SpiComIF(object_id_t objectId, std::string devname, GpioIF& gpioComIF)
|
||||
: SystemObject(objectId), gpioComIF(gpioComIF), dev(std::move(devname)) {
|
||||
if (gpioComIF == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::SpiComIF: GPIO communication interface invalid!" << std::endl;
|
||||
#else
|
||||
sif::printError("SpiComIF::SpiComIF: GPIO communication interface invalid!\n");
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
}
|
||||
|
||||
csMutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
@ -75,7 +65,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
||||
/* Pull CS high in any case to be sure that device is inactive */
|
||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||
if (gpioId != gpio::NO_GPIO) {
|
||||
gpioComIF->pullHigh(gpioId);
|
||||
gpioComIF.pullHigh(gpioId);
|
||||
}
|
||||
|
||||
uint32_t spiSpeed = 0;
|
||||
@ -215,7 +205,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
return result;
|
||||
}
|
||||
updateLinePolarity(fileDescriptor);
|
||||
result = gpioComIF->pullLow(gpioId);
|
||||
result = gpioComIF.pullLow(gpioId);
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -256,7 +246,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
}
|
||||
|
||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
||||
gpioComIF->pullHigh(gpioId);
|
||||
gpioComIF.pullHigh(gpioId);
|
||||
result = csMutex->unlockMutex();
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -317,7 +307,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
gpioComIF->pullLow(gpioId);
|
||||
gpioComIF.pullLow(gpioId);
|
||||
}
|
||||
|
||||
if (read(fileDescriptor, rxBuf, readSize) != static_cast<ssize_t>(readSize)) {
|
||||
@ -332,7 +322,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||
}
|
||||
|
||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
||||
gpioComIF->pullHigh(gpioId);
|
||||
gpioComIF.pullHigh(gpioId);
|
||||
result = csMutex->unlockMutex();
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -397,7 +387,7 @@ ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
GpioIF* SpiComIF::getGpioInterface() { return gpioComIF; }
|
||||
GpioIF& SpiComIF::getGpioInterface() { return gpioComIF; }
|
||||
|
||||
void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
||||
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast<uint8_t*>(&mode));
|
||||
|
@ -31,7 +31,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED =
|
||||
returnvalue::makeCode(spiRetvalId, 2);
|
||||
|
||||
SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF);
|
||||
SpiComIF(object_id_t objectId, std::string devname, GpioIF& gpioComIF);
|
||||
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
@ -57,7 +57,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
ReturnValue_t performRegularSendOperation(SpiCookie* spiCookie, const uint8_t* sendData,
|
||||
size_t sendLen);
|
||||
|
||||
GpioIF* getGpioInterface();
|
||||
GpioIF& getGpioInterface();
|
||||
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
||||
void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const;
|
||||
|
||||
@ -83,7 +83,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
std::vector<uint8_t> replyBuffer;
|
||||
};
|
||||
|
||||
GpioIF* gpioComIF = nullptr;
|
||||
GpioIF& gpioComIF;
|
||||
std::string dev = "";
|
||||
/**
|
||||
* Protects the chip select operations. Lock when GPIO is pulled low, unlock after it was
|
||||
|
@ -1 +0,0 @@
|
||||
target_sources(${LIB_FSFW_NAME} PUBLIC UartComIF.cpp UartCookie.cpp helper.cpp)
|
@ -1,6 +1,7 @@
|
||||
#include "UioMapper.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <filesystem>
|
||||
@ -13,7 +14,23 @@ const char UioMapper::UIO_PATH_PREFIX[] = "/sys/class/uio/";
|
||||
const char UioMapper::MAP_SUBSTR[] = "/maps/map";
|
||||
const char UioMapper::SIZE_FILE_PATH[] = "/size";
|
||||
|
||||
UioMapper::UioMapper(std::string uioFile, int mapNum) : uioFile(uioFile), mapNum(mapNum) {}
|
||||
UioMapper::UioMapper(std::string uioFile, int mapNum) : mapNum(mapNum) {
|
||||
struct stat buf;
|
||||
lstat(uioFile.c_str(), &buf);
|
||||
if (S_ISLNK(buf.st_mode)) {
|
||||
char* res = realpath(uioFile.c_str(), nullptr);
|
||||
if (res) {
|
||||
this->uioFile = res;
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Could not resolve real path of UIO file " << uioFile << std::endl;
|
||||
#endif
|
||||
}
|
||||
free(res);
|
||||
} else {
|
||||
this->uioFile = std::move(uioFile);
|
||||
}
|
||||
}
|
||||
|
||||
UioMapper::~UioMapper() {}
|
||||
|
||||
@ -22,7 +39,7 @@ ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permiss
|
||||
int fd = open(uioFile.c_str(), O_RDWR);
|
||||
if (fd < 1) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "PtmeAxiConfig::initialize: Invalid UIO device file" << std::endl;
|
||||
sif::error << "UioMapper::getMappedAdress: Invalid UIO device file " << uioFile << std::endl;
|
||||
#endif
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
@ -2,19 +2,17 @@
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
|
||||
TestAssembly::TestAssembly(object_id_t objectId, object_id_t parentId, object_id_t testDevice0,
|
||||
object_id_t testDevice1)
|
||||
: AssemblyBase(objectId, parentId),
|
||||
deviceHandler0Id(testDevice0),
|
||||
deviceHandler1Id(testDevice1) {
|
||||
TestAssembly::TestAssembly(object_id_t objectId, object_id_t parentId, ModeTreeChildIF& testDevice0,
|
||||
ModeTreeChildIF& testDevice1)
|
||||
: AssemblyBase(objectId, parentId), deviceHandler0(testDevice0), deviceHandler1(testDevice1) {
|
||||
ModeListEntry newModeListEntry;
|
||||
newModeListEntry.setObject(testDevice0);
|
||||
newModeListEntry.setObject(testDevice0.getObjectId());
|
||||
newModeListEntry.setMode(MODE_OFF);
|
||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||
|
||||
commandTable.insert(newModeListEntry);
|
||||
|
||||
newModeListEntry.setObject(testDevice1);
|
||||
newModeListEntry.setObject(testDevice1.getObjectId());
|
||||
newModeListEntry.setMode(MODE_OFF);
|
||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||
|
||||
@ -43,8 +41,8 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||
if (isDeviceAvailable(deviceHandler0Id)) {
|
||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
||||
if (isDeviceAvailable(deviceHandler0.getObjectId())) {
|
||||
if (childrenMap[deviceHandler0.getObjectId()].mode == MODE_ON) {
|
||||
commandTable[0].setMode(mode);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
@ -53,7 +51,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
} else {
|
||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
||||
if (childrenMap[deviceHandler1.getObjectId()].mode == MODE_ON) {
|
||||
commandTable[1].setMode(mode);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
@ -64,7 +62,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
}
|
||||
} else {
|
||||
// Dual Mode Normal
|
||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
||||
if (childrenMap[deviceHandler0.getObjectId()].mode == MODE_ON) {
|
||||
commandTable[0].setMode(mode);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
@ -72,7 +70,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
||||
if (childrenMap[deviceHandler1.getObjectId()].mode == MODE_ON) {
|
||||
commandTable[1].setMode(mode);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
@ -89,7 +87,7 @@ ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||
if (isDeviceAvailable(deviceHandler0Id)) {
|
||||
if (isDeviceAvailable(deviceHandler0.getObjectId())) {
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
@ -133,23 +131,14 @@ ReturnValue_t TestAssembly::initialize() {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
handler0 = ObjectManager::instance()->get<TestDevice>(deviceHandler0Id);
|
||||
handler1 = ObjectManager::instance()->get<TestDevice>(deviceHandler1Id);
|
||||
auto* handler0 = ObjectManager::instance()->get<TestDevice>(deviceHandler0.getObjectId());
|
||||
auto* handler1 = ObjectManager::instance()->get<TestDevice>(deviceHandler1.getObjectId());
|
||||
if ((handler0 == nullptr) or (handler1 == nullptr)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
handler0->setParentQueue(this->getCommandQueue());
|
||||
handler1->setParentQueue(this->getCommandQueue());
|
||||
|
||||
result = registerChild(deviceHandler0Id);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = registerChild(deviceHandler1Id);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
handler0->connectModeTreeParent(*this);
|
||||
handler1->connectModeTreeParent(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
class TestAssembly : public AssemblyBase {
|
||||
public:
|
||||
TestAssembly(object_id_t objectId, object_id_t parentId, object_id_t testDevice0,
|
||||
object_id_t testDevice1);
|
||||
TestAssembly(object_id_t objectId, object_id_t parentId, ModeTreeChildIF& testDevice0,
|
||||
ModeTreeChildIF& testDevice1);
|
||||
virtual ~TestAssembly();
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
@ -41,10 +41,8 @@ class TestAssembly : public AssemblyBase {
|
||||
|
||||
private:
|
||||
FixedArrayList<ModeListEntry, 2> commandTable;
|
||||
object_id_t deviceHandler0Id = 0;
|
||||
object_id_t deviceHandler1Id = 0;
|
||||
TestDevice* handler0 = nullptr;
|
||||
TestDevice* handler1 = nullptr;
|
||||
ModeTreeChildIF& deviceHandler0;
|
||||
ModeTreeChildIF& deviceHandler1;
|
||||
|
||||
bool isDeviceAvailable(object_id_t object);
|
||||
};
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
TestController::TestController(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth)
|
||||
: ExtendedControllerBase(objectId, parentId, commandQueueDepth) {}
|
||||
TestController::TestController(object_id_t objectId, size_t commandQueueDepth)
|
||||
: ExtendedControllerBase(objectId, commandQueueDepth) {}
|
||||
|
||||
TestController::~TestController() {}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
class TestController : public ExtendedControllerBase {
|
||||
public:
|
||||
TestController(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 10);
|
||||
TestController(object_id_t objectId, size_t commandQueueDepth = 10);
|
||||
virtual ~TestController();
|
||||
|
||||
protected:
|
||||
|
@ -65,7 +65,7 @@ ReturnValue_t TestDevice::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
}
|
||||
|
||||
ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (mode == _MODE_TO_ON) {
|
||||
if (getMode() == _MODE_TO_ON) {
|
||||
if (fullInfoPrintout) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "TestDevice" << deviceIdx
|
||||
@ -80,7 +80,7 @@ ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (mode == _MODE_TO_NORMAL) {
|
||||
if (getMode() == _MODE_TO_NORMAL) {
|
||||
if (fullInfoPrintout) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "TestDevice" << deviceIdx
|
||||
@ -97,7 +97,7 @@ ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
|
||||
setMode(MODE_NORMAL);
|
||||
}
|
||||
if (mode == _MODE_SHUT_DOWN) {
|
||||
if (getMode() == _MODE_SHUT_DOWN) {
|
||||
if (fullInfoPrintout) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "TestDevice" << deviceIdx
|
||||
@ -118,7 +118,7 @@ ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
}
|
||||
|
||||
void TestDevice::doTransition(Mode_t modeFrom, Submode_t submodeFrom) {
|
||||
if (mode == _MODE_TO_NORMAL) {
|
||||
if (getMode() == _MODE_TO_NORMAL) {
|
||||
if (fullInfoPrintout) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "TestDevice" << deviceIdx
|
||||
|
Reference in New Issue
Block a user