Compare commits

...

120 Commits

Author SHA1 Message Date
4b5e3e70f7 add option to directly check switch state 2022-03-22 20:35:04 +01:00
bbe21e7e89 doc additions 2022-03-22 16:14:23 +01:00
2823420c46 more docs 2022-03-22 16:10:20 +01:00
6dd6f28db0 added active function 2022-03-22 15:55:18 +01:00
d791fc87b7 some improvements for PowerSwitcher 2022-03-22 15:49:04 +01:00
16f2fa9327 Merge remote-tracking branch 'upstream/development' into mueller/master 2022-03-21 10:12:06 +01:00
927041209b added override specifiers 2022-03-21 09:12:56 +01:00
b6ed45a85c small form fix 2022-03-17 19:59:16 +01:00
ddc1cdb1f5 additional docs 2022-03-17 19:22:24 +01:00
543daaa95a various tweaks and improvements 2022-03-17 19:19:02 +01:00
fec5f83f4f minor event changes 2022-03-11 14:25:01 +01:00
17262a1da9 Merge branch 'mueller/version-getter-upstream' into mueller/master 2022-03-10 09:59:18 +01:00
b5d6b9745f undef major and minor 2022-03-10 09:56:23 +01:00
60639f56dc Merge branch 'mueller/version-getter' into mueller/master 2022-03-10 09:47:32 +01:00
3aa0bbde68 Merge branch 'mueller/version-getter-upstream' into mueller/version-getter 2022-03-10 09:47:10 +01:00
97bc71a3ff added tests 2022-03-10 09:34:29 +01:00
06577ed78a Merge branch 'mueller/version-getter' into mueller/master 2022-03-09 19:11:57 +01:00
b27f3b84aa getter not required anymore 2022-03-09 19:10:05 +01:00
9509847b84 Merge branch 'mueller/version-getter' into mueller/master 2022-03-09 19:05:30 +01:00
45b51f9ac8 improved version.h 2022-03-09 19:05:07 +01:00
d63c01b96f set timeout in countdown ctor 2022-03-08 11:50:47 +01:00
3b497dbb8d Merge branch 'mueller/version-getter' into mueller/master 2022-03-08 10:16:56 +01:00
bf733162eb Merge remote-tracking branch 'origin/eive/develop' into mueller/master 2022-03-08 10:15:54 +01:00
73f0b9c0dc Merge pull request 'define FSFW_DISABLE_PRINTOUT in any case' (#42) from mueller/define-fsfw-disabled-printout into eive/develop
Reviewed-on: #42
2022-03-08 10:11:45 +01:00
b5e55f64b0 Merge pull request 'Another HasModesIF improvement' (#41) from mueller/master into eive/develop
Reviewed-on: #41
2022-03-08 10:11:05 +01:00
7ca6d1a695 function to get fsfw version 2022-03-08 10:05:18 +01:00
cc3210f366 Merge branch 'eive/develop' into mueller/define-fsfw-disabled-printout 2022-03-08 09:57:43 +01:00
155d66e534 define FSFW_DISABLE_PRINTOUT in any case 2022-03-08 09:57:11 +01:00
d4c76a7e46 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/fsfw into mueller/master 2022-03-08 09:56:39 +01:00
dba3c27b99 define FSFW_DISABLE_PRINTOUT in any case 2022-03-08 09:56:24 +01:00
202cfc6dbb Merge branch 'eive/develop' into mueller/master 2022-03-08 09:47:37 +01:00
84f95e8d76 this is better 2022-03-08 09:45:58 +01:00
6de4798805 Merge pull request 'better name of invalid mode retval' (#40) from mueller/master into eive/develop
Reviewed-on: #40
2022-03-08 09:37:58 +01:00
82a645deba Merge branch 'eive/develop' into mueller/master 2022-03-08 09:36:25 +01:00
8b1c277c58 better name of invalid mode retval 2022-03-08 09:34:22 +01:00
5f23f709cc Merge pull request 'Update for Assembly Base' (#38) from mueller/master into eive/develop
Reviewed-on: #38
2022-03-08 07:53:04 +01:00
a7cb2d4354 small test device handler fixes 2022-03-07 15:54:56 +01:00
7571987a1d Merge branch 'eive/develop' into mueller/master 2022-03-07 15:43:52 +01:00
d6c1041133 Merge remote-tracking branch 'upstream/development' into eive/develop 2022-03-07 15:34:11 +01:00
3c53e2c259 renamed some ModeIF definitions 2022-03-05 03:01:43 +01:00
45f0d7fd45 docs 2022-03-04 18:06:57 +01:00
aebab4c73c Merge remote-tracking branch 'upstream/development' into mueller/master 2022-03-04 15:08:45 +01:00
c3c2e1c0dd Merge remote-tracking branch 'upstream/development' into eive/develop 2022-03-04 15:08:07 +01:00
4e6c1cb72a docs 2022-03-04 00:55:41 +01:00
e2eb6a46b6 Merge branch 'eive/develop' into mueller/master 2022-03-03 13:43:15 +01:00
75c56280ad Merge pull request 'GPIO HAL Updates' (#36) from mueller/gpio-hal-updates into eive/develop
Reviewed-on: #36
2022-03-03 09:44:42 +01:00
0ccaf27fcb better printout for parameter code 2022-03-01 19:43:21 +01:00
e05e203c83 fix merge conflict 2022-02-28 15:50:27 +01:00
ac036b2a70 Merge remote-tracking branch 'origin/eive/develop' into mueller/gpio-hal-updates 2022-02-28 15:49:11 +01:00
2d9216ba19 Merge branch 'mueller/gpio-hal-updates' into mueller/master 2022-02-28 15:37:03 +01:00
2fed161eff Merge branch 'eive/develop' into mueller/gpio-hal-updates 2022-02-28 15:34:48 +01:00
4cf2a384f3 Merge remote-tracking branch 'upstream/development' into mueller/gpio-hal-updates 2022-02-28 15:22:32 +01:00
27267b7cb0 Merge remote-tracking branch 'upstream/development' into mueller/gpio-hal-updates 2022-02-28 15:21:39 +01:00
505e00c067 Merge remote-tracking branch 'origin/eive/develop' into mueller/master 2022-02-28 15:17:29 +01:00
68225586d2 some fixes 2022-02-28 15:16:43 +01:00
6d825a1aa6 some fixes 2022-02-28 15:16:24 +01:00
fa73ad6731 Merge branch 'mueller/gpio-hal-updates' into mueller/master 2022-02-28 15:01:41 +01:00
331aa9442d some updates 2022-02-28 14:56:37 +01:00
28b28b5684 Merge branch 'mueller/gpio-hal-updates' into mueller/master 2022-02-28 14:48:27 +01:00
afd3a942e2 use enum class 2022-02-28 14:46:12 +01:00
729bcc4aaf Merge remote-tracking branch 'upstream/development' into mueller/gpio-hal-updates 2022-02-28 14:39:35 +01:00
6e0b90696d Merge pull request 'initial submode' (#35) from meier/dhbInitialSubmode into eive/develop
Reviewed-on: #35
2022-02-28 13:23:26 +01:00
eacb4ac407 initial submode 2022-02-25 14:41:43 +01:00
09c1918c1f Merge pull request 'Update FSFW' (#34) from mueller/master into eive/develop
Reviewed-on: #34
2022-02-25 11:38:11 +01:00
123f2ff360 removed unnecessary warning 2022-02-25 11:10:48 +01:00
7ce2c1b624 Merge branch 'development' into mueller/gpio-hal-updates 2022-02-23 11:02:02 +01:00
4747e54c5d no default values for srv5 params 2022-02-22 20:08:19 +01:00
2e230daa14 additional comment 2022-02-22 18:59:50 +01:00
e909c6b6f7 Merge branch 'mueller/spi-update-clock-polarity' into mueller/master 2022-02-22 18:59:06 +01:00
d88d7c938f update spi clock polarity
- Perform an empty SPI transfer after setting speed and mode
2022-02-22 18:58:20 +01:00
389641f8fd display run commands 2022-02-22 14:00:34 +01:00
b440c30223 update changelog 2022-02-22 11:26:11 +01:00
3966b656e9 apply .clang format 2022-02-22 11:15:01 +01:00
3a5881a0cb more time 2022-02-22 11:10:02 +01:00
1e982ec00b updated for windows compatibility 2022-02-22 11:00:39 +01:00
701135e2a6 applied clang format 2022-02-22 10:17:56 +01:00
19f8e41c7f Merge pull request 'Update FSFW' (#33) from mueller/master into eive/develop
Reviewed-on: #33
2022-02-21 11:00:17 +01:00
c4a055986c Merge remote-tracking branch 'origin/eive/develop' into mueller/master 2022-02-21 10:37:53 +01:00
d74a373f1d make periodic printout run time configurable 2022-02-19 16:41:30 +01:00
cf69af4e7e passing mqArgs to all mq ctor calls 2022-02-19 16:14:02 +01:00
508979d32d cache mq args 2022-02-18 14:52:25 +01:00
0d66569687 this is a bit cleaner 2022-02-18 14:07:41 +01:00
a5871ed0b1 added void* args to queue factory and mq ctor 2022-02-18 14:00:06 +01:00
a12e98d948 update event mngr printout 2022-02-18 13:39:42 +01:00
bd05afbddd printout improvements 2022-02-18 13:09:18 +01:00
b3482eba24 error check in event manager 2022-02-17 20:41:47 +01:00
9e92afbf07 bugfix in test task 2022-02-16 18:54:55 +01:00
0d6d44f72f Merge remote-tracking branch 'upstream/development' into mueller/master 2022-02-15 17:08:29 +01:00
81f5b0c3bf Merge branch 'mueller/dhb-docs' into mueller/master 2022-02-10 14:03:28 +01:00
062e93fd88 started DHB docs 2022-02-10 13:53:01 +01:00
c20bf31d5d Merge pull request 'meier/halAdjustments' (#32) from meier/halAdjustments into eive/develop
Reviewed-on: #32
2022-02-07 11:03:09 +01:00
3c06d2dbbb run clang format script 2022-02-05 18:11:23 +01:00
018d814f29 adapt to develop 2022-02-05 17:12:42 +01:00
c0648a789b merged develop 2022-02-05 17:07:06 +01:00
9579e94a71 option to exclude libgpiod from build 2022-02-05 16:09:23 +01:00
235fd79dfb added missing baudrates 2022-02-05 16:08:28 +01:00
83635d3667 Merge pull request 'Fix for event definitions' (#31) from mueller/fix-events into eive/develop
Reviewed-on: #31
2022-02-03 18:20:48 +01:00
581ae4c990 another include removed 2022-02-03 17:37:29 +01:00
32a9e0c704 another include removed 2022-02-03 17:37:11 +01:00
940c53eba6 removed HK switch helper from cmake file 2022-02-03 17:34:15 +01:00
0d4bd856bd removed HK switch helper from cmake file 2022-02-03 17:33:46 +01:00
b7f6a6961b delete switch helper, some other fixes 2022-02-03 17:14:11 +01:00
a910a05541 parser is not perfect.. 2022-02-03 17:09:58 +01:00
973996e102 more fixes 2022-02-03 17:08:30 +01:00
b3aee76d91 fixes for event definitoons for parser 2022-02-03 17:06:18 +01:00
b3151a0ba0 added i2c wiretapping 2022-02-03 13:37:28 +01:00
fca48257b7 zero initialize array 2022-02-03 12:02:08 +01:00
8f95b03e6a fixes warning for good 2022-02-03 11:13:26 +01:00
527dba9a9d Merge branch 'mueller/comp-branch' into mueller/master 2022-02-02 20:15:20 +01:00
22cd38fffd this should work for c++11 2022-02-02 20:05:46 +01:00
1a518109d0 Merge branch 'mueller/comp-branch' into mueller/master 2022-02-02 19:49:03 +01:00
8030d9ac1b this fixes the warning 2022-02-02 19:47:58 +01:00
992c05df56 added cpp printout preprocessor guards 2022-02-02 17:52:09 +01:00
6698d283b6 device wants hard reboot event added 2022-02-02 16:04:36 +01:00
33386550cf add uio subdir 2022-02-02 12:17:42 +01:00
3a65c0db91 use C++ casts 2022-02-02 12:13:42 +01:00
41614303d7 renamed variable 2022-02-02 12:11:39 +01:00
783176848a include fixes 2022-02-02 12:10:39 +01:00
07cb980e06 apply clang script 2022-02-02 12:05:03 +01:00
d8c5bd125e All EIVE changes 2022-02-02 12:02:58 +01:00
64 changed files with 538 additions and 270 deletions

View File

@ -269,6 +269,50 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
cfsetispeed(options, B460800); cfsetispeed(options, B460800);
cfsetospeed(options, B460800); cfsetospeed(options, B460800);
break; break;
case 500000:
cfsetispeed(options, B500000);
cfsetospeed(options, B500000);
break;
case 576000:
cfsetispeed(options, B576000);
cfsetospeed(options, B576000);
break;
case 921600:
cfsetispeed(options, B921600);
cfsetospeed(options, B921600);
break;
case 1000000:
cfsetispeed(options, B1000000);
cfsetospeed(options, B1000000);
break;
case 1152000:
cfsetispeed(options, B1152000);
cfsetospeed(options, B1152000);
break;
case 1500000:
cfsetispeed(options, B1500000);
cfsetospeed(options, B1500000);
break;
case 2000000:
cfsetispeed(options, B2000000);
cfsetospeed(options, B2000000);
break;
case 2500000:
cfsetispeed(options, B2500000);
cfsetospeed(options, B2500000);
break;
case 3000000:
cfsetispeed(options, B3000000);
cfsetospeed(options, B3000000);
break;
case 3500000:
cfsetispeed(options, B3500000);
cfsetospeed(options, B3500000);
break;
case 4000000:
cfsetispeed(options, B4000000);
cfsetospeed(options, B4000000);
break;
default: default:
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl; sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;

View File

@ -1,4 +1,4 @@
#include "fsfw_hal/linux/uart/UartCookie.h" #include "UartCookie.h"
#include <fsfw/serviceinterface.h> #include <fsfw/serviceinterface.h>

View File

@ -12,7 +12,9 @@ object_id_t CFDPHandler::packetDestination = 0;
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist) CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
: SystemObject(setObjectId) { : SystemObject(setObjectId) {
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION); auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
requestQueue = QueueFactory::instance()->createMessageQueue(
CFDP_HANDLER_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
distributor = dist; distributor = dist;
} }

View File

@ -13,7 +13,9 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
submode(SUBMODE_NONE), submode(SUBMODE_NONE),
modeHelper(this), modeHelper(this),
healthHelper(this, setObjectId) { healthHelper(this, setObjectId) {
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth); auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue(
commandQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); } ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }

View File

@ -1,4 +1,4 @@
target_sources(${LIB_FSFW_NAME} PRIVATE target_sources(${LIB_FSFW_NAME} PRIVATE
PoolDataSetBase.cpp PoolDataSetBase.cpp
PoolEntry.cpp PoolEntry.cpp
) )

View File

@ -47,13 +47,14 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner); HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
if (hkOwner == nullptr) { if (hkOwner == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPoolVariable: The supplied pool owner did not implement the correct " sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
"interface HasLocalDataPoolIF!" << std::dec << " did not implement the correct interface "
<< std::endl; << "HasLocalDataPoolIF" << std::endl;
#else #else
sif::printError( sif::printError(
"LocalPoolVariable: The supplied pool owner did not implement the correct " "LocalPoolVariable: The supplied pool owner 0x%08x did not implement the correct "
"interface HasLocalDataPoolIF!\n"); "interface HasLocalDataPoolIF\n",
poolOwner);
#endif #endif
return; return;
} }

View File

@ -46,7 +46,7 @@ class StaticLocalDataSet : public LocalPoolDataSetBase {
} }
private: private:
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList; std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList = {};
}; };
#endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */ #endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */

View File

@ -26,11 +26,7 @@ void AssemblyBase::performChildOperation() {
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) { void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
doStartTransition(mode, submode); doStartTransition(mode, submode);
if (modeHelper.isForced()) { triggerModeHelperEvents(mode, submode);
triggerEvent(FORCING_MODE, mode, submode);
} else {
triggerEvent(CHANGING_MODE, mode, submode);
}
} }
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) { void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
@ -77,9 +73,10 @@ bool AssemblyBase::handleChildrenChangedHealth() {
} }
HealthState healthState = healthHelper.healthTable->getHealth(iter->first); HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
if (healthState == HasHealthIF::NEEDS_RECOVERY) { if (healthState == HasHealthIF::NEEDS_RECOVERY) {
triggerEvent(TRYING_RECOVERY); triggerEvent(TRYING_RECOVERY, iter->first, 0);
recoveryState = RECOVERY_STARTED; recoveryState = RECOVERY_STARTED;
recoveringDevice = iter; recoveringDevice = iter;
// The user needs to take care of commanding the children off in commandChildren
doStartTransition(targetMode, targetSubmode); doStartTransition(targetMode, targetSubmode);
} else { } else {
triggerEvent(CHILD_CHANGED_HEALTH); triggerEvent(CHILD_CHANGED_HEALTH);
@ -228,6 +225,9 @@ ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
bool AssemblyBase::checkAndHandleRecovery() { bool AssemblyBase::checkAndHandleRecovery() {
switch (recoveryState) { switch (recoveryState) {
case RECOVERY_STARTED: case RECOVERY_STARTED:
// The recovery was already start in #handleChildrenChangedHealth and we just need
// to wait for an off time period.
// TODO: make time period configurable
recoveryState = RECOVERY_WAIT; recoveryState = RECOVERY_WAIT;
recoveryOffTimer.resetTimer(); recoveryOffTimer.resetTimer();
return true; return true;
@ -266,3 +266,11 @@ void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, HasHealthIF::Heal
modeHelper.setForced(true); modeHelper.setForced(true);
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL); sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
} }
void AssemblyBase::triggerModeHelperEvents(Mode_t mode, Submode_t submode) {
if (modeHelper.isForced()) {
triggerEvent(FORCING_MODE, mode, submode);
} else {
triggerEvent(CHANGING_MODE, mode, submode);
}
}

View File

@ -12,7 +12,8 @@
* Documentation: Dissertation Baetz p.156, 157. * Documentation: Dissertation Baetz p.156, 157.
* *
* This class reduces the complexity of controller components which would * This class reduces the complexity of controller components which would
* otherwise be needed for the handling of redundant devices. * otherwise be needed for the handling of redundant devices. However, it can also be used to
* manage the mode keeping and recovery of non-redundant devices
* *
* The template class monitors mode and health state of its children * The template class monitors mode and health state of its children
* and checks availability of devices on every detected change. * and checks availability of devices on every detected change.
@ -26,11 +27,9 @@
* *
* Important: * Important:
* *
* The implementation must call registerChild(object_id_t child) * The implementation must call #registerChild for all commanded children during initialization.
* for all commanded children during initialization.
* The implementation must call the initialization function of the base class. * The implementation must call the initialization function of the base class.
* (This will call the function in SubsystemBase) * (This will call the function in SubsystemBase)
*
*/ */
class AssemblyBase : public SubsystemBase { class AssemblyBase : public SubsystemBase {
public: public:
@ -47,13 +46,14 @@ class AssemblyBase : public SubsystemBase {
protected: protected:
/** /**
* Command children to reach [mode,submode] combination * Command children to reach [mode,submode] combination. Can be done by setting
* Can be done by setting #commandsOutstanding correctly, * #commandsOutstanding correctly, or using #executeTable. In case of an FDIR recovery,
* or using executeTable() * the user needs to ensure that the target devices are healthy. If a device is not healthy,
* a recovery might be on-going and the device needs to be commanded to off first.
* @param mode * @param mode
* @param submode * @param submode
* @return * @return
* - @c RETURN_OK if ok * - @c RETURN_OK if OK
* - @c NEED_SECOND_STEP if children need to be commanded again * - @c NEED_SECOND_STEP if children need to be commanded again
*/ */
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0; virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
@ -120,8 +120,19 @@ class AssemblyBase : public SubsystemBase {
virtual ReturnValue_t handleHealthReply(CommandMessage *message); virtual ReturnValue_t handleHealthReply(CommandMessage *message);
virtual void performChildOperation(); /**
* @brief Default periodic handler
* @details
* This is the default periodic handler which will be called by the SubsystemBase
* performOperation. It performs the child transitions or reacts to changed health/mode states
* of children objects
*/
virtual void performChildOperation() override;
/**
* This function handles changed mode or health states of children
* @return
*/
bool handleChildrenChanged(); bool handleChildrenChanged();
/** /**
@ -134,12 +145,37 @@ class AssemblyBase : public SubsystemBase {
bool handleChildrenChangedHealth(); bool handleChildrenChangedHealth();
/**
* Core transition handler. The default implementation will only do something if
* #commandsOutstanding is smaller or equal to zero, which means that all mode commands
* from the #doPerformTransition call were executed successfully.
*
* Unless a second step was requested, the function will then use #checkChildrenState to
* determine whether the target mode was reached.
*
* There is some special handling for certain (internal) modes:
* - A second step is necessary. #commandChildren will be performed again
* - The device health was overwritten. #commandChildren will be called
* - A recovery is ongoing. #checkAndHandleRecovery will be called.
*/
virtual void handleChildrenTransition(); virtual void handleChildrenTransition();
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
/**
* Calls #doStartTransition and triggers an informative event as well that the mode will
* change
* @param mode
* @param submode
*/
virtual void startTransition(Mode_t mode, Submode_t submode); virtual void startTransition(Mode_t mode, Submode_t submode);
/**
* This function starts the transition by setting the internal #targetSubmode and #targetMode
* variables and then calling the #commandChildren function.
* @param mode
* @param submode
*/
virtual void doStartTransition(Mode_t mode, Submode_t submode); virtual void doStartTransition(Mode_t mode, Submode_t submode);
virtual bool isInTransition(); virtual bool isInTransition();
@ -160,7 +196,7 @@ class AssemblyBase : public SubsystemBase {
* Manages recovery of a device * Manages recovery of a device
* @return true if recovery is still ongoing, false else. * @return true if recovery is still ongoing, false else.
*/ */
bool checkAndHandleRecovery(); virtual bool checkAndHandleRecovery();
/** /**
* Helper method to overwrite health state of one of the children. * Helper method to overwrite health state of one of the children.
@ -168,6 +204,8 @@ class AssemblyBase : public SubsystemBase {
* @param objectId Must be a registered child. * @param objectId Must be a registered child.
*/ */
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth); void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
void triggerModeHelperEvents(Mode_t mode, Submode_t submode);
}; };
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */ #endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */

View File

@ -39,8 +39,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
childTransitionDelay(5000), childTransitionDelay(5000),
transitionSourceMode(_MODE_POWER_DOWN), transitionSourceMode(_MODE_POWER_DOWN),
transitionSourceSubMode(SUBMODE_NONE) { transitionSourceSubMode(SUBMODE_NONE) {
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue( commandQueue = QueueFactory::instance()->createMessageQueue(
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
insertInCommandMap(RAW_COMMAND_ID); insertInCommandMap(RAW_COMMAND_ID);
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
cookieInfo.pendingCommand = deviceCommandMap.end(); cookieInfo.pendingCommand = deviceCommandMap.end();
@ -48,9 +49,6 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase", printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie"); HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
} }
if (this->fdirInstance == nullptr) {
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFdirParentId);
}
} }
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) { void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
@ -126,6 +124,17 @@ ReturnValue_t DeviceHandlerBase::initialize() {
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
if (this->fdirInstance == nullptr) {
this->fdirInstance = 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 = communicationInterface =
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId); ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
@ -1385,6 +1394,8 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task) { executingTask = task;
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId, void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
uint32_t parameter) {} uint32_t parameter) {}
Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
void DeviceHandlerBase::performOperationHook() {} void DeviceHandlerBase::performOperationHook() {}
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -1407,7 +1418,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
this->poolManager.initializeAfterTaskCreation(); this->poolManager.initializeAfterTaskCreation();
if (setStartupImmediately) { if (setStartupImmediately) {
startTransition(MODE_ON, SUBMODE_NONE); startTransition(MODE_ON, getInitialSubmode());
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -1491,3 +1502,9 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
} }
return commandIter->second.sendReplyTo; return commandIter->second.sendReplyTo;
} }
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; }

View File

@ -103,6 +103,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie, DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20); FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
void setCustomFdir(FailureIsolationBase* fdir);
void setParent(object_id_t parent);
void setPowerSwitcher(PowerSwitchIF* switcher);
void setHkDestination(object_id_t hkDestination); void setHkDestination(object_id_t hkDestination);
/** /**
@ -647,6 +650,12 @@ class DeviceHandlerBase : public DeviceHandlerIF,
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0, virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
uint32_t parameter = 0); uint32_t parameter = 0);
/**
* @brief Can be overwritten by a child to specify the initial submode when device has been set
* to startup immediately.
*/
virtual Submode_t getInitialSubmode();
protected: protected:
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
@ -818,6 +827,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
/** Pointer to the used FDIR instance. If not provided by child, /** Pointer to the used FDIR instance. If not provided by child,
* default class is instantiated. */ * default class is instantiated. */
FailureIsolationBase *fdirInstance; FailureIsolationBase *fdirInstance;
object_id_t parent = objects::NO_OBJECT;
//! To correctly delete the default instance. //! To correctly delete the default instance.
bool defaultFDIRUsed; bool defaultFDIRUsed;

