Compare commits
169 Commits
action-upd
...
85a6e4b129
Author | SHA1 | Date | |
---|---|---|---|
85a6e4b129 | |||
f94bc02b6c | |||
5bda877d97 | |||
51e7f1c2f2 | |||
a11d7455df | |||
4dc903fe20 | |||
3325cc18fc | |||
43917d98c0 | |||
e3ffcae3e0 | |||
0677de39aa | |||
aded4fae1e | |||
7df51f7202 | |||
7530c44849 | |||
e4c6a69f77 | |||
761a0c9bac | |||
518666f822 | |||
318cd8e244 | |||
1bc7a91869 | |||
8e26e287c3 | |||
ce2f7c4fdf | |||
b3d2d440d7 | |||
![]() |
fbf9626fde | ||
29cf8c9009 | |||
61d0815de8 | |||
127fbeb980 | |||
c2581ff4f5 | |||
7b6f68c509 | |||
![]() |
532607bf8f | ||
![]() |
a230dc4313 | ||
3ea9f999b7 | |||
79f3c7324a | |||
60972228ef | |||
6ea1eabb2d | |||
283a37dccc | |||
acf0cdfba3 | |||
a01002aa5d | |||
![]() |
b52f19254b | ||
79615e47e4 | |||
e6130263ef | |||
6895dbcc81 | |||
4b5e3e70f7 | |||
bbe21e7e89 | |||
2823420c46 | |||
6dd6f28db0 | |||
d791fc87b7 | |||
16f2fa9327 | |||
927041209b | |||
![]() |
bac8b40880 | ||
![]() |
caf78835b2 | ||
b6ed45a85c | |||
ddc1cdb1f5 | |||
543daaa95a | |||
38c87fdeb2 | |||
5ca5fe4040 | |||
![]() |
1b7e0371c3 | ||
![]() |
d4ade5e885 | ||
fec5f83f4f | |||
17262a1da9 | |||
b5d6b9745f | |||
60639f56dc | |||
3aa0bbde68 | |||
97bc71a3ff | |||
06577ed78a | |||
b27f3b84aa | |||
9509847b84 | |||
45b51f9ac8 | |||
d5ff6da40b | |||
e498136273 | |||
47d158156b | |||
d63c01b96f | |||
3b497dbb8d | |||
bf733162eb | |||
73f0b9c0dc | |||
b5e55f64b0 | |||
7ca6d1a695 | |||
cc3210f366 | |||
155d66e534 | |||
d4c76a7e46 | |||
dba3c27b99 | |||
202cfc6dbb | |||
84f95e8d76 | |||
6de4798805 | |||
82a645deba | |||
8b1c277c58 | |||
5f23f709cc | |||
a7cb2d4354 | |||
7571987a1d | |||
d6c1041133 | |||
3c53e2c259 | |||
45f0d7fd45 | |||
aebab4c73c | |||
c3c2e1c0dd | |||
4e6c1cb72a | |||
e2eb6a46b6 | |||
75c56280ad | |||
0ccaf27fcb | |||
e05e203c83 | |||
ac036b2a70 | |||
2d9216ba19 | |||
2fed161eff | |||
4cf2a384f3 | |||
27267b7cb0 | |||
505e00c067 | |||
68225586d2 | |||
6d825a1aa6 | |||
fa73ad6731 | |||
331aa9442d | |||
28b28b5684 | |||
afd3a942e2 | |||
729bcc4aaf | |||
6e0b90696d | |||
![]() |
eacb4ac407 | ||
09c1918c1f | |||
123f2ff360 | |||
7ce2c1b624 | |||
4747e54c5d | |||
2e230daa14 | |||
e909c6b6f7 | |||
d88d7c938f | |||
389641f8fd | |||
b440c30223 | |||
3966b656e9 | |||
3a5881a0cb | |||
1e982ec00b | |||
701135e2a6 | |||
19f8e41c7f | |||
c4a055986c | |||
d74a373f1d | |||
cf69af4e7e | |||
508979d32d | |||
0d66569687 | |||
a5871ed0b1 | |||
a12e98d948 | |||
bd05afbddd | |||
b3482eba24 | |||
9e92afbf07 | |||
0d6d44f72f | |||
81f5b0c3bf | |||
062e93fd88 | |||
c20bf31d5d | |||
![]() |
3c06d2dbbb | ||
![]() |
018d814f29 | ||
![]() |
c0648a789b | ||
![]() |
9579e94a71 | ||
![]() |
235fd79dfb | ||
83635d3667 | |||
581ae4c990 | |||
32a9e0c704 | |||
940c53eba6 | |||
0d4bd856bd | |||
b7f6a6961b | |||
a910a05541 | |||
973996e102 | |||
b3aee76d91 | |||
b3151a0ba0 | |||
fca48257b7 | |||
8f95b03e6a | |||
527dba9a9d | |||
22cd38fffd | |||
1a518109d0 | |||
8030d9ac1b | |||
992c05df56 | |||
6698d283b6 | |||
33386550cf | |||
3a65c0db91 | |||
41614303d7 | |||
783176848a | |||
07cb980e06 | |||
d8c5bd125e |
27
hal/src/fsfw_hal/linux/gpio/Gpio.h
Normal file
27
hal/src/fsfw_hal/linux/gpio/Gpio.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
||||||
|
#define FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
||||||
|
|
||||||
|
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||||
|
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Additional abstraction layer for handling GPIOs.
|
||||||
|
*
|
||||||
|
* @author J. Meier
|
||||||
|
*/
|
||||||
|
class Gpio {
|
||||||
|
public:
|
||||||
|
Gpio(gpioId_t gpioId, GpioIF* gpioIF) : gpioId(gpioId), gpioIF(gpioIF) {
|
||||||
|
if (gpioIF == nullptr) {
|
||||||
|
sif::error << "Gpio::Gpio: Invalid GpioIF" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReturnValue_t pullHigh() { return gpioIF->pullHigh(gpioId); }
|
||||||
|
ReturnValue_t pullLow() { return gpioIF->pullLow(gpioId); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
gpioId_t gpioId = gpio::NO_GPIO;
|
||||||
|
GpioIF* gpioIF = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_ */
|
@@ -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;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#include "fsfw_hal/linux/uart/UartCookie.h"
|
#include "UartCookie.h"
|
||||||
|
|
||||||
#include <fsfw/serviceinterface.h>
|
#include <fsfw/serviceinterface.h>
|
||||||
|
|
||||||
|
@@ -16,8 +16,8 @@ class CommandActionHelper {
|
|||||||
public:
|
public:
|
||||||
CommandActionHelper(CommandsActionsIF* owner);
|
CommandActionHelper(CommandsActionsIF* owner);
|
||||||
virtual ~CommandActionHelper();
|
virtual ~CommandActionHelper();
|
||||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
|
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||||
uint32_t size);
|
const uint8_t* data = nullptr, uint32_t size = 0);
|
||||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
ReturnValue_t handleReply(CommandMessage* reply);
|
ReturnValue_t handleReply(CommandMessage* reply);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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); }
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||||
PoolDataSetBase.cpp
|
PoolDataSetBase.cpp
|
||||||
PoolEntry.cpp
|
PoolEntry.cpp
|
||||||
)
|
)
|
@@ -7,24 +7,26 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, bool setValid)
|
PoolEntry<T>::PoolEntry(uint8_t len, bool setValid): length(len), valid(setValid) {
|
||||||
: length(static_cast<uint8_t>(initValue.size())), valid(setValid) {
|
this->address = new T[this->length]();
|
||||||
this->address = new T[this->length];
|
std::memset(this->address, 0, this->getByteSize());
|
||||||
if (initValue.size() == 0) {
|
}
|
||||||
std::memset(this->address, 0, this->getByteSize());
|
|
||||||
} else {
|
template <typename T>
|
||||||
std::copy(initValue.begin(), initValue.end(), this->address);
|
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValues, bool setValid)
|
||||||
|
: length(static_cast<uint8_t>(initValues.size())), valid(setValid) {
|
||||||
|
this->address = new T[this->length]();
|
||||||
|
if (initValues.size() > 0) {
|
||||||
|
std::copy(initValues.begin(), initValues.end(), this->address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
PoolEntry<T>::PoolEntry(T* initValue, uint8_t setLength, bool setValid)
|
PoolEntry<T>::PoolEntry(T* initValue, uint8_t setLength, bool setValid)
|
||||||
: length(setLength), valid(setValid) {
|
: length(setLength), valid(setValid) {
|
||||||
this->address = new T[this->length];
|
this->address = new T[this->length]();
|
||||||
if (initValue != nullptr) {
|
if (initValue != nullptr) {
|
||||||
std::memcpy(this->address, initValue, this->getByteSize());
|
std::memcpy(this->address, initValue, this->getByteSize());
|
||||||
} else {
|
|
||||||
std::memset(this->address, 0, this->getByteSize());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,6 +33,9 @@ class PoolEntry : public PoolEntryIF {
|
|||||||
"instead! The ECSS standard defines a boolean as a one bit "
|
"instead! The ECSS standard defines a boolean as a one bit "
|
||||||
"field. Therefore it is preferred to store a boolean as an "
|
"field. Therefore it is preferred to store a boolean as an "
|
||||||
"uint8_t");
|
"uint8_t");
|
||||||
|
|
||||||
|
PoolEntry(uint8_t len = 1, bool setValid = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief In the classe's constructor, space is allocated on the heap and
|
* @brief In the classe's constructor, space is allocated on the heap and
|
||||||
* potential initialization values are copied to that space.
|
* potential initialization values are copied to that space.
|
||||||
@@ -49,7 +52,7 @@ class PoolEntry : public PoolEntryIF {
|
|||||||
* @param setValid
|
* @param setValid
|
||||||
* Sets the initialization flag. It is invalid by default.
|
* Sets the initialization flag. It is invalid by default.
|
||||||
*/
|
*/
|
||||||
PoolEntry(std::initializer_list<T> initValue = {0}, bool setValid = false);
|
PoolEntry(std::initializer_list<T> initValue, bool setValid = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief In the classe's constructor, space is allocated on the heap and
|
* @brief In the classe's constructor, space is allocated on the heap and
|
||||||
|
@@ -162,6 +162,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
object_id_t getCreatorObjectId();
|
object_id_t getCreatorObjectId();
|
||||||
|
|
||||||
bool getReportingEnabled() const;
|
bool getReportingEnabled() const;
|
||||||
|
void setReportingEnabled(bool enabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current periodic HK generation interval this set
|
* Returns the current periodic HK generation interval this set
|
||||||
@@ -189,7 +190,6 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* Used for periodic generation.
|
* Used for periodic generation.
|
||||||
*/
|
*/
|
||||||
bool reportingEnabled = false;
|
bool reportingEnabled = false;
|
||||||
void setReportingEnabled(bool enabled);
|
|
||||||
|
|
||||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||||
uint8_t nonDiagIntervalFactor = 5);
|
uint8_t nonDiagIntervalFactor = 5);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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_ */
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -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_ */
|
||||||
|
@@ -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,18 @@ 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);
|
||||||
@@ -352,14 +362,12 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case _MODE_WAIT_OFF: {
|
case _MODE_WAIT_OFF: {
|
||||||
uint32_t currentUptime;
|
|
||||||
Clock::getUptime(¤tUptime);
|
|
||||||
|
|
||||||
if (powerSwitcher == nullptr) {
|
if (powerSwitcher == nullptr) {
|
||||||
setMode(MODE_OFF);
|
setMode(MODE_OFF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
uint32_t currentUptime;
|
||||||
|
Clock::getUptime(¤tUptime);
|
||||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||||
setMode(MODE_ERROR_ON);
|
setMode(MODE_ERROR_ON);
|
||||||
@@ -410,7 +418,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
|||||||
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet,
|
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet,
|
||||||
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
||||||
// No need to check, as we may try to insert multiple times.
|
// No need to check, as we may try to insert multiple times.
|
||||||
insertInCommandMap(deviceCommand);
|
insertInCommandMap(deviceCommand, hasDifferentReplyId, replyId);
|
||||||
if (hasDifferentReplyId) {
|
if (hasDifferentReplyId) {
|
||||||
return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic);
|
return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic);
|
||||||
} else {
|
} else {
|
||||||
@@ -437,11 +445,15 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
|
ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand,
|
||||||
|
bool useAlternativeReply,
|
||||||
|
DeviceCommandId_t alternativeReplyId) {
|
||||||
DeviceCommandInfo info;
|
DeviceCommandInfo info;
|
||||||
info.expectedReplies = 0;
|
info.expectedReplies = 0;
|
||||||
info.isExecuting = false;
|
info.isExecuting = false;
|
||||||
info.sendReplyTo = NO_COMMANDER;
|
info.sendReplyTo = NO_COMMANDER;
|
||||||
|
info.useAlternativeReplyId = alternativeReplyId;
|
||||||
|
info.alternativeReplyId = alternativeReplyId;
|
||||||
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
|
auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
|
||||||
if (resultPair.second) {
|
if (resultPair.second) {
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
@@ -451,12 +463,20 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) {
|
size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) {
|
||||||
DeviceReplyIter iter = deviceReplyMap.find(commandId);
|
DeviceCommandId_t replyId = NO_COMMAND_ID;
|
||||||
if (iter != deviceReplyMap.end()) {
|
DeviceCommandMap::iterator command = cookieInfo.pendingCommand;
|
||||||
return iter->second.replyLen;
|
if (command->second.useAlternativeReplyId) {
|
||||||
|
replyId = command->second.alternativeReplyId;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
replyId = commandId;
|
||||||
}
|
}
|
||||||
|
DeviceReplyIter iter = deviceReplyMap.find(replyId);
|
||||||
|
if (iter != deviceReplyMap.end()) {
|
||||||
|
if (iter->second.delayCycles != 0) {
|
||||||
|
return iter->second.replyLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
|
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
|
||||||
@@ -651,7 +671,9 @@ void DeviceHandlerBase::doGetWrite() {
|
|||||||
|
|
||||||
// We need to distinguish here, because a raw command never expects a reply.
|
// We need to distinguish here, because a raw command never expects a reply.
|
||||||
//(Could be done in eRIRM, but then child implementations need to be careful.
|
//(Could be done in eRIRM, but then child implementations need to be careful.
|
||||||
result = enableReplyInReplyMap(cookieInfo.pendingCommand);
|
DeviceCommandMap::iterator command = cookieInfo.pendingCommand;
|
||||||
|
result = enableReplyInReplyMap(command, 1, command->second.useAlternativeReplyId,
|
||||||
|
command->second.alternativeReplyId);
|
||||||
} else {
|
} else {
|
||||||
// always generate a failure event, so that FDIR knows what's up
|
// always generate a failure event, so that FDIR knows what's up
|
||||||
triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first);
|
triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first);
|
||||||
@@ -1385,6 +1407,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 +1431,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 +1515,11 @@ 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;
|
||||||
|
}
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -478,7 +481,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||||
* - @c RETURN_FAILED else.
|
* - @c RETURN_FAILED else.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand);
|
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand,
|
||||||
|
bool useAlternativeReply = false,
|
||||||
|
DeviceCommandId_t alternativeReplyId = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables a periodic reply for a given command. It sets to delay cycles to the specified
|
* Enables a periodic reply for a given command. It sets to delay cycles to the specified
|
||||||
@@ -647,6 +652,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;
|
||||||
|
|
||||||
@@ -751,6 +762,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
//! if this is != NO_COMMANDER, DHB was commanded externally and shall
|
//! if this is != NO_COMMANDER, DHB was commanded externally and shall
|
||||||
//! report everything to commander.
|
//! report everything to commander.
|
||||||
MessageQueueId_t sendReplyTo;
|
MessageQueueId_t sendReplyTo;
|
||||||
|
bool useAlternativeReplyId;
|
||||||
|
DeviceCommandId_t alternativeReplyId;
|
||||||
};
|
};
|
||||||
using DeviceCommandMap = std::map<DeviceCommandId_t, DeviceCommandInfo>;
|
using DeviceCommandMap = std::map<DeviceCommandId_t, DeviceCommandInfo>;
|
||||||
/**
|
/**
|
||||||
@@ -818,6 +831,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;
|
||||||
|
@@ -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());
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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); }
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
12
src/fsfw/ipc/definitions.h
Normal file
12
src/fsfw/ipc/definitions.h
Normal 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_ */
|
@@ -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;
|
||||||
|
@@ -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++;
|
||||||
}
|
}
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
#include "fsfw/timemanager/Clock.h"
|
#include "fsfw/timemanager/Clock.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
#include <linux/sysinfo.h>
|
#include <linux/sysinfo.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
@@ -7,12 +8,13 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <cstring>
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
|
|
||||||
uint16_t Clock::leapSeconds = 0;
|
uint16_t Clock::leapSeconds = 0;
|
||||||
MutexIF* Clock::timeMutex = NULL;
|
MutexIF* Clock::timeMutex = NULL;
|
||||||
|
|
||||||
|
void handleClockError(const char* func);
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void) {
|
uint32_t Clock::getTicksPerSecond(void) {
|
||||||
uint32_t ticks = sysconf(_SC_CLK_TCK);
|
uint32_t ticks = sysconf(_SC_CLK_TCK);
|
||||||
return ticks;
|
return ticks;
|
||||||
@@ -27,7 +29,7 @@ ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
|||||||
|
|
||||||
int status = clock_settime(CLOCK_REALTIME, &timeUnix);
|
int status = clock_settime(CLOCK_REALTIME, &timeUnix);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
// TODO errno
|
handleClockError("setClock");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@@ -39,7 +41,7 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
|||||||
timeUnix.tv_nsec = (__syscall_slong_t)time->tv_usec * 1000;
|
timeUnix.tv_nsec = (__syscall_slong_t)time->tv_usec * 1000;
|
||||||
int status = clock_settime(CLOCK_REALTIME, &timeUnix);
|
int status = clock_settime(CLOCK_REALTIME, &timeUnix);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
// TODO errno
|
handleClockError("setClock");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@@ -49,6 +51,7 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
|||||||
timespec timeUnix;
|
timespec timeUnix;
|
||||||
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
|
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
|
handleClockError("getClock_timeval");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
time->tv_sec = timeUnix.tv_sec;
|
time->tv_sec = timeUnix.tv_sec;
|
||||||
@@ -151,3 +154,15 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
|||||||
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
|
*JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. / 3600.;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleClockError(const char* func) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "Clock::" << func << ": Failed with code " << errno << ": " << strerror(errno)
|
||||||
|
<< std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("Clock::%s: Failed with code %d: %s\n", func, errno, strerror(errno));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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 =
|
||||||
|
@@ -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.
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
@@ -4,4 +4,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
|
|||||||
PowerSensor.cpp
|
PowerSensor.cpp
|
||||||
PowerSwitcher.cpp
|
PowerSwitcher.cpp
|
||||||
DummyPowerSwitcher.cpp
|
DummyPowerSwitcher.cpp
|
||||||
|
PowerSwitcherComponent.cpp
|
||||||
)
|
)
|
@@ -15,8 +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 =
|
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||||
QueueFactory::instance()->createMessageQueue(3, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
|
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
108
src/fsfw/power/PowerSwitcherComponent.cpp
Normal file
108
src/fsfw/power/PowerSwitcherComponent.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#include "PowerSwitcherComponent.h"
|
||||||
|
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
|
#include <fsfw/power/PowerSwitchIF.h>
|
||||||
|
|
||||||
|
PowerSwitcherComponent::PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power::Switch_t pwrSwitch)
|
||||||
|
: SystemObject(objectId), switcher(pwrSwitcher, pwrSwitch), modeHelper(this),
|
||||||
|
healthHelper(this, objectId) {
|
||||||
|
queue = QueueFactory::instance()->createMessageQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherComponent::performOperation(uint8_t opCode) {
|
||||||
|
ReturnValue_t result;
|
||||||
|
CommandMessage command;
|
||||||
|
|
||||||
|
for (result = queue->receiveMessage(&command); result == RETURN_OK;
|
||||||
|
result = queue->receiveMessage(&command)) {
|
||||||
|
result = healthHelper.handleHealthCommand(&command);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = modeHelper.handleModeCommand(&command);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(switcher.active()) {
|
||||||
|
switcher.doStateMachine();
|
||||||
|
auto currState = switcher.getState();
|
||||||
|
if (currState == PowerSwitcher::SWITCH_IS_OFF) {
|
||||||
|
setMode(MODE_OFF, 0);
|
||||||
|
} else if(currState == PowerSwitcher::SWITCH_IS_ON) {
|
||||||
|
setMode(MODE_ON, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherComponent::initialize() {
|
||||||
|
ReturnValue_t result = modeHelper.initialize();
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = healthHelper.initialize();
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return SystemObject::initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t PowerSwitcherComponent::getCommandQueue() const {
|
||||||
|
return queue->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSwitcherComponent::getMode(Mode_t *mode, Submode_t *submode) {
|
||||||
|
*mode = this->mode;
|
||||||
|
*submode = this->submode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherComponent::setHealth(HealthState health) {
|
||||||
|
healthHelper.setHealth(health);
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherComponent::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
|
uint32_t *msToReachTheMode) {
|
||||||
|
*msToReachTheMode = 5000;
|
||||||
|
if(mode != MODE_ON and mode != MODE_OFF) {
|
||||||
|
return TRANS_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSwitcherComponent::startTransition(Mode_t mode, Submode_t submode) {
|
||||||
|
if(mode == MODE_OFF) {
|
||||||
|
switcher.turnOff(true);
|
||||||
|
switcher.doStateMachine();
|
||||||
|
if(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF) {
|
||||||
|
setMode(MODE_OFF, 0);
|
||||||
|
}
|
||||||
|
} else if (mode == MODE_ON) {
|
||||||
|
switcher.turnOn(true);
|
||||||
|
switcher.doStateMachine();
|
||||||
|
if(switcher.getState() == PowerSwitcher::SWITCH_IS_ON) {
|
||||||
|
setMode(MODE_ON, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSwitcherComponent::setToExternalControl() {
|
||||||
|
healthHelper.setHealth(HasHealthIF::EXTERNAL_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSwitcherComponent::announceMode(bool recursive) {
|
||||||
|
triggerEvent(MODE_INFO, mode, submode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSwitcherComponent::setMode(Mode_t newMode, Submode_t newSubmode) {
|
||||||
|
this->mode = newMode;
|
||||||
|
this->submode = newSubmode;
|
||||||
|
modeHelper.modeChanged(mode, submode);
|
||||||
|
announceMode(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
HasHealthIF::HealthState PowerSwitcherComponent::getHealth() {
|
||||||
|
return healthHelper.getHealth();
|
||||||
|
}
|
64
src/fsfw/power/PowerSwitcherComponent.h
Normal file
64
src/fsfw/power/PowerSwitcherComponent.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef _FSFW_POWER_POWERSWITCHERCOMPONENT_H_
|
||||||
|
#define _FSFW_POWER_POWERSWITCHERCOMPONENT_H_
|
||||||
|
|
||||||
|
#include <fsfw/health/HasHealthIF.h>
|
||||||
|
#include <fsfw/health/HealthHelper.h>
|
||||||
|
#include <fsfw/modes/HasModesIF.h>
|
||||||
|
#include <fsfw/modes/ModeHelper.h>
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/power/definitions.h>
|
||||||
|
#include <fsfw/power/PowerSwitcher.h>
|
||||||
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
|
||||||
|
class PowerSwitchIF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allows to create an power switch object with its own mode and health
|
||||||
|
* @details
|
||||||
|
* This basic component allows to create an object which is solely responsible for managing a
|
||||||
|
* switch. It also has a mode and a health by implementing the respective interface components
|
||||||
|
* which allows integrating this component into a system mode tree.
|
||||||
|
*
|
||||||
|
* Commanding this component to MODE_OFF will cause the switcher to turn the switch off while
|
||||||
|
* commanding in to MODE_ON will cause the switcher to turn the switch on.
|
||||||
|
*/
|
||||||
|
class PowerSwitcherComponent:
|
||||||
|
public SystemObject,
|
||||||
|
public HasReturnvaluesIF,
|
||||||
|
public ExecutableObjectIF,
|
||||||
|
public HasModesIF,
|
||||||
|
public HasHealthIF {
|
||||||
|
public:
|
||||||
|
PowerSwitcherComponent(object_id_t objectId, PowerSwitchIF* pwrSwitcher,
|
||||||
|
power::Switch_t pwrSwitch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
MessageQueueIF* queue = nullptr;
|
||||||
|
PowerSwitcher switcher;
|
||||||
|
|
||||||
|
Mode_t mode = MODE_OFF;
|
||||||
|
Submode_t submode = 0;
|
||||||
|
|
||||||
|
ModeHelper modeHelper;
|
||||||
|
HealthHelper healthHelper;
|
||||||
|
|
||||||
|
void setMode(Mode_t newMode, Submode_t newSubmode);
|
||||||
|
|
||||||
|
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
MessageQueueId_t getCommandQueue() const override;
|
||||||
|
void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||||
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
|
uint32_t *msToReachTheMode) override;
|
||||||
|
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
|
void setToExternalControl() override;
|
||||||
|
void announceMode(bool recursive) override;
|
||||||
|
|
||||||
|
ReturnValue_t setHealth(HealthState health) override;
|
||||||
|
HasHealthIF::HealthState getHealth() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _FSFW_POWER_POWERSWITCHERCOMPONENT_H_ */
|
@@ -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() {
|
||||||
|
@@ -214,11 +214,11 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
|
|||||||
default:
|
default:
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
|
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
|
||||||
<< "reply command " << command << "!" << std::endl;
|
<< "reply command " << command << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"Service3Housekeeping::handleReply: Invalid reply with "
|
"Service3Housekeeping::handleReply: Invalid reply with "
|
||||||
"reply command %hu!\n",
|
"reply command %hu\n",
|
||||||
command);
|
command);
|
||||||
#endif
|
#endif
|
||||||
return CommandingServiceBase::INVALID_REPLY;
|
return CommandingServiceBase::INVALID_REPLY;
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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:
|
||||||
|
@@ -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;
|
||||||
|
@@ -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();
|
||||||
|
|
||||||
|
@@ -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); }
|
||||||
|
@@ -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() {
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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); }
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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() {}
|
||||||
|
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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); }
|
||||||
|
@@ -19,6 +19,19 @@ class SourceSequenceCounter {
|
|||||||
void reset(uint16_t toValue = 0) {
|
void reset(uint16_t toValue = 0) {
|
||||||
sequenceCount = toValue % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
sequenceCount = toValue % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
||||||
}
|
}
|
||||||
|
SourceSequenceCounter& operator++(int) {
|
||||||
|
this->increment();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
SourceSequenceCounter& operator--(int) {
|
||||||
|
this->decrement();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
SourceSequenceCounter& operator=(const uint16_t& newCount) {
|
||||||
|
sequenceCount = newCount;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
operator uint16_t() { return this->get(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_TMTCSERVICES_SOURCESEQUENCECOUNTER_H_ */
|
#endif /* FSFW_TMTCSERVICES_SOURCESEQUENCECOUNTER_H_ */
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user