adapted object factory to fsfw changes
This commit is contained in:
commit
52b549b97c
@ -184,6 +184,7 @@ endif()
|
|||||||
target_include_directories(${LIB_FSFW_NAME} INTERFACE
|
target_include_directories(${LIB_FSFW_NAME} INTERFACE
|
||||||
${CMAKE_SOURCE_DIR}
|
${CMAKE_SOURCE_DIR}
|
||||||
${FSFW_CONFIG_PATH_ABSOLUTE}
|
${FSFW_CONFIG_PATH_ABSOLUTE}
|
||||||
|
${FSFW_ADD_INC_PATHS_ABS}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Includes path required to compile FSFW itself as well
|
# Includes path required to compile FSFW itself as well
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
const char* const FSFW_VERSION_NAME = "ASTP";
|
const char* const FSFW_VERSION_NAME = "ASTP";
|
||||||
|
|
||||||
#define FSFW_VERSION 0
|
#define FSFW_VERSION 1
|
||||||
#define FSFW_SUBVERSION 0
|
#define FSFW_SUBVERSION 0
|
||||||
#define FSFW_REVISION 1
|
#define FSFW_REVISION 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,11 +147,6 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
ipcStore->deleteData(storeAddress);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't need to report the objectId, as we receive REQUESTED data before the completion
|
/* We don't need to report the objectId, as we receive REQUESTED data before the completion
|
||||||
success message. True aperiodic replies need to be reported with another dedicated message. */
|
success message. True aperiodic replies need to be reported with another dedicated message. */
|
||||||
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
||||||
|
@ -17,6 +17,9 @@ SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
|||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedRingBuffer::~SharedRingBuffer() {
|
||||||
|
MutexFactory::instance()->deleteMutex(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
|
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
|
||||||
this->fifoDepth = fifoDepth;
|
this->fifoDepth = fifoDepth;
|
||||||
|
@ -26,6 +26,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
SharedRingBuffer(object_id_t objectId, const size_t size,
|
SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||||
bool overwriteOld, size_t maxExcessBytes);
|
bool overwriteOld, size_t maxExcessBytes);
|
||||||
|
/**
|
||||||
|
* This constructor takes an external buffer with the specified size.
|
||||||
|
* @param buffer
|
||||||
|
* @param size
|
||||||
|
* @param overwriteOld
|
||||||
|
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||||
|
* will be overwritten.
|
||||||
|
*/
|
||||||
|
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
|
||||||
|
bool overwriteOld, size_t maxExcessBytes);
|
||||||
|
|
||||||
|
virtual~ SharedRingBuffer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function can be used to add an optional FIFO to the class
|
* @brief This function can be used to add an optional FIFO to the class
|
||||||
@ -37,16 +49,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setToUseReceiveSizeFIFO(size_t fifoDepth);
|
void setToUseReceiveSizeFIFO(size_t fifoDepth);
|
||||||
|
|
||||||
/**
|
|
||||||
* This constructor takes an external buffer with the specified size.
|
|
||||||
* @param buffer
|
|
||||||
* @param size
|
|
||||||
* @param overwriteOld
|
|
||||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
|
||||||
* will be overwritten.
|
|
||||||
*/
|
|
||||||
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
|
|
||||||
bool overwriteOld, size_t maxExcessBytes);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unless a read-only constant value is read, all operations on the
|
* Unless a read-only constant value is read, all operations on the
|
||||||
|
@ -7,7 +7,7 @@ HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
HkSwitchHelper::~HkSwitchHelper() {
|
HkSwitchHelper::~HkSwitchHelper() {
|
||||||
// TODO Auto-generated destructor stub
|
QueueFactory::instance()->deleteMessageQueue(actionQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HkSwitchHelper::initialize() {
|
ReturnValue_t HkSwitchHelper::initialize() {
|
||||||
|
@ -909,27 +909,29 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
|||||||
errorPrint = "Unknown error";
|
errorPrint = "Unknown error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
object_id_t objectId = 0xffffffff;
|
||||||
|
if(owner != nullptr) {
|
||||||
|
objectId = owner->getObjectId();
|
||||||
|
}
|
||||||
|
|
||||||
if(outputType == sif::OutputTypes::OUT_WARNING) {
|
if(outputType == sif::OutputTypes::OUT_WARNING) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LocalDataPoolManager::" << functionName
|
sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID 0x" <<
|
||||||
<< ": Object ID 0x" << std::setw(8) << std::setfill('0')
|
std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint <<
|
||||||
<< std::hex << owner->getObjectId() << " | " << errorPrint
|
std::dec << std::setfill(' ') << std::endl;
|
||||||
<< std::dec << std::setfill(' ') << std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
|
sif::printWarning("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
|
||||||
functionName, owner->getObjectId(), errorPrint);
|
functionName, objectId, errorPrint);
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
}
|
}
|
||||||
else if(outputType == sif::OutputTypes::OUT_ERROR) {
|
else if(outputType == sif::OutputTypes::OUT_ERROR) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "LocalDataPoolManager::" << functionName
|
sif::error << "LocalDataPoolManager::" << functionName << ": Object ID 0x" <<
|
||||||
<< ": Object ID 0x" << std::setw(8) << std::setfill('0')
|
std::setw(8) << std::setfill('0') << std::hex << objectId << " | " << errorPrint <<
|
||||||
<< std::hex << owner->getObjectId() << " | " << errorPrint
|
std::dec << std::setfill(' ') << std::endl;
|
||||||
<< std::dec << std::setfill(' ') << std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
|
sif::printError("LocalDataPoolManager::%s: Object ID 0x%08x | %s\n",
|
||||||
functionName, owner->getObjectId(), errorPrint);
|
functionName, objectId, errorPrint);
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
}
|
}
|
||||||
#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* #if FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
|
@ -40,6 +40,13 @@
|
|||||||
//! Specify whether a special mode store is used for Subsystem components.
|
//! Specify whether a special mode store is used for Subsystem components.
|
||||||
#define FSFW_USE_MODESTORE 0
|
#define FSFW_USE_MODESTORE 0
|
||||||
|
|
||||||
|
//! Defines if the real time scheduler for linux should be used.
|
||||||
|
//! If set to 0, this will also disable priority settings for linux
|
||||||
|
//! as most systems will not allow to set nice values without privileges
|
||||||
|
//! For embedded linux system set this to 1.
|
||||||
|
//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run
|
||||||
|
#define FSFW_USE_REALTIME_FOR_LINUX 1
|
||||||
|
|
||||||
namespace fsfwconfig {
|
namespace fsfwconfig {
|
||||||
//! Default timestamp size. The default timestamp will be an eight byte CDC
|
//! Default timestamp size. The default timestamp will be an eight byte CDC
|
||||||
//! short timestamp.
|
//! short timestamp.
|
||||||
@ -52,11 +59,12 @@ static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
|||||||
|
|
||||||
//! Defines the FIFO depth of each commanding service base which
|
//! Defines the FIFO depth of each commanding service base which
|
||||||
//! also determines how many commands a CSB service can handle in one cycle
|
//! also determines how many commands a CSB service can handle in one cycle
|
||||||
//! simulataneously. This will increase the required RAM for
|
//! simultaneously. This will increase the required RAM for
|
||||||
//! each CSB service !
|
//! each CSB service !
|
||||||
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
|
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
|
||||||
|
|
||||||
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
|
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
#endif /* CONFIG_FSFWCONFIG_H_ */
|
||||||
|
@ -24,6 +24,13 @@
|
|||||||
* 1. check logic when active-> checkChildrenStateOn
|
* 1. check logic when active-> checkChildrenStateOn
|
||||||
* 2. transition logic to change the mode -> commandChildren
|
* 2. transition logic to change the mode -> commandChildren
|
||||||
*
|
*
|
||||||
|
* Important:
|
||||||
|
*
|
||||||
|
* The implementation must call registerChild(object_id_t child)
|
||||||
|
* for all commanded children during initialization.
|
||||||
|
* The implementation must call the initialization function of the base class.
|
||||||
|
* (This will call the function in SubsystemBase)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class AssemblyBase: public SubsystemBase {
|
class AssemblyBase: public SubsystemBase {
|
||||||
public:
|
public:
|
||||||
@ -41,9 +48,6 @@ public:
|
|||||||
virtual ~AssemblyBase();
|
virtual ~AssemblyBase();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// SHOULDDO: Change that OVERWRITE_HEALTH may be returned
|
|
||||||
// (or return internalState directly?)
|
|
||||||
/**
|
/**
|
||||||
* Command children to reach [mode,submode] combination
|
* Command children to reach [mode,submode] combination
|
||||||
* Can be done by setting #commandsOutstanding correctly,
|
* Can be done by setting #commandsOutstanding correctly,
|
||||||
@ -68,6 +72,18 @@ protected:
|
|||||||
virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode,
|
virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode,
|
||||||
Submode_t wantedSubmode) = 0;
|
Submode_t wantedSubmode) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a combination of mode and submode is valid.
|
||||||
|
*
|
||||||
|
* Ground Controller like precise return values from HasModesIF.
|
||||||
|
* So, please return any of them.
|
||||||
|
*
|
||||||
|
* @param mode The targeted mode
|
||||||
|
* @param submode The targeted submmode
|
||||||
|
* @return Any information why this combination is invalid from HasModesIF
|
||||||
|
* like HasModesIF::INVALID_SUBMODE.
|
||||||
|
* On success return HasReturnvaluesIF::RETURN_OK
|
||||||
|
*/
|
||||||
virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
|
virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
|
||||||
Submode_t submode) = 0;
|
Submode_t submode) = 0;
|
||||||
|
|
||||||
|
@ -1496,7 +1496,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType,
|
|||||||
if(errorCode == ObjectManagerIF::CHILD_INIT_FAILED) {
|
if(errorCode == ObjectManagerIF::CHILD_INIT_FAILED) {
|
||||||
errorPrint = "Initialization error";
|
errorPrint = "Initialization error";
|
||||||
}
|
}
|
||||||
if(errorCode == HasReturnvaluesIF::RETURN_FAILED) {
|
else if(errorCode == HasReturnvaluesIF::RETURN_FAILED) {
|
||||||
if(errorType == sif::OutputTypes::OUT_WARNING) {
|
if(errorType == sif::OutputTypes::OUT_WARNING) {
|
||||||
errorPrint = "Generic Warning";
|
errorPrint = "Generic Warning";
|
||||||
}
|
}
|
||||||
@ -1508,6 +1508,9 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType,
|
|||||||
errorPrint = "Unknown error";
|
errorPrint = "Unknown error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(functionName == nullptr) {
|
||||||
|
functionName = "unknown function";
|
||||||
|
}
|
||||||
|
|
||||||
if(errorType == sif::OutputTypes::OUT_WARNING) {
|
if(errorType == sif::OutputTypes::OUT_WARNING) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -1516,7 +1519,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType,
|
|||||||
std::dec << std::setfill(' ') << std::endl;
|
std::dec << std::setfill(' ') << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n",
|
sif::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n",
|
||||||
this->getObjectId(), errorPrint);
|
functionName, this->getObjectId(), errorPrint);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if(errorType == sif::OutputTypes::OUT_ERROR) {
|
else if(errorType == sif::OutputTypes::OUT_ERROR) {
|
||||||
@ -1527,7 +1530,7 @@ void DeviceHandlerBase::printWarningOrError(sif::OutputTypes errorType,
|
|||||||
<< std::setfill(' ') << std::endl;
|
<< std::setfill(' ') << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n",
|
sif::printError("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n",
|
||||||
this->getObjectId(), errorPrint);
|
functionName, this->getObjectId(), errorPrint);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@ ReturnValue_t HealthDevice::performOperation(uint8_t opCode) {
|
|||||||
CommandMessage command;
|
CommandMessage command;
|
||||||
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
healthHelper.handleHealthCommand(&command);
|
result = healthHelper.handleHealthCommand(&command);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t HealthDevice::initialize() {
|
ReturnValue_t HealthDevice::initialize() {
|
||||||
|
@ -109,6 +109,6 @@ bool EventMessage::isClearedEventMessage() {
|
|||||||
return getEvent() == INVALID_EVENT;
|
return getEvent() == INVALID_EVENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t EventMessage::getMinimumMessageSize() {
|
size_t EventMessage::getMinimumMessageSize() const {
|
||||||
return EVENT_MESSAGE_SIZE;
|
return EVENT_MESSAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const Event INVALID_EVENT = 0;
|
static const Event INVALID_EVENT = 0;
|
||||||
virtual size_t getMinimumMessageSize();
|
virtual size_t getMinimumMessageSize() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ void arrayprinter::printHex(const uint8_t *data, size_t size,
|
|||||||
#else
|
#else
|
||||||
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
// General format: 0x01, 0x02, 0x03 so it is number of chars times 6
|
||||||
// plus line break plus small safety margin.
|
// plus line break plus small safety margin.
|
||||||
char printBuffer[(size + 1) * 7 + 1];
|
char printBuffer[(size + 1) * 7 + 1] = {};
|
||||||
size_t currentPos = 0;
|
size_t currentPos = 0;
|
||||||
for(size_t i = 0; i < size; i++) {
|
for(size_t i = 0; i < size; i++) {
|
||||||
// To avoid buffer overflows.
|
// To avoid buffer overflows.
|
||||||
@ -103,7 +103,7 @@ void arrayprinter::printDec(const uint8_t *data, size_t size,
|
|||||||
#else
|
#else
|
||||||
// General format: 32, 243, -12 so it is number of chars times 5
|
// General format: 32, 243, -12 so it is number of chars times 5
|
||||||
// plus line break plus small safety margin.
|
// plus line break plus small safety margin.
|
||||||
char printBuffer[(size + 1) * 5 + 1];
|
char printBuffer[(size + 1) * 5 + 1] = {};
|
||||||
size_t currentPos = 0;
|
size_t currentPos = 0;
|
||||||
for(size_t i = 0; i < size; i++) {
|
for(size_t i = 0; i < size; i++) {
|
||||||
// To avoid buffer overflows.
|
// To avoid buffer overflows.
|
||||||
|
@ -68,14 +68,30 @@ void HealthTable::printAll(uint8_t* pointer, size_t maxSize) {
|
|||||||
MutexGuard(mutex, timeoutType, mutexTimeoutMs);
|
MutexGuard(mutex, timeoutType, mutexTimeoutMs);
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
uint16_t count = healthMap.size();
|
uint16_t count = healthMap.size();
|
||||||
SerializeAdapter::serialize(&count,
|
ReturnValue_t result = SerializeAdapter::serialize(&count,
|
||||||
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "HealthTable::printAll: Serialization of health table failed" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("HealthTable::printAll: Serialization of health table failed\n");
|
||||||
|
#endif
|
||||||
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (const auto& health: healthMap) {
|
for (const auto& health: healthMap) {
|
||||||
SerializeAdapter::serialize(&health.first,
|
result = SerializeAdapter::serialize(&health.first,
|
||||||
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
&pointer, &size, maxSize, SerializeIF::Endianness::BIG);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint8_t healthValue = health.second;
|
uint8_t healthValue = health.second;
|
||||||
SerializeAdapter::serialize(&healthValue, &pointer, &size,
|
result = SerializeAdapter::serialize(&healthValue, &pointer, &size,
|
||||||
maxSize, SerializeIF::Endianness::BIG);
|
maxSize, SerializeIF::Endianness::BIG);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +102,7 @@ ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) {
|
|||||||
mapIterator = healthMap.begin();
|
mapIterator = healthMap.begin();
|
||||||
}
|
}
|
||||||
if (mapIterator == healthMap.end()) {
|
if (mapIterator == healthMap.end()) {
|
||||||
result = HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
*value = *mapIterator;
|
*value = *mapIterator;
|
||||||
mapIterator++;
|
mapIterator++;
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
//! Returned if a reply method was called without partner
|
//! Returned if a reply method was called without partner
|
||||||
static const ReturnValue_t NO_REPLY_PARTNER = MAKE_RETURN_CODE(3);
|
static const ReturnValue_t NO_REPLY_PARTNER = MAKE_RETURN_CODE(3);
|
||||||
//! Returned if the target destination is invalid.
|
//! Returned if the target destination is invalid.
|
||||||
static constexpr ReturnValue_t DESTINVATION_INVALID = MAKE_RETURN_CODE(4);
|
static constexpr ReturnValue_t DESTINATION_INVALID = MAKE_RETURN_CODE(4);
|
||||||
|
|
||||||
virtual ~MessageQueueIF() {}
|
virtual ~MessageQueueIF() {}
|
||||||
/**
|
/**
|
||||||
|
@ -86,3 +86,7 @@ size_t MessageQueueMessage::getMaximumMessageSize() const {
|
|||||||
return this->MAX_MESSAGE_SIZE;
|
return this->MAX_MESSAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t MessageQueueMessage::getMaximumDataSize() const {
|
||||||
|
return this->MAX_DATA_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ public:
|
|||||||
virtual void setMessageSize(size_t messageSize) override;
|
virtual void setMessageSize(size_t messageSize) override;
|
||||||
virtual size_t getMinimumMessageSize() const override;
|
virtual size_t getMinimumMessageSize() const override;
|
||||||
virtual size_t getMaximumMessageSize() const override;
|
virtual size_t getMaximumMessageSize() const override;
|
||||||
|
virtual size_t getMaximumDataSize() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a debug method that prints the content.
|
* @brief This is a debug method that prints the content.
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
virtual void setMessageSize(size_t messageSize) = 0;
|
virtual void setMessageSize(size_t messageSize) = 0;
|
||||||
virtual size_t getMinimumMessageSize() const = 0;
|
virtual size_t getMinimumMessageSize() const = 0;
|
||||||
virtual size_t getMaximumMessageSize() const = 0;
|
virtual size_t getMaximumMessageSize() const = 0;
|
||||||
|
virtual size_t getMaximumDataSize() const = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,35 +1,34 @@
|
|||||||
# Check the OS_FSFW variable
|
# Check the OS_FSFW variable
|
||||||
if(${OS_FSFW} STREQUAL "freertos")
|
if(${OS_FSFW} STREQUAL "freertos")
|
||||||
add_subdirectory(FreeRTOS)
|
add_subdirectory(FreeRTOS)
|
||||||
elseif(${OS_FSFW} STREQUAL "rtems")
|
elseif(${OS_FSFW} STREQUAL "rtems")
|
||||||
add_subdirectory(rtems)
|
add_subdirectory(rtems)
|
||||||
elseif(${OS_FSFW} STREQUAL "linux")
|
elseif(${OS_FSFW} STREQUAL "linux")
|
||||||
add_subdirectory(linux)
|
add_subdirectory(linux)
|
||||||
elseif(${OS_FSFW} STREQUAL "host")
|
elseif(${OS_FSFW} STREQUAL "host")
|
||||||
add_subdirectory(host)
|
add_subdirectory(host)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_subdirectory(windows)
|
add_subdirectory(windows)
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
target_sources(${LIB_FSFW_NAME}
|
# We still need to pull in some Linux specific sources
|
||||||
PUBLIC
|
target_sources(${LIB_FSFW_NAME} PUBLIC
|
||||||
linux/TcUnixUdpPollingTask.cpp
|
linux/tcpipHelpers.cpp
|
||||||
linux/TmTcUnixUdpBridge.cpp
|
)
|
||||||
)
|
endif ()
|
||||||
endif ()
|
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
|
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
|
||||||
# Not set. Assumuing this is a host build, try to determine host OS
|
# Not set. Assumuing this is a host build, try to determine host OS
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_subdirectory(host)
|
add_subdirectory(host)
|
||||||
add_subdirectory(windows)
|
add_subdirectory(windows)
|
||||||
elseif (UNIX)
|
elseif (UNIX)
|
||||||
add_subdirectory(linux)
|
add_subdirectory(linux)
|
||||||
else ()
|
else ()
|
||||||
# MacOS or other OSes have not been tested yet / are not supported.
|
# MacOS or other OSes have not been tested yet / are not supported.
|
||||||
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
|
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
|||||||
|
|
||||||
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from,
|
ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from,
|
||||||
timeval* to) {
|
timeval* to) {
|
||||||
struct tm time_tm;
|
struct tm time_tm = {};
|
||||||
|
|
||||||
time_tm.tm_year = from->year - 1900;
|
time_tm.tm_year = from->year - 1900;
|
||||||
time_tm.tm_mon = from->month - 1;
|
time_tm.tm_mon = from->month - 1;
|
||||||
|
@ -135,7 +135,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
QueueHandle_t destination = nullptr;
|
QueueHandle_t destination = nullptr;
|
||||||
|
|
||||||
if(sendTo == MessageQueueIF::NO_QUEUE or sendTo == 0x00) {
|
if(sendTo == MessageQueueIF::NO_QUEUE or sendTo == 0x00) {
|
||||||
return MessageQueueIF::DESTINVATION_INVALID;
|
return MessageQueueIF::DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
destination = reinterpret_cast<QueueHandle_t>(sendTo);
|
destination = reinterpret_cast<QueueHandle_t>(sendTo);
|
||||||
|
@ -70,6 +70,7 @@ ReturnValue_t TcpTmTcServer::initialize() {
|
|||||||
#endif
|
#endif
|
||||||
freeaddrinfo(addrResult);
|
freeaddrinfo(addrResult);
|
||||||
handleError(Protocol::TCP, ErrorSources::BIND_CALL);
|
handleError(Protocol::TCP, ErrorSources::BIND_CALL);
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
freeaddrinfo(addrResult);
|
freeaddrinfo(addrResult);
|
||||||
@ -84,8 +85,8 @@ TcpTmTcServer::~TcpTmTcServer() {
|
|||||||
ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
|
ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
|
||||||
using namespace tcpip;
|
using namespace tcpip;
|
||||||
/* If a connection is accepted, the corresponding socket will be assigned to the new socket */
|
/* If a connection is accepted, the corresponding socket will be assigned to the new socket */
|
||||||
socket_t clientSocket;
|
socket_t clientSocket = 0;
|
||||||
sockaddr clientSockAddr;
|
sockaddr clientSockAddr = {};
|
||||||
socklen_t connectorSockAddrLen = 0;
|
socklen_t connectorSockAddrLen = 0;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
@ -101,6 +102,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
|
|||||||
|
|
||||||
if(clientSocket == INVALID_SOCKET) {
|
if(clientSocket == INVALID_SOCKET) {
|
||||||
handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500);
|
handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500);
|
||||||
|
closeSocket(clientSocket);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -122,6 +124,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
|
|||||||
|
|
||||||
/* Done, shut down connection */
|
/* Done, shut down connection */
|
||||||
retval = shutdown(clientSocket, SHUT_SEND);
|
retval = shutdown(clientSocket, SHUT_SEND);
|
||||||
|
closeSocket(clientSocket);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Debugging preprocessor define.
|
//! Debugging preprocessor define.
|
||||||
#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0
|
#define FSFW_UDP_RECV_WIRETAPPING_ENABLED 0
|
||||||
|
|
||||||
UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId,
|
UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId,
|
||||||
object_id_t tmtcUnixUdpBridge, size_t maxRecvSize,
|
object_id_t tmtcUnixUdpBridge, size_t maxRecvSize,
|
||||||
@ -66,10 +66,13 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) {
|
|||||||
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000);
|
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
|
#if FSFW_UDP_RECV_WIRETAPPING_ENABLED == 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived <<
|
sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived <<
|
||||||
" bytes received" << std::endl;
|
" bytes received" << std::endl;
|
||||||
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 */
|
||||||
|
|
||||||
ReturnValue_t result = handleSuccessfullTcRead(bytesReceived);
|
ReturnValue_t result = handleSuccessfullTcRead(bytesReceived);
|
||||||
if(result != HasReturnvaluesIF::RETURN_FAILED) {
|
if(result != HasReturnvaluesIF::RETURN_FAILED) {
|
||||||
@ -84,7 +87,7 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) {
|
|||||||
ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
|
ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
|
|
||||||
#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
|
#if FSFW_UDP_RECV_WIRETAPPING_ENABLED == 1
|
||||||
arrayprinter::print(receptionBuffer.data(), bytesRead);
|
arrayprinter::print(receptionBuffer.data(), bytesRead);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ ReturnValue_t UdpTmTcBridge::initialize() {
|
|||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
hints.ai_protocol = IPPROTO_UDP;
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
/* Set up UDP socket:
|
/* Set up UDP socket:
|
||||||
https://en.wikipedia.org/wiki/Getaddrinfo
|
https://en.wikipedia.org/wiki/Getaddrinfo
|
||||||
@ -95,6 +96,10 @@ ReturnValue_t UdpTmTcBridge::initialize() {
|
|||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
||||||
|
tcpip::printAddress(addrResult->ai_addr);
|
||||||
|
#endif
|
||||||
|
|
||||||
retval = bind(serverSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
|
retval = bind(serverSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
|
||||||
if(retval != 0) {
|
if(retval != 0) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -103,6 +108,7 @@ ReturnValue_t UdpTmTcBridge::initialize() {
|
|||||||
#endif
|
#endif
|
||||||
freeaddrinfo(addrResult);
|
freeaddrinfo(addrResult);
|
||||||
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::BIND_CALL);
|
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::BIND_CALL);
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
freeaddrinfo(addrResult);
|
freeaddrinfo(addrResult);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@ -120,10 +126,8 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
|||||||
/* The target address can be set by different threads so this lock ensures thread-safety */
|
/* The target address can be set by different threads so this lock ensures thread-safety */
|
||||||
MutexGuard lock(mutex, timeoutType, mutexTimeoutMs);
|
MutexGuard lock(mutex, timeoutType, mutexTimeoutMs);
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
||||||
char ipAddress [15];
|
tcpip::printAddress(&clientAddress);
|
||||||
sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET,
|
|
||||||
&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int bytesSent = sendto(
|
int bytesSent = sendto(
|
||||||
@ -151,13 +155,11 @@ void UdpTmTcBridge::checkAndSetClientAddress(sockaddr& newAddress) {
|
|||||||
/* The target address can be set by different threads so this lock ensures thread-safety */
|
/* The target address can be set by different threads so this lock ensures thread-safety */
|
||||||
MutexGuard lock(mutex, timeoutType, mutexTimeoutMs);
|
MutexGuard lock(mutex, timeoutType, mutexTimeoutMs);
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
#if FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
||||||
char ipAddress [15];
|
tcpip::printAddress(&newAddress);
|
||||||
sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET,
|
tcpip::printAddress(&clientAddress);
|
||||||
&newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
|
|
||||||
sif::debug << "IP Address Old: " << inet_ntop(AF_INET,
|
|
||||||
&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
registerCommConnect();
|
registerCommConnect();
|
||||||
|
|
||||||
/* Set new IP address to reply to */
|
/* Set new IP address to reply to */
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
#include "tcpipCommon.h"
|
#include "tcpipCommon.h"
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string &protStr,
|
void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string &protStr,
|
||||||
std::string &srcString) {
|
std::string &srcString) {
|
||||||
@ -34,3 +39,37 @@ void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std:
|
|||||||
srcString = "unknown call";
|
srcString = "unknown call";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcpip::printAddress(struct sockaddr* addr) {
|
||||||
|
char ipAddress[INET6_ADDRSTRLEN] = {};
|
||||||
|
const char* stringPtr = NULL;
|
||||||
|
switch(addr->sa_family) {
|
||||||
|
case AF_INET: {
|
||||||
|
struct sockaddr_in *addrIn = reinterpret_cast<struct sockaddr_in*>(addr);
|
||||||
|
stringPtr = inet_ntop(AF_INET, &(addrIn->sin_addr), ipAddress, INET_ADDRSTRLEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AF_INET6: {
|
||||||
|
struct sockaddr_in6 *addrIn = reinterpret_cast<struct sockaddr_in6*>(addr);
|
||||||
|
stringPtr = inet_ntop(AF_INET6, &(addrIn->sin6_addr), ipAddress, INET6_ADDRSTRLEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
if(stringPtr == NULL) {
|
||||||
|
sif::debug << "Could not convert IP address to text representation, error code "
|
||||||
|
<< errno << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::debug << "IP Address Sender: " << ipAddress << std::endl;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(stringPtr == NULL) {
|
||||||
|
sif::printDebug("Could not convert IP address to text representation, error code %d\n",
|
||||||
|
errno);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::printDebug("IP Address Sender: %s\n", ipAddress);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
#include "../../timemanager/clockDefinitions.h"
|
#include "../../timemanager/clockDefinitions.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tcpip {
|
namespace tcpip {
|
||||||
|
|
||||||
const char* const DEFAULT_SERVER_PORT = "7301";
|
const char* const DEFAULT_SERVER_PORT = "7301";
|
||||||
@ -28,8 +35,8 @@ enum class ErrorSources {
|
|||||||
void determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string& protStr,
|
void determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string& protStr,
|
||||||
std::string& srcString);
|
std::string& srcString);
|
||||||
|
|
||||||
|
void printAddress(struct sockaddr* addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* FSFW_OSAL_COMMON_TCPIPCOMMON_H_ */
|
#endif /* FSFW_OSAL_COMMON_TCPIPCOMMON_H_ */
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "../../ipc/MutexFactory.h"
|
#include "../../ipc/MutexFactory.h"
|
||||||
#include "../../osal/host/Mutex.h"
|
#include "../../osal/host/Mutex.h"
|
||||||
#include "../../osal/host/FixedTimeslotTask.h"
|
#include "../../osal/host/FixedTimeslotTask.h"
|
||||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
#include "../../serviceinterface/ServiceInterface.h"
|
||||||
#include "../../tasks/ExecutableObjectIF.h"
|
#include "../../tasks/ExecutableObjectIF.h"
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -38,7 +38,6 @@ FixedTimeslotTask::~FixedTimeslotTask(void) {
|
|||||||
if(mainThread.joinable()) {
|
if(mainThread.joinable()) {
|
||||||
mainThread.join();
|
mainThread.join();
|
||||||
}
|
}
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedTimeslotTask::taskEntryPoint(void* argument) {
|
void FixedTimeslotTask::taskEntryPoint(void* argument) {
|
||||||
@ -119,8 +118,11 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Component " << std::hex << componentId <<
|
sif::error << "Component " << std::hex << "0x" << componentId << "not found, "
|
||||||
" not found, not adding it to pst" << std::endl;
|
"not adding it to PST.." << std::dec << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("Component 0x%08x not found, not adding it to PST..\n",
|
||||||
|
static_cast<unsigned int>(componentId));
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,8 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
|||||||
return MessageQueueIF::EMPTY;
|
return MessageQueueIF::EMPTY;
|
||||||
}
|
}
|
||||||
MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20);
|
MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20);
|
||||||
MessageQueueMessage* currentMessage = &messageQueue.front();
|
std::copy(messageQueue.front().data(), messageQueue.front().data() + messageSize,
|
||||||
std::copy(currentMessage->getBuffer(),
|
message->getBuffer());
|
||||||
currentMessage->getBuffer() + messageSize, message->getBuffer());
|
|
||||||
messageQueue.pop();
|
messageQueue.pop();
|
||||||
// The last partner is the first uint32_t field in the message
|
// The last partner is the first uint32_t field in the message
|
||||||
this->lastPartner = message->getSender();
|
this->lastPartner = message->getSender();
|
||||||
@ -80,7 +79,7 @@ MessageQueueId_t MessageQueue::getLastPartner() const {
|
|||||||
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
ReturnValue_t MessageQueue::flush(uint32_t* count) {
|
||||||
*count = messageQueue.size();
|
*count = messageQueue.size();
|
||||||
// Clears the queue.
|
// Clears the queue.
|
||||||
messageQueue = std::queue<MessageQueueMessage>();
|
messageQueue = std::queue<std::vector<uint8_t>>();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +105,9 @@ bool MessageQueue::isDefaultDestinationSet() const {
|
|||||||
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||||
bool ignoreFault) {
|
bool ignoreFault) {
|
||||||
|
if(message == nullptr) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
message->setSender(sentFrom);
|
message->setSender(sentFrom);
|
||||||
if(message->getMessageSize() > message->getMaximumMessageSize()) {
|
if(message->getMessageSize() > message->getMaximumMessageSize()) {
|
||||||
// Actually, this should never happen or an error will be emitted
|
// Actually, this should never happen or an error will be emitted
|
||||||
@ -128,21 +130,10 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if(targetQueue->messageQueue.size() < targetQueue->messageDepth) {
|
if(targetQueue->messageQueue.size() < targetQueue->messageDepth) {
|
||||||
MutexGuard mutexLock(targetQueue->queueLock,
|
MutexGuard mutexLock(targetQueue->queueLock, MutexIF::TimeoutType::WAITING, 20);
|
||||||
MutexIF::TimeoutType::WAITING, 20);
|
targetQueue->messageQueue.push(std::vector<uint8_t>(message->getMaximumMessageSize()));
|
||||||
// not ideal, works for now though.
|
memcpy(targetQueue->messageQueue.back().data(), message->getBuffer(),
|
||||||
MessageQueueMessage* mqmMessage =
|
message->getMaximumMessageSize());
|
||||||
dynamic_cast<MessageQueueMessage*>(message);
|
|
||||||
if(message != nullptr) {
|
|
||||||
targetQueue->messageQueue.push(*mqmMessage);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message"
|
|
||||||
"is not MessageQueueMessage!" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return MessageQueueIF::FULL;
|
return MessageQueueIF::FULL;
|
||||||
|
@ -212,7 +212,7 @@ protected:
|
|||||||
//static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault);
|
//static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::queue<MessageQueueMessage> messageQueue;
|
std::queue<std::vector<uint8_t>> messageQueue;
|
||||||
/**
|
/**
|
||||||
* @brief The class stores the queue id it got assigned.
|
* @brief The class stores the queue id it got assigned.
|
||||||
* If initialization fails, the queue id is set to zero.
|
* If initialization fails, the queue id is set to zero.
|
||||||
|
@ -21,7 +21,7 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
|
|||||||
void (*setDeadlineMissedFunc)()) :
|
void (*setDeadlineMissedFunc)()) :
|
||||||
started(false), taskName(name), period(setPeriod),
|
started(false), taskName(name), period(setPeriod),
|
||||||
deadlineMissedFunc(setDeadlineMissedFunc) {
|
deadlineMissedFunc(setDeadlineMissedFunc) {
|
||||||
// It is propably possible to set task priorities by using the native
|
// It is probably possible to set task priorities by using the native
|
||||||
// task handles for Windows / Linux
|
// task handles for Windows / Linux
|
||||||
mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this);
|
mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this);
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -38,7 +38,6 @@ PeriodicTask::~PeriodicTask(void) {
|
|||||||
if(mainThread.joinable()) {
|
if(mainThread.joinable()) {
|
||||||
mainThread.join();
|
mainThread.join();
|
||||||
}
|
}
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeriodicTask::taskEntryPoint(void* argument) {
|
void PeriodicTask::taskEntryPoint(void* argument) {
|
||||||
|
@ -10,6 +10,10 @@ QueueMapManager::QueueMapManager() {
|
|||||||
mapLock = MutexFactory::instance()->createMutex();
|
mapLock = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueueMapManager::~QueueMapManager() {
|
||||||
|
MutexFactory::instance()->deleteMutex(mapLock);
|
||||||
|
}
|
||||||
|
|
||||||
QueueMapManager* QueueMapManager::instance() {
|
QueueMapManager* QueueMapManager::instance() {
|
||||||
if (mqManagerInstance == nullptr){
|
if (mqManagerInstance == nullptr){
|
||||||
mqManagerInstance = new QueueMapManager();
|
mqManagerInstance = new QueueMapManager();
|
||||||
|
@ -36,6 +36,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
//! External instantiation is forbidden.
|
//! External instantiation is forbidden.
|
||||||
QueueMapManager();
|
QueueMapManager();
|
||||||
|
~QueueMapManager();
|
||||||
|
|
||||||
uint32_t queueCounter = 0;
|
uint32_t queueCounter = 0;
|
||||||
MutexIF* mapLock;
|
MutexIF* mapLock;
|
||||||
QueueMap queueMap;
|
QueueMap queueMap;
|
||||||
|
@ -190,13 +190,15 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
|||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}else if(status==0){
|
}
|
||||||
|
else if (status==0) {
|
||||||
//Success but no message received
|
//Success but no message received
|
||||||
return MessageQueueIF::EMPTY;
|
return MessageQueueIF::EMPTY;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
//No message was received. Keep lastPartner anyway, I might send
|
//No message was received. Keep lastPartner anyway, I might send
|
||||||
//something later. But still, delete packet content.
|
//something later. But still, delete packet content.
|
||||||
memset(message->getData(), 0, message->getMaximumMessageSize());
|
memset(message->getData(), 0, message->getMaximumDataSize());
|
||||||
switch(errno){
|
switch(errno){
|
||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages
|
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages
|
||||||
@ -371,7 +373,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
<<"mq_send to: " << sendTo << " sent from "
|
<<"mq_send to: " << sendTo << " sent from "
|
||||||
<< sentFrom << std::endl;
|
<< sentFrom << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return DESTINVATION_INVALID;
|
return DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
case EINTR:
|
case EINTR:
|
||||||
//The call was interrupted by a signal.
|
//The call was interrupted by a signal.
|
||||||
|
@ -12,54 +12,56 @@ PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
|
|||||||
}
|
}
|
||||||
|
|
||||||
PosixThread::~PosixThread() {
|
PosixThread::~PosixThread() {
|
||||||
//No deletion and no free of Stack Pointer
|
//No deletion and no free of Stack Pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PosixThread::sleep(uint64_t ns) {
|
ReturnValue_t PosixThread::sleep(uint64_t ns) {
|
||||||
//TODO sleep might be better with timer instead of sleep()
|
//TODO sleep might be better with timer instead of sleep()
|
||||||
timespec time;
|
timespec time;
|
||||||
time.tv_sec = ns/1000000000;
|
time.tv_sec = ns/1000000000;
|
||||||
time.tv_nsec = ns - time.tv_sec*1e9;
|
time.tv_nsec = ns - time.tv_sec*1e9;
|
||||||
|
|
||||||
//Remaining Time is not set here
|
//Remaining Time is not set here
|
||||||
int status = nanosleep(&time,NULL);
|
int status = nanosleep(&time,NULL);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
switch(errno){
|
switch(errno){
|
||||||
case EINTR:
|
case EINTR:
|
||||||
//The nanosleep() function was interrupted by a signal.
|
//The nanosleep() function was interrupted by a signal.
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
//The rqtp argument specified a nanosecond value less than zero or
|
//The rqtp argument specified a nanosecond value less than zero or
|
||||||
// greater than or equal to 1000 million.
|
// greater than or equal to 1000 million.
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
default:
|
default:
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PosixThread::suspend() {
|
void PosixThread::suspend() {
|
||||||
//Wait for SIGUSR1
|
//Wait for SIGUSR1
|
||||||
int caughtSig = 0;
|
int caughtSig = 0;
|
||||||
sigset_t waitSignal;
|
sigset_t waitSignal;
|
||||||
sigemptyset(&waitSignal);
|
sigemptyset(&waitSignal);
|
||||||
sigaddset(&waitSignal, SIGUSR1);
|
sigaddset(&waitSignal, SIGUSR1);
|
||||||
sigwait(&waitSignal, &caughtSig);
|
sigwait(&waitSignal, &caughtSig);
|
||||||
if (caughtSig != SIGUSR1) {
|
if (caughtSig != SIGUSR1) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FixedTimeslotTask: Unknown Signal received: " <<
|
sif::error << "FixedTimeslotTask: Unknown Signal received: " <<
|
||||||
caughtSig << std::endl;
|
caughtSig << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PosixThread::resume(){
|
void PosixThread::resume(){
|
||||||
/* Signal the thread to start. Makes sense to call kill to start or? ;)
|
/* Signal the thread to start. Makes sense to call kill to start or? ;)
|
||||||
According to POSIX raise(signal) will call pthread_kill(pthread_self(), sig),
|
*
|
||||||
but as the call must be done from the thread itself this is not possible here */
|
* According to Posix raise(signal) will call pthread_kill(pthread_self(), sig),
|
||||||
pthread_kill(thread,SIGUSR1);
|
* but as the call must be done from the thread itsself this is not possible here
|
||||||
|
*/
|
||||||
|
pthread_kill(thread,SIGUSR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
|
bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
|
||||||
@ -91,165 +93,176 @@ bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the wake time ready for the next call. */
|
/* Update the wake time ready for the next call. */
|
||||||
|
|
||||||
(*prevoiusWakeTime_ms) = nextTimeToWake_ms;
|
(*prevoiusWakeTime_ms) = nextTimeToWake_ms;
|
||||||
|
|
||||||
if (shouldDelay) {
|
if (shouldDelay) {
|
||||||
uint64_t sleepTime = nextTimeToWake_ms - currentTime_ms;
|
uint64_t sleepTime = nextTimeToWake_ms - currentTime_ms;
|
||||||
PosixThread::sleep(sleepTime * 1000000ull);
|
PosixThread::sleep(sleepTime * 1000000ull);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* We are shifting the time in case the deadline was missed like RTEMS */
|
//We are shifting the time in case the deadline was missed like rtems
|
||||||
(*prevoiusWakeTime_ms) = currentTime_ms;
|
(*prevoiusWakeTime_ms) = currentTime_ms;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint64_t PosixThread::getCurrentMonotonicTimeMs(){
|
uint64_t PosixThread::getCurrentMonotonicTimeMs(){
|
||||||
timespec timeNow;
|
timespec timeNow;
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &timeNow);
|
clock_gettime(CLOCK_MONOTONIC_RAW, &timeNow);
|
||||||
uint64_t currentTime_ms = (uint64_t) timeNow.tv_sec * 1000
|
uint64_t currentTime_ms = (uint64_t) timeNow.tv_sec * 1000
|
||||||
+ timeNow.tv_nsec / 1000000;
|
+ timeNow.tv_nsec / 1000000;
|
||||||
|
|
||||||
return currentTime_ms;
|
return currentTime_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
//sif::debug << "PosixThread::createTask" << std::endl;
|
//sif::debug << "PosixThread::createTask" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* The attr argument points to a pthread_attr_t structure whose contents
|
* The attr argument points to a pthread_attr_t structure whose contents
|
||||||
* are used at thread creation time to determine attributes for the new
|
are used at thread creation time to determine attributes for the new
|
||||||
* thread; this structure is initialized using pthread_attr_init(3) and
|
thread; this structure is initialized using pthread_attr_init(3) and
|
||||||
* related functions. If attr is NULL, then the thread is created with
|
related functions. If attr is NULL, then the thread is created with
|
||||||
* default attributes.
|
default attributes.
|
||||||
*/
|
*/
|
||||||
pthread_attr_t attributes;
|
pthread_attr_t attributes;
|
||||||
int status = pthread_attr_init(&attributes);
|
int status = pthread_attr_init(&attributes);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Posix Thread attribute init failed with: " <<
|
sif::error << "Posix Thread attribute init failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void* stackPointer;
|
void* stackPointer;
|
||||||
status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize);
|
status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PosixThread::createTask: Stack init failed with: " <<
|
sif::error << "PosixThread::createTask: Stack init failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if(errno == ENOMEM) {
|
if(errno == ENOMEM) {
|
||||||
size_t stackMb = stackSize/10e6;
|
size_t stackMb = stackSize/10e6;
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PosixThread::createTask: Insufficient memory for"
|
sif::error << "PosixThread::createTask: Insufficient memory for"
|
||||||
" the requested " << stackMb << " MB" << std::endl;
|
" the requested " << stackMb << " MB" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("PosixThread::createTask: Insufficient memory for "
|
sif::printError("PosixThread::createTask: Insufficient memory for "
|
||||||
"the requested %lu MB\n", static_cast<unsigned long>(stackMb));
|
"the requested %lu MB\n", static_cast<unsigned long>(stackMb));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if(errno == EINVAL) {
|
else if(errno == EINVAL) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PosixThread::createTask: Wrong alignment argument!"
|
sif::error << "PosixThread::createTask: Wrong alignment argument!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("PosixThread::createTask: "
|
sif::printError("PosixThread::createTask: "
|
||||||
"Wrong alignment argument!\n");
|
"Wrong alignment argument!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pthread_attr_setstack(&attributes, stackPointer, stackSize);
|
status = pthread_attr_setstack(&attributes, stackPointer, stackSize);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PosixThread::createTask: pthread_attr_setstack "
|
sif::error << "PosixThread::createTask: pthread_attr_setstack "
|
||||||
" failed with: " << strerror(status) << std::endl;
|
" failed with: " << strerror(status) << std::endl;
|
||||||
sif::error << "Make sure the specified stack size is valid and is "
|
sif::error << "Make sure the specified stack size is valid and is "
|
||||||
"larger than the minimum allowed stack size." << std::endl;
|
"larger than the minimum allowed stack size." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED);
|
status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Posix Thread attribute setinheritsched failed with: " <<
|
sif::error << "Posix Thread attribute setinheritsched failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifndef FSFW_USE_REALTIME_FOR_LINUX
|
||||||
|
#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1"
|
||||||
|
#endif
|
||||||
|
#if FSFW_USE_REALTIME_FOR_LINUX == 1
|
||||||
|
// FIFO -> This needs root privileges for the process
|
||||||
|
status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO);
|
||||||
|
if(status != 0){
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "Posix Thread attribute schedule policy failed with: " <<
|
||||||
|
strerror(status) << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// TODO FIFO -> This needs root privileges for the process
|
sched_param scheduleParams;
|
||||||
status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO);
|
scheduleParams.__sched_priority = priority;
|
||||||
if(status != 0){
|
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
|
||||||
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Posix Thread attribute schedule policy failed with: " <<
|
sif::error << "Posix Thread attribute schedule params failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
sched_param scheduleParams;
|
//Set Signal Mask for suspend until startTask is called
|
||||||
scheduleParams.__sched_priority = priority;
|
sigset_t waitSignal;
|
||||||
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
|
sigemptyset(&waitSignal);
|
||||||
if(status != 0){
|
sigaddset(&waitSignal, SIGUSR1);
|
||||||
|
status = pthread_sigmask(SIG_BLOCK, &waitSignal, NULL);
|
||||||
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Posix Thread attribute schedule params failed with: " <<
|
sif::error << "Posix Thread sigmask failed failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << " errno: " << strerror(errno) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set Signal Mask for suspend until startTask is called
|
|
||||||
sigset_t waitSignal;
|
|
||||||
sigemptyset(&waitSignal);
|
|
||||||
sigaddset(&waitSignal, SIGUSR1);
|
|
||||||
status = pthread_sigmask(SIG_BLOCK, &waitSignal, NULL);
|
|
||||||
if(status != 0){
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << "Posix Thread sigmask failed failed with: " <<
|
|
||||||
strerror(status) << " errno: " << strerror(errno) << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status = pthread_create(&thread,&attributes,fnc_,arg_);
|
status = pthread_create(&thread,&attributes,fnc_,arg_);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Posix Thread create failed with: " <<
|
sif::error << "PosixThread::createTask: Failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
|
sif::error << "For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call " <<
|
||||||
|
"\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set "
|
||||||
|
"/etc/security/limit.conf" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("PosixThread::createTask: Create failed with: %s\n", strerror(status));
|
||||||
|
sif::printError("For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call "
|
||||||
|
"\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set "
|
||||||
|
"/etc/security/limit.conf\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pthread_setname_np(thread,name);
|
status = pthread_setname_np(thread,name);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PosixThread::createTask: setname failed with: " <<
|
sif::error << "PosixThread::createTask: setname failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if(status == ERANGE) {
|
if(status == ERANGE) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PosixThread::createTask: Task name length longer"
|
sif::error << "PosixThread::createTask: Task name length longer"
|
||||||
" than 16 chars. Truncating.." << std::endl;
|
" than 16 chars. Truncating.." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
name[15] = '\0';
|
name[15] = '\0';
|
||||||
status = pthread_setname_np(thread,name);
|
status = pthread_setname_np(thread,name);
|
||||||
if(status != 0){
|
if(status != 0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PosixThread::createTask: Setting name"
|
sif::error << "PosixThread::createTask: Setting name"
|
||||||
" did not work.." << std::endl;
|
" did not work.." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pthread_attr_destroy(&attributes);
|
status = pthread_attr_destroy(&attributes);
|
||||||
if(status!=0){
|
if(status!=0){
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Posix Thread attribute destroy failed with: " <<
|
sif::error << "Posix Thread attribute destroy failed with: " <<
|
||||||
strerror(status) << std::endl;
|
strerror(status) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "TmTcUnixUdpBridge.h"
|
#include "TmTcUnixUdpBridge.h"
|
||||||
#include "tcpipHelpers.h"
|
#include "../common/tcpipHelpers.h"
|
||||||
#include "../../serviceinterface/ServiceInterface.h"
|
#include "../../serviceinterface/ServiceInterface.h"
|
||||||
#include "../../ipc/MutexGuard.h"
|
#include "../../ipc/MutexGuard.h"
|
||||||
|
|
||||||
@ -12,7 +12,7 @@
|
|||||||
//! Debugging preprocessor define.
|
//! Debugging preprocessor define.
|
||||||
#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0
|
#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0
|
||||||
|
|
||||||
const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_UDP_SERVER_PORT;
|
const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination,
|
TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination,
|
||||||
object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort):
|
object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort):
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
class TmTcUnixUdpBridge:
|
class TmTcUnixUdpBridge:
|
||||||
public TmTcBridge {
|
public TmTcBridge {
|
||||||
friend class TcUnixUdpPollingTask;
|
friend class UdpTcPollingTask;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* The ports chosen here should not be used by any other process.
|
/* The ports chosen here should not be used by any other process.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "../common/tcpipHelpers.h"
|
#include "../common/tcpipHelpers.h"
|
||||||
|
|
||||||
|
#include "../../serviceinterface/ServiceInterface.h"
|
||||||
#include "../../tasks/TaskFactory.h"
|
#include "../../tasks/TaskFactory.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -98,8 +99,8 @@ void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t s
|
|||||||
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
|
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
|
||||||
" | " << infoString << std::endl;
|
" | " << infoString << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString,
|
sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString.c_str(),
|
||||||
errorSrcString, infoString);
|
errorSrcString.c_str(), infoString.c_str());
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
|
||||||
if(sleepDuration > 0) {
|
if(sleepDuration > 0) {
|
||||||
|
@ -61,7 +61,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
|||||||
} else {
|
} else {
|
||||||
//No message was received. Keep lastPartner anyway, I might send something later.
|
//No message was received. Keep lastPartner anyway, I might send something later.
|
||||||
//But still, delete packet content.
|
//But still, delete packet content.
|
||||||
memset(message->getData(), 0, message->getMaximumMessageSize());
|
memset(message->getData(), 0, message->getMaximumDataSize());
|
||||||
}
|
}
|
||||||
return convertReturnCode(status);
|
return convertReturnCode(status);
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,7 @@ ReturnValue_t CService200ModeCommanding::prepareCommand(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModeMessage::setModeMessage(dynamic_cast<CommandMessage*>(message),
|
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
|
||||||
ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
|
|
||||||
modeCommandPacket.getSubmode());
|
modeCommandPacket.getSubmode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,9 @@ Service1TelecommandVerification::Service1TelecommandVerification(
|
|||||||
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
Service1TelecommandVerification::~Service1TelecommandVerification() {}
|
Service1TelecommandVerification::~Service1TelecommandVerification() {
|
||||||
|
QueueFactory::instance()->deleteMessageQueue(tmQueue);
|
||||||
|
}
|
||||||
|
|
||||||
MessageQueueId_t Service1TelecommandVerification::getVerificationQueue(){
|
MessageQueueId_t Service1TelecommandVerification::getVerificationQueue(){
|
||||||
return tmQueue->getId();
|
return tmQueue->getId();
|
||||||
|
@ -75,9 +75,8 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue
|
|||||||
#else
|
#else
|
||||||
sif::printError("Service20ParameterManagement::checkInterfaceAndAcquire"
|
sif::printError("Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||||
"MessageQueue: Can't access object\n");
|
"MessageQueue: Can't access object\n");
|
||||||
sif::printError("Object ID: 0x%08x\n", objectId);
|
sif::printError("Object ID: 0x%08x\n", *objectId);
|
||||||
sif::printError("Make sure it implements "
|
sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n");
|
||||||
"ReceivesParameterMessagesIF!\n");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return CommandingServiceBase::INVALID_OBJECT;
|
return CommandingServiceBase::INVALID_OBJECT;
|
||||||
|
@ -15,7 +15,9 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId,
|
|||||||
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
Service5EventReporting::~Service5EventReporting(){}
|
Service5EventReporting::~Service5EventReporting() {
|
||||||
|
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t Service5EventReporting::performService() {
|
ReturnValue_t Service5EventReporting::performService() {
|
||||||
EventMessage message;
|
EventMessage message;
|
||||||
|
@ -53,12 +53,14 @@ ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue(
|
|||||||
ReturnValue_t Service8FunctionManagement::prepareCommand(
|
ReturnValue_t Service8FunctionManagement::prepareCommand(
|
||||||
CommandMessage* message, uint8_t subservice, const uint8_t* tcData,
|
CommandMessage* message, uint8_t subservice, const uint8_t* tcData,
|
||||||
size_t tcDataLen, uint32_t* state, object_id_t objectId) {
|
size_t tcDataLen, uint32_t* state, object_id_t objectId) {
|
||||||
return prepareDirectCommand(dynamic_cast<CommandMessage*>(message),
|
return prepareDirectCommand(message, tcData, tcDataLen);
|
||||||
tcData, tcDataLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Service8FunctionManagement::prepareDirectCommand(
|
ReturnValue_t Service8FunctionManagement::prepareDirectCommand(
|
||||||
CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) {
|
CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) {
|
||||||
|
if(message == nullptr) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
if(tcDataLen < sizeof(object_id_t) + sizeof(ActionId_t)) {
|
if(tcDataLen < sizeof(object_id_t) + sizeof(ActionId_t)) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Service8FunctionManagement::prepareDirectCommand:"
|
sif::debug << "Service8FunctionManagement::prepareDirectCommand:"
|
||||||
|
@ -43,8 +43,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
DirectCommand(const DirectCommand &command);
|
DirectCommand(const DirectCommand &command);
|
||||||
object_id_t objectId;
|
object_id_t objectId = 0;
|
||||||
ActionId_t actionId;
|
ActionId_t actionId = 0;
|
||||||
uint32_t parametersSize; //!< [EXPORT] : [IGNORE]
|
uint32_t parametersSize; //!< [EXPORT] : [IGNORE]
|
||||||
const uint8_t * parameterBuffer; //!< [EXPORT] : [MAXSIZE] 65535 Bytes
|
const uint8_t * parameterBuffer; //!< [EXPORT] : [MAXSIZE] 65535 Bytes
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
SerializeElement() :
|
SerializeElement() :
|
||||||
LinkedElement<SerializeIF>(this) {
|
LinkedElement<SerializeIF>(this), entry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
|
|
||||||
SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent,
|
SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent,
|
||||||
Mode_t initialMode, uint16_t commandQueueDepth) :
|
Mode_t initialMode, uint16_t commandQueueDepth) :
|
||||||
SystemObject(setObjectId), mode(initialMode), submode(SUBMODE_NONE),
|
SystemObject(setObjectId), mode(initialMode),
|
||||||
childrenChangedMode(false),
|
|
||||||
commandQueue(QueueFactory::instance()->createMessageQueue(
|
commandQueue(QueueFactory::instance()->createMessageQueue(
|
||||||
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE)),
|
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE)),
|
||||||
healthHelper(this, setObjectId), modeHelper(this), parentId(parent) {
|
healthHelper(this, setObjectId), modeHelper(this), parentId(parent) {
|
||||||
@ -167,16 +166,16 @@ MessageQueueId_t SubsystemBase::getCommandQueue() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::initialize() {
|
ReturnValue_t SubsystemBase::initialize() {
|
||||||
MessageQueueId_t parentQueue = 0;
|
MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE;
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentId != 0) {
|
if (parentId != objects::NO_OBJECT) {
|
||||||
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
|
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
|
||||||
if (parent == NULL) {
|
if (parent == nullptr) {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
parentQueue = parent->getCommandQueue();
|
parentQueue = parent->getCommandQueue();
|
||||||
|
@ -37,6 +37,17 @@ public:
|
|||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const override;
|
virtual MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to register the child objects.
|
||||||
|
* Performs a checks if the child does implement HasHealthIF and/or HasModesIF
|
||||||
|
*
|
||||||
|
* Also adds them to the internal childrenMap.
|
||||||
|
*
|
||||||
|
* @param objectId
|
||||||
|
* @return RETURN_OK if successful
|
||||||
|
* CHILD_DOESNT_HAVE_MODES if Child is no HasHealthIF and no HasModesIF
|
||||||
|
* COULD_NOT_INSERT_CHILD If the Child could not be added to the ChildrenMap
|
||||||
|
*/
|
||||||
ReturnValue_t registerChild(object_id_t objectId);
|
ReturnValue_t registerChild(object_id_t objectId);
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
virtual ReturnValue_t initialize() override;
|
||||||
@ -56,9 +67,9 @@ protected:
|
|||||||
|
|
||||||
Mode_t mode;
|
Mode_t mode;
|
||||||
|
|
||||||
Submode_t submode;
|
Submode_t submode = SUBMODE_NONE;
|
||||||
|
|
||||||
bool childrenChangedMode;
|
bool childrenChangedMode = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always check this against <=0, so you are robust against too many replies
|
* Always check this against <=0, so you are robust against too many replies
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include "CCSDSDistributor.h"
|
#include "CCSDSDistributor.h"
|
||||||
|
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../tmtcpacket/SpacePacketBase.h"
|
#include "../tmtcpacket/SpacePacketBase.h"
|
||||||
|
|
||||||
|
#define CCSDS_DISTRIBUTOR_DEBUGGING 0
|
||||||
|
|
||||||
CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid,
|
CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid,
|
||||||
object_id_t setObjectId):
|
object_id_t setObjectId):
|
||||||
TcDistributor(setObjectId), defaultApid( setDefaultApid ) {
|
TcDistributor(setObjectId), defaultApid( setDefaultApid ) {
|
||||||
@ -11,26 +13,36 @@ CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid,
|
|||||||
CCSDSDistributor::~CCSDSDistributor() {}
|
CCSDSDistributor::~CCSDSDistributor() {}
|
||||||
|
|
||||||
TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
|
TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() {
|
||||||
|
#if CCSDS_DISTRIBUTOR_DEBUGGING == 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// sif::debug << "CCSDSDistributor::selectDestination received: " <<
|
sif::debug << "CCSDSDistributor::selectDestination received: " <<
|
||||||
// this->currentMessage.getStorageId().pool_index << ", " <<
|
this->currentMessage.getStorageId().poolIndex << ", " <<
|
||||||
// this->currentMessage.getStorageId().packet_index << std::endl;
|
this->currentMessage.getStorageId().packetIndex << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printDebug("CCSDSDistributor::selectDestination received: %d, %d\n",
|
||||||
|
currentMessage.getStorageId().poolIndex, currentMessage.getStorageId().packetIndex);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
const uint8_t* packet = nullptr;
|
const uint8_t* packet = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(),
|
ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(),
|
||||||
&packet, &size );
|
&packet, &size );
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CCSDSDistributor::selectDestination: Getting data from"
|
sif::error << "CCSDSDistributor::selectDestination: Getting data from"
|
||||||
" store failed!" << std::endl;
|
" store failed!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("CCSDSDistributor::selectDestination: Getting data from"
|
||||||
|
" store failed!\n");
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
SpacePacketBase currentPacket(packet);
|
SpacePacketBase currentPacket(packet);
|
||||||
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1 && CCSDS_DISTRIBUTOR_DEBUGGING == 1
|
||||||
// sif:: info << "CCSDSDistributor::selectDestination has packet with APID "
|
sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex <<
|
||||||
// << std::hex << currentPacket.getAPID() << std::dec << std::endl;
|
currentPacket.getAPID() << std::dec << std::endl;
|
||||||
#endif
|
#endif
|
||||||
TcMqMapIter position = this->queueMap.find(currentPacket.getAPID());
|
TcMqMapIter position = this->queueMap.find(currentPacket.getAPID());
|
||||||
if ( position != this->queueMap.end() ) {
|
if ( position != this->queueMap.end() ) {
|
||||||
@ -76,9 +88,14 @@ ReturnValue_t CCSDSDistributor::initialize() {
|
|||||||
ReturnValue_t status = this->TcDistributor::initialize();
|
ReturnValue_t status = this->TcDistributor::initialize();
|
||||||
this->tcStore = objectManager->get<StorageManagerIF>( objects::TC_STORE );
|
this->tcStore = objectManager->get<StorageManagerIF>( objects::TC_STORE );
|
||||||
if (this->tcStore == nullptr) {
|
if (this->tcStore == nullptr) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "CCSDSDistributor::initialize: Could not initialize"
|
sif::error << "CCSDSDistributor::initialize: Could not initialize"
|
||||||
" TC store!" << std::endl;
|
" TC store!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("CCSDSDistributor::initialize: Could not initialize"
|
||||||
|
" TC store!\n");
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
status = RETURN_FAILED;
|
status = RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
#include "CCSDSDistributorIF.h"
|
#include "CCSDSDistributorIF.h"
|
||||||
#include "PUSDistributor.h"
|
#include "PUSDistributor.h"
|
||||||
|
|
||||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
#include "../serviceinterface/ServiceInterface.h"
|
||||||
#include "../tmtcpacket/pus/TcPacketStored.h"
|
#include "../tmtcpacket/pus/TcPacketStored.h"
|
||||||
#include "../tmtcservices/PusVerificationReport.h"
|
#include "../tmtcservices/PusVerificationReport.h"
|
||||||
|
|
||||||
|
#define PUS_DISTRIBUTOR_DEBUGGING 0
|
||||||
|
|
||||||
PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId,
|
PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId,
|
||||||
object_id_t setPacketSource) :
|
object_id_t setPacketSource) :
|
||||||
TcDistributor(setObjectId), checker(setApid), verifyChannel(),
|
TcDistributor(setObjectId), checker(setApid), verifyChannel(),
|
||||||
tcStatus(RETURN_FAILED), packetSource(setPacketSource) {}
|
tcStatus(RETURN_FAILED), packetSource(setPacketSource) {}
|
||||||
|
|
||||||
PUSDistributor::~PUSDistributor() {}
|
PUSDistributor::~PUSDistributor() {}
|
||||||
|
|
||||||
PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
|
PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1 && PUS_DISTRIBUTOR_DEBUGGING == 1
|
||||||
// sif:: debug << "PUSDistributor::handlePacket received: "
|
store_address_t storeId = this->currentMessage.getStorageId());
|
||||||
// << this->current_packet_id.store_index << ", "
|
sif:: debug << "PUSDistributor::handlePacket received: " << storeId.poolIndex << ", " <<
|
||||||
// << this->current_packet_id.packet_index << std::endl;
|
storeId.packetIndex << std::endl;
|
||||||
#endif
|
#endif
|
||||||
TcMqMapIter queueMapIt = this->queueMap.end();
|
TcMqMapIter queueMapIt = this->queueMap.end();
|
||||||
if(this->currentPacket == nullptr) {
|
if(this->currentPacket == nullptr) {
|
||||||
@ -25,15 +27,17 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
|
|||||||
this->currentPacket->setStoreAddress(this->currentMessage.getStorageId());
|
this->currentPacket->setStoreAddress(this->currentMessage.getStorageId());
|
||||||
if (currentPacket->getWholeData() != nullptr) {
|
if (currentPacket->getWholeData() != nullptr) {
|
||||||
tcStatus = checker.checkPacket(currentPacket);
|
tcStatus = checker.checkPacket(currentPacket);
|
||||||
#ifdef DEBUG
|
|
||||||
if(tcStatus != HasReturnvaluesIF::RETURN_OK) {
|
if(tcStatus != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "PUSDistributor::handlePacket: Packet format "
|
sif::debug << "PUSDistributor::handlePacket: Packet format invalid, code " <<
|
||||||
<< "invalid, code "<< static_cast<int>(tcStatus)
|
static_cast<int>(tcStatus) << std::endl;
|
||||||
<< std::endl;
|
#else
|
||||||
|
sif::printDebug("PUSDistributor::handlePacket: Packet format invalid, code %d\n",
|
||||||
|
static_cast<int>(tcStatus));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
uint32_t queue_id = currentPacket->getService();
|
uint32_t queue_id = currentPacket->getService();
|
||||||
queueMapIt = this->queueMap.find(queue_id);
|
queueMapIt = this->queueMap.find(queue_id);
|
||||||
}
|
}
|
||||||
@ -43,11 +47,12 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
|
|||||||
|
|
||||||
if (queueMapIt == this->queueMap.end()) {
|
if (queueMapIt == this->queueMap.end()) {
|
||||||
tcStatus = DESTINATION_NOT_FOUND;
|
tcStatus = DESTINATION_NOT_FOUND;
|
||||||
#ifdef DEBUG
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "PUSDistributor::handlePacket: Destination not found, "
|
sif::debug << "PUSDistributor::handlePacket: Destination not found" << std::endl;
|
||||||
<< "code "<< static_cast<int>(tcStatus) << std::endl;
|
#else
|
||||||
#endif
|
sif::printDebug("PUSDistributor::handlePacket: Destination not found\n");
|
||||||
|
#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,46 +67,54 @@ PUSDistributor::TcMqMapIter PUSDistributor::selectDestination() {
|
|||||||
|
|
||||||
|
|
||||||
ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) {
|
ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) {
|
||||||
uint16_t serviceId = service->getIdentifier();
|
uint16_t serviceId = service->getIdentifier();
|
||||||
|
#if PUS_DISTRIBUTOR_DEBUGGING == 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// sif::info << "Service ID: " << (int)serviceId << std::endl;
|
sif::info << "Service ID: " << static_cast<int>(serviceId) << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printInfo("Service ID: %d\n", static_cast<int>(serviceId));
|
||||||
#endif
|
#endif
|
||||||
MessageQueueId_t queue = service->getRequestQueue();
|
#endif
|
||||||
auto returnPair = queueMap.emplace(serviceId, queue);
|
MessageQueueId_t queue = service->getRequestQueue();
|
||||||
if (not returnPair.second) {
|
auto returnPair = queueMap.emplace(serviceId, queue);
|
||||||
|
if (not returnPair.second) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PUSDistributor::registerService: Service ID already"
|
sif::error << "PUSDistributor::registerService: Service ID already"
|
||||||
" exists in map." << std::endl;
|
" exists in map" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("PUSDistributor::registerService: Service ID already exists in map\n");
|
||||||
#endif
|
#endif
|
||||||
return SERVICE_ID_ALREADY_EXISTS;
|
#endif
|
||||||
}
|
return SERVICE_ID_ALREADY_EXISTS;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t PUSDistributor::getRequestQueue() {
|
MessageQueueId_t PUSDistributor::getRequestQueue() {
|
||||||
return tcQueue->getId();
|
return tcQueue->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PUSDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
|
ReturnValue_t PUSDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
|
||||||
if (queueStatus != RETURN_OK) {
|
if (queueStatus != RETURN_OK) {
|
||||||
tcStatus = queueStatus;
|
tcStatus = queueStatus;
|
||||||
}
|
}
|
||||||
if (tcStatus != RETURN_OK) {
|
if (tcStatus != RETURN_OK) {
|
||||||
this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE,
|
this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE,
|
||||||
currentPacket, tcStatus);
|
currentPacket, tcStatus);
|
||||||
// A failed packet is deleted immediately after reporting,
|
// A failed packet is deleted immediately after reporting,
|
||||||
// otherwise it will block memory.
|
// otherwise it will block memory.
|
||||||
currentPacket->deletePacket();
|
currentPacket->deletePacket();
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
} else {
|
} else {
|
||||||
this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS,
|
this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS,
|
||||||
currentPacket);
|
currentPacket);
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t PUSDistributor::getIdentifier() {
|
uint16_t PUSDistributor::getIdentifier() {
|
||||||
return checker.getApid();
|
return checker.getApid();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PUSDistributor::initialize() {
|
ReturnValue_t PUSDistributor::initialize() {
|
||||||
@ -111,15 +124,17 @@ ReturnValue_t PUSDistributor::initialize() {
|
|||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCSDSDistributorIF* ccsdsDistributor =
|
CCSDSDistributorIF* ccsdsDistributor =
|
||||||
objectManager->get<CCSDSDistributorIF>(packetSource);
|
objectManager->get<CCSDSDistributorIF>(packetSource);
|
||||||
if (ccsdsDistributor == nullptr) {
|
if (ccsdsDistributor == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "PUSDistributor::initialize: Packet source invalid."
|
sif::error << "PUSDistributor::initialize: Packet source invalid" << std::endl;
|
||||||
<< " Make sure it exists and implements CCSDSDistributorIF!"
|
sif::error << " Make sure it exists and implements CCSDSDistributorIF!" << std::endl;
|
||||||
<< std::endl;
|
#else
|
||||||
|
sif::printError("PUSDistributor::initialize: Packet source invalid\n");
|
||||||
|
sif::printError("Make sure it exists and implements CCSDSDistributorIF\n");
|
||||||
#endif
|
#endif
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return ccsdsDistributor->registerApplication(this);
|
return ccsdsDistributor->registerApplication(this);
|
||||||
}
|
}
|
||||||
|
@ -1,350 +1,352 @@
|
|||||||
#include "../devicehandlers/DeviceHandlerFailureIsolation.h"
|
|
||||||
#include "Heater.h"
|
#include "Heater.h"
|
||||||
|
|
||||||
|
#include "../devicehandlers/DeviceHandlerFailureIsolation.h"
|
||||||
#include "../power/Fuse.h"
|
#include "../power/Fuse.h"
|
||||||
#include "../ipc/QueueFactory.h"
|
#include "../ipc/QueueFactory.h"
|
||||||
|
|
||||||
Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1) :
|
Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1) :
|
||||||
HealthDevice(objectId, 0), internalState(STATE_OFF), powerSwitcher(
|
HealthDevice(objectId, 0), internalState(STATE_OFF), switch0(switch0), switch1(switch1),
|
||||||
NULL), pcduQueueId(0), switch0(switch0), switch1(switch1), wasOn(
|
heaterOnCountdown(10800000)/*about two orbits*/,
|
||||||
false), timedOut(false), reactedToBeingFaulty(false), passive(
|
parameterHelper(this) {
|
||||||
false), eventQueue(NULL), heaterOnCountdown(10800000)/*about two orbits*/, parameterHelper(
|
eventQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
this), lastAction(CLEAR) {
|
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Heater::~Heater() {
|
Heater::~Heater() {
|
||||||
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Heater::set() {
|
ReturnValue_t Heater::set() {
|
||||||
passive = false;
|
passive = false;
|
||||||
//wait for clear before doing anything
|
//wait for clear before doing anything
|
||||||
if (internalState == STATE_WAIT) {
|
if (internalState == STATE_WAIT) {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
||||||
doAction(SET);
|
doAction(SET);
|
||||||
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)){
|
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
} else {
|
} else {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||||
if (!reactedToBeingFaulty) {
|
if (!reactedToBeingFaulty) {
|
||||||
reactedToBeingFaulty = true;
|
reactedToBeingFaulty = true;
|
||||||
doAction(CLEAR);
|
doAction(CLEAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heater::clear(bool passive) {
|
void Heater::clear(bool passive) {
|
||||||
this->passive = passive;
|
this->passive = passive;
|
||||||
//Force switching off
|
//Force switching off
|
||||||
if (internalState == STATE_WAIT) {
|
if (internalState == STATE_WAIT) {
|
||||||
internalState = STATE_ON;
|
internalState = STATE_ON;
|
||||||
}
|
}
|
||||||
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
||||||
doAction(CLEAR);
|
doAction(CLEAR);
|
||||||
} else if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
} else if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||||
if (!reactedToBeingFaulty) {
|
if (!reactedToBeingFaulty) {
|
||||||
reactedToBeingFaulty = true;
|
reactedToBeingFaulty = true;
|
||||||
doAction(CLEAR);
|
doAction(CLEAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heater::doAction(Action action) {
|
void Heater::doAction(Action action) {
|
||||||
//only act if we are not in the right state or in a transition
|
//only act if we are not in the right state or in a transition
|
||||||
if (action == SET) {
|
if (action == SET) {
|
||||||
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)
|
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)
|
||||||
|| (internalState == STATE_EXTERNAL_CONTROL)) {
|
|| (internalState == STATE_EXTERNAL_CONTROL)) {
|
||||||
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
||||||
internalState = STATE_WAIT_FOR_SWITCHES_ON;
|
internalState = STATE_WAIT_FOR_SWITCHES_ON;
|
||||||
powerSwitcher->sendSwitchCommand(switch0, PowerSwitchIF::SWITCH_ON);
|
powerSwitcher->sendSwitchCommand(switch0, PowerSwitchIF::SWITCH_ON);
|
||||||
powerSwitcher->sendSwitchCommand(switch1, PowerSwitchIF::SWITCH_ON);
|
powerSwitcher->sendSwitchCommand(switch1, PowerSwitchIF::SWITCH_ON);
|
||||||
}
|
}
|
||||||
} else { //clear
|
} else { //clear
|
||||||
if ((internalState == STATE_ON) || (internalState == STATE_FAULTY)
|
if ((internalState == STATE_ON) || (internalState == STATE_FAULTY)
|
||||||
|| (internalState == STATE_EXTERNAL_CONTROL)) {
|
|| (internalState == STATE_EXTERNAL_CONTROL)) {
|
||||||
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
|
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
|
||||||
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
||||||
powerSwitcher->sendSwitchCommand(switch0,
|
powerSwitcher->sendSwitchCommand(switch0,
|
||||||
PowerSwitchIF::SWITCH_OFF);
|
PowerSwitchIF::SWITCH_OFF);
|
||||||
powerSwitcher->sendSwitchCommand(switch1,
|
powerSwitcher->sendSwitchCommand(switch1,
|
||||||
PowerSwitchIF::SWITCH_OFF);
|
PowerSwitchIF::SWITCH_OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heater::setPowerSwitcher(PowerSwitchIF* powerSwitch) {
|
void Heater::setPowerSwitcher(PowerSwitchIF* powerSwitch) {
|
||||||
this->powerSwitcher = powerSwitch;
|
this->powerSwitcher = powerSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Heater::performOperation(uint8_t opCode) {
|
ReturnValue_t Heater::performOperation(uint8_t opCode) {
|
||||||
handleQueue();
|
handleQueue();
|
||||||
handleEventQueue();
|
handleEventQueue();
|
||||||
|
|
||||||
if (!healthHelper.healthTable->isFaulty(getObjectId())) {
|
if (!healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||||
reactedToBeingFaulty = false;
|
reactedToBeingFaulty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (internalState) {
|
switch (internalState) {
|
||||||
case STATE_ON:
|
case STATE_ON:
|
||||||
if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_OFF)
|
if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_OFF)
|
||||||
|| (powerSwitcher->getSwitchState(switch1)
|
|| (powerSwitcher->getSwitchState(switch1)
|
||||||
== PowerSwitchIF::SWITCH_OFF)) {
|
== PowerSwitchIF::SWITCH_OFF)) {
|
||||||
//switch went off on its own
|
//switch went off on its own
|
||||||
//trigger event. FDIR can confirm if it is caused by MniOps and decide on the action
|
//trigger event. FDIR can confirm if it is caused by MniOps and decide on the action
|
||||||
//do not trigger FD events when under external control
|
//do not trigger FD events when under external control
|
||||||
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
|
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
|
||||||
triggerEvent(PowerSwitchIF::SWITCH_WENT_OFF);
|
triggerEvent(PowerSwitchIF::SWITCH_WENT_OFF);
|
||||||
} else {
|
} else {
|
||||||
internalState = STATE_EXTERNAL_CONTROL;
|
internalState = STATE_EXTERNAL_CONTROL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_OFF:
|
case STATE_OFF:
|
||||||
//check if heater is on, ie both switches are on
|
//check if heater is on, ie both switches are on
|
||||||
//if so, just command it to off, to resolve the situation or force a switch stayed on event
|
//if so, just command it to off, to resolve the situation or force a switch stayed on event
|
||||||
//But, only do anything if not already faulty (state off is the stable point for being faulty)
|
//But, only do anything if not already faulty (state off is the stable point for being faulty)
|
||||||
if ((!healthHelper.healthTable->isFaulty(getObjectId()))
|
if ((!healthHelper.healthTable->isFaulty(getObjectId()))
|
||||||
&& (powerSwitcher->getSwitchState(switch0)
|
&& (powerSwitcher->getSwitchState(switch0)
|
||||||
== PowerSwitchIF::SWITCH_ON)
|
== PowerSwitchIF::SWITCH_ON)
|
||||||
&& (powerSwitcher->getSwitchState(switch1)
|
&& (powerSwitcher->getSwitchState(switch1)
|
||||||
== PowerSwitchIF::SWITCH_ON)) {
|
== PowerSwitchIF::SWITCH_ON)) {
|
||||||
//do not trigger FD events when under external control
|
//do not trigger FD events when under external control
|
||||||
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
|
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
|
||||||
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
|
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
|
||||||
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
||||||
powerSwitcher->sendSwitchCommand(switch0,
|
powerSwitcher->sendSwitchCommand(switch0,
|
||||||
PowerSwitchIF::SWITCH_OFF);
|
PowerSwitchIF::SWITCH_OFF);
|
||||||
powerSwitcher->sendSwitchCommand(switch1,
|
powerSwitcher->sendSwitchCommand(switch1,
|
||||||
PowerSwitchIF::SWITCH_OFF);
|
PowerSwitchIF::SWITCH_OFF);
|
||||||
} else {
|
} else {
|
||||||
internalState = STATE_EXTERNAL_CONTROL;
|
internalState = STATE_EXTERNAL_CONTROL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_PASSIVE:
|
case STATE_PASSIVE:
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_FOR_SWITCHES_ON:
|
case STATE_WAIT_FOR_SWITCHES_ON:
|
||||||
if (switchCountdown.hasTimedOut()) {
|
if (switchCountdown.hasTimedOut()) {
|
||||||
if ((powerSwitcher->getSwitchState(switch0)
|
if ((powerSwitcher->getSwitchState(switch0)
|
||||||
== PowerSwitchIF::SWITCH_OFF)
|
== PowerSwitchIF::SWITCH_OFF)
|
||||||
|| (powerSwitcher->getSwitchState(switch1)
|
|| (powerSwitcher->getSwitchState(switch1)
|
||||||
== PowerSwitchIF::SWITCH_OFF)) {
|
== PowerSwitchIF::SWITCH_OFF)) {
|
||||||
triggerEvent(HEATER_STAYED_OFF);
|
triggerEvent(HEATER_STAYED_OFF);
|
||||||
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
|
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(HEATER_ON);
|
triggerEvent(HEATER_ON);
|
||||||
internalState = STATE_ON;
|
internalState = STATE_ON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_FOR_SWITCHES_OFF:
|
case STATE_WAIT_FOR_SWITCHES_OFF:
|
||||||
if (switchCountdown.hasTimedOut()) {
|
if (switchCountdown.hasTimedOut()) {
|
||||||
//only check for both being on (ie heater still on)
|
//only check for both being on (ie heater still on)
|
||||||
if ((powerSwitcher->getSwitchState(switch0)
|
if ((powerSwitcher->getSwitchState(switch0)
|
||||||
== PowerSwitchIF::SWITCH_ON)
|
== PowerSwitchIF::SWITCH_ON)
|
||||||
&& (powerSwitcher->getSwitchState(switch1)
|
&& (powerSwitcher->getSwitchState(switch1)
|
||||||
== PowerSwitchIF::SWITCH_ON)) {
|
== PowerSwitchIF::SWITCH_ON)) {
|
||||||
if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||||
if (passive) {
|
if (passive) {
|
||||||
internalState = STATE_PASSIVE;
|
internalState = STATE_PASSIVE;
|
||||||
} else {
|
} else {
|
||||||
internalState = STATE_OFF; //just accept it
|
internalState = STATE_OFF; //just accept it
|
||||||
}
|
}
|
||||||
triggerEvent(HEATER_ON); //but throw an event to make it more visible
|
triggerEvent(HEATER_ON); //but throw an event to make it more visible
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
triggerEvent(HEATER_STAYED_ON);
|
triggerEvent(HEATER_STAYED_ON);
|
||||||
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
|
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(HEATER_OFF);
|
triggerEvent(HEATER_OFF);
|
||||||
if (passive) {
|
if (passive) {
|
||||||
internalState = STATE_PASSIVE;
|
internalState = STATE_PASSIVE;
|
||||||
} else {
|
} else {
|
||||||
internalState = STATE_OFF;
|
internalState = STATE_OFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_ON)
|
if ((powerSwitcher->getSwitchState(switch0) == PowerSwitchIF::SWITCH_ON)
|
||||||
&& (powerSwitcher->getSwitchState(switch1)
|
&& (powerSwitcher->getSwitchState(switch1)
|
||||||
== PowerSwitchIF::SWITCH_ON)) {
|
== PowerSwitchIF::SWITCH_ON)) {
|
||||||
if (wasOn) {
|
if (wasOn) {
|
||||||
if (heaterOnCountdown.hasTimedOut()) {
|
if (heaterOnCountdown.hasTimedOut()) {
|
||||||
//SHOULDDO this means if a heater fails in single mode, the timeout will start again
|
//SHOULDDO this means if a heater fails in single mode, the timeout will start again
|
||||||
//I am not sure if this is a bug, but atm I have no idea how to fix this and think
|
//I am not sure if this is a bug, but atm I have no idea how to fix this and think
|
||||||
//it will be ok. whatcouldpossiblygowrong™
|
//it will be ok. whatcouldpossiblygowrong™
|
||||||
if (!timedOut) {
|
if (!timedOut) {
|
||||||
triggerEvent(HEATER_TIMEOUT);
|
triggerEvent(HEATER_TIMEOUT);
|
||||||
timedOut = true;
|
timedOut = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wasOn = true;
|
wasOn = true;
|
||||||
heaterOnCountdown.resetTimer();
|
heaterOnCountdown.resetTimer();
|
||||||
timedOut = false;
|
timedOut = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wasOn = false;
|
wasOn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heater::setSwitch(uint8_t number, ReturnValue_t state,
|
void Heater::setSwitch(uint8_t number, ReturnValue_t state,
|
||||||
uint32_t* uptimeOfSwitching) {
|
uint32_t* uptimeOfSwitching) {
|
||||||
if (powerSwitcher == NULL) {
|
if (powerSwitcher == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (powerSwitcher->getSwitchState(number) == state) {
|
if (powerSwitcher->getSwitchState(number) == state) {
|
||||||
*uptimeOfSwitching = INVALID_UPTIME;
|
*uptimeOfSwitching = INVALID_UPTIME;
|
||||||
} else {
|
} else {
|
||||||
if ((*uptimeOfSwitching == INVALID_UPTIME)) {
|
if ((*uptimeOfSwitching == INVALID_UPTIME)) {
|
||||||
powerSwitcher->sendSwitchCommand(number, state);
|
powerSwitcher->sendSwitchCommand(number, state);
|
||||||
Clock::getUptime(uptimeOfSwitching);
|
Clock::getUptime(uptimeOfSwitching);
|
||||||
} else {
|
} else {
|
||||||
uint32_t currentUptime;
|
uint32_t currentUptime;
|
||||||
Clock::getUptime(¤tUptime);
|
Clock::getUptime(¤tUptime);
|
||||||
if (currentUptime - *uptimeOfSwitching
|
if (currentUptime - *uptimeOfSwitching
|
||||||
> powerSwitcher->getSwitchDelayMs()) {
|
> powerSwitcher->getSwitchDelayMs()) {
|
||||||
*uptimeOfSwitching = INVALID_UPTIME;
|
*uptimeOfSwitching = INVALID_UPTIME;
|
||||||
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
||||||
if (state == PowerSwitchIF::SWITCH_ON) {
|
if (state == PowerSwitchIF::SWITCH_ON) {
|
||||||
triggerEvent(HEATER_STAYED_OFF);
|
triggerEvent(HEATER_STAYED_OFF);
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(HEATER_STAYED_ON);
|
triggerEvent(HEATER_STAYED_ON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//SHOULDDO MiniOps during switch timeout leads to a faulty switch
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t Heater::getCommandQueue() const {
|
MessageQueueId_t Heater::getCommandQueue() const {
|
||||||
return commandQueue->getId();
|
return commandQueue->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Heater::initialize() {
|
ReturnValue_t Heater::initialize() {
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManagerIF* manager = objectManager->get<EventManagerIF>(
|
EventManagerIF* manager = objectManager->get<EventManagerIF>(
|
||||||
objects::EVENT_MANAGER);
|
objects::EVENT_MANAGER);
|
||||||
if (manager == NULL) {
|
if (manager == NULL) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
result = manager->registerListener(eventQueue->getId());
|
result = manager->registerListener(eventQueue->getId());
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmsFailuresIF* pcdu = objectManager->get<ConfirmsFailuresIF>(
|
ConfirmsFailuresIF* pcdu = objectManager->get<ConfirmsFailuresIF>(
|
||||||
DeviceHandlerFailureIsolation::powerConfirmationId);
|
DeviceHandlerFailureIsolation::powerConfirmationId);
|
||||||
if (pcdu == NULL) {
|
if (pcdu == NULL) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
pcduQueueId = pcdu->getEventReceptionQueue();
|
pcduQueueId = pcdu->getEventReceptionQueue();
|
||||||
|
|
||||||
result = manager->subscribeToAllEventsFrom(eventQueue->getId(),
|
result = manager->subscribeToAllEventsFrom(eventQueue->getId(),
|
||||||
getObjectId());
|
getObjectId());
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = parameterHelper.initialize();
|
result = parameterHelper.initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = healthHelper.initialize();
|
result = healthHelper.initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heater::handleQueue() {
|
void Heater::handleQueue() {
|
||||||
CommandMessage command;
|
CommandMessage command;
|
||||||
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
result = healthHelper.handleHealthCommand(&command);
|
result = healthHelper.handleHealthCommand(&command);
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
parameterHelper.handleParameterMessage(&command);
|
result = parameterHelper.handleParameterMessage(&command);
|
||||||
}
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Heater::getParameter(uint8_t domainId, uint8_t uniqueId,
|
ReturnValue_t Heater::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||||
uint16_t startAtIndex) {
|
uint16_t startAtIndex) {
|
||||||
if (domainId != DOMAIN_ID_BASE) {
|
if (domainId != DOMAIN_ID_BASE) {
|
||||||
return INVALID_DOMAIN_ID;
|
return INVALID_DOMAIN_ID;
|
||||||
}
|
}
|
||||||
switch (uniqueId) {
|
switch (uniqueId) {
|
||||||
case 0:
|
case 0:
|
||||||
parameterWrapper->set(heaterOnCountdown.timeout);
|
parameterWrapper->set(heaterOnCountdown.timeout);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heater::handleEventQueue() {
|
void Heater::handleEventQueue() {
|
||||||
EventMessage event;
|
EventMessage event;
|
||||||
for (ReturnValue_t result = eventQueue->receiveMessage(&event);
|
for (ReturnValue_t result = eventQueue->receiveMessage(&event);
|
||||||
result == HasReturnvaluesIF::RETURN_OK;
|
result == HasReturnvaluesIF::RETURN_OK;
|
||||||
result = eventQueue->receiveMessage(&event)) {
|
result = eventQueue->receiveMessage(&event)) {
|
||||||
switch (event.getMessageId()) {
|
switch (event.getMessageId()) {
|
||||||
case EventMessage::EVENT_MESSAGE:
|
case EventMessage::EVENT_MESSAGE:
|
||||||
switch (event.getEvent()) {
|
switch (event.getEvent()) {
|
||||||
case Fuse::FUSE_WENT_OFF:
|
case Fuse::FUSE_WENT_OFF:
|
||||||
case HEATER_STAYED_OFF:
|
case HEATER_STAYED_OFF:
|
||||||
case HEATER_STAYED_ON://Setting it faulty does not help, but we need to reach a stable state and can check for being faulty before throwing this event again.
|
// HEATER_STAYED_ON is a setting if faulty does not help, but we need to reach a stable state and can check
|
||||||
if (healthHelper.healthTable->isCommandable(getObjectId())) {
|
// for being faulty before throwing this event again.
|
||||||
healthHelper.setHealth(HasHealthIF::FAULTY);
|
case HEATER_STAYED_ON:
|
||||||
internalState = STATE_FAULTY;
|
if (healthHelper.healthTable->isCommandable(getObjectId())) {
|
||||||
}
|
healthHelper.setHealth(HasHealthIF::FAULTY);
|
||||||
break;
|
internalState = STATE_FAULTY;
|
||||||
case PowerSwitchIF::SWITCH_WENT_OFF:
|
}
|
||||||
internalState = STATE_WAIT;
|
break;
|
||||||
event.setMessageId(EventMessage::CONFIRMATION_REQUEST);
|
case PowerSwitchIF::SWITCH_WENT_OFF:
|
||||||
if (pcduQueueId != 0) {
|
internalState = STATE_WAIT;
|
||||||
eventQueue->sendMessage(pcduQueueId, &event);
|
event.setMessageId(EventMessage::CONFIRMATION_REQUEST);
|
||||||
} else {
|
if (pcduQueueId != 0) {
|
||||||
healthHelper.setHealth(HasHealthIF::FAULTY);
|
eventQueue->sendMessage(pcduQueueId, &event);
|
||||||
internalState = STATE_FAULTY;
|
} else {
|
||||||
}
|
healthHelper.setHealth(HasHealthIF::FAULTY);
|
||||||
break;
|
internalState = STATE_FAULTY;
|
||||||
default:
|
}
|
||||||
return;
|
break;
|
||||||
}
|
default:
|
||||||
break;
|
return;
|
||||||
case EventMessage::YOUR_FAULT:
|
}
|
||||||
healthHelper.setHealth(HasHealthIF::FAULTY);
|
break;
|
||||||
internalState = STATE_FAULTY;
|
case EventMessage::YOUR_FAULT:
|
||||||
break;
|
healthHelper.setHealth(HasHealthIF::FAULTY);
|
||||||
case EventMessage::MY_FAULT:
|
internalState = STATE_FAULTY;
|
||||||
//do nothing, we are already in STATE_WAIT and wait for a clear()
|
break;
|
||||||
break;
|
case EventMessage::MY_FAULT:
|
||||||
default:
|
//do nothing, we are already in STATE_WAIT and wait for a clear()
|
||||||
return;
|
break;
|
||||||
}
|
default:
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
115
thermal/Heater.h
115
thermal/Heater.h
@ -1,90 +1,93 @@
|
|||||||
#ifndef FRAMEWORK_THERMAL_HEATER_H_
|
#ifndef FSFW_THERMAL_HEATER_H_
|
||||||
#define FRAMEWORK_THERMAL_HEATER_H_
|
#define FSFW_THERMAL_HEATER_H_
|
||||||
|
|
||||||
#include "../devicehandlers/HealthDevice.h"
|
#include "../devicehandlers/HealthDevice.h"
|
||||||
#include "../parameters/ParameterHelper.h"
|
#include "../parameters/ParameterHelper.h"
|
||||||
#include "../power/PowerSwitchIF.h"
|
#include "../power/PowerSwitchIF.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../timemanager/Countdown.h"
|
#include "../timemanager/Countdown.h"
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
//class RedundantHeater;
|
|
||||||
|
|
||||||
class Heater: public HealthDevice, public ReceivesParameterMessagesIF {
|
class Heater: public HealthDevice, public ReceivesParameterMessagesIF {
|
||||||
friend class RedundantHeater;
|
friend class RedundantHeater;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER;
|
||||||
static const Event HEATER_ON = MAKE_EVENT(0, severity::INFO);
|
static const Event HEATER_ON = MAKE_EVENT(0, severity::INFO);
|
||||||
static const Event HEATER_OFF = MAKE_EVENT(1, severity::INFO);
|
static const Event HEATER_OFF = MAKE_EVENT(1, severity::INFO);
|
||||||
static const Event HEATER_TIMEOUT = MAKE_EVENT(2, severity::LOW);
|
static const Event HEATER_TIMEOUT = MAKE_EVENT(2, severity::LOW);
|
||||||
static const Event HEATER_STAYED_ON = MAKE_EVENT(3, severity::LOW);
|
static const Event HEATER_STAYED_ON = MAKE_EVENT(3, severity::LOW);
|
||||||
static const Event HEATER_STAYED_OFF = MAKE_EVENT(4, severity::LOW);
|
static const Event HEATER_STAYED_OFF = MAKE_EVENT(4, severity::LOW);
|
||||||
|
|
||||||
Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1);
|
Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1);
|
||||||
virtual ~Heater();
|
virtual ~Heater();
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t opCode);
|
ReturnValue_t performOperation(uint8_t opCode);
|
||||||
|
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
|
|
||||||
ReturnValue_t set();
|
ReturnValue_t set();
|
||||||
void clear(bool passive);
|
void clear(bool passive);
|
||||||
|
|
||||||
void setPowerSwitcher(PowerSwitchIF *powerSwitch);
|
void setPowerSwitcher(PowerSwitchIF *powerSwitch);
|
||||||
|
|
||||||
MessageQueueId_t getCommandQueue() const;
|
MessageQueueId_t getCommandQueue() const;
|
||||||
|
|
||||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||||
ParameterWrapper *parameterWrapper,
|
ParameterWrapper *parameterWrapper,
|
||||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const uint32_t INVALID_UPTIME = 0;
|
static const uint32_t INVALID_UPTIME = 0;
|
||||||
|
|
||||||
enum InternalState {
|
enum InternalState {
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
STATE_PASSIVE,
|
STATE_PASSIVE,
|
||||||
STATE_WAIT_FOR_SWITCHES_ON,
|
STATE_WAIT_FOR_SWITCHES_ON,
|
||||||
STATE_WAIT_FOR_SWITCHES_OFF,
|
STATE_WAIT_FOR_SWITCHES_OFF,
|
||||||
STATE_WAIT_FOR_FDIR, //used to avoid doing anything until fdir decided what to do
|
STATE_WAIT_FOR_FDIR, // Used to avoid doing anything until fdir decided what to do
|
||||||
STATE_FAULTY,
|
STATE_FAULTY,
|
||||||
STATE_WAIT, //used when waiting for system to recover from miniops
|
STATE_WAIT, // Used when waiting for system to recover from miniops
|
||||||
STATE_EXTERNAL_CONTROL //entered when under external control and a fdir reaction would be triggered. This is useful when leaving external control into an unknown state
|
// Entered when under external control and a fdir reaction would be triggered.
|
||||||
//if no fdir reaction is triggered under external control the state is still ok and no need for any special treatment is needed
|
// This is useful when leaving external control into an unknown state
|
||||||
} internalState;
|
STATE_EXTERNAL_CONTROL
|
||||||
|
// If no fdir reaction is triggered under external control the state is still ok and
|
||||||
|
// no need for any special treatment is needed
|
||||||
|
} internalState;
|
||||||
|
|
||||||
PowerSwitchIF *powerSwitcher;
|
PowerSwitchIF *powerSwitcher = nullptr;
|
||||||
MessageQueueId_t pcduQueueId;
|
MessageQueueId_t pcduQueueId = MessageQueueIF::NO_QUEUE;
|
||||||
|
|
||||||
uint8_t switch0;
|
uint8_t switch0;
|
||||||
uint8_t switch1;
|
uint8_t switch1;
|
||||||
|
|
||||||
bool wasOn;
|
bool wasOn = false;
|
||||||
|
|
||||||
bool timedOut;
|
bool timedOut = false;
|
||||||
|
|
||||||
bool reactedToBeingFaulty;
|
bool reactedToBeingFaulty = false;
|
||||||
|
|
||||||
bool passive;
|
bool passive = false;
|
||||||
|
|
||||||
MessageQueueIF* eventQueue;
|
MessageQueueIF* eventQueue = nullptr;
|
||||||
Countdown heaterOnCountdown;
|
Countdown heaterOnCountdown;
|
||||||
Countdown switchCountdown;
|
Countdown switchCountdown;
|
||||||
ParameterHelper parameterHelper;
|
ParameterHelper parameterHelper;
|
||||||
|
|
||||||
enum Action {
|
enum Action {
|
||||||
SET, CLEAR
|
SET, CLEAR
|
||||||
} lastAction;
|
} lastAction = CLEAR;
|
||||||
|
|
||||||
void doAction(Action action);
|
void doAction(Action action);
|
||||||
|
|
||||||
void setSwitch(uint8_t number, ReturnValue_t state,
|
void setSwitch(uint8_t number, ReturnValue_t state,
|
||||||
uint32_t *upTimeOfSwitching);
|
uint32_t *upTimeOfSwitching);
|
||||||
|
|
||||||
void handleQueue();
|
void handleQueue();
|
||||||
|
|
||||||
void handleEventQueue();
|
void handleEventQueue();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_THERMAL_HEATER_H_ */
|
#endif /* FSFW_THERMAL_HEATER_H_ */
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#ifndef TEMPERATURESENSOR_H_
|
#ifndef FSFW_THERMAL_TEMPERATURESENSOR_H_
|
||||||
#define TEMPERATURESENSOR_H_
|
#define FSFW_THERMAL_TEMPERATURESENSOR_H_
|
||||||
|
|
||||||
#include "../thermal/AbstractTemperatureSensor.h"
|
#include "tcsDefinitions.h"
|
||||||
#include "../datapoolglob/GlobalDataSet.h"
|
#include "AbstractTemperatureSensor.h"
|
||||||
#include "../datapoolglob/GlobalPoolVariable.h"
|
|
||||||
|
#include "../datapoollocal/LocalPoolDataSetBase.h"
|
||||||
|
#include "../datapoollocal/LocalPoolVariable.h"
|
||||||
#include "../monitoring/LimitMonitor.h"
|
#include "../monitoring/LimitMonitor.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This building block handles non-linear value conversion and
|
* @brief This building block handles non-linear value conversion and
|
||||||
* range checks for analog temperature sensors.
|
* range checks for analog temperature sensors.
|
||||||
@ -57,27 +60,25 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate Temperature Sensor Object.
|
* Instantiate Temperature Sensor Object.
|
||||||
* @param setObjectid objectId of the sensor object
|
* @param setObjectid objectId of the sensor object
|
||||||
* @param inputValue Input value which is converted to a temperature
|
* @param inputTemperature Pointer to a raw input value which is converted to an floating
|
||||||
* @param poolVariable Pool Variable to store the temperature value
|
* point C output temperature
|
||||||
* @param vectorIndex Vector Index for the sensor monitor
|
* @param outputGpid Global Pool ID of the output value
|
||||||
* @param parameters Calculation parameters, temperature limits, gradient limit
|
* @param vectorIndex Vector Index for the sensor monitor
|
||||||
* @param datapoolId Datapool ID of the output temperature
|
* @param parameters Calculation parameters, temperature limits, gradient limit
|
||||||
* @param outputSet Output dataset for the output temperature to fetch it with read()
|
* @param outputSet Output dataset for the output temperature to fetch it with read()
|
||||||
* @param thermalModule respective thermal module, if it has one
|
* @param thermalModule Respective thermal module, if it has one
|
||||||
*/
|
*/
|
||||||
TemperatureSensor(object_id_t setObjectid,
|
TemperatureSensor(object_id_t setObjectid,lp_var_t<limitType>* inputTemperature,
|
||||||
inputType *inputValue, PoolVariableIF *poolVariable,
|
gp_id_t outputGpid, uint8_t vectorIndex, Parameters parameters = {0, 0, 0, 0, 0, 0},
|
||||||
uint8_t vectorIndex, uint32_t datapoolId, Parameters parameters = {0, 0, 0, 0, 0, 0},
|
LocalPoolDataSetBase *outputSet = nullptr, ThermalModuleIF *thermalModule = nullptr) :
|
||||||
GlobDataSet *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) :
|
|
||||||
AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters),
|
AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters),
|
||||||
inputValue(inputValue), poolVariable(poolVariable),
|
inputTemperature(inputTemperature),
|
||||||
outputTemperature(datapoolId, outputSet, PoolVariableIF::VAR_WRITE),
|
outputTemperature(outputGpid, outputSet, PoolVariableIF::VAR_WRITE),
|
||||||
sensorMonitor(setObjectid, DOMAIN_ID_SENSOR,
|
sensorMonitor(setObjectid, DOMAIN_ID_SENSOR, outputGpid,
|
||||||
GlobalDataPool::poolIdAndPositionToPid(poolVariable->getDataPoolId(), vectorIndex),
|
|
||||||
DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit,
|
DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit,
|
||||||
TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH),
|
TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH),
|
||||||
oldTemperature(20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) {
|
oldTemperature(20), uptimeOfOldTemperature({ thermal::INVALID_TEMPERATURE, 0 }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void setInvalid() {
|
void setInvalid() {
|
||||||
outputTemperature = INVALID_TEMPERATURE;
|
outputTemperature = thermal::INVALID_TEMPERATURE;
|
||||||
outputTemperature.setValid(false);
|
outputTemperature.setValid(false);
|
||||||
uptimeOfOldTemperature.tv_sec = INVALID_UPTIME;
|
uptimeOfOldTemperature.tv_sec = INVALID_UPTIME;
|
||||||
sensorMonitor.setToInvalid();
|
sensorMonitor.setToInvalid();
|
||||||
@ -108,11 +109,8 @@ protected:
|
|||||||
|
|
||||||
UsedParameters parameters;
|
UsedParameters parameters;
|
||||||
|
|
||||||
inputType * inputValue;
|
lp_var_t<limitType>* inputTemperature;
|
||||||
|
lp_var_t<float> outputTemperature;
|
||||||
PoolVariableIF *poolVariable;
|
|
||||||
|
|
||||||
gp_float_t outputTemperature;
|
|
||||||
|
|
||||||
LimitMonitor<limitType> sensorMonitor;
|
LimitMonitor<limitType> sensorMonitor;
|
||||||
|
|
||||||
@ -120,22 +118,27 @@ protected:
|
|||||||
timeval uptimeOfOldTemperature;
|
timeval uptimeOfOldTemperature;
|
||||||
|
|
||||||
void doChildOperation() {
|
void doChildOperation() {
|
||||||
if (!poolVariable->isValid()
|
ReturnValue_t result = inputTemperature->read(MutexIF::TimeoutType::WAITING, 20);
|
||||||
|| !healthHelper.healthTable->isHealthy(getObjectId())) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((not inputTemperature->isValid()) or
|
||||||
|
(not healthHelper.healthTable->isHealthy(getObjectId()))) {
|
||||||
setInvalid();
|
setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputTemperature = calculateOutputTemperature(*inputValue);
|
outputTemperature = calculateOutputTemperature(inputTemperature->value);
|
||||||
outputTemperature.setValid(PoolVariableIF::VALID);
|
outputTemperature.setValid(PoolVariableIF::VALID);
|
||||||
|
|
||||||
timeval uptime;
|
timeval uptime;
|
||||||
Clock::getUptime(&uptime);
|
Clock::getUptime(&uptime);
|
||||||
|
|
||||||
if (uptimeOfOldTemperature.tv_sec != INVALID_UPTIME) {
|
if (uptimeOfOldTemperature.tv_sec != INVALID_UPTIME) {
|
||||||
//In theory, we could use an AbsValueMonitor to monitor the gradient.
|
// In theory, we could use an AbsValueMonitor to monitor the gradient.
|
||||||
//But this would require storing the maxGradient in DP and quite some overhead.
|
// But this would require storing the maxGradient in DP and quite some overhead.
|
||||||
//The concept of delta limits is a bit strange anyway.
|
// The concept of delta limits is a bit strange anyway.
|
||||||
float deltaTime;
|
float deltaTime;
|
||||||
float deltaTemp;
|
float deltaTemp;
|
||||||
|
|
||||||
@ -148,17 +151,17 @@ protected:
|
|||||||
}
|
}
|
||||||
if (parameters.gradient < deltaTemp / deltaTime) {
|
if (parameters.gradient < deltaTemp / deltaTime) {
|
||||||
triggerEvent(TEMP_SENSOR_GRADIENT);
|
triggerEvent(TEMP_SENSOR_GRADIENT);
|
||||||
//Don't set invalid, as we did not recognize it as invalid with full authority, let FDIR handle it
|
// Don't set invalid, as we did not recognize it as invalid with full authority,
|
||||||
|
// let FDIR handle it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check is done against raw limits. SHOULDDO: Why? Using <20>C would be more easy to handle.
|
|
||||||
sensorMonitor.doCheck(outputTemperature.value);
|
sensorMonitor.doCheck(outputTemperature.value);
|
||||||
|
|
||||||
if (sensorMonitor.isOutOfLimits()) {
|
if (sensorMonitor.isOutOfLimits()) {
|
||||||
uptimeOfOldTemperature.tv_sec = INVALID_UPTIME;
|
uptimeOfOldTemperature.tv_sec = INVALID_UPTIME;
|
||||||
outputTemperature.setValid(PoolVariableIF::INVALID);
|
outputTemperature.setValid(PoolVariableIF::INVALID);
|
||||||
outputTemperature = INVALID_TEMPERATURE;
|
outputTemperature = thermal::INVALID_TEMPERATURE;
|
||||||
} else {
|
} else {
|
||||||
oldTemperature = outputTemperature;
|
oldTemperature = outputTemperature;
|
||||||
uptimeOfOldTemperature = uptime;
|
uptimeOfOldTemperature = uptime;
|
||||||
@ -179,7 +182,10 @@ public:
|
|||||||
static const uint16_t ADDRESS_C = 2;
|
static const uint16_t ADDRESS_C = 2;
|
||||||
static const uint16_t ADDRESS_GRADIENT = 3;
|
static const uint16_t ADDRESS_GRADIENT = 3;
|
||||||
|
|
||||||
static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1; //!< Changed due to issue with later temperature checking even tough the sensor monitor was confirming already (Was 10 before with comment = Correlates to a 10s confirmation time. Chosen rather large, should not be so bad for components and helps survive glitches.)
|
//! Changed due to issue with later temperature checking even tough the sensor monitor was
|
||||||
|
//! confirming already (Was 10 before with comment = Correlates to a 10s confirmation time.
|
||||||
|
//! Chosen rather large, should not be so bad for components and helps survive glitches.)
|
||||||
|
static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1;
|
||||||
|
|
||||||
static const uint8_t DOMAIN_ID_SENSOR = 1;
|
static const uint8_t DOMAIN_ID_SENSOR = 1;
|
||||||
|
|
||||||
@ -219,4 +225,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TEMPERATURESENSOR_H_ */
|
#endif /* FSFW_THERMAL_TEMPERATURESENSOR_H_ */
|
||||||
|
@ -25,6 +25,6 @@ uint32_t TimeMessage::getCounterValue() {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TimeMessage::getMinimumMessageSize() {
|
size_t TimeMessage::getMinimumMessageSize() const {
|
||||||
return this->MAX_SIZE;
|
return this->MAX_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ protected:
|
|||||||
* @brief This call always returns the same fixed size of the message.
|
* @brief This call always returns the same fixed size of the message.
|
||||||
* @return Returns HEADER_SIZE + \c sizeof(timeval) + sizeof(uint32_t).
|
* @return Returns HEADER_SIZE + \c sizeof(timeval) + sizeof(uint32_t).
|
||||||
*/
|
*/
|
||||||
size_t getMinimumMessageSize();
|
size_t getMinimumMessageSize() const override;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +16,9 @@ TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
|||||||
createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
|
createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
TmTcBridge::~TmTcBridge() {}
|
TmTcBridge::~TmTcBridge() {
|
||||||
|
QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue);
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(
|
ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(
|
||||||
uint8_t sentPacketsPerCycle) {
|
uint8_t sentPacketsPerCycle) {
|
||||||
|
Loading…
Reference in New Issue
Block a user