View File

@ -29,6 +29,7 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
switch (event->getEvent()) { switch (event->getEvent()) {
case HasModesIF::MODE_TRANSITION_FAILED: case HasModesIF::MODE_TRANSITION_FAILED:
case HasModesIF::OBJECT_IN_INVALID_MODE: case HasModesIF::OBJECT_IN_INVALID_MODE:
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
// We'll try a recovery as long as defined in MAX_REBOOT. // We'll try a recovery as long as defined in MAX_REBOOT.
// Might cause some AssemblyBase cycles, so keep number low. // Might cause some AssemblyBase cycles, so keep number low.
handleRecovery(event->getEvent()); handleRecovery(event->getEvent());

View File

@ -109,6 +109,7 @@ class DeviceHandlerIF {
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW); static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW); static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH); static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
static const Event DEVICE_WANTS_HARD_REBOOT = MAKE_EVENT(11, severity::HIGH);
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;

View File

@ -8,7 +8,9 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
parentQueue(parentQueue), parentQueue(parentQueue),
commandQueue(), commandQueue(),
healthHelper(this, setObjectId) { healthHelper(this, setObjectId) {
commandQueue = QueueFactory::instance()->createMessageQueue(3); auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue(
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); } HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }

View File

@ -18,8 +18,9 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
EventManager::EventManager(object_id_t setObjectId) EventManager::EventManager(object_id_t setObjectId)
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) { : SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE, auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
EventMessage::EVENT_MESSAGE_SIZE); eventReportQueue = QueueFactory::instance()->createMessageQueue(
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
} }
EventManager::~EventManager() { EventManager::~EventManager() {
@ -46,9 +47,20 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
void EventManager::notifyListeners(EventMessage* message) { void EventManager::notifyListeners(EventMessage* message) {
lockMutex(); lockMutex();
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) { for (auto& listener : listenerList) {
if (iter->second.match(message)) { if (listener.second.match(message)) {
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender()); ReturnValue_t result =
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
<< result << std::setfill(' ') << std::endl;
#else
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
listener.first, result);
#endif
}
} }
} }
unlockMutex(); unlockMutex();
@ -189,4 +201,19 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
} }
} }
void EventManager::printListeners() {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
for (auto& listener : listenerList) {
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
}
sif::info << std::dec << std::setfill(' ');
#else
sif::printInfo("Event manager listener MQ IDs:\n");
for (auto& listener : listenerList) {
sif::printInfo("0x%08x\n", listener.first);
}
#endif
}
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */ #endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */

