Merge remote-tracking branch 'upstream/development' into fsfw_update

This commit is contained in:
2023-05-04 12:37:18 +02:00
48 changed files with 855 additions and 294 deletions
@@ -1,5 +1,6 @@
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/datapool/PoolReadGuard.h"
#include "fsfw/datapoollocal/LocalPoolVariable.h"
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
@@ -1508,7 +1509,10 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
for (const auto& reply : deviceReplyMap) {
if (reply.second.dataSet != nullptr) {
reply.second.dataSet->setValidity(false, true);
PoolReadGuard pg(reply.second.dataSet);
if (pg.getReadResult() == returnvalue::OK) {
reply.second.dataSet->setValidity(false, true);
}
}
}
}
+6
View File
@@ -23,6 +23,7 @@ EventManager::EventManager(object_id_t setObjectId)
}
EventManager::~EventManager() {
listenerList.clear();
QueueFactory::instance()->deleteMessageQueue(eventReportQueue);
MutexFactory::instance()->deleteMutex(mutex);
}
@@ -61,9 +62,14 @@ ReturnValue_t EventManager::registerListener(MessageQueueId_t listener,
if (!result.second) {
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t EventManager::unregisterListener(MessageQueueId_t listener) {
return listenerList.erase(listener) == 1 ? returnvalue::OK : returnvalue::FAILED;
}
ReturnValue_t EventManager::subscribeToEvent(MessageQueueId_t listener, EventId_t event) {
return subscribeToEventRange(listener, event);
}
+1
View File
@@ -31,6 +31,7 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
MessageQueueId_t getEventReportQueue();
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
ReturnValue_t unregisterListener(MessageQueueId_t listener) override;
ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event);
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
+1
View File
@@ -18,6 +18,7 @@ class EventManagerIF {
virtual ReturnValue_t registerListener(MessageQueueId_t listener,
bool forwardAllButSelected = false) = 0;
virtual ReturnValue_t unregisterListener(MessageQueueId_t listener) = 0;
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0;
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 0;
virtual ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) = 0;
+1 -1
View File
@@ -23,7 +23,7 @@ FailureIsolationBase::~FailureIsolationBase() {
#endif
return;
}
manager->unsubscribeFromAllEvents(eventQueue->getId(), ownerId);
manager->unregisterListener(eventQueue->getId());
QueueFactory::instance()->deleteMessageQueue(eventQueue);
}
+40 -1
View File
@@ -24,7 +24,7 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
MatchTree(iterator root, uint8_t maxDepth = -1)
: BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(maxDepth) {}
MatchTree() : BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {}
virtual ~MatchTree() {}
virtual ~MatchTree() { clear(); }
virtual bool match(T number) override { return matchesTree(number); }
bool matchesTree(T number) {
iterator iter = this->begin();
@@ -176,6 +176,45 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
return cleanUpElement(position);
}
void clear() {
Node* localRoot = BinaryTree<SerializeableMatcherIF<T>>::rootNode;
if (localRoot == nullptr) {
return;
}
Node* node = localRoot->left;
while (true) {
if (node->left != nullptr) {
node = node->left;
continue;
}
if (node->right != nullptr) {
node = node->right;
continue;
}
if (node->parent == nullptr) {
// this is the root node with no children
if (node->value != nullptr) {
cleanUpElement(iterator(node));
}
return;
}
// leaf
{
Node* parent = node->parent;
if (parent->left == node) {
parent->left = nullptr;
} else {
parent->right = nullptr;
}
cleanUpElement(iterator(node));
node = parent;
}
}
}
virtual ReturnValue_t cleanUpElement(iterator position) { return returnvalue::OK; }
bool matchSubtree(iterator iter, T number) {
+13 -15
View File
@@ -16,26 +16,24 @@ class HasHealthIF {
};
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
static constexpr ReturnValue_t OBJECT_NOT_HEALTHY = returnvalue::makeCode(INTERFACE_ID, 1);
static constexpr ReturnValue_t INVALID_HEALTH_STATE = returnvalue::makeCode(INTERFACE_ID, 2);
static constexpr ReturnValue_t IS_EXTERNALLY_CONTROLLED = returnvalue::makeCode(INTERFACE_ID, 3);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
//! P1: New Health, P2: Old Health
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
static const Event OVERWRITING_HEALTH =
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
//!< satellite alive.
static const Event TRYING_RECOVERY =
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
//!< power-cycle). No parameters.
static const Event RECOVERY_STEP =
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
//!< 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_DONE = MAKE_EVENT(
12,
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
//! Assembly overwrites health information of children to keep satellite alive.
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
//! Recovery is ongoing. Comes twice during recovery.
//! P1: 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
//! Recovery was completed. Not necessarily successful. No parameters.
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
virtual ~HasHealthIF() {}
virtual MessageQueueId_t getCommandQueue() const = 0;
-2
View File
@@ -6,8 +6,6 @@
HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) {
mutex = MutexFactory::instance()->createMutex();
;
mapIterator = healthMap.begin();
}
+2
View File
@@ -8,6 +8,8 @@
#include "HealthTableIF.h"
class HealthTable : public HealthTableIF, public SystemObject {
friend class CServiceHealthCommanding;
public:
explicit HealthTable(object_id_t objectid);
~HealthTable() override;
@@ -7,14 +7,17 @@
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
: SystemObject(setObjectId),
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
poolManager(this, commandQueue),
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
internalErrorDataset(this) {
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
mutex = MutexFactory::instance()->createMutex();
}
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
InternalErrorReporter::~InternalErrorReporter() {
MutexFactory::instance()->deleteMutex(mutex);
QueueFactory::instance()->deleteMessageQueue(commandQueue);
}
void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
this->diagnosticPrintout = enable;
+16
View File
@@ -24,3 +24,19 @@ void ModeMessage::setCantReachMode(CommandMessage* message, ReturnValue_t reason
message->setParameter(reason);
message->setParameter2(0);
}
void ModeMessage::setModeAnnounceMessage(CommandMessage& message, bool recursive) {
Command_t cmd;
if (recursive) {
cmd = CMD_MODE_ANNOUNCE_RECURSIVELY;
} else {
cmd = CMD_MODE_ANNOUNCE;
}
message.setCommand(cmd);
}
void ModeMessage::setCmdModeMessage(CommandMessage& message, Mode_t mode, Submode_t submode) {
setModeMessage(&message, CMD_MODE_COMMAND, mode, submode);
}
void ModeMessage::setModeReadMessage(CommandMessage& message) { message.setCommand(CMD_MODE_READ); }
+3
View File
@@ -45,6 +45,9 @@ class ModeMessage {
static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode,
Submode_t submode);
static void setCmdModeMessage(CommandMessage& message, Mode_t mode, Submode_t submode);
static void setModeAnnounceMessage(CommandMessage& message, bool recursive);
static void setModeReadMessage(CommandMessage& message);
static void setCantReachMode(CommandMessage* message, ReturnValue_t reason);
static void clear(CommandMessage* message);
};
+16 -2
View File
@@ -23,9 +23,17 @@ void ObjectManager::setObjectFactoryFunction(produce_function_t objFactoryFunc,
ObjectManager::ObjectManager() = default;
void ObjectManager::clear() {
if (objManagerInstance != nullptr) {
delete objManagerInstance;
objManagerInstance = nullptr;
}
}
ObjectManager::~ObjectManager() {
for (auto const& iter : objectList) {
delete iter.second;
teardown = true;
for (auto iter = objectList.begin(); iter != objectList.end(); iter = objectList.erase(iter)) {
delete iter->second;
}
}
@@ -53,6 +61,12 @@ ReturnValue_t ObjectManager::insert(object_id_t id, SystemObjectIF* object) {
}
ReturnValue_t ObjectManager::remove(object_id_t id) {
// this function is called during destruction of System Objects
// disabeld for teardown to avoid iterator invalidation and
// double free
if (teardown) {
return returnvalue::OK;
}
if (this->getSystemObject(id) != nullptr) {
this->objectList.erase(id);
#if FSFW_CPP_OSTREAM_ENABLED == 1
+9 -1
View File
@@ -24,12 +24,17 @@ class ObjectManager : public ObjectManagerIF {
using produce_function_t = void (*)(void* args);
/**
* Returns the single instance of TaskFactory.
* Returns the single instance of ObjectManager.
* The implementation of #instance is found in its subclasses.
* Thus, we choose link-time variability of the instance.
*/
static ObjectManager* instance();
/**
* Deletes the single instance of ObjectManager
*/
static void clear();
void setObjectFactoryFunction(produce_function_t prodFunc, void* args);
template <typename T>
@@ -66,6 +71,9 @@ class ObjectManager : public ObjectManagerIF {
*/
std::map<object_id_t, SystemObjectIF*> objectList;
static ObjectManager* objManagerInstance;
// used when the OM itself is deleted to modify behaviour of remove()
// to avoid iterator invalidation and double free
bool teardown = false;
};
// Documentation can be found in the class method declaration above
+11 -2
View File
@@ -1,10 +1,13 @@
# Check the OS_FSFW variable
if(FSFW_OSAL MATCHES "freertos")
add_subdirectory(freertos)
set(FSFW_OSAL_FREERTOS 1)
elseif(FSFW_OSAL MATCHES "rtems")
add_subdirectory(rtems)
set(FSFW_OSAL_RTEMS 1)
elseif(FSFW_OSAL MATCHES "linux")
add_subdirectory(linux)
set(FSFW_OSAL_LINUX 1)
elseif(FSFW_OSAL MATCHES "host")
add_subdirectory(host)
if(WIN32)
@@ -13,16 +16,20 @@ elseif(FSFW_OSAL MATCHES "host")
# We still need to pull in some Linux specific sources
target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp)
endif()
set(FSFW_OSAL_HOST 1)
else()
message(
WARNING
"${MSG_PREFIX} The FSFW_OSAL 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
if(WIN32)
add_subdirectory(host)
add_subdirectory(windows)
set(FSFW_OSAL_HOST 1)
elseif(UNIX)
add_subdirectory(linux)
set(FSFW_OSAL_LINUX 1)
else()
# MacOS or other OSes have not been tested yet / are not supported.
message(FATAL_ERROR "The host OS could not be determined! Aborting.")
@@ -31,3 +38,5 @@ else()
endif()
add_subdirectory(common)
configure_file(osal.h.in ${CMAKE_BINARY_DIR}/fsfw/osal/osal.h)
+12 -3
View File
@@ -26,12 +26,12 @@
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
size_t receptionBufferSize, size_t ringBufferSize,
std::string customTcpServerPort, ReceptionModes receptionMode)
TcpTmTcServer::TcpConfig cfg, size_t receptionBufferSize,
size_t ringBufferSize, ReceptionModes receptionMode)
: SystemObject(objectId),
tmtcBridgeId(tmtcTcpBridge),
receptionMode(receptionMode),
tcpConfig(std::move(customTcpServerPort)),
tcpConfig(cfg),
receptionBuffer(receptionBufferSize),
ringBuffer(ringBufferSize, true) {}
@@ -91,6 +91,15 @@ ReturnValue_t TcpTmTcServer::initialize() {
return returnvalue::FAILED;
}
if (tcpConfig.reuseAddr) {
unsigned int enable = 1;
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
}
if (tcpConfig.reusePort) {
unsigned int enable = 1;
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
}
// Bind to the address found by getaddrinfo
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
if (retval == SOCKET_ERROR) {
+20 -6
View File
@@ -41,11 +41,11 @@ class SpacePacketParser;
*/
class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableObjectIF {
public:
enum class ReceptionModes { SPACE_PACKETS };
struct TcpConfig {
public:
explicit TcpConfig(std::string tcpPort) : tcpPort(std::move(tcpPort)) {}
TcpConfig(bool reuseAddr, bool reusePort) : reuseAddr(reuseAddr), reusePort(reusePort) {}
TcpConfig(std::string tcpPort, bool reuseAddr, bool reusePort)
: tcpPort(std::move(tcpPort)), reuseAddr(reuseAddr), reusePort(reusePort) {}
/**
* Passed to the recv call
@@ -63,8 +63,23 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
*/
int tcpTmFlags = 0;
const std::string tcpPort;
std::string tcpPort = DEFAULT_SERVER_PORT;
/**
* Sets the SO_REUSEADDR option on the socket. See
* https://man7.org/linux/man-pages/man7/socket.7.html for more details. This option is
* especially useful in a debugging and development environment where an OBSW image might be
* re-flashed oftentimes and where all incoming telecommands are received on a dedicated TCP
* port.
*/
bool reuseAddr = false;
/**
* Sets the SO_REUSEPORT option on the socket. See
* https://man7.org/linux/man-pages/man7/socket.7.html for more details.
*/
bool reusePort = false;
};
enum class ReceptionModes { SPACE_PACKETS };
static const std::string DEFAULT_SERVER_PORT;
@@ -80,10 +95,9 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
* size will be the Ethernet MTU size
* @param customTcpServerPort The user can specify another port than the default (7301) here.
*/
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, TcpTmTcServer::TcpConfig cfg,
size_t receptionBufferSize = RING_BUFFER_SIZE,
size_t ringBufferSize = RING_BUFFER_SIZE,
std::string customTcpServerPort = DEFAULT_SERVER_PORT,
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
~TcpTmTcServer() override;
+1 -1
View File
@@ -21,7 +21,7 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs*
attributes.mq_msgsize = maxMessageSize;
attributes.mq_flags = 0; // Flags are ignored on Linux during mq_open
// Set the name of the queue. The slash is mandatory!
sprintf(name, "/FSFW_MQ%u\n", queueCounter++);
sprintf(name, "/FSFW_MQ%u", queueCounter++);
// Create a nonblocking queue if the name is available (the queue is read
// and writable for the owner as well as the group)
+36
View File
@@ -0,0 +1,36 @@
#pragma once
namespace osal {
enum osalTarget{
HOST,
LINUX,
WINDOWS,
FREERTOS,
RTEMS,
};
#cmakedefine FSFW_OSAL_HOST
#cmakedefine FSFW_OSAL_LINUX
#cmakedefine FSFW_OSAL_WINDOWS
#cmakedefine FSFW_OSAL_FREERTOS
#cmakedefine FSFW_OSAL_RTEMS
constexpr osalTarget getTarget() {
#ifdef FSFW_OSAL_HOST
return HOST;
#endif
#ifdef FSFW_OSAL_LINUX
return LINUX;
#endif
#ifdef FSFW_OSAL_WINDOWS
return WINDOWS;
#endif
#ifdef FSFW_OSAL_FREERTOS
return FREERTOS;
#endif
#ifdef FSFW_OSAL_RTEMS
return RTEMS;
#endif
}
};
+1 -1
View File
@@ -1,5 +1,5 @@
#include "fsfw/osal/rtems/BinarySemaphore.h"
//#include "fsfw/osal/rtems/CountingSemaphore.h"
// #include "fsfw/osal/rtems/CountingSemaphore.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/tasks/SemaphoreFactory.h"
+1 -1
View File
@@ -9,4 +9,4 @@ target_sources(
Service17Test.cpp
Service20ParameterManagement.cpp
CService200ModeCommanding.cpp
CService201HealthCommanding.cpp)
CServiceHealthCommanding.cpp)
+31 -12
View File
@@ -19,7 +19,8 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservice::COMMAND_MODE_COMMAND):
case (Subservice::COMMAND_MODE_READ):
case (Subservice::COMMAND_MODE_ANNCOUNCE):
case (Subservice::COMMAND_MODE_ANNOUNCE):
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
return returnvalue::OK;
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
@@ -53,16 +54,32 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) {
ModePacket modeCommandPacket;
ReturnValue_t result =
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
return result;
}
bool recursive = false;
switch (subservice) {
case (Subservice::COMMAND_MODE_COMMAND): {
ModePacket modeCommandPacket;
ReturnValue_t result =
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
return result;
}
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
modeCommandPacket.getSubmode());
return result;
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND,
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
return returnvalue::OK;
}
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
recursive = true;
[[fallthrough]];
case (Subservice::COMMAND_MODE_ANNOUNCE):
ModeMessage::setModeAnnounceMessage(*message, recursive);
return EXECUTION_COMPLETE;
case (Subservice::COMMAND_MODE_READ):
ModeMessage::setModeReadMessage(*message);
return returnvalue::OK;
default:
return CommandingServiceBase::INVALID_SUBSERVICE;
}
}
ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply,
@@ -73,8 +90,10 @@ ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply
ReturnValue_t result = returnvalue::FAILED;
switch (replyId) {
case (ModeMessage::REPLY_MODE_REPLY): {
result = prepareModeReply(reply, objectId);
break;
if (previousCommand != ModeMessage::CMD_MODE_COMMAND) {
return prepareModeReply(reply, objectId);
}
return returnvalue::OK;
}
case (ModeMessage::REPLY_WRONG_MODE_REPLY): {
result = prepareWrongModeReply(reply, objectId);
+1 -1
View File
@@ -52,7 +52,7 @@ class CService200ModeCommanding : public CommandingServiceBase {
COMMAND_MODE_READ = 3,
//!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event.
//! This command does NOT have a reply
COMMAND_MODE_ANNCOUNCE = 4,
COMMAND_MODE_ANNOUNCE = 4,
//!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this
//! command to every child. This command does NOT have a reply.
COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5,
@@ -1,106 +0,0 @@
#include "fsfw/pus/CService201HealthCommanding.h"
#include "fsfw/health/HasHealthIF.h"
#include "fsfw/health/HealthMessage.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/pus/servicepackets/Service201Packets.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId, uint16_t apid,
uint8_t serviceId,
uint8_t numParallelCommands,
uint16_t commandTimeoutSeconds)
: CommandingServiceBase(objectId, apid, "PUS 201 Health MGMT", serviceId, numParallelCommands,
commandTimeoutSeconds) {}
ReturnValue_t CService201HealthCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL):
return returnvalue::OK;
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Invalid Subservice" << std::endl;
#endif
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
}
ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData,
size_t tcDataLen,
MessageQueueId_t *id,
object_id_t *objectId) {
if (tcDataLen < sizeof(object_id_t)) {
return CommandingServiceBase::INVALID_TC;
}
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
return checkInterfaceAndAcquireMessageQueue(id, objectId);
}
ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
if (destination == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}
*messageQueueToSet = destination->getCommandQueue();
return returnvalue::OK;
}
ReturnValue_t CService201HealthCommanding::prepareCommand(CommandMessage *message,
uint8_t subservice, const uint8_t *tcData,
size_t tcDataLen, uint32_t *state,
object_id_t objectId) {
ReturnValue_t result = returnvalue::OK;
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH): {
HealthSetCommand healthCommand;
result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
break;
}
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET,
healthCommand.getHealth());
break;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
break;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE_ALL);
break;
}
default: {
// Should never happen, subservice was already checked
result = returnvalue::FAILED;
}
}
return result;
}
ReturnValue_t CService201HealthCommanding::handleReply(const CommandMessage *reply,
Command_t previousCommand, uint32_t *state,
CommandMessage *optionalNextCommand,
object_id_t objectId, bool *isStep) {
Command_t replyId = reply->getCommand();
if (replyId == HealthMessage::REPLY_HEALTH_SET) {
return EXECUTION_COMPLETE;
} else if (replyId == CommandMessageIF::REPLY_REJECTED) {
return reply->getReplyRejectedReason();
}
return CommandingServiceBase::INVALID_REPLY;
}
// Not used for now, health state already reported by event
[[maybe_unused]] ReturnValue_t CService201HealthCommanding::prepareHealthSetReply(
const CommandMessage *reply) {
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
HealthSetReply healthSetReply(health, oldHealth);
return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply);
}
+161
View File
@@ -0,0 +1,161 @@
#include <fsfw/events/EventManagerIF.h>
#include <fsfw/pus/CServiceHealthCommanding.h>
#include "fsfw/health/HasHealthIF.h"
#include "fsfw/health/HealthMessage.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/pus/servicepackets/Service201Packets.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
CServiceHealthCommanding::CServiceHealthCommanding(HealthServiceCfg args)
: CommandingServiceBase(args.objectId, args.apid, "PUS 201 Health MGMT", args.service,
args.numParallelCommands, args.commandTimeoutSeconds),
healthTableId(args.table),
maxNumHealthInfoPerCycle(args.maxNumHealthInfoPerCycle) {}
ReturnValue_t CServiceHealthCommanding::initialize() {
ReturnValue_t result = CommandingServiceBase::initialize();
if (result != returnvalue::OK) {
return result;
}
healthTable = ObjectManager::instance()->get<HealthTable>(healthTableId);
if (healthTable == nullptr) {
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t CServiceHealthCommanding::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL):
return returnvalue::OK;
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Invalid Subservice" << std::endl;
#endif
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
}
ReturnValue_t CServiceHealthCommanding::getMessageQueueAndObject(uint8_t subservice,
const uint8_t *tcData,
size_t tcDataLen,
MessageQueueId_t *id,
object_id_t *objectId) {
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH):
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
if (tcDataLen < sizeof(object_id_t)) {
return CommandingServiceBase::INVALID_TC;
}
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
return checkInterfaceAndAcquireMessageQueue(id, objectId);
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
return returnvalue::OK;
}
default: {
return returnvalue::FAILED;
}
}
}
ReturnValue_t CServiceHealthCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t *messageQueueToSet, const object_id_t *objectId) {
auto *destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
if (destination == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}
*messageQueueToSet = destination->getCommandQueue();
return returnvalue::OK;
}
ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) {
ReturnValue_t result = returnvalue::OK;
switch (subservice) {
case (Subservice::COMMAND_SET_HEALTH): {
if (tcDataLen != sizeof(object_id_t) + sizeof(HasHealthIF::HealthState)) {
return CommandingServiceBase::INVALID_TC;
}
HealthSetCommand healthCommand;
result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
break;
}
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_SET,
healthCommand.getHealth());
break;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
return CommandingServiceBase::EXECUTION_COMPLETE;
}
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
ReturnValue_t result = iterateHealthTable(true);
if (result == returnvalue::OK) {
reportAllHealth = true;
return EXECUTION_COMPLETE;
}
return result;
}
default: {
// Should never happen, subservice was already checked
result = returnvalue::FAILED;
}
}
return result;
}
ReturnValue_t CServiceHealthCommanding::handleReply(const CommandMessage *reply,
Command_t previousCommand, uint32_t *state,
CommandMessage *optionalNextCommand,
object_id_t objectId, bool *isStep) {
Command_t replyId = reply->getCommand();
if (replyId == HealthMessage::REPLY_HEALTH_SET) {
return EXECUTION_COMPLETE;
} else if (replyId == CommandMessageIF::REPLY_REJECTED) {
return reply->getReplyRejectedReason();
}
return CommandingServiceBase::INVALID_REPLY;
}
void CServiceHealthCommanding::doPeriodicOperation() {
if (reportAllHealth) {
for (uint8_t i = 0; i < maxNumHealthInfoPerCycle; i++) {
ReturnValue_t result = iterateHealthTable(false);
if (result != returnvalue::OK) {
reportAllHealth = false;
break;
}
}
}
}
// Not used for now, health state already reported by event
[[maybe_unused]] ReturnValue_t CServiceHealthCommanding::prepareHealthSetReply(
const CommandMessage *reply) {
auto health = static_cast<uint8_t>(HealthMessage::getHealth(reply));
auto oldHealth = static_cast<uint8_t>(HealthMessage::getOldHealth(reply));
HealthSetReply healthSetReply(health, oldHealth);
return sendTmPacket(Subservice::REPLY_HEALTH_SET, healthSetReply);
}
ReturnValue_t CServiceHealthCommanding::iterateHealthTable(bool reset) {
std::pair<object_id_t, HasHealthIF::HealthState> pair;
ReturnValue_t result = healthTable->iterate(&pair, reset);
if (result != returnvalue::OK) {
return result;
} else {
EventManagerIF::triggerEvent(pair.first, HasHealthIF::HEALTH_INFO, pair.second, pair.second);
return returnvalue::OK;
}
}
@@ -1,8 +1,26 @@
#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
#include <fsfw/health/HealthTable.h>
#include "fsfw/tmtcservices/CommandingServiceBase.h"
struct HealthServiceCfg {
HealthServiceCfg(object_id_t objectId, uint16_t apid, object_id_t healthTable,
uint16_t maxNumHealthInfoPerCycle)
: objectId(objectId),
apid(apid),
table(healthTable),
maxNumHealthInfoPerCycle(maxNumHealthInfoPerCycle) {}
object_id_t objectId;
uint16_t apid;
object_id_t table;
uint16_t maxNumHealthInfoPerCycle;
uint8_t service = 201;
uint8_t numParallelCommands = 4;
uint16_t commandTimeoutSeconds = 60;
};
/**
* @brief Custom PUS service to set health of all objects
* implementing hasHealthIF.
@@ -17,11 +35,12 @@
* child class like this service
*
*/
class CService201HealthCommanding : public CommandingServiceBase {
class CServiceHealthCommanding : public CommandingServiceBase {
public:
CService201HealthCommanding(object_id_t objectId, uint16_t apid, uint8_t serviceId,
uint8_t numParallelCommands = 4, uint16_t commandTimeoutSeconds = 60);
~CService201HealthCommanding() override = default;
CServiceHealthCommanding(HealthServiceCfg args);
~CServiceHealthCommanding() override = default;
ReturnValue_t initialize() override;
protected:
/* CSB abstract function implementations */
@@ -37,7 +56,14 @@ class CService201HealthCommanding : public CommandingServiceBase {
CommandMessage *optionalNextCommand, object_id_t objectId,
bool *isStep) override;
void doPeriodicOperation() override;
private:
const object_id_t healthTableId;
HealthTable *healthTable;
uint16_t maxNumHealthInfoPerCycle = 0;
bool reportAllHealth = false;
ReturnValue_t iterateHealthTable(bool reset);
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
const object_id_t *objectId);
@@ -41,6 +41,8 @@ class Service11TelecommandScheduling final : public PusServiceBase {
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
static constexpr ReturnValue_t CONTAINED_TC_TOO_SMALL = returnvalue::makeCode(CLASS_ID, 5);
static constexpr ReturnValue_t CONTAINED_TC_CRC_MISSMATCH = returnvalue::makeCode(CLASS_ID, 6);
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
@@ -2,9 +2,11 @@
#include <cstddef>
#include "fsfw/globalfunctions/CRC.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serviceinterface.h"
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
@@ -171,6 +173,14 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
return returnvalue::FAILED;
}
if (size < PusTcIF::MIN_SIZE) {
return CONTAINED_TC_TOO_SMALL;
}
if (CRC::crc16ccitt(data, size) != 0) {
return CONTAINED_TC_CRC_MISSMATCH;
}
// store currentPacket and receive the store address
store_address_t addr{};
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
@@ -69,14 +69,14 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
<< "MessageQueue: Can't access object" << std::endl;
sif::error << "Object ID: " << std::hex << objectId << std::dec << std::endl;
sif::error << "Make sure it implements ReceivesParameterMessagesIF!" << std::endl;
sif::error << "Object ID: 0x" << std::hex << *objectId << std::dec << std::endl;
sif::error << "Make sure it implements ReceivesParameterMessagesIF" << std::endl;
#else
sif::printError(
"Service20ParameterManagement::checkInterfaceAndAcquire"
"MessageQueue: Can't access object\n");
sif::printError("Object ID: 0x%08x\n", *objectId);
sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n");
sif::printError("Make sure it implements ReceivesParameterMessagesIF\n");
#endif
return CommandingServiceBase::INVALID_OBJECT;
+16 -6
View File
@@ -1,5 +1,7 @@
#include "fsfw/pus/Service9TimeManagement.h"
#include <cmath>
#include "fsfw/events/EventManagerIF.h"
#include "fsfw/pus/servicepackets/Service9Packets.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
@@ -15,9 +17,17 @@ ReturnValue_t Service9TimeManagement::performService() { return returnvalue::OK;
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
switch (subservice) {
case SUBSERVICE::SET_TIME: {
case Subservice::SET_TIME: {
return setTime();
}
case Subservice::DUMP_TIME: {
timeval newTime;
Clock::getClock_timeval(&newTime);
uint32_t subsecondMs =
static_cast<uint32_t>(std::floor(static_cast<double>(newTime.tv_usec) / 1000.0));
triggerEvent(CLOCK_DUMP, newTime.tv_sec, subsecondMs);
return returnvalue::OK;
}
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
@@ -33,14 +43,14 @@ ReturnValue_t Service9TimeManagement::setTime() {
return result;
}
uint32_t formerUptime;
Clock::getUptime(&formerUptime);
timeval time;
Clock::getClock_timeval(&time);
result = Clock::setClock(&timeToSet);
if (result == returnvalue::OK) {
uint32_t newUptime;
Clock::getUptime(&newUptime);
triggerEvent(CLOCK_SET, newUptime, formerUptime);
timeval newTime;
Clock::getClock_timeval(&newTime);
triggerEvent(CLOCK_SET, time.tv_sec, newTime.tv_sec);
return returnvalue::OK;
} else {
triggerEvent(CLOCK_SET_FAILURE, result, 0);
+10 -6
View File
@@ -6,10 +6,13 @@
class Service9TimeManagement : public PusServiceBase {
public:
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
static constexpr Event CLOCK_SET =
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
static constexpr Event CLOCK_SET_FAILURE =
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
//!< Clock has been set. P1: old timeval seconds. P2: new timeval seconds.
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
//!< Clock dump event. P1: timeval seconds P2: timeval milliseconds.
static constexpr Event CLOCK_DUMP = MAKE_EVENT(1, severity::INFO);
//!< Clock could not be set. P1: Returncode.
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(2, severity::LOW);
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
@@ -30,8 +33,9 @@ class Service9TimeManagement : public PusServiceBase {
virtual ReturnValue_t setTime();
private:
enum SUBSERVICE {
SET_TIME = 128 //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
enum Subservice {
SET_TIME = 128, //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
DUMP_TIME = 129,
};
};
+12 -12
View File
@@ -10,11 +10,11 @@
//////////////////////////////////////////////////////////////////////////////////
// RMAP command bits
//#define RMAP_COMMAND_BIT_INCREMENT 2
//#define RMAP_COMMAND_BIT_REPLY 3
//#define RMAP_COMMAND_BIT_WRITE 5
//#define RMAP_COMMAND_BIT_VERIFY 4
//#define RMAP_COMMAND_BIT 6
// #define RMAP_COMMAND_BIT_INCREMENT 2
// #define RMAP_COMMAND_BIT_REPLY 3
// #define RMAP_COMMAND_BIT_WRITE 5
// #define RMAP_COMMAND_BIT_VERIFY 4
// #define RMAP_COMMAND_BIT 6
namespace RMAPIds {
@@ -32,14 +32,14 @@ static const uint8_t RMAP_COMMAND_READ = ((1 << RMAP_COMMAND_BIT) | (1 << RMAP_C
static const uint8_t RMAP_REPLY_WRITE =
((1 << RMAP_COMMAND_BIT_WRITE) | (1 << RMAP_COMMAND_BIT_REPLY));
static const uint8_t RMAP_REPLY_READ = ((1 << RMAP_COMMAND_BIT_REPLY));
//#define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE)
// #define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE)
//| (1<<RMAP_COMMAND_BIT_REPLY)) #define RMAP_COMMAND_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT) |
//(1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define
// RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
// RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
//#define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
// #define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
//(1<<RMAP_COMMAND_BIT_REPLY))
//#define RMAP_REPLY_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT_WRITE) |
// #define RMAP_REPLY_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT_WRITE) |
//(1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define RMAP_REPLY_READ
//((1<<RMAP_COMMAND_BIT_REPLY))
@@ -49,9 +49,9 @@ static const uint8_t RMAP_COMMAND_HEADER_LEN = 16;
static const uint8_t RMAP_WRITE_REPLY_HEADER_LEN = 8;
static const uint8_t RMAP_READ_REPLY_HEADER_LEN = 12;
static const uint8_t RMAP_DATA_FOOTER_SIZE = 1; // SIZE OF CRC
//#define RMAP_COMMAND_HEADER_LEN 16
//#define RMAP_WRITE_REPLY_HEADER_LEN 8
//#define RMAP_READ_REPLY_HEADER_LEN 12
// #define RMAP_COMMAND_HEADER_LEN 16
// #define RMAP_WRITE_REPLY_HEADER_LEN 8
// #define RMAP_READ_REPLY_HEADER_LEN 12
} // namespace RMAPIds
@@ -4,6 +4,8 @@
#include "fsfw/timemanager/Clock.h"
CdsShortTimeStamper::CdsShortTimeStamper() : SystemObject(0, false) {}
CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {}
ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
@@ -18,6 +18,7 @@
class CdsShortTimeStamper : public TimeWriterIF, public TimeReaderIF, public SystemObject {
public:
static constexpr size_t TIMESTAMP_LEN = 7;
CdsShortTimeStamper();
/**
* @brief Default constructor which also registers the time stamper as a
* system object so it can be found with the #objectManager.
@@ -100,5 +100,6 @@ ReturnValue_t PusTcCreator::setSerializableUserData(const SerializeIF &serializa
void PusTcCreator::setup() {
spCreator.setPacketType(ccsds::PacketType::TC);
spCreator.setSecHeaderFlag();
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
updateSpLengthField();
}
@@ -119,6 +119,7 @@ void PusTmCreator::setup() {
updateSpLengthField();
spCreator.setPacketType(ccsds::PacketType::TM);
spCreator.setSecHeaderFlag();
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
}
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
+20 -10
View File
@@ -16,7 +16,9 @@ TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDes
tcDestination(tcDestination)
{
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(
TMTC_RECEPTION_QUEUE_DEPTH, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
}
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
@@ -35,7 +37,7 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(uint8_t sentPacketsPerC
}
}
ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored) {
ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored) {
if (maxNumberOfPacketsStored <= LIMIT_DOWNLINK_PACKETS_STORED) {
this->maxNumberOfPacketsStored = maxNumberOfPacketsStored;
return returnvalue::OK;
@@ -143,13 +145,17 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
storeDownlinkData(&message);
ReturnValue_t result = storeDownlinkData(&message);
if (result != returnvalue::OK) {
tmStore->deleteData(message.getStorageId());
}
continue;
}
result = tmStore->getData(message.getStorageId(), &data, &size);
if (result != returnvalue::OK) {
status = result;
tmStore->deleteData(message.getStorageId());
continue;
}
@@ -157,9 +163,9 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
if (result != returnvalue::OK) {
status = result;
} else {
tmStore->deleteData(message.getStorageId());
packetSentCounter++;
}
tmStore->deleteData(message.getStorageId());
}
return status;
}
@@ -171,15 +177,18 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
}
if (tmFifo->full()) {
if (warningSwitch) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!"
<< std::endl;
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!"
<< std::endl;
#else
sif::printWarning(
"TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!\n");
sif::printWarning(
"TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!\n");
#endif
warningSwitch = false;
}
if (overwriteOld) {
tmFifo->retrieve(&storeId);
tmStore->deleteData(storeId);
@@ -221,6 +230,7 @@ ReturnValue_t TmTcBridge::handleStoredTm() {
packetSentCounter++;
if (tmFifo->empty()) {
warningSwitch = true;
tmStored = false;
}
tmStore->deleteData(storeId);
+4 -3
View File
@@ -17,7 +17,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
public:
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 200;
static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 500;
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
@@ -42,7 +42,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
* @return -@c returnvalue::OK if value was set successfully
* -@c returnvalue::FAILED otherwise, stored value stays the same
*/
ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored);
ReturnValue_t setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored);
/**
* This will set up the bridge to overwrite old data in the FIFO.
@@ -91,6 +91,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
//! by default, so telemetry will be handled immediately.
bool communicationLinkUp = true;
bool tmStored = false;
bool warningSwitch = true;
bool overwriteOld = true;
uint8_t packetSentCounter = 0;
@@ -152,7 +153,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
*/
DynamicFIFO<store_address_t>* tmFifo = nullptr;
uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE;
uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED;
unsigned int maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED;
};
#endif /* FSFW_TMTCSERVICES_TMTCBRIDGE_H_ */
@@ -325,12 +325,12 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
// trickery here to calculate the raw values first
int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8;
int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8;
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8;
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[9] << 8)) >> 8;
// Now scale to physical value in microtesla
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;
float fieldStrengthY = fieldStrengthRawY * scaleFactorX;
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX;
float fieldStrengthY = fieldStrengthRawY * scaleFactorY;
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorZ;
if (periodicPrintout) {
if (debugDivider.checkAndIncrement()) {
-4
View File
@@ -180,10 +180,6 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
}
#else
#endif
#endif
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
<< " bytes" << std::endl;
#endif
return returnvalue::FAILED;
}