Compare commits
33 Commits
43fd0b2f59
...
ffa2fa477f
Author | SHA1 | Date | |
---|---|---|---|
ffa2fa477f | |||
894d1e3b87 | |||
285d327b97 | |||
e97fa5ac84 | |||
5a9304765f | |||
6650c293da | |||
9fca7581dd | |||
4af90f99f3 | |||
94cdf67a80 | |||
7966ede11b | |||
7a392dc33a | |||
1e3c89b672 | |||
e2e87b149d | |||
4f632e2c68 | |||
314f0fa2cd | |||
b31e1037fb | |||
b814e7198f | |||
6328b70d7b | |||
a937b457f9 | |||
4415dc24e1 | |||
e704295cce | |||
d16b3c7e67 | |||
3b86545725 | |||
cf6150cc18 | |||
bfb5c2ff03 | |||
bf02061d47 | |||
2c4e110254 | |||
7ed75ea87b | |||
db4587bb59 | |||
33ac395072 | |||
f8a7c1d4ed | |||
341437df13 | |||
227524a21d |
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Health functions are virtual now.
|
||||||
|
|
||||||
# [v6.0.0] 2023-02-10
|
# [v6.0.0] 2023-02-10
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
@@ -59,17 +59,24 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
|
|||||||
|
|
||||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||||
store_address_t dataAddress) {
|
store_address_t dataAddress) {
|
||||||
|
bool hasAdditionalData = false;
|
||||||
const uint8_t* dataPtr = nullptr;
|
const uint8_t* dataPtr = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
ReturnValue_t result;
|
||||||
if (result != returnvalue::OK) {
|
if (dataAddress != store_address_t::invalid()) {
|
||||||
CommandMessage reply;
|
hasAdditionalData = true;
|
||||||
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||||
queueToUse->sendMessage(commandedBy, &reply);
|
if (result != returnvalue::OK) {
|
||||||
return;
|
CommandMessage reply;
|
||||||
|
ActionMessage::setStepReply(&reply, actionId, 0, result);
|
||||||
|
queueToUse->sendMessage(commandedBy, &reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
result = owner->executeAction(actionId, commandedBy, dataPtr, size);
|
||||||
ipcStore->deleteData(dataAddress);
|
if (hasAdditionalData) {
|
||||||
|
ipcStore->deleteData(dataAddress);
|
||||||
|
}
|
||||||
if (result == HasActionsIF::EXECUTION_FINISHED) {
|
if (result == HasActionsIF::EXECUTION_FINISHED) {
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
ActionMessage::setCompletionReply(&reply, actionId, true, result);
|
ActionMessage::setCompletionReply(&reply, actionId, true, result);
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
#define FSFW_CFDP_H
|
#define FSFW_CFDP_H
|
||||||
|
|
||||||
#include "cfdp/definitions.h"
|
#include "cfdp/definitions.h"
|
||||||
#include "cfdp/handler/CfdpHandler.h"
|
|
||||||
#include "cfdp/handler/DestHandler.h"
|
#include "cfdp/handler/DestHandler.h"
|
||||||
#include "cfdp/handler/FaultHandlerBase.h"
|
#include "cfdp/handler/FaultHandlerBase.h"
|
||||||
#include "cfdp/helpers.h"
|
#include "cfdp/helpers.h"
|
||||||
|
@@ -1,3 +1,2 @@
|
|||||||
target_sources(
|
target_sources(${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp
|
||||||
${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp
|
FaultHandlerBase.cpp UserBase.cpp)
|
||||||
FaultHandlerBase.cpp UserBase.cpp CfdpHandler.cpp)
|
|
||||||
|
@@ -1,134 +0,0 @@
|
|||||||
#include "CfdpHandler.h"
|
|
||||||
|
|
||||||
#include "fsfw/cfdp/pdu/AckPduReader.h"
|
|
||||||
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
|
|
||||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
|
||||||
|
|
||||||
using namespace returnvalue;
|
|
||||||
using namespace cfdp;
|
|
||||||
|
|
||||||
CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg)
|
|
||||||
: SystemObject(fsfwParams.objectId),
|
|
||||||
msgQueue(fsfwParams.msgQueue),
|
|
||||||
destHandler(
|
|
||||||
DestHandlerParams(LocalEntityCfg(cfdpCfg.id, cfdpCfg.indicCfg, cfdpCfg.faultHandler),
|
|
||||||
cfdpCfg.userHandler, cfdpCfg.remoteCfgProvider, cfdpCfg.packetInfoList,
|
|
||||||
cfdpCfg.lostSegmentsList),
|
|
||||||
FsfwParams(fsfwParams.packetDest, nullptr, this, fsfwParams.tcStore,
|
|
||||||
fsfwParams.tmStore)) {
|
|
||||||
destHandler.setMsgQueue(msgQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const char* CfdpHandler::getName() const { return "CFDP Handler"; }
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t CfdpHandler::getIdentifier() const {
|
|
||||||
return destHandler.getDestHandlerParams().cfg.localId.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] MessageQueueId_t CfdpHandler::getRequestQueue() const { return msgQueue.getId(); }
|
|
||||||
|
|
||||||
ReturnValue_t CfdpHandler::initialize() {
|
|
||||||
ReturnValue_t result = destHandler.initialize();
|
|
||||||
if (result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
tcStore = destHandler.getTcStore();
|
|
||||||
tmStore = destHandler.getTmStore();
|
|
||||||
|
|
||||||
return SystemObject::initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CfdpHandler::performOperation(uint8_t operationCode) {
|
|
||||||
// TODO: Receive TC packets and route them to source and dest handler, depending on which is
|
|
||||||
// correct or more appropriate
|
|
||||||
ReturnValue_t status;
|
|
||||||
ReturnValue_t result = OK;
|
|
||||||
TmTcMessage tmtcMsg;
|
|
||||||
for (status = msgQueue.receiveMessage(&tmtcMsg); status == returnvalue::OK;
|
|
||||||
status = msgQueue.receiveMessage(&tmtcMsg)) {
|
|
||||||
result = handleCfdpPacket(tmtcMsg);
|
|
||||||
if (result != OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto& fsmRes = destHandler.performStateMachine();
|
|
||||||
// TODO: Error handling?
|
|
||||||
while (fsmRes.callStatus == CallStatus::CALL_AGAIN) {
|
|
||||||
destHandler.performStateMachine();
|
|
||||||
// TODO: Error handling?
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) {
|
|
||||||
auto accessorPair = tcStore->getData(msg.getStorageId());
|
|
||||||
if (accessorPair.first != OK) {
|
|
||||||
return accessorPair.first;
|
|
||||||
}
|
|
||||||
PduHeaderReader reader(accessorPair.second.data(), accessorPair.second.size());
|
|
||||||
ReturnValue_t result = reader.parseData();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return INVALID_PDU_FORMAT;
|
|
||||||
}
|
|
||||||
// The CFDP distributor should have taken care of ensuring the destination ID is correct
|
|
||||||
PduType type = reader.getPduType();
|
|
||||||
// Only the destination handler can process these PDUs
|
|
||||||
if (type == PduType::FILE_DATA) {
|
|
||||||
// Disable auto-deletion of packet
|
|
||||||
accessorPair.second.release();
|
|
||||||
PacketInfo info(type, msg.getStorageId());
|
|
||||||
result = destHandler.passPacket(info);
|
|
||||||
} else {
|
|
||||||
// Route depending on PDU type and directive type if applicable. It retrieves directive type
|
|
||||||
// from the raw stream for better performance (with sanity and directive code check).
|
|
||||||
// The routing is based on section 4.5 of the CFDP standard which specifies the PDU forwarding
|
|
||||||
// procedure.
|
|
||||||
|
|
||||||
// PDU header only. Invalid supplied data. A directive packet should have a valid data field
|
|
||||||
// with at least one byte being the directive code
|
|
||||||
const uint8_t* pduDataField = reader.getPduDataField();
|
|
||||||
if (pduDataField == nullptr) {
|
|
||||||
return INVALID_PDU_FORMAT;
|
|
||||||
}
|
|
||||||
if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) {
|
|
||||||
return INVALID_DIRECTIVE_FIELD;
|
|
||||||
}
|
|
||||||
auto directive = static_cast<FileDirective>(pduDataField[0]);
|
|
||||||
|
|
||||||
auto passToDestHandler = [&]() {
|
|
||||||
accessorPair.second.release();
|
|
||||||
PacketInfo info(type, msg.getStorageId(), directive);
|
|
||||||
result = destHandler.passPacket(info);
|
|
||||||
};
|
|
||||||
auto passToSourceHandler = [&]() {
|
|
||||||
|
|
||||||
};
|
|
||||||
if (directive == FileDirective::METADATA or directive == FileDirective::EOF_DIRECTIVE or
|
|
||||||
directive == FileDirective::PROMPT) {
|
|
||||||
// Section b) of 4.5.3: These PDUs should always be targeted towards the file receiver a.k.a.
|
|
||||||
// the destination handler
|
|
||||||
passToDestHandler();
|
|
||||||
} else if (directive == FileDirective::FINISH or directive == FileDirective::NAK or
|
|
||||||
directive == FileDirective::KEEP_ALIVE) {
|
|
||||||
// Section c) of 4.5.3: These PDUs should always be targeted towards the file sender a.k.a.
|
|
||||||
// the source handler
|
|
||||||
passToSourceHandler();
|
|
||||||
} else if (directive == FileDirective::ACK) {
|
|
||||||
// Section a): Recipient depends of the type of PDU that is being acknowledged. We can simply
|
|
||||||
// extract the PDU type from the raw stream. If it is an EOF PDU, this packet is passed to
|
|
||||||
// the source handler, for a Finished PDU, it is passed to the destination handler.
|
|
||||||
FileDirective ackedDirective;
|
|
||||||
if (not AckPduReader::checkAckedDirectiveField(pduDataField[1], ackedDirective)) {
|
|
||||||
return INVALID_ACK_DIRECTIVE_FIELDS;
|
|
||||||
}
|
|
||||||
if (ackedDirective == FileDirective::EOF_DIRECTIVE) {
|
|
||||||
passToSourceHandler();
|
|
||||||
} else if (ackedDirective == FileDirective::FINISH) {
|
|
||||||
passToDestHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@@ -1,71 +0,0 @@
|
|||||||
#ifndef FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
|
||||||
#define FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "fsfw/cfdp/handler/DestHandler.h"
|
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
|
||||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
|
||||||
|
|
||||||
struct FsfwHandlerParams {
|
|
||||||
FsfwHandlerParams(object_id_t objectId, HasFileSystemIF& vfs, AcceptsTelemetryIF& packetDest,
|
|
||||||
StorageManagerIF& tcStore, StorageManagerIF& tmStore, MessageQueueIF& msgQueue)
|
|
||||||
: objectId(objectId),
|
|
||||||
vfs(vfs),
|
|
||||||
packetDest(packetDest),
|
|
||||||
tcStore(tcStore),
|
|
||||||
tmStore(tmStore),
|
|
||||||
msgQueue(msgQueue) {}
|
|
||||||
object_id_t objectId{};
|
|
||||||
HasFileSystemIF& vfs;
|
|
||||||
AcceptsTelemetryIF& packetDest;
|
|
||||||
StorageManagerIF& tcStore;
|
|
||||||
StorageManagerIF& tmStore;
|
|
||||||
MessageQueueIF& msgQueue;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CfdpHandlerCfg {
|
|
||||||
CfdpHandlerCfg(cfdp::EntityId localId, cfdp::IndicationCfg indicationCfg,
|
|
||||||
cfdp::UserBase& userHandler, cfdp::FaultHandlerBase& userFaultHandler,
|
|
||||||
cfdp::PacketInfoListBase& packetInfo, cfdp::LostSegmentsListBase& lostSegmentsList,
|
|
||||||
cfdp::RemoteConfigTableIF& remoteCfgProvider)
|
|
||||||
: id(std::move(localId)),
|
|
||||||
indicCfg(indicationCfg),
|
|
||||||
packetInfoList(packetInfo),
|
|
||||||
lostSegmentsList(lostSegmentsList),
|
|
||||||
remoteCfgProvider(remoteCfgProvider),
|
|
||||||
userHandler(userHandler),
|
|
||||||
faultHandler(userFaultHandler) {}
|
|
||||||
|
|
||||||
cfdp::EntityId id;
|
|
||||||
cfdp::IndicationCfg indicCfg;
|
|
||||||
cfdp::PacketInfoListBase& packetInfoList;
|
|
||||||
cfdp::LostSegmentsListBase& lostSegmentsList;
|
|
||||||
cfdp::RemoteConfigTableIF& remoteCfgProvider;
|
|
||||||
cfdp::UserBase& userHandler;
|
|
||||||
cfdp::FaultHandlerBase& faultHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CfdpHandler : public SystemObject, public ExecutableObjectIF, public AcceptsTelecommandsIF {
|
|
||||||
public:
|
|
||||||
explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg);
|
|
||||||
|
|
||||||
[[nodiscard]] const char* getName() const override;
|
|
||||||
[[nodiscard]] uint32_t getIdentifier() const override;
|
|
||||||
[[nodiscard]] MessageQueueId_t getRequestQueue() const override;
|
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
|
||||||
ReturnValue_t performOperation(uint8_t operationCode) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
MessageQueueIF& msgQueue;
|
|
||||||
cfdp::DestHandler destHandler;
|
|
||||||
StorageManagerIF* tcStore = nullptr;
|
|
||||||
StorageManagerIF* tmStore = nullptr;
|
|
||||||
|
|
||||||
ReturnValue_t handleCfdpPacket(TmTcMessage& msg);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
|
@@ -58,7 +58,7 @@ void ControllerBase::handleQueue() {
|
|||||||
|
|
||||||
void ControllerBase::startTransition(Mode_t mode_, Submode_t submode_) {
|
void ControllerBase::startTransition(Mode_t mode_, Submode_t submode_) {
|
||||||
changeHK(this->mode, this->submode, false);
|
changeHK(this->mode, this->submode, false);
|
||||||
triggerEvent(CHANGING_MODE, mode, submode);
|
triggerEvent(CHANGING_MODE, mode_, submode_);
|
||||||
mode = mode_;
|
mode = mode_;
|
||||||
submode = submode_;
|
submode = submode_;
|
||||||
modeHelper.modeChanged(mode, submode);
|
modeHelper.modeChanged(mode, submode);
|
||||||
|
@@ -505,9 +505,9 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
|||||||
float newCollIntvl = 0;
|
float newCollIntvl = 0;
|
||||||
HousekeepingMessage::getCollectionIntervalModificationCommand(message, &newCollIntvl);
|
HousekeepingMessage::getCollectionIntervalModificationCommand(message, &newCollIntvl);
|
||||||
if (command == HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL) {
|
if (command == HousekeepingMessage::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL) {
|
||||||
result = changeCollectionInterval(sid, newCollIntvl, true);
|
result = changeCollectionInterval(sid, newCollIntvl);
|
||||||
} else {
|
} else {
|
||||||
result = changeCollectionInterval(sid, newCollIntvl, false);
|
result = changeCollectionInterval(sid, newCollIntvl);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -720,8 +720,8 @@ ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool ena
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float newCollectionInterval,
|
ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid,
|
||||||
bool isDiagnostics) {
|
float newCollectionInterval) {
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
||||||
if (dataSet == nullptr) {
|
if (dataSet == nullptr) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval",
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "changeCollectionInterval",
|
||||||
@@ -729,11 +729,6 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float ne
|
|||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool targetIsDiagnostics = LocalPoolDataSetAttorney::isDiagnostics(*dataSet);
|
|
||||||
if ((targetIsDiagnostics and not isDiagnostics) or (not targetIsDiagnostics and isDiagnostics)) {
|
|
||||||
return WRONG_HK_PACKET_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeriodicHousekeepingHelper* periodicHelper =
|
PeriodicHousekeepingHelper* periodicHelper =
|
||||||
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
|
LocalPoolDataSetAttorney::getPeriodicHelper(*dataSet);
|
||||||
|
|
||||||
|
@@ -174,6 +174,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
ReturnValue_t generateHousekeepingPacket(sid_t sid, LocalPoolDataSetBase* dataSet,
|
ReturnValue_t generateHousekeepingPacket(sid_t sid, LocalPoolDataSetBase* dataSet,
|
||||||
bool forDownlink,
|
bool forDownlink,
|
||||||
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
|
||||||
|
ReturnValue_t changeCollectionInterval(sid_t sid, float newCollectionInterval);
|
||||||
|
|
||||||
HasLocalDataPoolIF* getOwner();
|
HasLocalDataPoolIF* getOwner();
|
||||||
|
|
||||||
@@ -337,8 +338,6 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
|
|
||||||
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
|
void performPeriodicHkGeneration(HkReceiver& hkReceiver);
|
||||||
ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable, bool isDiagnostics);
|
ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable, bool isDiagnostics);
|
||||||
ReturnValue_t changeCollectionInterval(sid_t sid, float newCollectionInterval,
|
|
||||||
bool isDiagnostics);
|
|
||||||
ReturnValue_t generateSetStructurePacket(sid_t sid, bool isDiagnostics);
|
ReturnValue_t generateSetStructurePacket(sid_t sid, bool isDiagnostics);
|
||||||
|
|
||||||
void handleHkUpdateResetListInsertion(DataType dataType, DataId dataId);
|
void handleHkUpdateResetListInsertion(DataType dataType, DataId dataId);
|
||||||
|
@@ -49,6 +49,7 @@ class DeviceCommunicationIF {
|
|||||||
// is this needed if there is no open/close call?
|
// is this needed if there is no open/close call?
|
||||||
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05);
|
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05);
|
||||||
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x06);
|
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x06);
|
||||||
|
static constexpr ReturnValue_t BUSY = MAKE_RETURN_CODE(0x07);
|
||||||
|
|
||||||
virtual ~DeviceCommunicationIF() {}
|
virtual ~DeviceCommunicationIF() {}
|
||||||
|
|
||||||
|
@@ -567,7 +567,7 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
|||||||
continueToNormal = false;
|
continueToNormal = false;
|
||||||
// TODO: Check whether the following two lines are okay to do so.
|
// TODO: Check whether the following two lines are okay to do so.
|
||||||
transitionSourceMode = MODE_ON;
|
transitionSourceMode = MODE_ON;
|
||||||
transitionSourceSubMode = submode;
|
transitionSourceSubMode = newSubmode;
|
||||||
mode = _MODE_TO_NORMAL;
|
mode = _MODE_TO_NORMAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -257,8 +257,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
Mode_t getTransitionSourceMode() const;
|
Mode_t getTransitionSourceMode() const;
|
||||||
Submode_t getTransitionSourceSubMode() const;
|
Submode_t getTransitionSourceSubMode() const;
|
||||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||||
HealthState getHealth();
|
virtual HealthState getHealth() override;
|
||||||
ReturnValue_t setHealth(HealthState health);
|
virtual ReturnValue_t setHealth(HealthState health) override;
|
||||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||||
ParameterWrapper *parameterWrapper,
|
ParameterWrapper *parameterWrapper,
|
||||||
const ParameterWrapper *newValues,
|
const ParameterWrapper *newValues,
|
||||||
|
@@ -29,11 +29,10 @@ ReturnValue_t HealthDevice::initialize() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (parentQueue != 0) {
|
if (parentQueue != MessageQueueIF::NO_QUEUE) {
|
||||||
return healthHelper.initialize(parentQueue);
|
return healthHelper.initialize(parentQueue);
|
||||||
} else {
|
|
||||||
return healthHelper.initialize();
|
|
||||||
}
|
}
|
||||||
|
return healthHelper.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t HealthDevice::getCommandQueue() const { return commandQueue->getId(); }
|
MessageQueueId_t HealthDevice::getCommandQueue() const { return commandQueue->getId(); }
|
||||||
|
@@ -29,10 +29,8 @@ class HealthDevice : public SystemObject, public ExecutableObjectIF, public HasH
|
|||||||
protected:
|
protected:
|
||||||
HealthState lastHealth;
|
HealthState lastHealth;
|
||||||
|
|
||||||
MessageQueueId_t parentQueue;
|
MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE;
|
||||||
MessageQueueIF* commandQueue;
|
MessageQueueIF* commandQueue;
|
||||||
|
|
||||||
public:
|
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -18,8 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
class DleParser {
|
class DleParser {
|
||||||
public:
|
public:
|
||||||
|
//! [EXPORT] : [SKIP]
|
||||||
static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(1, 1);
|
static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(1, 1);
|
||||||
|
//! [EXPORT] : [SKIP]
|
||||||
static constexpr ReturnValue_t POSSIBLE_PACKET_LOSS = returnvalue::makeCode(1, 2);
|
static constexpr ReturnValue_t POSSIBLE_PACKET_LOSS = returnvalue::makeCode(1, 2);
|
||||||
|
|
||||||
using BufPair = std::pair<uint8_t*, size_t>;
|
using BufPair = std::pair<uint8_t*, size_t>;
|
||||||
|
|
||||||
enum class ContextType { NONE, PACKET_FOUND, ERROR };
|
enum class ContextType { NONE, PACKET_FOUND, ERROR };
|
||||||
|
@@ -20,16 +20,18 @@ TaskFactory::~TaskFactory() = default;
|
|||||||
|
|
||||||
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
|
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
|
||||||
|
|
||||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(
|
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
|
||||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
TaskStackSize stackSize_,
|
||||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
TaskPeriod periodInSeconds_,
|
||||||
|
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||||
|
void* args) {
|
||||||
return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||||
deadLineMissedFunction_);
|
deadLineMissedFunction_);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
|
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
|
||||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
|
||||||
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||||
deadLineMissedFunction_);
|
deadLineMissedFunction_);
|
||||||
}
|
}
|
||||||
|
@@ -7,10 +7,15 @@
|
|||||||
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
|
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
|
||||||
|
|
||||||
FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
|
FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
|
||||||
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_)
|
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
|
||||||
|
PosixThreadArgs* args)
|
||||||
: FixedTimeslotTaskBase(periodSeconds_, dlmFunc_),
|
: FixedTimeslotTaskBase(periodSeconds_, dlmFunc_),
|
||||||
posixThread(name_, priority_, stackSize_),
|
posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
|
||||||
started(false) {}
|
started(false) {
|
||||||
|
if (args != nullptr) {
|
||||||
|
posixThread.setSchedPolicy(args->policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void* FixedTimeslotTask::taskEntryPoint(void* arg) {
|
void* FixedTimeslotTask::taskEntryPoint(void* arg) {
|
||||||
// The argument is re-interpreted as PollingTask.
|
// The argument is re-interpreted as PollingTask.
|
||||||
|
@@ -23,7 +23,8 @@ class FixedTimeslotTask : public FixedTimeslotTaskBase {
|
|||||||
* @param deadlineMissedFunc_
|
* @param deadlineMissedFunc_
|
||||||
*/
|
*/
|
||||||
FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
|
FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
|
||||||
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_);
|
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
|
||||||
|
PosixThreadArgs* args);
|
||||||
~FixedTimeslotTask() override = default;
|
~FixedTimeslotTask() override = default;
|
||||||
|
|
||||||
ReturnValue_t startTask() override;
|
ReturnValue_t startTask() override;
|
||||||
|
@@ -4,10 +4,15 @@
|
|||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
|
|
||||||
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
|
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
|
||||||
TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_)
|
TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_,
|
||||||
|
PosixThreadArgs* args)
|
||||||
: PeriodicTaskBase(period_, dlmFunc_),
|
: PeriodicTaskBase(period_, dlmFunc_),
|
||||||
posixThread(name_, priority_, stackSize_),
|
posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
|
||||||
started(false) {}
|
started(false) {
|
||||||
|
if (args != nullptr) {
|
||||||
|
posixThread.setSchedPolicy(args->policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void* PeriodicPosixTask::taskEntryPoint(void* arg) {
|
void* PeriodicPosixTask::taskEntryPoint(void* arg) {
|
||||||
// The argument is re-interpreted as PollingTask.
|
// The argument is re-interpreted as PollingTask.
|
||||||
|
@@ -24,7 +24,7 @@ class PeriodicPosixTask : public PeriodicTaskBase {
|
|||||||
* @param deadlineMissedFunc_
|
* @param deadlineMissedFunc_
|
||||||
*/
|
*/
|
||||||
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_,
|
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_,
|
||||||
TaskDeadlineMissedFunction dlmFunc_);
|
TaskDeadlineMissedFunction dlmFunc_, PosixThreadArgs* args);
|
||||||
~PeriodicPosixTask() override = default;
|
~PeriodicPosixTask() override = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -7,8 +7,9 @@
|
|||||||
#include "fsfw/osal/linux/unixUtility.h"
|
#include "fsfw/osal/linux/unixUtility.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_)
|
PosixThread::PosixThread(const char* name_, SchedulingPolicy schedPolciy, int priority_,
|
||||||
: thread(0), priority(priority_), stackSize(stackSize_) {
|
size_t stackSize_)
|
||||||
|
: thread(0), schedPolicy(schedPolciy), priority(priority_), stackSize(stackSize_) {
|
||||||
name[0] = '\0';
|
name[0] = '\0';
|
||||||
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
|
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
|
||||||
}
|
}
|
||||||
@@ -178,20 +179,30 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
|||||||
#ifndef FSFW_USE_REALTIME_FOR_LINUX
|
#ifndef FSFW_USE_REALTIME_FOR_LINUX
|
||||||
#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1"
|
#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1"
|
||||||
#endif
|
#endif
|
||||||
|
if (schedPolicy == SchedulingPolicy::RR) {
|
||||||
|
// RR -> This needs root privileges for the process
|
||||||
#if FSFW_USE_REALTIME_FOR_LINUX == 1
|
#if FSFW_USE_REALTIME_FOR_LINUX == 1
|
||||||
// FIFO -> This needs root privileges for the process
|
status = pthread_attr_setschedpolicy(&attributes, SCHED_RR);
|
||||||
status = pthread_attr_setschedpolicy(&attributes, SCHED_FIFO);
|
if (status != 0) {
|
||||||
if (status != 0) {
|
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
|
||||||
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
|
}
|
||||||
|
sched_param scheduleParams;
|
||||||
|
scheduleParams.sched_priority = priority;
|
||||||
|
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
|
||||||
|
if (status != 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "PosixThread: Setting priority failed" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning
|
||||||
|
<< "Real time priorities are only allowed if FSFW_USE_REALTIME_FOR_LINUX is set to 1"
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
sched_param scheduleParams;
|
|
||||||
scheduleParams.__sched_priority = priority;
|
|
||||||
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
|
|
||||||
if (status != 0) {
|
|
||||||
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedparam");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Set Signal Mask for suspend until startTask is called
|
// Set Signal Mask for suspend until startTask is called
|
||||||
sigset_t waitSignal;
|
sigset_t waitSignal;
|
||||||
sigemptyset(&waitSignal);
|
sigemptyset(&waitSignal);
|
||||||
@@ -243,3 +254,5 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
|||||||
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_destroy");
|
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_destroy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PosixThread::setSchedPolicy(SchedulingPolicy policy) { this->schedPolicy = policy; }
|
||||||
|
@@ -9,10 +9,15 @@
|
|||||||
|
|
||||||
#include "../../returnvalues/returnvalue.h"
|
#include "../../returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
enum SchedulingPolicy { REGULAR, RR };
|
||||||
|
struct PosixThreadArgs {
|
||||||
|
SchedulingPolicy policy = SchedulingPolicy::REGULAR;
|
||||||
|
};
|
||||||
|
|
||||||
class PosixThread {
|
class PosixThread {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
|
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
|
||||||
PosixThread(const char* name_, int priority_, size_t stackSize_);
|
PosixThread(const char* name_, SchedulingPolicy schedPolicy, int priority_, size_t stackSize_);
|
||||||
virtual ~PosixThread();
|
virtual ~PosixThread();
|
||||||
/**
|
/**
|
||||||
* Set the Thread to sleep state
|
* Set the Thread to sleep state
|
||||||
@@ -20,6 +25,9 @@ class PosixThread {
|
|||||||
* @return Returns Failed if sleep fails
|
* @return Returns Failed if sleep fails
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t sleep(uint64_t ns);
|
static ReturnValue_t sleep(uint64_t ns);
|
||||||
|
|
||||||
|
void setSchedPolicy(SchedulingPolicy policy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function to suspend the task until SIGUSR1 was received
|
* @brief Function to suspend the task until SIGUSR1 was received
|
||||||
*
|
*
|
||||||
@@ -72,6 +80,7 @@ class PosixThread {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
char name[PTHREAD_MAX_NAMELEN];
|
char name[PTHREAD_MAX_NAMELEN];
|
||||||
|
SchedulingPolicy schedPolicy;
|
||||||
int priority;
|
int priority;
|
||||||
size_t stackSize = 0;
|
size_t stackSize = 0;
|
||||||
|
|
||||||
|
@@ -12,18 +12,20 @@ TaskFactory::~TaskFactory() = default;
|
|||||||
|
|
||||||
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
|
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
|
||||||
|
|
||||||
PeriodicTaskIF* TaskFactory::createPeriodicTask(
|
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
|
||||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
TaskStackSize stackSize_,
|
||||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
TaskPeriod periodInSeconds_,
|
||||||
|
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||||
|
void* args) {
|
||||||
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||||
deadLineMissedFunction_);
|
deadLineMissedFunction_, reinterpret_cast<PosixThreadArgs*>(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
|
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
|
||||||
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
|
||||||
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) {
|
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
|
||||||
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
|
||||||
deadLineMissedFunction_);
|
deadLineMissedFunction_, reinterpret_cast<PosixThreadArgs*>(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
|
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {
|
||||||
|
@@ -6,7 +6,11 @@ DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwit
|
|||||||
: SystemObject(objectId, registerGlobally),
|
: SystemObject(objectId, registerGlobally),
|
||||||
switcherList(numberOfSwitches),
|
switcherList(numberOfSwitches),
|
||||||
fuseList(numberOfFuses),
|
fuseList(numberOfFuses),
|
||||||
switchDelayMs(switchDelayMs) {}
|
switchDelayMs(switchDelayMs) {
|
||||||
|
for (auto &switchState : switcherList) {
|
||||||
|
switchState = PowerSwitchIF::SWITCH_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DummyPowerSwitcher::setInitialSwitcherList(std::vector<ReturnValue_t> switcherList) {
|
void DummyPowerSwitcher::setInitialSwitcherList(std::vector<ReturnValue_t> switcherList) {
|
||||||
this->switcherList = switcherList;
|
this->switcherList = switcherList;
|
||||||
|
@@ -42,7 +42,7 @@ class PowerSwitcherComponent : public SystemObject,
|
|||||||
private:
|
private:
|
||||||
MessageQueueIF *queue = nullptr;
|
MessageQueueIF *queue = nullptr;
|
||||||
|
|
||||||
Mode_t mode = MODE_OFF;
|
Mode_t mode = MODE_UNDEFINED;
|
||||||
Submode_t submode = 0;
|
Submode_t submode = 0;
|
||||||
|
|
||||||
ModeHelper modeHelper;
|
ModeHelper modeHelper;
|
||||||
|
@@ -4,9 +4,10 @@
|
|||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/pus/servicepackets/Service3Packets.h"
|
#include "fsfw/pus/servicepackets/Service3Packets.h"
|
||||||
|
|
||||||
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId)
|
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
||||||
|
uint32_t queueDepth)
|
||||||
: CommandingServiceBase(objectId, apid, "PUS 3 HK", serviceId, NUM_OF_PARALLEL_COMMANDS,
|
: CommandingServiceBase(objectId, apid, "PUS 3 HK", serviceId, NUM_OF_PARALLEL_COMMANDS,
|
||||||
COMMAND_TIMEOUT_SECONDS) {}
|
COMMAND_TIMEOUT_SECONDS, queueDepth) {}
|
||||||
|
|
||||||
Service3Housekeeping::~Service3Housekeeping() {}
|
Service3Housekeeping::~Service3Housekeeping() {}
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ class Service3Housekeeping : public CommandingServiceBase, public AcceptsHkPacke
|
|||||||
static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4;
|
static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4;
|
||||||
static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60;
|
static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60;
|
||||||
|
|
||||||
Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId);
|
Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId, uint32_t queueDepth);
|
||||||
virtual ~Service3Housekeeping();
|
virtual ~Service3Housekeeping();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -315,20 +315,7 @@ object_id_t SubsystemBase::getObjectId() const { return SystemObject::getObjectI
|
|||||||
void SubsystemBase::modeChanged() {}
|
void SubsystemBase::modeChanged() {}
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::registerChild(const ModeTreeChildIF& child) {
|
ReturnValue_t SubsystemBase::registerChild(const ModeTreeChildIF& child) {
|
||||||
ChildInfo info;
|
return registerChild(child.getObjectId(), child.getModeIF().getCommandQueue());
|
||||||
|
|
||||||
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 HasHealthIF* SubsystemBase::getOptHealthIF() const { return this; }
|
||||||
@@ -336,3 +323,19 @@ const HasHealthIF* SubsystemBase::getOptHealthIF() const { return this; }
|
|||||||
const HasModesIF& SubsystemBase::getModeIF() const { return *this; }
|
const HasModesIF& SubsystemBase::getModeIF() const { return *this; }
|
||||||
|
|
||||||
ModeTreeChildIF& SubsystemBase::getModeTreeChildIF() { return *this; }
|
ModeTreeChildIF& SubsystemBase::getModeTreeChildIF() { return *this; }
|
||||||
|
|
||||||
|
ReturnValue_t SubsystemBase::registerChild(object_id_t childObjectId, MessageQueueId_t childQueue) {
|
||||||
|
ChildInfo info;
|
||||||
|
|
||||||
|
// intentional to force an initial command during system startup
|
||||||
|
info.commandQueue = childQueue;
|
||||||
|
info.mode = HasModesIF::MODE_UNDEFINED;
|
||||||
|
info.submode = SUBMODE_NONE;
|
||||||
|
info.healthChanged = false;
|
||||||
|
|
||||||
|
auto resultPair = childrenMap.emplace(childObjectId, info);
|
||||||
|
if (not resultPair.second) {
|
||||||
|
return COULD_NOT_INSERT_CHILD;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
@@ -61,6 +61,8 @@ class SubsystemBase : public SystemObject,
|
|||||||
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
|
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
|
||||||
*/
|
*/
|
||||||
ReturnValue_t registerChild(const ModeTreeChildIF &child) override;
|
ReturnValue_t registerChild(const ModeTreeChildIF &child) override;
|
||||||
|
// TODO: Add this to HasModeTreeChildrenIF.
|
||||||
|
ReturnValue_t registerChild(object_id_t childObjectId, MessageQueueId_t childQueue);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
@@ -47,7 +47,8 @@ class TaskFactory {
|
|||||||
*/
|
*/
|
||||||
PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
|
PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
|
||||||
TaskStackSize stackSize_, TaskPeriod periodInSeconds_,
|
TaskStackSize stackSize_, TaskPeriod periodInSeconds_,
|
||||||
TaskDeadlineMissedFunction deadLineMissedFunction_);
|
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||||
|
void* args = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks.
|
* The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks.
|
||||||
@@ -62,7 +63,8 @@ class TaskFactory {
|
|||||||
FixedTimeslotTaskIF* createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_,
|
FixedTimeslotTaskIF* createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_,
|
||||||
TaskStackSize stackSize_,
|
TaskStackSize stackSize_,
|
||||||
TaskPeriod periodInSeconds_,
|
TaskPeriod periodInSeconds_,
|
||||||
TaskDeadlineMissedFunction deadLineMissedFunction_);
|
TaskDeadlineMissedFunction deadLineMissedFunction_,
|
||||||
|
void* args = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to be called to delete a task
|
* Function to be called to delete a task
|
||||||
|
@@ -5,8 +5,18 @@
|
|||||||
|
|
||||||
namespace spi {
|
namespace spi {
|
||||||
|
|
||||||
|
static constexpr uint8_t CLASS_ID = CLASS_ID::HAL_SPI;
|
||||||
|
static constexpr ReturnValue_t OPENING_FILE_FAILED = returnvalue::makeCode(CLASS_ID, 0);
|
||||||
|
/* Full duplex (ioctl) transfer failure */
|
||||||
|
static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED = returnvalue::makeCode(CLASS_ID, 1);
|
||||||
|
/* Half duplex (read/write) transfer failure */
|
||||||
|
static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = returnvalue::makeCode(CLASS_ID, 2);
|
||||||
|
static constexpr ReturnValue_t TIMEOUT = returnvalue::makeCode(CLASS_ID, 3);
|
||||||
|
static constexpr ReturnValue_t BUSY = returnvalue::makeCode(CLASS_ID, 4);
|
||||||
|
static constexpr ReturnValue_t GENERIC_ERROR = returnvalue::makeCode(CLASS_ID, 5);
|
||||||
|
|
||||||
enum SpiModes : uint8_t { MODE_0, MODE_1, MODE_2, MODE_3 };
|
enum SpiModes : uint8_t { MODE_0, MODE_1, MODE_2, MODE_3 };
|
||||||
|
|
||||||
}
|
} // namespace spi
|
||||||
|
|
||||||
#endif /* FSFW_HAL_COMMON_SPI_SPICOMMON_H_ */
|
#endif /* FSFW_HAL_COMMON_SPI_SPICOMMON_H_ */
|
||||||
|
@@ -88,11 +88,11 @@ int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart::setParity(options, uartCookie->getParity());
|
serial::setParity(options, uartCookie->getParity());
|
||||||
setStopBitOptions(&options, uartCookie);
|
setStopBitOptions(&options, uartCookie);
|
||||||
setDatasizeOptions(&options, uartCookie);
|
setDatasizeOptions(&options, uartCookie);
|
||||||
setFixedOptions(&options);
|
setFixedOptions(&options);
|
||||||
uart::setMode(options, uartCookie->getUartMode());
|
serial::setMode(options, uartCookie->getUartMode());
|
||||||
if (uartCookie->getInputShouldBeFlushed()) {
|
if (uartCookie->getInputShouldBeFlushed()) {
|
||||||
tcflush(fd, TCIFLUSH);
|
tcflush(fd, TCIFLUSH);
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
|
|||||||
options.c_cc[VTIME] = 0;
|
options.c_cc[VTIME] = 0;
|
||||||
options.c_cc[VMIN] = 0;
|
options.c_cc[VMIN] = 0;
|
||||||
|
|
||||||
uart::setBaudrate(options, uartCookie->getBaudrate());
|
serial::setBaudrate(options, uartCookie->getBaudrate());
|
||||||
|
|
||||||
/* Save option settings */
|
/* Save option settings */
|
||||||
if (tcsetattr(fd, TCSANOW, &options) != 0) {
|
if (tcsetattr(fd, TCSANOW, &options) != 0) {
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
void uart::setMode(struct termios& options, UartModes mode) {
|
void serial::setMode(struct termios& options, UartModes mode) {
|
||||||
if (mode == UartModes::NON_CANONICAL) {
|
if (mode == UartModes::NON_CANONICAL) {
|
||||||
/* Disable canonical mode */
|
/* Disable canonical mode */
|
||||||
options.c_lflag &= ~ICANON;
|
options.c_lflag &= ~ICANON;
|
||||||
@@ -12,7 +12,7 @@ void uart::setMode(struct termios& options, UartModes mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
void serial::setBaudrate(struct termios& options, UartBaudRate baud) {
|
||||||
switch (baud) {
|
switch (baud) {
|
||||||
case UartBaudRate::RATE_50:
|
case UartBaudRate::RATE_50:
|
||||||
cfsetspeed(&options, B50);
|
cfsetspeed(&options, B50);
|
||||||
@@ -114,7 +114,7 @@ void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
void serial::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
||||||
options.c_cflag &= ~CSIZE; // Clear all the size bits
|
options.c_cflag &= ~CSIZE; // Clear all the size bits
|
||||||
if (bits == BitsPerWord::BITS_5) {
|
if (bits == BitsPerWord::BITS_5) {
|
||||||
options.c_cflag |= CS5;
|
options.c_cflag |= CS5;
|
||||||
@@ -127,11 +127,11 @@ void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
|
void serial::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
|
||||||
|
|
||||||
void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
|
void serial::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
|
||||||
|
|
||||||
void uart::setParity(struct termios& options, Parity parity) {
|
void serial::setParity(struct termios& options, Parity parity) {
|
||||||
/* Clear parity bit */
|
/* Clear parity bit */
|
||||||
options.c_cflag &= ~PARENB;
|
options.c_cflag &= ~PARENB;
|
||||||
switch (parity) {
|
switch (parity) {
|
||||||
@@ -148,11 +148,11 @@ void uart::setParity(struct termios& options, Parity parity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
int serial::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
||||||
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart::setStopbits(struct termios& options, StopBits bits) {
|
void serial::setStopbits(struct termios& options, StopBits bits) {
|
||||||
if (bits == StopBits::TWO_STOP_BITS) {
|
if (bits == StopBits::TWO_STOP_BITS) {
|
||||||
// Use two stop bits
|
// Use two stop bits
|
||||||
options.c_cflag |= CSTOPB;
|
options.c_cflag |= CSTOPB;
|
||||||
@@ -161,3 +161,7 @@ void uart::setStopbits(struct termios& options, StopBits bits) {
|
|||||||
options.c_cflag &= ~CSTOPB;
|
options.c_cflag &= ~CSTOPB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void serial::flushRxBuf(int fd) { tcflush(fd, TCIFLUSH); }
|
||||||
|
|
||||||
|
void serial::flushTxRxBuf(int fd) { tcflush(fd, TCIOFLUSH); }
|
||||||
|
@@ -45,7 +45,7 @@ enum class UartBaudRate {
|
|||||||
RATE_4000000
|
RATE_4000000
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace uart {
|
namespace serial {
|
||||||
|
|
||||||
void setMode(struct termios& options, UartModes mode);
|
void setMode(struct termios& options, UartModes mode);
|
||||||
/**
|
/**
|
||||||
@@ -64,8 +64,11 @@ void setParity(struct termios& options, Parity parity);
|
|||||||
|
|
||||||
void ignoreCtrlLines(struct termios& options);
|
void ignoreCtrlLines(struct termios& options);
|
||||||
|
|
||||||
|
void flushRxBuf(int fd);
|
||||||
|
void flushTxRxBuf(int fd);
|
||||||
|
|
||||||
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
||||||
|
|
||||||
} // namespace uart
|
} // namespace serial
|
||||||
|
|
||||||
#endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */
|
#endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */
|
||||||
|
@@ -173,7 +173,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
return OPENING_FILE_FAILED;
|
return spi::OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||||
uint32_t spiSpeed = 0;
|
uint32_t spiSpeed = 0;
|
||||||
@@ -234,7 +234,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
spiCookie->setTransferSize(0);
|
spiCookie->setTransferSize(0);
|
||||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
result = FULL_DUPLEX_TRANSFER_FAILED;
|
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
performSpiWiretapping(spiCookie);
|
performSpiWiretapping(spiCookie);
|
||||||
@@ -250,7 +250,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
sif::printWarning("SpiComIF::sendMessage: Half-Duplex write operation failed!\n");
|
sif::printWarning("SpiComIF::sendMessage: Half-Duplex write operation failed!\n");
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
result = HALF_DUPLEX_TRANSFER_FAILED;
|
result = spi::HALF_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
|||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
return OPENING_FILE_FAILED;
|
return spi::OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* rxBuf = nullptr;
|
uint8_t* rxBuf = nullptr;
|
||||||
@@ -327,7 +327,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
|||||||
sif::printWarning("SpiComIF::sendMessage: Half-Duplex read operation failed!\n");
|
sif::printWarning("SpiComIF::sendMessage: Half-Duplex read operation failed!\n");
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
result = HALF_DUPLEX_TRANSFER_FAILED;
|
result = spi::HALF_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
||||||
|
@@ -22,15 +22,6 @@ class SpiCookie;
|
|||||||
*/
|
*/
|
||||||
class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI;
|
|
||||||
static constexpr ReturnValue_t OPENING_FILE_FAILED = returnvalue::makeCode(spiRetvalId, 0);
|
|
||||||
/* Full duplex (ioctl) transfer failure */
|
|
||||||
static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED =
|
|
||||||
returnvalue::makeCode(spiRetvalId, 1);
|
|
||||||
/* Half duplex (read/write) transfer failure */
|
|
||||||
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 initializeInterface(CookieIF* cookie) override;
|
||||||
|
@@ -36,7 +36,7 @@ UioMapper::~UioMapper() {}
|
|||||||
|
|
||||||
ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permissions) {
|
ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permissions) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
int fd = open(uioFile.c_str(), O_RDWR);
|
int fd = open(uioFile.c_str(), O_RDWR | O_SYNC);
|
||||||
if (fd < 1) {
|
if (fd < 1) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "UioMapper::getMappedAdress: Invalid UIO device file " << uioFile << std::endl;
|
sif::error << "UioMapper::getMappedAdress: Invalid UIO device file " << uioFile << std::endl;
|
||||||
|
@@ -357,13 +357,13 @@ ReturnValue_t SpiComIF::halErrorHandler(HAL_StatusTypeDef status, spi::TransferM
|
|||||||
sif::printWarning("SpiComIF::handle%sSendOperation: HAL error %d occured\n", modeString, status);
|
sif::printWarning("SpiComIF::handle%sSendOperation: HAL error %d occured\n", modeString, status);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case (HAL_BUSY): {
|
case (HAL_BUSY): {
|
||||||
return spi::HAL_BUSY_RETVAL;
|
return spi::BUSY;
|
||||||
}
|
}
|
||||||
case (HAL_ERROR): {
|
case (HAL_ERROR): {
|
||||||
return spi::HAL_ERROR_RETVAL;
|
return spi::GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
case (HAL_TIMEOUT): {
|
case (HAL_TIMEOUT): {
|
||||||
return spi::HAL_TIMEOUT_RETVAL;
|
return spi::TIMEOUT;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
Reference in New Issue
Block a user