View File

@ -42,6 +42,7 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
object_id_t reporterFrom = 0, object_id_t reporterTo = 0, object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
bool reporterInverted = false); bool reporterInverted = false);
ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t performOperation(uint8_t opCode);
void printListeners();
protected: protected:
MessageQueueIF* eventReportQueue = nullptr; MessageQueueIF* eventReportQueue = nullptr;

View File

@ -9,8 +9,9 @@
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent, FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
uint8_t messageDepth, uint8_t parameterDomainBase) uint8_t messageDepth, uint8_t parameterDomainBase)
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) { : ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
eventQueue = auto mqArgs = MqArgs(owner, static_cast<void*>(this));
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE); eventQueue = QueueFactory::instance()->createMessageQueue(
messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
} }
FailureIsolationBase::~FailureIsolationBase() { FailureIsolationBase::~FailureIsolationBase() {
@ -51,11 +52,12 @@ ReturnValue_t FailureIsolationBase::initialize() {
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent); ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
if (parentIF == nullptr) { if (parentIF == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FailureIsolationBase::intialize: Parent object" sif::error << "FailureIsolationBase::intialize: Parent object "
<< "invalid." << std::endl; << "invalid" << std::endl;
#endif sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
#if FSFW_CPP_OSTREAM_ENABLED == 1 #else
sif::error << "Make sure it implements ConfirmsFailuresIF." << std::endl; sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
sif::printError("Make sure it implements ConfirmsFailuresIF\n");
#endif #endif
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
return RETURN_FAILED; return RETURN_FAILED;

View File

@ -14,13 +14,12 @@ class FailureIsolationBase : public HasReturnvaluesIF,
public HasParametersIF { public HasParametersIF {
public: public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
static const Event FDIR_CHANGED_STATE = //! FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2 static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO);
//!< (oldState) to par1 (newState). //! FDIR tries to restart device. Par1: event that caused recovery.
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT( static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
2, severity::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery. //! FDIR turns off device. Par1: event that caused recovery.
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT( static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM);
3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT, FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0); uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);

View File

@ -23,19 +23,15 @@ class HasHealthIF {
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO); static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO); static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW); static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
static const Event OVERWRITING_HEALTH = //! Assembly overwrites health information of children to keep satellite alive.
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
//!< satellite alive. //! Someone starts a recovery of a component (typically power-cycle). No parameters.
static const Event TRYING_RECOVERY = static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically //! Recovery is ongoing. Comes twice during recovery.
//!< power-cycle). No parameters. //! P1: 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_STEP = static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1: //! Recovery was completed. Not necessarily successful. No parameters.
//!< 0 for the first, 1 for the second event. P2: 0 static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
static const Event RECOVERY_DONE = MAKE_EVENT(
12,
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
virtual ~HasHealthIF() {} virtual ~HasHealthIF() {}
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@ -7,11 +7,13 @@
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth) InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
: SystemObject(setObjectId), : SystemObject(setObjectId),
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
poolManager(this, commandQueue), poolManager(this, commandQueue),
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID), internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
internalErrorDataset(this) { internalErrorDataset(this) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
commandQueue = QueueFactory::instance()->createMessageQueue(
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); } InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
@ -36,15 +38,14 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) { if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "InternalErrorReporter::performOperation: Errors " sif::debug << "InternalErrorReporter::performOperation: Errors "
<< "occured!" << std::endl; << "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
sif::debug << "Queue errors: " << newQueueHits << std::endl; << newStoreHits << std::endl;
sif::debug << "TM errors: " << newTmHits << std::endl;
sif::debug << "Store errors: " << newStoreHits << std::endl;
#else #else
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n"); sif::printDebug(
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits)); "InternalErrorReporter::performOperation: Errors occured: Queue | TM | Store: %lu | %lu "
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits)); "| %lu\n",
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits)); static_cast<unsigned int>(newQueueHits), static_cast<unsigned int>(newTmHits),
static_cast<unsigned int>(newStoreHits));
#endif #endif
} }
} }

View File

@ -5,6 +5,7 @@
#include "MessageQueueIF.h" #include "MessageQueueIF.h"
#include "MessageQueueMessage.h" #include "MessageQueueMessage.h"
#include "definitions.h"
/** /**
* Creates message queues. * Creates message queues.
@ -22,7 +23,8 @@ class QueueFactory {
static QueueFactory* instance(); static QueueFactory* instance();
MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3, MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3,
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
MqArgs* args = nullptr);
void deleteMessageQueue(MessageQueueIF* queue); void deleteMessageQueue(MessageQueueIF* queue);

View File

@ -0,0 +1,12 @@
#ifndef FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
#define FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
#include <fsfw/objectmanager/SystemObjectIF.h>
struct MqArgs {
MqArgs(){};
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
object_id_t objectId = 0;
void* args = nullptr;
};
#endif /* FSFW_SRC_FSFW_IPC_DEFINITIONS_H_ */

View File

@ -19,32 +19,33 @@ class HasModesIF {
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04); static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
static const Event CHANGING_MODE = //! An object announces changing the mode. p1: target mode. p2: target submode
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode. static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO);
//!< p2: target submode //! An Object announces its mode; parameter1 is mode, parameter2 is submode
static const Event MODE_INFO = MAKE_EVENT( static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
1,
severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH); static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW); static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH); static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
static const Event OBJECT_IN_INVALID_MODE = //! Indicates a bug or configuration failure: Object is in a mode it should never be in.
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW);
//!< mode it should never be in. //! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
static const Event FORCING_MODE = MAKE_EVENT( //! p1: target mode. p2: target submode
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced, static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode //! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
static const Event MODE_CMD_REJECTED = static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1:
//!< called object id, Par2: return code.
static const Mode_t MODE_ON = //! The device is powered and ready to perform operations. In this mode, no commands are
1; //!< The device is powered and ready to perform operations. In this mode, no commands are //! sent by the device handler itself, but direct commands van be commanded and will be
//!< sent by the device handler itself, but direct commands van be commanded and will be //! interpreted
//!< interpreted static constexpr Mode_t MODE_ON = 1;
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in //! The device is powered off. The only command accepted in this mode is a mode change to on.
//!< this mode is a mode change to on. static constexpr Mode_t MODE_OFF = 0;
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
static constexpr Mode_t MODE_INVALID = -1;
static constexpr Mode_t MODE_UNDEFINED = -2;
//! To avoid checks against magic number "0".
static const Submode_t SUBMODE_NONE = 0;
virtual ~HasModesIF() {} virtual ~HasModesIF() {}
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@ -95,13 +95,16 @@ void ObjectManager::initialize() {
for (auto const& it : objectList) { for (auto const& it : objectList) {
result = it.second->initialize(); result = it.second->initialize();
if (result != RETURN_OK) { if (result != RETURN_OK) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
object_id_t var = it.first;
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8) sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
<< std::setfill('0') << var << std::setfill('0') << it.first << " failed to initialize with code 0x" << result
<< " failed to " << std::dec << std::setfill(' ') << std::endl;
"initialize with code 0x" #else
<< result << std::dec << std::setfill(' ') << std::endl; sif::printError(
"ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", var,
it.first);
#endif
#endif #endif
errorCount++; errorCount++;
} }

View File

@ -4,7 +4,7 @@
#include "fsfw/osal/freertos/QueueMapManager.h" #include "fsfw/osal/freertos/QueueMapManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
: maxMessageSize(maxMessageSize) { : maxMessageSize(maxMessageSize) {
handle = xQueueCreate(messageDepth, maxMessageSize); handle = xQueueCreate(messageDepth, maxMessageSize);
if (handle == nullptr) { if (handle == nullptr) {

View File

@ -7,6 +7,7 @@
#include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw/ipc/MessageQueueMessage.h"
#include "fsfw/ipc/MessageQueueMessageIF.h" #include "fsfw/ipc/MessageQueueMessageIF.h"
#include "fsfw/ipc/definitions.h"
#include "queue.h" #include "queue.h"
/** /**
@ -53,7 +54,8 @@ class MessageQueue : public MessageQueueIF {
* This should be left default. * This should be left default.
*/ */
MessageQueue(size_t messageDepth = 3, MessageQueue(size_t messageDepth = 3,
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
MqArgs* args = nullptr);
/** Copying message queues forbidden */ /** Copying message queues forbidden */
MessageQueue(const MessageQueue&) = delete; MessageQueue(const MessageQueue&) = delete;

View File

@ -22,8 +22,9 @@ QueueFactory::QueueFactory() {}
QueueFactory::~QueueFactory() {} QueueFactory::~QueueFactory() {}
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
return new MessageQueue(messageDepth, maxMessageSize); MqArgs* args) {
return new MessageQueue(messageDepth, maxMessageSize, args);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }

View File

@ -8,7 +8,7 @@
#include "fsfw/osal/host/QueueMapManager.h" #include "fsfw/osal/host/QueueMapManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
: messageSize(maxMessageSize), messageDepth(messageDepth) { : messageSize(maxMessageSize), messageDepth(messageDepth) {
queueLock = MutexFactory::instance()->createMutex(); queueLock = MutexFactory::instance()->createMutex();
auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId); auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId);

View File

@ -8,6 +8,7 @@
#include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw/ipc/MessageQueueMessage.h"
#include "fsfw/ipc/MutexIF.h" #include "fsfw/ipc/MutexIF.h"
#include "fsfw/ipc/definitions.h"
#include "fsfw/timemanager/Clock.h" #include "fsfw/timemanager/Clock.h"
/** /**
@ -54,7 +55,8 @@ class MessageQueue : public MessageQueueIF {
* This should be left default. * This should be left default.
*/ */
MessageQueue(size_t messageDepth = 3, MessageQueue(size_t messageDepth = 3,
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
MqArgs* args = nullptr);
/** Copying message queues forbidden */ /** Copying message queues forbidden */
MessageQueue(const MessageQueue&) = delete; MessageQueue(const MessageQueue&) = delete;

View File

@ -27,12 +27,13 @@ QueueFactory::QueueFactory() {}
QueueFactory::~QueueFactory() {} QueueFactory::~QueueFactory() {}
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
MqArgs* args) {
// A thread-safe queue can be implemented by using a combination // A thread-safe queue can be implemented by using a combination
// of std::queue and std::mutex. This uses dynamic memory allocation // of std::queue and std::mutex. This uses dynamic memory allocation
// which could be alleviated by using a custom allocator, external library // which could be alleviated by using a custom allocator, external library
// (etl::queue) or simply using std::queue, we're on a host machine anyway. // (etl::queue) or simply using std::queue, we're on a host machine anyway.
return new MessageQueue(messageDepth, maxMessageSize); return new MessageQueue(messageDepth, maxMessageSize, args);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }

View File

@ -1,29 +1,29 @@
target_sources(${LIB_FSFW_NAME} PRIVATE target_sources(${LIB_FSFW_NAME} PRIVATE
Clock.cpp Clock.cpp
BinarySemaphore.cpp BinarySemaphore.cpp
CountingSemaphore.cpp CountingSemaphore.cpp
FixedTimeslotTask.cpp FixedTimeslotTask.cpp
InternalErrorCodes.cpp InternalErrorCodes.cpp
MessageQueue.cpp MessageQueue.cpp
Mutex.cpp Mutex.cpp
MutexFactory.cpp MutexFactory.cpp
PeriodicPosixTask.cpp PeriodicPosixTask.cpp
PosixThread.cpp PosixThread.cpp
QueueFactory.cpp QueueFactory.cpp
SemaphoreFactory.cpp SemaphoreFactory.cpp
TaskFactory.cpp TaskFactory.cpp
tcpipHelpers.cpp tcpipHelpers.cpp
unixUtility.cpp unixUtility.cpp
) )
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE target_link_libraries(${LIB_FSFW_NAME} PRIVATE
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
rt rt
) )
target_link_libraries(${LIB_FSFW_NAME} INTERFACE target_link_libraries(${LIB_FSFW_NAME} INTERFACE
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
) )

View File

@ -11,7 +11,7 @@
#include "fsfw/osal/linux/unixUtility.h" #include "fsfw/osal/linux/unixUtility.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize) MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs* args)
: id(MessageQueueIF::NO_QUEUE), : id(MessageQueueIF::NO_QUEUE),
lastPartner(MessageQueueIF::NO_QUEUE), lastPartner(MessageQueueIF::NO_QUEUE),
defaultDestination(MessageQueueIF::NO_QUEUE), defaultDestination(MessageQueueIF::NO_QUEUE),
@ -37,6 +37,9 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize)
// Successful mq_open call // Successful mq_open call
this->id = tempId; this->id = tempId;
} }
if (args != nullptr) {
this->mqArgs = *args;
}
} }
MessageQueue::~MessageQueue() { MessageQueue::~MessageQueue() {
@ -240,9 +243,9 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
bool ignoreFault) { bool ignoreFault) {
if (message == nullptr) { if (message == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is nullptr!" << std::endl; sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is nullptr" << std::endl;
#else #else
sif::printError("MessageQueue::sendMessageFromMessageQueue: Message is nullptr!\n"); sif::printError("MessageQueue::sendMessageFromMessageQueue: Message is nullptr\n");
#endif #endif
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -256,7 +259,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
if (!ignoreFault) { if (!ignoreFault) {
InternalErrorReporterIF* internalErrorReporter = InternalErrorReporterIF* internalErrorReporter =
ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER); ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != NULL) { if (internalErrorReporter != nullptr) {
internalErrorReporter->queueMessageNotSent(); internalErrorReporter->queueMessageNotSent();
} }
} }

View File

@ -6,6 +6,7 @@
#include "fsfw/internalerror/InternalErrorReporterIF.h" #include "fsfw/internalerror/InternalErrorReporterIF.h"
#include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw/ipc/MessageQueueMessage.h"
#include "fsfw/ipc/definitions.h"
/** /**
* @brief This class manages sending and receiving of message queue messages. * @brief This class manages sending and receiving of message queue messages.
* *
@ -42,7 +43,8 @@ class MessageQueue : public MessageQueueIF {
* This should be left default. * This should be left default.
*/ */
MessageQueue(uint32_t messageDepth = 3, MessageQueue(uint32_t messageDepth = 3,
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
MqArgs* args = nullptr);
/** /**
* @brief The destructor deletes the formerly created message queue. * @brief The destructor deletes the formerly created message queue.
* @details This is accomplished by using the delete call provided by the operating system. * @details This is accomplished by using the delete call provided by the operating system.
@ -184,6 +186,8 @@ class MessageQueue : public MessageQueueIF {
*/ */
char name[16]; char name[16];
MqArgs mqArgs = {};
static uint16_t queueCounter; static uint16_t queueCounter;
const size_t maxMessageSize; const size_t maxMessageSize;

View File

@ -28,8 +28,9 @@ QueueFactory::QueueFactory() {}
QueueFactory::~QueueFactory() {} QueueFactory::~QueueFactory() {}
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
return new MessageQueue(messageDepth, maxMessageSize); MqArgs* args) {
return new MessageQueue(messageDepth, maxMessageSize, args);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }

View File

@ -6,7 +6,7 @@
#include "fsfw/osal/rtems/RtemsBasic.h" #include "fsfw/osal/rtems/RtemsBasic.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size, MqArgs* args)
: id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) { : id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
rtems_name name = ('Q' << 24) + (queueCounter++ << 8); rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
rtems_status_code status = rtems_status_code status =

View File

@ -5,6 +5,7 @@
#include "fsfw/internalerror/InternalErrorReporterIF.h" #include "fsfw/internalerror/InternalErrorReporterIF.h"
#include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/ipc/MessageQueueMessage.h" #include "fsfw/ipc/MessageQueueMessage.h"
#include "fsfw/ipc/definitions.h"
/** /**
* @brief This class manages sending and receiving of message queue messages. * @brief This class manages sending and receiving of message queue messages.
@ -34,7 +35,8 @@ class MessageQueue : public MessageQueueIF {
* This should be left default. * This should be left default.
*/ */
MessageQueue(size_t message_depth = 3, MessageQueue(size_t message_depth = 3,
size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE); size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE,
MqArgs* args = nullptr);
/** /**
* @brief The destructor deletes the formerly created message queue. * @brief The destructor deletes the formerly created message queue.
* @details This is accomplished by using the delete call provided by the operating system. * @details This is accomplished by using the delete call provided by the operating system.

View File

@ -49,8 +49,9 @@ QueueFactory::QueueFactory() {}
QueueFactory::~QueueFactory() {} QueueFactory::~QueueFactory() {}
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
return new MessageQueue(messageDepth, maxMessageSize); MqArgs* args) {
return new MessageQueue(messageDepth, maxMessageSize, args);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }

View File

@ -66,7 +66,7 @@ class HasParametersIF {
* @param newValues * @param newValues
* @param startAtIndex Linear index, runs left to right, top to bottom for * @param startAtIndex Linear index, runs left to right, top to bottom for
* matrix indexes. * matrix indexes.
* @return * @return RETURN_OK if parameter is valid and a set function of the parameter wrapper was called.
*/ */
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier, virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,

View File

@ -211,9 +211,13 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
if (data == nullptr) { if (data == nullptr) {
#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable!" << std::endl; sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable or "
"data pointer not set"
<< std::endl;
#else #else
sif::printWarning("ParameterWrapper::copyFrom: Called on read-only variable!\n"); sif::printWarning(
"ParameterWrapper::copyFrom: Called on read-only variable "
"or data pointer not set\n");
#endif #endif
#endif /* FSFW_VERBOSE_LEVEL >= 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */
return READONLY; return READONLY;
@ -222,9 +226,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
if (from->readonlyData == nullptr) { if (from->readonlyData == nullptr) {
#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ParameterWrapper::copyFrom: Source not set!" << std::endl; sif::warning << "ParameterWrapper::copyFrom: Source not set" << std::endl;
#else #else
sif::printWarning("ParameterWrapper::copyFrom: Source not set!\n"); sif::printWarning("ParameterWrapper::copyFrom: Source not set\n");
#endif #endif
#endif /* FSFW_VERBOSE_LEVEL >= 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */
return SOURCE_NOT_SET; return SOURCE_NOT_SET;
@ -233,9 +237,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
if (type != from->type) { if (type != from->type) {
#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch!" << std::endl; sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch" << std::endl;
#else #else
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch!\n"); sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch\n");
#endif #endif
#endif /* FSFW_VERBOSE_LEVEL >= 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */
return DATATYPE_MISSMATCH; return DATATYPE_MISSMATCH;
@ -245,9 +249,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
if (rows == 0 or columns == 0) { if (rows == 0 or columns == 0) {
#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero!" << std::endl; sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero" << std::endl;
#else #else
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero!\n"); sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero\n");
#endif #endif
#endif /* FSFW_VERBOSE_LEVEL >= 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */
return COLUMN_OR_ROWS_ZERO; return COLUMN_OR_ROWS_ZERO;

View File

@ -34,14 +34,14 @@ class Fuse : public SystemObject,
}; };
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT( //! PSS detected that current on a fuse is totally out of bounds.
1, severity::LOW); //!< PSS detected that current on a fuse is totally out of bounds. static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(1, severity::LOW);
static const Event FUSE_WENT_OFF = //! PSS detected a fuse that went off.
MAKE_EVENT(2, severity::LOW); //!< PSS detected a fuse that went off. static const Event FUSE_WENT_OFF = MAKE_EVENT(2, severity::LOW);
static const Event POWER_ABOVE_HIGH_LIMIT = //! PSS detected a fuse that violates its limits.
MAKE_EVENT(4, severity::LOW); //!< PSS detected a fuse that violates its limits. static const Event POWER_ABOVE_HIGH_LIMIT = MAKE_EVENT(4, severity::LOW);
static const Event POWER_BELOW_LOW_LIMIT = //! PSS detected a fuse that violates its limits.
MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits. static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW);
typedef std::list<PowerComponentIF *> DeviceList; typedef std::list<PowerComponentIF *> DeviceList;
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids, Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,

View File

@ -15,7 +15,9 @@ PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, Def
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh), limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount, voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) { limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) {
commandQueue = QueueFactory::instance()->createMessageQueue(); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue(
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); } PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }

View File

@ -1,6 +1,7 @@
#ifndef FSFW_POWER_POWERSWITCHIF_H_ #ifndef FSFW_POWER_POWERSWITCHIF_H_
#define FSFW_POWER_POWERSWITCHIF_H_ #define FSFW_POWER_POWERSWITCHIF_H_
#include "definitions.h"
#include "../events/Event.h" #include "../events/Event.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
/** /**
@ -37,7 +38,7 @@ class PowerSwitchIF : public HasReturnvaluesIF {
* @param switchNr * @param switchNr
* @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON * @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
*/ */
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const = 0; virtual void sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) const = 0;
/** /**
* Sends a command to the Power Unit to enable a certain fuse. * Sends a command to the Power Unit to enable a certain fuse.
*/ */
@ -51,7 +52,7 @@ class PowerSwitchIF : public HasReturnvaluesIF {
* - @c SWITCH_OFF if the specified switch is off. * - @c SWITCH_OFF if the specified switch is off.
* - @c RETURN_FAILED if an error occured * - @c RETURN_FAILED if an error occured
*/ */
virtual ReturnValue_t getSwitchState(uint8_t switchNr) const = 0; virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const = 0;
/** /**
* get state of a fuse. * get state of a fuse.
* @param fuseNr * @param fuseNr

View File

@ -1,19 +1,12 @@
#include "definitions.h"
#include "fsfw/power/PowerSwitcher.h" #include "fsfw/power/PowerSwitcher.h"
#include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2, PowerSwitcher::PowerSwitcher(PowerSwitchIF* switcher, power::Switch_t setSwitch1,
PowerSwitcher::State_t setStartState) power::Switch_t setSwitch2, PowerSwitcher::State_t setStartState)
: state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {} : power(switcher), state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {}
ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) {
power = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitchId);
if (power == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PowerSwitcher::getStateOfSwitches() { ReturnValue_t PowerSwitcher::getStateOfSwitches() {
SwitchReturn_t result = howManySwitches(); SwitchReturn_t result = howManySwitches();
@ -52,18 +45,37 @@ void PowerSwitcher::commandSwitches(ReturnValue_t onOff) {
return; return;
} }
void PowerSwitcher::turnOn() { void PowerSwitcher::turnOn(bool checkCurrentState) {
if(checkCurrentState) {
if(getStateOfSwitches() == PowerSwitchIF::SWITCH_ON) {
state = SWITCH_IS_ON;
return;
}
}
commandSwitches(PowerSwitchIF::SWITCH_ON); commandSwitches(PowerSwitchIF::SWITCH_ON);
state = WAIT_ON; state = WAIT_ON;
} }
void PowerSwitcher::turnOff() { void PowerSwitcher::turnOff(bool checkCurrentState) {
if(checkCurrentState) {
if(getStateOfSwitches() == PowerSwitchIF::SWITCH_OFF) {
state = SWITCH_IS_OFF;
return;
}
}
commandSwitches(PowerSwitchIF::SWITCH_OFF); commandSwitches(PowerSwitchIF::SWITCH_OFF);
state = WAIT_OFF; state = WAIT_OFF;
} }
bool PowerSwitcher::active() {
if(state == WAIT_OFF or state == WAIT_ON) {
return true;
}
return false;
}
PowerSwitcher::SwitchReturn_t PowerSwitcher::howManySwitches() { PowerSwitcher::SwitchReturn_t PowerSwitcher::howManySwitches() {
if (secondSwitch == NO_SWITCH) { if (secondSwitch == power::NO_SWITCH) {
return ONE_SWITCH; return ONE_SWITCH;
} else { } else {
return TWO_SWITCHES; return TWO_SWITCHES;

View File

@ -14,28 +14,28 @@ class PowerSwitcher : public HasReturnvaluesIF {
SWITCH_IS_OFF, SWITCH_IS_OFF,
SWITCH_IS_ON, SWITCH_IS_ON,
}; };
State_t state;
static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER; static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER;
static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1); static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1);
static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2); static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2);
PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH, PowerSwitcher(PowerSwitchIF* switcher, uint8_t setSwitch1, uint8_t setSwitch2 = power::NO_SWITCH,
State_t setStartState = SWITCH_IS_OFF); State_t setStartState = SWITCH_IS_OFF);
ReturnValue_t initialize(object_id_t powerSwitchId); void turnOn(bool checkCurrentState = true);
void turnOn(); void turnOff(bool checkCurrentState = true);
void turnOff(); bool active();
void doStateMachine(); void doStateMachine();
State_t getState(); State_t getState();
ReturnValue_t checkSwitchState(); ReturnValue_t checkSwitchState();
uint32_t getSwitchDelay(); uint32_t getSwitchDelay();
uint8_t getFirstSwitch() const; power::Switch_t getFirstSwitch() const;
uint8_t getSecondSwitch() const; power::Switch_t getSecondSwitch() const;
private: private:
uint8_t firstSwitch;
uint8_t secondSwitch;
PowerSwitchIF* power = nullptr; PowerSwitchIF* power = nullptr;
State_t state;
power::Switch_t firstSwitch = power::NO_SWITCH;
power::Switch_t secondSwitch = power::NO_SWITCH;
static const uint8_t NO_SWITCH = 0xFF;
enum SwitchReturn_t { ONE_SWITCH = 1, TWO_SWITCHES = 2 }; enum SwitchReturn_t { ONE_SWITCH = 1, TWO_SWITCHES = 2 };
ReturnValue_t getStateOfSwitches(); ReturnValue_t getStateOfSwitches();
void commandSwitches(ReturnValue_t onOff); void commandSwitches(ReturnValue_t onOff);

View File

@ -0,0 +1,13 @@
#ifndef FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
#define FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
#include <cstdint>
namespace power {
using Switch_t = uint8_t;
static constexpr Switch_t NO_SWITCH = 0xFF;
}
#endif /* FSFW_SRC_FSFW_POWER_DEFINITIONS_H_ */

View File

@ -16,7 +16,9 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
apid(apid), apid(apid),
serviceId(serviceId), serviceId(serviceId),
targetDestination(targetDestination) { targetDestination(targetDestination) {
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
tmQueue = QueueFactory::instance()->createMessageQueue(
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
Service1TelecommandVerification::~Service1TelecommandVerification() { Service1TelecommandVerification::~Service1TelecommandVerification() {

View File

@ -12,7 +12,9 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, uint16_t ap
uint32_t messageQueueDepth) uint32_t messageQueueDepth)
: PusServiceBase(objectId, apid, serviceId), : PusServiceBase(objectId, apid, serviceId),
maxNumberReportsPerCycle(maxNumberReportsPerCycle) { maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
eventQueue = QueueFactory::instance()->createMessageQueue(
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
Service5EventReporting::~Service5EventReporting() { Service5EventReporting::~Service5EventReporting() {
@ -36,9 +38,6 @@ ReturnValue_t Service5EventReporting::performService() {
} }
} }
} }
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Service5EventReporting::generateEventReport: Too many events" << std::endl;
#endif
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -87,7 +86,7 @@ ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) {
// to be registered to the event manager to listen for events. // to be registered to the event manager to listen for events.
ReturnValue_t Service5EventReporting::initialize() { ReturnValue_t Service5EventReporting::initialize() {
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER); EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == NULL) { if (manager == nullptr) {
return RETURN_FAILED; return RETURN_FAILED;
} }
// register Service 5 as listener for events // register Service 5 as listener for events

View File

@ -41,7 +41,7 @@
class Service5EventReporting : public PusServiceBase { class Service5EventReporting : public PusServiceBase {
public: public:
Service5EventReporting(object_id_t objectId, uint16_t apid, uint8_t serviceId, Service5EventReporting(object_id_t objectId, uint16_t apid, uint8_t serviceId,
size_t maxNumberReportsPerCycle = 10, uint32_t messageQueueDepth = 10); size_t maxNumberReportsPerCycle, uint32_t messageQueueDepth);
virtual ~Service5EventReporting(); virtual ~Service5EventReporting();
/*** /***

View File

@ -6,10 +6,10 @@
class Service9TimeManagement : public PusServiceBase { class Service9TimeManagement : public PusServiceBase {
public: public:
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
static constexpr Event CLOCK_SET = //!< Clock has been set. P1: New Uptime. P2: Old Uptime
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
static constexpr Event CLOCK_SET_FAILURE = //!< Clock could not be set. P1: Returncode.
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode. static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9; static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;

View File

@ -12,8 +12,12 @@
#include "modes/ModeDefinitions.h" #include "modes/ModeDefinitions.h"
/** /**
* @brief TODO: documentation missing * @brief This class extends the SubsystemBase to perform the management of mode tables
* and mode sequences
* @details * @details
* This class is able to use mode tables and sequences to command all its children into the
* right mode. Fallback sequences can be used to handle failed transitions or have a fallback
* in case a component can't keep its current mode.
*/ */
class Subsystem : public SubsystemBase, public HasModeSequenceIF { class Subsystem : public SubsystemBase, public HasModeSequenceIF {
public: public:

View File

@ -8,11 +8,13 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t
uint16_t commandQueueDepth) uint16_t commandQueueDepth)
: SystemObject(setObjectId), : SystemObject(setObjectId),
mode(initialMode), mode(initialMode),
commandQueue(QueueFactory::instance()->createMessageQueue(commandQueueDepth,
CommandMessage::MAX_MESSAGE_SIZE)),
healthHelper(this, setObjectId), healthHelper(this, setObjectId),
modeHelper(this), modeHelper(this),
parentId(parent) {} parentId(parent) {
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue(
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
}
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); } SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
@ -31,8 +33,9 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
info.mode = MODE_OFF; info.mode = MODE_OFF;
} }
} else { } else {
// intentional to force an initial command during system startup
info.commandQueue = child->getCommandQueue(); info.commandQueue = child->getCommandQueue();
info.mode = -1; // intentional to force an initial command during system startup info.mode = HasModesIF::MODE_UNDEFINED;
} }
info.submode = SUBMODE_NONE; info.submode = SUBMODE_NONE;

View File

@ -15,7 +15,14 @@
/** /**
* @defgroup subsystems Subsystem Objects * @defgroup subsystems Subsystem Objects
* Contains all Subsystem and Assemblies * All Subsystem and Assemblies can derive from this class. It contains helper classes to
* perform mode and health handling, which allows OBSW developers to build a mode tree for
* the whole satellite.
*
* Aside from setting up a mode tree and being able to executing mode tables, this class does not
* provide an implementation on what to do with the features. To build a mode tree, helper classes
* like the #AssemblyBase or the #Subsystem class extend and use the functionality of the base
* class.
*/ */
class SubsystemBase : public SystemObject, class SubsystemBase : public SystemObject,
public HasModesIF, public HasModesIF,
@ -96,6 +103,7 @@ class SubsystemBase : public SystemObject,
Submode_t targetSubmode); Submode_t targetSubmode);
/** /**
* This function takes care of sending all according mode commands specified inside a mode table.
* We need to know the target Submode, as children are able to inherit the submode * We need to know the target Submode, as children are able to inherit the submode
* Still, we have a default for all child implementations which do not use submode inheritance * Still, we have a default for all child implementations which do not use submode inheritance
*/ */
@ -123,11 +131,11 @@ class SubsystemBase : public SystemObject,
virtual void performChildOperation() = 0; virtual void performChildOperation() = 0;
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) = 0; uint32_t *msToReachTheMode) override = 0;
virtual void startTransition(Mode_t mode, Submode_t submode) = 0; virtual void startTransition(Mode_t mode, Submode_t submode) override = 0;
virtual void getMode(Mode_t *mode, Submode_t *submode); virtual void getMode(Mode_t *mode, Submode_t *submode) override;
virtual void setToExternalControl(); virtual void setToExternalControl();

View File

@ -5,7 +5,9 @@
#include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/tmtcservices/TmTcMessage.h"
TcDistributor::TcDistributor(object_id_t objectId) : SystemObject(objectId) { TcDistributor::TcDistributor(object_id_t objectId) : SystemObject(objectId) {
tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS); auto mqArgs = MqArgs(objectId);
tcQueue = QueueFactory::instance()->createMessageQueue(
DISTRIBUTER_MAX_PACKETS, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
TcDistributor::~TcDistributor() { QueueFactory::instance()->deleteMessageQueue(tcQueue); } TcDistributor::~TcDistributor() { QueueFactory::instance()->deleteMessageQueue(tcQueue); }

View File

@ -4,14 +4,13 @@
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid, AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
ThermalModuleIF *thermalModule) ThermalModuleIF *thermalModule)
: SystemObject(setObjectid), : SystemObject(setObjectid), healthHelper(this, setObjectid), parameterHelper(this) {
commandQueue(NULL), if (thermalModule != nullptr) {
healthHelper(this, setObjectid),
parameterHelper(this) {
if (thermalModule != NULL) {
thermalModule->registerSensor(this); thermalModule->registerSensor(this);
} }
commandQueue = QueueFactory::instance()->createMessageQueue(); auto mqArgs = MqArgs(setObjectid, static_cast<void *>(this));
commandQueue = QueueFactory::instance()->createMessageQueue(
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
AbstractTemperatureSensor::~AbstractTemperatureSensor() { AbstractTemperatureSensor::~AbstractTemperatureSensor() {

View File

@ -51,7 +51,7 @@ class AbstractTemperatureSensor : public HasHealthIF,
HasHealthIF::HealthState getHealth(); HasHealthIF::HealthState getHealth();
protected: protected:
MessageQueueIF* commandQueue; MessageQueueIF* commandQueue = nullptr;
HealthHelper healthHelper; HealthHelper healthHelper;
ParameterHelper parameterHelper; ParameterHelper parameterHelper;

View File

@ -12,7 +12,9 @@ Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1)
switch1(switch1), switch1(switch1),
heaterOnCountdown(10800000) /*about two orbits*/, heaterOnCountdown(10800000) /*about two orbits*/,
parameterHelper(this) { parameterHelper(this) {
eventQueue = QueueFactory::instance()->createMessageQueue(); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
eventQueue = QueueFactory::instance()->createMessageQueue(
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); } Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }

View File

@ -99,6 +99,13 @@ class Clock {
*/ */
static ReturnValue_t getDateAndTime(TimeOfDay_t *time); static ReturnValue_t getDateAndTime(TimeOfDay_t *time);
/**
* Convert to time of day struct given the POSIX timeval struct
* @param from
* @param to
* @return
*/
static ReturnValue_t convertTimevalToTimeOfDay(const timeval *from, TimeOfDay_t *to);
/** /**
* Converts a time of day struct to POSIX seconds. * Converts a time of day struct to POSIX seconds.
* @param time The time of day as input * @param time The time of day as input

View File

@ -1,7 +1,9 @@
#include <ctime>
#include "fsfw/ipc/MutexGuard.h" #include "fsfw/ipc/MutexGuard.h"
#include "fsfw/timemanager/Clock.h" #include "fsfw/timemanager/Clock.h"
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval *tt) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
uint16_t leapSeconds; uint16_t leapSeconds;
ReturnValue_t result = getLeapSeconds(&leapSeconds); ReturnValue_t result = getLeapSeconds(&leapSeconds);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
@ -31,7 +33,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Clock::getLeapSeconds(uint16_t *leapSeconds_) { ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if (timeMutex == nullptr) { if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -42,9 +44,22 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t *leapSeconds_) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
struct tm* timeInfo;
timeInfo = gmtime(&from->tv_sec);
to->year = timeInfo->tm_year + 1900;
to->month = timeInfo->tm_mon + 1;
to->day = timeInfo->tm_mday;
to->hour = timeInfo->tm_hour;
to->minute = timeInfo->tm_min;
to->second = timeInfo->tm_sec;
to->usecond = from->tv_usec;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::checkOrCreateClockMutex() { ReturnValue_t Clock::checkOrCreateClockMutex() {
if (timeMutex == nullptr) { if (timeMutex == nullptr) {
MutexFactory *mutexFactory = MutexFactory::instance(); MutexFactory* mutexFactory = MutexFactory::instance();
if (mutexFactory == nullptr) { if (mutexFactory == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }

View File

@ -33,50 +33,47 @@ class TmStoreBackendIF : public HasParametersIF {
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15); static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
static const Event STORE_SEND_WRITE_FAILED = //! Initiating sending data to store failed. Low, par1:
MAKE_EVENT(0, severity::LOW); //!< Initiating sending data to store failed. Low, par1: //! returnCode, par2: integer (debug info)
//!< returnCode, par2: integer (debug info) static const Event STORE_SEND_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
static const Event STORE_WRITE_FAILED = MAKE_EVENT( //! Data was sent, but writing failed. Low, par1: returnCode, par2: 0
1, severity::LOW); //!< Data was sent, but writing failed. Low, par1: returnCode, par2: 0 static const Event STORE_WRITE_FAILED = MAKE_EVENT(1, severity::LOW);
static const Event STORE_SEND_READ_FAILED = //! Initiating reading data from store failed. Low, par1: returnCode, par2: 0
MAKE_EVENT(2, severity::LOW); //!< Initiating reading data from store failed. Low, par1: static const Event STORE_SEND_READ_FAILED = MAKE_EVENT(2, severity::LOW);
//!< returnCode, par2: 0 //! Data was requested, but access failed. Low, par1: returnCode, par2: 0
static const Event STORE_READ_FAILED = MAKE_EVENT( static const Event STORE_READ_FAILED = MAKE_EVENT(3, severity::LOW);
3, severity::LOW); //!< Data was requested, but access failed. Low, par1: returnCode, par2: 0 //! An unexpected TM packet or data message occurred. Low, par1: 0, par2: integer (debug info)
static const Event UNEXPECTED_MSG = static const Event UNEXPECTED_MSG = MAKE_EVENT(4, severity::LOW);
MAKE_EVENT(4, severity::LOW); //!< An unexpected TM packet or data message occurred. Low, //! Storing data failed. May simply be a full store. Low, par1: returnCode,
//!< par1: 0, par2: integer (debug info) //! par2: integer (sequence count of failed packet).
static const Event STORING_FAILED = MAKE_EVENT( static const Event STORING_FAILED = MAKE_EVENT(5, severity::LOW);
5, severity::LOW); //!< Storing data failed. May simply be a full store. Low, par1: //! Dumping retrieved data failed. Low, par1: returnCode,
//!< returnCode, par2: integer (sequence count of failed packet). //! par2: integer (sequence count of failed packet).
static const Event TM_DUMP_FAILED = static const Event TM_DUMP_FAILED = MAKE_EVENT(6, severity::LOW);
MAKE_EVENT(6, severity::LOW); //!< Dumping retrieved data failed. Low, par1: returnCode, //! Corrupted init data or read error. Low, par1: returnCode, par2: integer (debug info)
//!< par2: integer (sequence count of failed packet). //! Store was not initialized. Starts empty. Info, parameters both zero.
static const Event STORE_INIT_FAILED = static const Event STORE_INIT_FAILED = MAKE_EVENT(7, severity::LOW);
MAKE_EVENT(7, severity::LOW); //!< Corrupted init data or read error. Low, par1: returnCode, //! Data was read out, but it is inconsistent. Low par1:
//!< par2: integer (debug info) //! Memory address of corruption, par2: integer (debug info)
static const Event STORE_INIT_EMPTY = MAKE_EVENT( static const Event STORE_INIT_EMPTY = MAKE_EVENT(8, severity::INFO);
8, severity::INFO); //!< Store was not initialized. Starts empty. Info, parameters both zero.
static const Event STORE_CONTENT_CORRUPTED = static const Event STORE_CONTENT_CORRUPTED = MAKE_EVENT(9, severity::LOW);
MAKE_EVENT(9, severity::LOW); //!< Data was read out, but it is inconsistent. Low par1: //! Info event indicating the store will be initialized, either at boot or after IOB switch.
//!< Memory address of corruption, par2: integer (debug info) //! Info. pars: 0
static const Event STORE_INITIALIZE = static const Event STORE_INITIALIZE = MAKE_EVENT(10, severity::INFO);
MAKE_EVENT(10, severity::INFO); //!< Info event indicating the store will be initialized, //! Info event indicating the store was successfully initialized, either at boot or after
//!< either at boot or after IOB switch. Info. pars: 0 //! IOB switch. Info. pars: 0
static const Event INIT_DONE = MAKE_EVENT( static const Event INIT_DONE = MAKE_EVENT(11, severity::INFO);
11, severity::INFO); //!< Info event indicating the store was successfully initialized, //! Info event indicating that dumping finished successfully.
//!< either at boot or after IOB switch. Info. pars: 0 //! par1: Number of dumped packets. par2: APID/SSC (16bits each)
static const Event DUMP_FINISHED = MAKE_EVENT( static const Event DUMP_FINISHED = MAKE_EVENT(12, severity::INFO);
12, severity::INFO); //!< Info event indicating that dumping finished successfully. par1: //! Info event indicating that deletion finished successfully.
//!< Number of dumped packets. par2: APID/SSC (16bits each) //! par1:Number of deleted packets. par2: APID/SSC (16bits each)
static const Event DELETION_FINISHED = MAKE_EVENT( static const Event DELETION_FINISHED = MAKE_EVENT(13, severity::INFO);
13, severity::INFO); //!< Info event indicating that deletion finished successfully. par1: //! Info event indicating that something went wrong during deletion. pars: 0
//!< Number of deleted packets. par2: APID/SSC (16bits each) static const Event DELETION_FAILED = MAKE_EVENT(14, severity::LOW);
static const Event DELETION_FAILED = MAKE_EVENT( //! Info that the a auto catalog report failed
14, static const Event AUTO_CATALOGS_SENDING_FAILED = MAKE_EVENT(15, severity::INFO);
severity::LOW); //!< Info event indicating that something went wrong during deletion. pars: 0
static const Event AUTO_CATALOGS_SENDING_FAILED =
MAKE_EVENT(15, severity::INFO); //!< Info that the a auto catalog report failed
virtual ~TmStoreBackendIF() {} virtual ~TmStoreBackendIF() {}

View File

@ -20,8 +20,10 @@ CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t a
service(service), service(service),
timeoutSeconds(commandTimeoutSeconds), timeoutSeconds(commandTimeoutSeconds),
commandMap(numberOfParallelCommands) { commandMap(numberOfParallelCommands) {
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth); auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth); size_t mqSz = MessageQueueMessage::MAX_MESSAGE_SIZE;
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
} }
void CommandingServiceBase::setPacketSource(object_id_t packetSource) { void CommandingServiceBase::setPacketSource(object_id_t packetSource) {

View File

@ -13,7 +13,9 @@ object_id_t PusServiceBase::packetDestination = 0;
PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId) PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId)
: SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) { : SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) {
requestQueue = QueueFactory::instance()->createMessageQueue(PUS_SERVICE_MAX_RECEPTION); auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
requestQueue = QueueFactory::instance()->createMessageQueue(
PUS_SERVICE_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
PusServiceBase::~PusServiceBase() { QueueFactory::instance()->deleteMessageQueue(requestQueue); } PusServiceBase::~PusServiceBase() { QueueFactory::instance()->deleteMessageQueue(requestQueue); }

View File

@ -15,7 +15,9 @@ TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, object_i
tcDestination(tcDestination) tcDestination(tcDestination)
{ {
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(
TMTC_RECEPTION_QUEUE_DEPTH, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
} }
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); } TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
@ -172,15 +174,18 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
} }
if (tmFifo->full()) { if (tmFifo->full()) {
if (warningSwitch) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number " sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!" "of stored packet IDs reached!"
<< std::endl; << std::endl;
#else #else
sif::printWarning( sif::printWarning(
"TmTcBridge::storeDownlinkData: TM downlink max. number " "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!\n"); "of stored packet IDs reached!\n");
#endif #endif
warningSwitch = true;
}
if (overwriteOld) { if (overwriteOld) {
tmFifo->retrieve(&storeId); tmFifo->retrieve(&storeId);
tmStore->deleteData(storeId); tmStore->deleteData(storeId);

View File

@ -72,6 +72,8 @@ class TmTcBridge : public AcceptsTelemetryIF,
virtual uint16_t getIdentifier() override; virtual uint16_t getIdentifier() override;
virtual MessageQueueId_t getRequestQueue() override; virtual MessageQueueId_t getRequestQueue() override;
bool warningSwitch = true;
protected: protected:
//! Cached for initialize function. //! Cached for initialize function.
object_id_t tmStoreId = objects::NO_OBJECT; object_id_t tmStoreId = objects::NO_OBJECT;

View File

@ -73,7 +73,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
REQUIRE(result != CommandExecutor::COMMAND_ERROR); REQUIRE(result != CommandExecutor::COMMAND_ERROR);
// This ensures that the tests do not block indefinitely // This ensures that the tests do not block indefinitely
usleep(500); usleep(500);
REQUIRE(limitIdx < 500); REQUIRE(limitIdx < 50000);
} }
limitIdx = 0; limitIdx = 0;
CHECK(bytesHaveBeenRead == true); CHECK(bytesHaveBeenRead == true);