Compare commits
13 Commits
tmtcbridge
...
2aa4af6974
Author | SHA1 | Date | |
---|---|---|---|
2aa4af6974 | |||
75fc7a056d | |||
1b005d706a | |||
e68f54b9bd | |||
296bc56e2a | |||
2b6a33e718 | |||
61fd5d1b62 | |||
046dbe1deb | |||
0303c1a885 | |||
4d2802a470 | |||
819a2bfac4 | |||
096af44e39 | |||
56e8e5a8b3 |
49
CHANGELOG.md
49
CHANGELOG.md
@ -12,20 +12,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
- `CService200ModeManagement`: Various bugfixes which lead to now execution complete being generated
|
|
||||||
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
|
|
||||||
subservice not working properly.
|
|
||||||
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
|
|
||||||
seconds instead of uptime.
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
|
|
||||||
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
|
||||||
only the X scaling factor was used.
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
|
|
||||||
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
|
||||||
to false correctly because the `read` and `write` calls were missing.
|
|
||||||
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
|
||||||
of the correct unsegmented flags (0b11) as specified in the standard.
|
|
||||||
- TC Scheduler Service 11: Add size and CRC check for contained TC.
|
|
||||||
- Only delete health table entry in `HealthHelper` destructor if
|
- Only delete health table entry in `HealthHelper` destructor if
|
||||||
health table was set.
|
health table was set.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710/files
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710/files
|
||||||
@ -41,15 +27,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
- `CServiceHealthCommanding`: Add announce all health info implementation
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
|
||||||
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
|
|
||||||
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
|
|
||||||
option on the TCP server. CTOR prototype has changed and expects an explicit
|
|
||||||
TCP configuration struct to be passed.
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/722
|
|
||||||
- `DleParser` helper class to parse DLE encoded packets from a byte stream.
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711
|
|
||||||
- `UioMapper` is able to resolve symlinks now.
|
- `UioMapper` is able to resolve symlinks now.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
|
||||||
- Add new `UnsignedByteField` class
|
- Add new `UnsignedByteField` class
|
||||||
@ -57,10 +34,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
- `CService201HealthCommanding` renamed to `CServiceHealthCommanding`,
|
|
||||||
service ID customizable now. `CServiceHealthCommanding` expects configuration struct
|
|
||||||
`HealthServiceCfg` now
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
|
||||||
- `AcceptsTelemetryIF`: `getReportReceptionQueue` is const now
|
- `AcceptsTelemetryIF`: `getReportReceptionQueue` is const now
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/712
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/712
|
||||||
- Moved some container returnvalues to dedicated header and namespace
|
- Moved some container returnvalues to dedicated header and namespace
|
||||||
@ -125,16 +98,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
implementation without an extra component
|
implementation without an extra component
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/682
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/682
|
||||||
|
|
||||||
## HAL
|
|
||||||
|
|
||||||
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
|
||||||
lot more sense because each ComIF should be responsible for one SPI bus.
|
|
||||||
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
|
||||||
it is not automatically called when calling the setter function for SPI speed and mode.
|
|
||||||
The user should call this function after locking the CS mutex if multiple SPI devices with
|
|
||||||
differing speeds and modes are attached to one bus.
|
|
||||||
- SPI: Getter functions for SPI speed and mode.
|
|
||||||
|
|
||||||
# [v5.0.0] 25.07.2022
|
# [v5.0.0] 25.07.2022
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
@ -268,7 +231,6 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
||||||
Easiest solution for now: Keep this option OFF by default.
|
Easiest solution for now: Keep this option OFF by default.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
||||||
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
|
||||||
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
||||||
inside `fsfw/version.h`
|
inside `fsfw/version.h`
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||||
@ -283,6 +245,17 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||||
- `Subsystem`: New API to add table and sequence entries
|
- `Subsystem`: New API to add table and sequence entries
|
||||||
|
|
||||||
|
## HAL
|
||||||
|
|
||||||
|
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
||||||
|
lot more sense because each ComIF should be responsible for one SPI bus.
|
||||||
|
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
||||||
|
it is not automatically called when calling the setter function for SPI speed and mode.
|
||||||
|
The user should call this function after locking the CS mutex if multiple SPI devices with
|
||||||
|
differing speeds and modes are attached to one bus.
|
||||||
|
- SPI: Getter functions for SPI speed and mode.
|
||||||
|
- I2C: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1.
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- TCP TMTC Server: `MutexGuard` was not created properly in
|
- TCP TMTC Server: `MutexGuard` was not created properly in
|
||||||
|
96
automation/Jenkinsfile
vendored
96
automation/Jenkinsfile
vendored
@ -1,87 +1,45 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
environment {
|
environment {
|
||||||
BUILDDIR_HOST = 'cmake-build-tests-host'
|
BUILDDIR = 'cmake-build-tests'
|
||||||
BUILDDIR_LINUX = 'cmake-build-tests-linux'
|
|
||||||
DOCDDIR = 'cmake-build-documentation'
|
DOCDDIR = 'cmake-build-documentation'
|
||||||
}
|
}
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
image 'fsfw-ci:d6'
|
image 'fsfw-ci:d6'
|
||||||
args '--network host --sysctl fs.mqueue.msg_max=100'
|
args '--network host'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('Host') {
|
stage('Clean') {
|
||||||
stages{
|
steps {
|
||||||
stage('Clean') {
|
sh 'rm -rf $BUILDDIR'
|
||||||
steps {
|
}
|
||||||
sh 'rm -rf $BUILDDIR_HOST'
|
}
|
||||||
}
|
stage('Configure') {
|
||||||
}
|
steps {
|
||||||
stage('Configure') {
|
dir(BUILDDIR) {
|
||||||
steps {
|
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
||||||
dir(BUILDDIR_HOST) {
|
|
||||||
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Build') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_HOST) {
|
|
||||||
sh 'cmake --build . -j4'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Unittests') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_HOST) {
|
|
||||||
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Valgrind') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_HOST) {
|
|
||||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Linux') {
|
stage('Build') {
|
||||||
stages{
|
steps {
|
||||||
stage('Clean') {
|
dir(BUILDDIR) {
|
||||||
steps {
|
sh 'cmake --build . -j4'
|
||||||
sh 'rm -rf $BUILDDIR_LINUX'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
stage('Configure') {
|
}
|
||||||
steps {
|
}
|
||||||
dir(BUILDDIR_LINUX) {
|
stage('Unittests') {
|
||||||
sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
|
steps {
|
||||||
}
|
dir(BUILDDIR) {
|
||||||
}
|
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
||||||
}
|
}
|
||||||
stage('Build') {
|
}
|
||||||
steps {
|
}
|
||||||
dir(BUILDDIR_LINUX) {
|
stage('Valgrind') {
|
||||||
sh 'cmake --build . -j4'
|
steps {
|
||||||
}
|
dir(BUILDDIR) {
|
||||||
}
|
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
||||||
}
|
|
||||||
stage('Unittests') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_LINUX) {
|
|
||||||
sh 'cmake --build . -- fsfw-tests_coverage -j4'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Valgrind') {
|
|
||||||
steps {
|
|
||||||
dir(BUILDDIR_LINUX) {
|
|
||||||
sh 'valgrind --leak-check=full --error-exitcode=1 ./fsfw-tests'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,5 +109,5 @@ const HasModesIF& ControllerBase::getModeIF() const { return *this; }
|
|||||||
ModeTreeChildIF& ControllerBase::getModeTreeChildIF() { return *this; }
|
ModeTreeChildIF& ControllerBase::getModeTreeChildIF() { return *this; }
|
||||||
|
|
||||||
ReturnValue_t ControllerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
ReturnValue_t ControllerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||||
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
return modetree::connectModeTreeParent(parent, *this, healthHelper, modeHelper);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "DeviceHandlerBase.h"
|
#include "DeviceHandlerBase.h"
|
||||||
|
|
||||||
#include "fsfw/datapool/PoolReadGuard.h"
|
|
||||||
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
||||||
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
||||||
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
||||||
@ -1525,10 +1524,7 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
|||||||
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
||||||
for (const auto& reply : deviceReplyMap) {
|
for (const auto& reply : deviceReplyMap) {
|
||||||
if (reply.second.dataSet != nullptr) {
|
if (reply.second.dataSet != nullptr) {
|
||||||
PoolReadGuard pg(reply.second.dataSet);
|
reply.second.dataSet->setValidity(false, true);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
|
||||||
reply.second.dataSet->setValidity(false, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1612,7 +1608,7 @@ void DeviceHandlerBase::disableCommandsAndReplies() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
ReturnValue_t DeviceHandlerBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||||
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
return modetree::connectModeTreeParent(parent, *this, healthHelper, modeHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
const HasHealthIF* DeviceHandlerBase::getOptHealthIF() const { return this; }
|
const HasHealthIF* DeviceHandlerBase::getOptHealthIF() const { return this; }
|
||||||
|
@ -24,7 +24,6 @@ EventManager::EventManager(object_id_t setObjectId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EventManager::~EventManager() {
|
EventManager::~EventManager() {
|
||||||
listenerList.clear();
|
|
||||||
QueueFactory::instance()->deleteMessageQueue(eventReportQueue);
|
QueueFactory::instance()->deleteMessageQueue(eventReportQueue);
|
||||||
MutexFactory::instance()->deleteMutex(mutex);
|
MutexFactory::instance()->deleteMutex(mutex);
|
||||||
}
|
}
|
||||||
@ -74,14 +73,9 @@ ReturnValue_t EventManager::registerListener(MessageQueueId_t listener,
|
|||||||
if (!result.second) {
|
if (!result.second) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnvalue::OK;
|
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) {
|
ReturnValue_t EventManager::subscribeToEvent(MessageQueueId_t listener, EventId_t event) {
|
||||||
return subscribeToEventRange(listener, event);
|
return subscribeToEventRange(listener, event);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
MessageQueueId_t getEventReportQueue();
|
MessageQueueId_t getEventReportQueue();
|
||||||
|
|
||||||
ReturnValue_t registerListener(MessageQueueId_t listener, bool forwardAllButSelected = false);
|
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 subscribeToEvent(MessageQueueId_t listener, EventId_t event);
|
||||||
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
|
ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object);
|
||||||
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
|
||||||
|
@ -18,7 +18,6 @@ class EventManagerIF {
|
|||||||
|
|
||||||
virtual ReturnValue_t registerListener(MessageQueueId_t listener,
|
virtual ReturnValue_t registerListener(MessageQueueId_t listener,
|
||||||
bool forwardAllButSelected = false) = 0;
|
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 subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0;
|
||||||
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 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;
|
virtual ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener, object_id_t object) = 0;
|
||||||
|
@ -24,7 +24,7 @@ FailureIsolationBase::~FailureIsolationBase() {
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
manager->unregisterListener(eventQueue->getId());
|
manager->unsubscribeFromAllEvents(eventQueue->getId(), ownerId);
|
||||||
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
|
|||||||
MatchTree(iterator root, uint8_t maxDepth = -1)
|
MatchTree(iterator root, uint8_t maxDepth = -1)
|
||||||
: BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(maxDepth) {}
|
: BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(maxDepth) {}
|
||||||
MatchTree() : BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {}
|
MatchTree() : BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {}
|
||||||
virtual ~MatchTree() { clear(); }
|
virtual ~MatchTree() {}
|
||||||
virtual bool match(T number) override { return matchesTree(number); }
|
virtual bool match(T number) override { return matchesTree(number); }
|
||||||
bool matchesTree(T number) {
|
bool matchesTree(T number) {
|
||||||
iterator iter = this->begin();
|
iterator iter = this->begin();
|
||||||
@ -176,45 +176,6 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
|
|||||||
return cleanUpElement(position);
|
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; }
|
virtual ReturnValue_t cleanUpElement(iterator position) { return returnvalue::OK; }
|
||||||
|
|
||||||
bool matchSubtree(iterator iter, T number) {
|
bool matchSubtree(iterator iter, T number) {
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) {
|
HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
|
;
|
||||||
|
|
||||||
mapIterator = healthMap.begin();
|
mapIterator = healthMap.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
#include "HealthTableIF.h"
|
#include "HealthTableIF.h"
|
||||||
|
|
||||||
class HealthTable : public HealthTableIF, public SystemObject {
|
class HealthTable : public HealthTableIF, public SystemObject {
|
||||||
friend class CServiceHealthCommanding;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit HealthTable(object_id_t objectid);
|
explicit HealthTable(object_id_t objectid);
|
||||||
~HealthTable() override;
|
~HealthTable() override;
|
||||||
|
@ -10,17 +10,13 @@ InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t m
|
|||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||||
internalErrorDataset(this) {
|
internalErrorDataset(this) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalErrorReporter::~InternalErrorReporter() {
|
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
MutexFactory::instance()->deleteMutex(mutex);
|
|
||||||
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
|
void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
|
||||||
this->diagnosticPrintout = enable;
|
this->diagnosticPrintout = enable;
|
||||||
|
@ -34,9 +34,3 @@ void ModeMessage::setModeAnnounceMessage(CommandMessage& message, bool recursive
|
|||||||
}
|
}
|
||||||
message.setCommand(cmd);
|
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); }
|
|
||||||
|
@ -44,9 +44,7 @@ class ModeMessage {
|
|||||||
|
|
||||||
static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode,
|
static void setModeMessage(CommandMessage* message, Command_t command, Mode_t mode,
|
||||||
Submode_t submode);
|
Submode_t submode);
|
||||||
static void setCmdModeMessage(CommandMessage& message, Mode_t mode, Submode_t submode);
|
|
||||||
static void setModeAnnounceMessage(CommandMessage& message, bool recursive);
|
static void setModeAnnounceMessage(CommandMessage& message, bool recursive);
|
||||||
static void setModeReadMessage(CommandMessage& message);
|
|
||||||
static void setCantReachMode(CommandMessage* message, ReturnValue_t reason);
|
static void setCantReachMode(CommandMessage* message, ReturnValue_t reason);
|
||||||
static void clear(CommandMessage* message);
|
static void clear(CommandMessage* message);
|
||||||
};
|
};
|
||||||
|
@ -23,17 +23,9 @@ void ObjectManager::setObjectFactoryFunction(produce_function_t objFactoryFunc,
|
|||||||
|
|
||||||
ObjectManager::ObjectManager() = default;
|
ObjectManager::ObjectManager() = default;
|
||||||
|
|
||||||
void ObjectManager::clear() {
|
|
||||||
if (objManagerInstance != nullptr) {
|
|
||||||
delete objManagerInstance;
|
|
||||||
objManagerInstance = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectManager::~ObjectManager() {
|
ObjectManager::~ObjectManager() {
|
||||||
teardown = true;
|
for (auto const& iter : objectList) {
|
||||||
for (auto iter = objectList.begin(); iter != objectList.end(); iter = objectList.erase(iter)) {
|
delete iter.second;
|
||||||
delete iter->second;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +53,6 @@ ReturnValue_t ObjectManager::insert(object_id_t id, SystemObjectIF* object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ObjectManager::remove(object_id_t id) {
|
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) {
|
if (this->getSystemObject(id) != nullptr) {
|
||||||
this->objectList.erase(id);
|
this->objectList.erase(id);
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
@ -24,17 +24,12 @@ class ObjectManager : public ObjectManagerIF {
|
|||||||
using produce_function_t = void (*)(void* args);
|
using produce_function_t = void (*)(void* args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the single instance of ObjectManager.
|
* Returns the single instance of TaskFactory.
|
||||||
* The implementation of #instance is found in its subclasses.
|
* The implementation of #instance is found in its subclasses.
|
||||||
* Thus, we choose link-time variability of the instance.
|
* Thus, we choose link-time variability of the instance.
|
||||||
*/
|
*/
|
||||||
static ObjectManager* instance();
|
static ObjectManager* instance();
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the single instance of ObjectManager
|
|
||||||
*/
|
|
||||||
static void clear();
|
|
||||||
|
|
||||||
void setObjectFactoryFunction(produce_function_t prodFunc, void* args);
|
void setObjectFactoryFunction(produce_function_t prodFunc, void* args);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -71,9 +66,6 @@ class ObjectManager : public ObjectManagerIF {
|
|||||||
*/
|
*/
|
||||||
std::map<object_id_t, SystemObjectIF*> objectList;
|
std::map<object_id_t, SystemObjectIF*> objectList;
|
||||||
static ObjectManager* objManagerInstance;
|
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
|
// Documentation can be found in the class method declaration above
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
# Check the OS_FSFW variable
|
# Check the OS_FSFW variable
|
||||||
if(FSFW_OSAL MATCHES "freertos")
|
if(FSFW_OSAL MATCHES "freertos")
|
||||||
add_subdirectory(freertos)
|
add_subdirectory(freertos)
|
||||||
set(FSFW_OSAL_FREERTOS 1)
|
|
||||||
elseif(FSFW_OSAL MATCHES "rtems")
|
elseif(FSFW_OSAL MATCHES "rtems")
|
||||||
add_subdirectory(rtems)
|
add_subdirectory(rtems)
|
||||||
set(FSFW_OSAL_RTEMS 1)
|
|
||||||
elseif(FSFW_OSAL MATCHES "linux")
|
elseif(FSFW_OSAL MATCHES "linux")
|
||||||
add_subdirectory(linux)
|
add_subdirectory(linux)
|
||||||
set(FSFW_OSAL_LINUX 1)
|
|
||||||
elseif(FSFW_OSAL MATCHES "host")
|
elseif(FSFW_OSAL MATCHES "host")
|
||||||
add_subdirectory(host)
|
add_subdirectory(host)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@ -16,20 +13,18 @@ elseif(FSFW_OSAL MATCHES "host")
|
|||||||
# We still need to pull in some Linux specific sources
|
# We still need to pull in some Linux specific sources
|
||||||
target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp)
|
target_sources(${LIB_FSFW_NAME} PUBLIC linux/tcpipHelpers.cpp)
|
||||||
endif()
|
endif()
|
||||||
set(FSFW_OSAL_HOST 1)
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
message(
|
message(
|
||||||
WARNING
|
WARNING
|
||||||
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
"${MSG_PREFIX} The FSFW_OSAL 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)
|
||||||
set(FSFW_OSAL_HOST 1)
|
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
add_subdirectory(linux)
|
add_subdirectory(linux)
|
||||||
set(FSFW_OSAL_LINUX 1)
|
|
||||||
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.")
|
||||||
@ -38,5 +33,3 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
|
|
||||||
configure_file(osal.h.in ${CMAKE_BINARY_DIR}/fsfw/osal/osal.h)
|
|
||||||
|
@ -26,12 +26,12 @@
|
|||||||
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
||||||
TcpTmTcServer::TcpConfig cfg, size_t receptionBufferSize,
|
size_t receptionBufferSize, size_t ringBufferSize,
|
||||||
size_t ringBufferSize, ReceptionModes receptionMode)
|
std::string customTcpServerPort, ReceptionModes receptionMode)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
tmtcBridgeId(tmtcTcpBridge),
|
tmtcBridgeId(tmtcTcpBridge),
|
||||||
receptionMode(receptionMode),
|
receptionMode(receptionMode),
|
||||||
tcpConfig(cfg),
|
tcpConfig(std::move(customTcpServerPort)),
|
||||||
receptionBuffer(receptionBufferSize),
|
receptionBuffer(receptionBufferSize),
|
||||||
ringBuffer(ringBufferSize, true) {}
|
ringBuffer(ringBufferSize, true) {}
|
||||||
|
|
||||||
@ -91,15 +91,6 @@ ReturnValue_t TcpTmTcServer::initialize() {
|
|||||||
return returnvalue::FAILED;
|
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
|
// Bind to the address found by getaddrinfo
|
||||||
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
|
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
|
||||||
if (retval == SOCKET_ERROR) {
|
if (retval == SOCKET_ERROR) {
|
||||||
|
@ -41,11 +41,11 @@ class SpacePacketParser;
|
|||||||
*/
|
*/
|
||||||
class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableObjectIF {
|
class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
|
enum class ReceptionModes { SPACE_PACKETS };
|
||||||
|
|
||||||
struct TcpConfig {
|
struct TcpConfig {
|
||||||
public:
|
public:
|
||||||
TcpConfig(bool reuseAddr, bool reusePort) : reuseAddr(reuseAddr), reusePort(reusePort) {}
|
explicit TcpConfig(std::string tcpPort) : tcpPort(std::move(tcpPort)) {}
|
||||||
TcpConfig(std::string tcpPort, bool reuseAddr, bool reusePort)
|
|
||||||
: tcpPort(std::move(tcpPort)), reuseAddr(reuseAddr), reusePort(reusePort) {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Passed to the recv call
|
* Passed to the recv call
|
||||||
@ -63,25 +63,9 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
|||||||
*/
|
*/
|
||||||
int tcpTmFlags = 0;
|
int tcpTmFlags = 0;
|
||||||
|
|
||||||
std::string tcpPort = DEFAULT_SERVER_PORT;
|
const std::string tcpPort;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
static const std::string DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
static constexpr size_t ETHERNET_MTU_SIZE = 1500;
|
static constexpr size_t ETHERNET_MTU_SIZE = 1500;
|
||||||
@ -96,9 +80,10 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
|||||||
* size will be the Ethernet MTU size
|
* size will be the Ethernet MTU size
|
||||||
* @param customTcpServerPort The user can specify another port than the default (7301) here.
|
* @param customTcpServerPort The user can specify another port than the default (7301) here.
|
||||||
*/
|
*/
|
||||||
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, TcpTmTcServer::TcpConfig cfg,
|
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
||||||
size_t receptionBufferSize = RING_BUFFER_SIZE,
|
size_t receptionBufferSize = RING_BUFFER_SIZE,
|
||||||
size_t ringBufferSize = RING_BUFFER_SIZE,
|
size_t ringBufferSize = RING_BUFFER_SIZE,
|
||||||
|
std::string customTcpServerPort = DEFAULT_SERVER_PORT,
|
||||||
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
|
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
|
||||||
~TcpTmTcServer() override;
|
~TcpTmTcServer() override;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs*
|
|||||||
attributes.mq_msgsize = maxMessageSize;
|
attributes.mq_msgsize = maxMessageSize;
|
||||||
attributes.mq_flags = 0; // Flags are ignored on Linux during mq_open
|
attributes.mq_flags = 0; // Flags are ignored on Linux during mq_open
|
||||||
// Set the name of the queue. The slash is mandatory!
|
// Set the name of the queue. The slash is mandatory!
|
||||||
sprintf(name, "/FSFW_MQ%u", queueCounter++);
|
sprintf(name, "/FSFW_MQ%u\n", queueCounter++);
|
||||||
|
|
||||||
// Create a nonblocking queue if the name is available (the queue is read
|
// Create a nonblocking queue if the name is available (the queue is read
|
||||||
// and writable for the owner as well as the group)
|
// and writable for the owner as well as the group)
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
#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
|
|
||||||
}
|
|
||||||
};
|
|
@ -9,4 +9,4 @@ target_sources(
|
|||||||
Service17Test.cpp
|
Service17Test.cpp
|
||||||
Service20ParameterManagement.cpp
|
Service20ParameterManagement.cpp
|
||||||
CService200ModeCommanding.cpp
|
CService200ModeCommanding.cpp
|
||||||
CServiceHealthCommanding.cpp)
|
CService201HealthCommanding.cpp)
|
||||||
|
@ -54,36 +54,27 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
|
|||||||
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
||||||
const uint8_t *tcData, size_t tcDataLen,
|
const uint8_t *tcData, size_t tcDataLen,
|
||||||
uint32_t *state, object_id_t objectId) {
|
uint32_t *state, object_id_t objectId) {
|
||||||
switch (subservice) {
|
ReturnValue_t result = returnvalue::OK;
|
||||||
case (Subservice::COMMAND_MODE_COMMAND): {
|
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE or
|
||||||
ModePacket modeCommandPacket;
|
subservice == Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY) {
|
||||||
ReturnValue_t result =
|
bool recursive = true;
|
||||||
modeCommandPacket.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
|
||||||
if (result != returnvalue::OK) {
|
recursive = false;
|
||||||
return result;
|
}
|
||||||
}
|
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
||||||
|
} else {
|
||||||
|
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,
|
ModeMessage::setModeMessage(message, ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
|
||||||
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
|
modeCommandPacket.getSubmode());
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
|
||||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY): {
|
|
||||||
bool recursive = true;
|
|
||||||
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
|
|
||||||
recursive = false;
|
|
||||||
}
|
|
||||||
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
|
||||||
return EXECUTION_COMPLETE;
|
|
||||||
}
|
|
||||||
case (Subservice::COMMAND_MODE_READ): {
|
|
||||||
ModeMessage::setModeReadMessage(*message);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return CommandingServiceBase::INVALID_SUBSERVICE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply,
|
ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply,
|
||||||
@ -94,10 +85,8 @@ ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply
|
|||||||
ReturnValue_t result = returnvalue::FAILED;
|
ReturnValue_t result = returnvalue::FAILED;
|
||||||
switch (replyId) {
|
switch (replyId) {
|
||||||
case (ModeMessage::REPLY_MODE_REPLY): {
|
case (ModeMessage::REPLY_MODE_REPLY): {
|
||||||
if (previousCommand != ModeMessage::CMD_MODE_COMMAND) {
|
result = prepareModeReply(reply, objectId);
|
||||||
return prepareModeReply(reply, objectId);
|
break;
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
}
|
||||||
case (ModeMessage::REPLY_WRONG_MODE_REPLY): {
|
case (ModeMessage::REPLY_WRONG_MODE_REPLY): {
|
||||||
result = prepareWrongModeReply(reply, objectId);
|
result = prepareWrongModeReply(reply, objectId);
|
||||||
|
106
src/fsfw/pus/CService201HealthCommanding.cpp
Normal file
106
src/fsfw/pus/CService201HealthCommanding.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#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);
|
||||||
|
}
|
@ -1,26 +1,8 @@
|
|||||||
#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
#ifndef FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
||||||
#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
#define FSFW_PUS_CSERVICE201HEALTHCOMMANDING_H_
|
||||||
|
|
||||||
#include <fsfw/health/HealthTable.h>
|
|
||||||
|
|
||||||
#include "fsfw/tmtcservices/CommandingServiceBase.h"
|
#include "fsfw/tmtcservices/CommandingServiceBase.h"
|
||||||
|
|
||||||
struct HealthServiceCfg {
|
|
||||||
HealthServiceCfg(object_id_t objectId, uint16_t apid, HealthTable &healthTable,
|
|
||||||
uint16_t maxNumHealthInfoPerCycle)
|
|
||||||
: objectId(objectId),
|
|
||||||
apid(apid),
|
|
||||||
table(healthTable),
|
|
||||||
maxNumHealthInfoPerCycle(maxNumHealthInfoPerCycle) {}
|
|
||||||
object_id_t objectId;
|
|
||||||
uint16_t apid;
|
|
||||||
HealthTable &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
|
* @brief Custom PUS service to set health of all objects
|
||||||
* implementing hasHealthIF.
|
* implementing hasHealthIF.
|
||||||
@ -35,10 +17,11 @@ struct HealthServiceCfg {
|
|||||||
* child class like this service
|
* child class like this service
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CServiceHealthCommanding : public CommandingServiceBase {
|
class CService201HealthCommanding : public CommandingServiceBase {
|
||||||
public:
|
public:
|
||||||
CServiceHealthCommanding(HealthServiceCfg args);
|
CService201HealthCommanding(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
||||||
~CServiceHealthCommanding() override = default;
|
uint8_t numParallelCommands = 4, uint16_t commandTimeoutSeconds = 60);
|
||||||
|
~CService201HealthCommanding() override = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* CSB abstract function implementations */
|
/* CSB abstract function implementations */
|
||||||
@ -54,13 +37,7 @@ class CServiceHealthCommanding : public CommandingServiceBase {
|
|||||||
CommandMessage *optionalNextCommand, object_id_t objectId,
|
CommandMessage *optionalNextCommand, object_id_t objectId,
|
||||||
bool *isStep) override;
|
bool *isStep) override;
|
||||||
|
|
||||||
void doPeriodicOperation() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HealthTable &healthTable;
|
|
||||||
uint16_t maxNumHealthInfoPerCycle = 0;
|
|
||||||
bool reportAllHealth = false;
|
|
||||||
ReturnValue_t iterateHealthTable(bool reset);
|
|
||||||
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
|
static ReturnValue_t checkInterfaceAndAcquireMessageQueue(MessageQueueId_t *MessageQueueToSet,
|
||||||
const object_id_t *objectId);
|
const object_id_t *objectId);
|
||||||
|
|
@ -1,152 +0,0 @@
|
|||||||
#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),
|
|
||||||
healthTable(args.table),
|
|
||||||
maxNumHealthInfoPerCycle(args.maxNumHealthInfoPerCycle) {}
|
|
||||||
|
|
||||||
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): {
|
|
||||||
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): {
|
|
||||||
ReturnValue_t result = iterateHealthTable(true);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
reportAllHealth = true;
|
|
||||||
return EXECUTION_COMPLETE;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
while (true) {
|
|
||||||
ReturnValue_t result = iterateHealthTable(false);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -41,8 +41,6 @@ class Service11TelecommandScheduling final : public PusServiceBase {
|
|||||||
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
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 TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
||||||
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
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;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
||||||
|
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/CRC.h"
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
|
|
||||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
|
|
||||||
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
||||||
@ -173,14 +171,6 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
|||||||
return returnvalue::FAILED;
|
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 currentPacket and receive the store address
|
||||||
store_address_t addr{};
|
store_address_t addr{};
|
||||||
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
||||||
|
@ -69,14 +69,14 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
|
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||||
<< "MessageQueue: Can't access object" << std::endl;
|
<< "MessageQueue: Can't access object" << std::endl;
|
||||||
sif::error << "Object ID: 0x" << std::hex << *objectId << std::dec << std::endl;
|
sif::error << "Object ID: " << std::hex << objectId << std::dec << std::endl;
|
||||||
sif::error << "Make sure it implements ReceivesParameterMessagesIF" << std::endl;
|
sif::error << "Make sure it implements ReceivesParameterMessagesIF!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError(
|
sif::printError(
|
||||||
"Service20ParameterManagement::checkInterfaceAndAcquire"
|
"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 ReceivesParameterMessagesIF\n");
|
sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return CommandingServiceBase::INVALID_OBJECT;
|
return CommandingServiceBase::INVALID_OBJECT;
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#include "fsfw/pus/Service9TimeManagement.h"
|
#include "fsfw/pus/Service9TimeManagement.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "fsfw/events/EventManagerIF.h"
|
#include "fsfw/events/EventManagerIF.h"
|
||||||
#include "fsfw/pus/servicepackets/Service9Packets.h"
|
#include "fsfw/pus/servicepackets/Service9Packets.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
@ -17,17 +15,9 @@ ReturnValue_t Service9TimeManagement::performService() { return returnvalue::OK;
|
|||||||
|
|
||||||
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
|
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
|
||||||
switch (subservice) {
|
switch (subservice) {
|
||||||
case Subservice::SET_TIME: {
|
case SUBSERVICE::SET_TIME: {
|
||||||
return setTime();
|
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:
|
default:
|
||||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||||
}
|
}
|
||||||
@ -43,14 +33,14 @@ ReturnValue_t Service9TimeManagement::setTime() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeval time;
|
uint32_t formerUptime;
|
||||||
Clock::getClock_timeval(&time);
|
Clock::getUptime(&formerUptime);
|
||||||
result = Clock::setClock(&timeToSet);
|
result = Clock::setClock(&timeToSet);
|
||||||
|
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
timeval newTime;
|
uint32_t newUptime;
|
||||||
Clock::getClock_timeval(&newTime);
|
Clock::getUptime(&newUptime);
|
||||||
triggerEvent(CLOCK_SET, time.tv_sec, newTime.tv_sec);
|
triggerEvent(CLOCK_SET, newUptime, formerUptime);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(CLOCK_SET_FAILURE, result, 0);
|
triggerEvent(CLOCK_SET_FAILURE, result, 0);
|
||||||
|
@ -6,13 +6,10 @@
|
|||||||
class Service9TimeManagement : public PusServiceBase {
|
class Service9TimeManagement : public PusServiceBase {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
||||||
|
//!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||||
//!< Clock has been set. P1: old timeval seconds. P2: new timeval seconds.
|
|
||||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
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.
|
//!< Clock could not be set. P1: Returncode.
|
||||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(2, severity::LOW);
|
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||||
|
|
||||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||||
|
|
||||||
@ -33,9 +30,8 @@ class Service9TimeManagement : public PusServiceBase {
|
|||||||
virtual ReturnValue_t setTime();
|
virtual ReturnValue_t setTime();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Subservice {
|
enum SUBSERVICE {
|
||||||
SET_TIME = 128, //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
SET_TIME = 128 //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
||||||
DUMP_TIME = 129,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ ReturnValue_t SubsystemBase::checkTable(HybridIterator<ModeListEntry> tableIter)
|
|||||||
if (childrenMap.find(tableIter.value->getObject()) == childrenMap.end()) {
|
if (childrenMap.find(tableIter.value->getObject()) == childrenMap.end()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
using namespace std;
|
using namespace std;
|
||||||
sif::warning << "SubsystemBase::checkTable: Could not find object " << setfill('0') << hex
|
sif::warning << "SubsystemBase::checkTable: Could not find Object " << setfill('0') << hex
|
||||||
<< "0x" << setw(8) << tableIter.value->getObject() << " in object " << setw(8)
|
<< "0x" << setw(8) << tableIter.value->getObject() << " in object " << setw(8)
|
||||||
<< setw(0) << "0x" << setw(8) << SystemObject::getObjectId() << dec << std::endl;
|
<< setw(0) << "0x" << setw(8) << SystemObject::getObjectId() << dec << std::endl;
|
||||||
#endif
|
#endif
|
||||||
@ -284,7 +284,7 @@ ReturnValue_t SubsystemBase::setHealth(HealthState health) {
|
|||||||
HasHealthIF::HealthState SubsystemBase::getHealth() { return healthHelper.getHealth(); }
|
HasHealthIF::HealthState SubsystemBase::getHealth() { return healthHelper.getHealth(); }
|
||||||
|
|
||||||
ReturnValue_t SubsystemBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
ReturnValue_t SubsystemBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
|
||||||
return modetree::connectModeTreeParent(parent, *this, &healthHelper, modeHelper);
|
return modetree::connectModeTreeParent(parent, *this, healthHelper, modeHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
object_id_t SubsystemBase::getObjectId() const { return SystemObject::getObjectId(); }
|
object_id_t SubsystemBase::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
@ -2,14 +2,12 @@
|
|||||||
|
|
||||||
ReturnValue_t modetree::connectModeTreeParent(HasModeTreeChildrenIF& parent,
|
ReturnValue_t modetree::connectModeTreeParent(HasModeTreeChildrenIF& parent,
|
||||||
const ModeTreeChildIF& child,
|
const ModeTreeChildIF& child,
|
||||||
HealthHelper* healthHelper, ModeHelper& modeHelper) {
|
HealthHelper& healthHelper, ModeHelper& modeHelper) {
|
||||||
ReturnValue_t result = parent.registerChild(child);
|
ReturnValue_t result = parent.registerChild(child);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (healthHelper != nullptr) {
|
healthHelper.setParentQueue(parent.getCommandQueue());
|
||||||
healthHelper->setParentQueue(parent.getCommandQueue());
|
|
||||||
}
|
|
||||||
modeHelper.setParentQueue(parent.getCommandQueue());
|
modeHelper.setParentQueue(parent.getCommandQueue());
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
namespace modetree {
|
namespace modetree {
|
||||||
|
|
||||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent, const ModeTreeChildIF& child,
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent, const ModeTreeChildIF& child,
|
||||||
HealthHelper* healthHelper, ModeHelper& modeHelper);
|
HealthHelper& healthHelper, ModeHelper& modeHelper);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,6 +246,20 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t*
|
|||||||
return UNSUPPORTED_TIME_FORMAT;
|
return UNSUPPORTED_TIME_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CCSDSTime::convertToAsciiWithSecs(int8_t* to, const Clock::TimeOfDay_t* from,
|
||||||
|
uint8_t length) {
|
||||||
|
if (from == nullptr or to == nullptr) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
int count = snprintf(reinterpret_cast<char*>(to), length,
|
||||||
|
"%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32,
|
||||||
|
from->year, from->month, from->day, from->hour, from->minute, from->second);
|
||||||
|
if (count >= length) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) {
|
ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) {
|
||||||
const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time);
|
const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time);
|
||||||
|
|
||||||
|
@ -207,7 +207,8 @@ class CCSDSTime {
|
|||||||
|
|
||||||
static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from,
|
static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from,
|
||||||
uint8_t length);
|
uint8_t length);
|
||||||
|
static ReturnValue_t convertToAsciiWithSecs(int8_t *to, const Clock::TimeOfDay_t *from,
|
||||||
|
uint8_t length);
|
||||||
static uint32_t subsecondsToMicroseconds(uint16_t subseconds);
|
static uint32_t subsecondsToMicroseconds(uint16_t subseconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -6,47 +6,12 @@
|
|||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "tmStorageConf.h"
|
#include "tmStorageConf.h"
|
||||||
|
|
||||||
class TmPacketMinimal;
|
class PusTmReader;
|
||||||
class SpacePacketBase;
|
class SpacePacketReader;
|
||||||
class TmStoreBackendIF;
|
class TmStoreBackendIF;
|
||||||
|
|
||||||
class TmStoreFrontendIF {
|
class TmStoreFrontendIF {
|
||||||
public:
|
public:
|
||||||
virtual TmStoreBackendIF* getBackend() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* What do I need to implement here?
|
|
||||||
* This is propably used by PUS Service 15 so we should propably check for messages..
|
|
||||||
* Provide base implementation?
|
|
||||||
* @param opCode
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t performOperation(uint8_t opCode) = 0;
|
|
||||||
/**
|
|
||||||
* Callback from the back-end to indicate a certain packet was received.
|
|
||||||
* front-end takes care of discarding/downloading the packet.
|
|
||||||
* @param packet Pointer to the newly received Space Packet.
|
|
||||||
* @param address Start address of the packet found
|
|
||||||
* @param isLastPacket Indicates if no more packets can be fetched.
|
|
||||||
* @return If more packets shall be fetched, returnvalue::OK must be returned.
|
|
||||||
* Any other code stops fetching packets.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t packetRetrieved(TmPacketMinimal* packet, uint32_t address) = 0;
|
|
||||||
virtual void noMorePacketsInStore() = 0;
|
|
||||||
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
|
|
||||||
uint32_t parameter2 = 0) = 0;
|
|
||||||
/**
|
|
||||||
* To get the queue where commands shall be sent.
|
|
||||||
* @return Id of command queue.
|
|
||||||
*/
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
|
||||||
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
|
|
||||||
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
|
|
||||||
virtual ReturnValue_t checkPacket(SpacePacketBase* tmPacket) = 0;
|
|
||||||
virtual bool isEnabled() const = 0;
|
|
||||||
virtual void setEnabled(bool enabled) = 0;
|
|
||||||
virtual void resetDownlinkedPacketCount() = 0;
|
|
||||||
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::TM_STORE_FRONTEND_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::TM_STORE_FRONTEND_IF;
|
||||||
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t LAST_PACKET_FOUND = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t LAST_PACKET_FOUND = MAKE_RETURN_CODE(2);
|
||||||
@ -57,7 +22,38 @@ class TmStoreFrontendIF {
|
|||||||
static const ReturnValue_t ALL_DELETED = MAKE_RETURN_CODE(7);
|
static const ReturnValue_t ALL_DELETED = MAKE_RETURN_CODE(7);
|
||||||
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(8);
|
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(8);
|
||||||
static const ReturnValue_t NOT_READY = MAKE_RETURN_CODE(9);
|
static const ReturnValue_t NOT_READY = MAKE_RETURN_CODE(9);
|
||||||
virtual ~TmStoreFrontendIF() {}
|
|
||||||
|
virtual ~TmStoreFrontendIF() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To get the queue where commands shall be sent.
|
||||||
|
* @return Id of command queue.
|
||||||
|
*/
|
||||||
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
|
||||||
|
virtual TmStoreBackendIF* getBackend() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback from the back-end to indicate a certain packet was received.
|
||||||
|
* front-end takes care of discarding/downloading the packet.
|
||||||
|
* @param packet Pointer to the newly received Space Packet.
|
||||||
|
* @param address Start address of the packet found
|
||||||
|
* @param isLastPacket Indicates if no more packets can be fetched.
|
||||||
|
* @return If more packets shall be fetched, returnvalue::OK must be returned.
|
||||||
|
* Any other code stops fetching packets.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t packetRetrieved(PusTmReader* packet, uint32_t address) = 0;
|
||||||
|
virtual void noMorePacketsInStore() = 0;
|
||||||
|
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
|
||||||
|
uint32_t parameter2 = 0) = 0;
|
||||||
|
|
||||||
|
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
|
||||||
|
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
|
||||||
|
virtual ReturnValue_t checkPacket(SpacePacketReader* tmPacket) = 0;
|
||||||
|
virtual bool isEnabled() const = 0;
|
||||||
|
virtual void setEnabled(bool enabled) = 0;
|
||||||
|
virtual void resetDownlinkedPacketCount() = 0;
|
||||||
|
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_TMTCSERVICES_TMSTOREFRONTENDIF_H_ */
|
#endif /* FSFW_TMTCSERVICES_TMSTOREFRONTENDIF_H_ */
|
||||||
|
14
src/fsfw/tmstorage/TmStoreFrontendSimpleIF.h
Normal file
14
src/fsfw/tmstorage/TmStoreFrontendSimpleIF.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
|
||||||
|
#define FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
|
||||||
|
|
||||||
|
#include <fsfw/ipc/messageQueueDefinitions.h>
|
||||||
|
|
||||||
|
class TmStoreFrontendSimpleIF {
|
||||||
|
public:
|
||||||
|
virtual ~TmStoreFrontendSimpleIF() = default;
|
||||||
|
|
||||||
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_ */
|
@ -1,6 +1,10 @@
|
|||||||
#ifndef FSFW_TMSTORAGE_TMSTOREPACKETS_H_
|
#ifndef FSFW_TMSTORAGE_TMSTOREPACKETS_H_
|
||||||
#define FSFW_TMSTORAGE_TMSTOREPACKETS_H_
|
#define FSFW_TMSTORAGE_TMSTOREPACKETS_H_
|
||||||
|
|
||||||
|
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/timevalOperations.h"
|
#include "fsfw/globalfunctions/timevalOperations.h"
|
||||||
#include "fsfw/serialize/SerialBufferAdapter.h"
|
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||||
#include "fsfw/serialize/SerialFixedArrayListAdapter.h"
|
#include "fsfw/serialize/SerialFixedArrayListAdapter.h"
|
||||||
@ -24,7 +28,7 @@ class ServiceSubservice : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
|
|
||||||
class ApidSsc : public SerializeIF {
|
class ApidSsc : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
ApidSsc() : apid(SpacePacketBase::LIMIT_APID), ssc(0) {}
|
ApidSsc() : apid(ccsds::LIMIT_APID), ssc(0) {}
|
||||||
ApidSsc(uint16_t apid, uint16_t ssc) : apid(apid), ssc(ssc) {}
|
ApidSsc(uint16_t apid, uint16_t ssc) : apid(apid), ssc(ssc) {}
|
||||||
uint16_t apid;
|
uint16_t apid;
|
||||||
uint16_t ssc;
|
uint16_t ssc;
|
||||||
@ -62,51 +66,59 @@ class ChangeSelectionDefinition : public SerialLinkedListAdapter<SerializeIF> {
|
|||||||
|
|
||||||
class TmPacketInformation : public SerializeIF {
|
class TmPacketInformation : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
TmPacketInformation(TmPacketMinimal* packet) { setContent(packet); }
|
TmPacketInformation(PusTmReader* packet, size_t timestampLen) : rawTimestamp(timestampLen) {
|
||||||
TmPacketInformation()
|
setContent(packet);
|
||||||
: apid(SpacePacketBase::LIMIT_APID),
|
}
|
||||||
|
TmPacketInformation(size_t timestampLen)
|
||||||
|
: apid(ccsds::LIMIT_APID),
|
||||||
sourceSequenceCount(0),
|
sourceSequenceCount(0),
|
||||||
serviceType(0),
|
serviceType(0),
|
||||||
serviceSubtype(0),
|
serviceSubtype(0),
|
||||||
subCounter(0) {}
|
subCounter(0),
|
||||||
|
rawTimestamp(timestampLen) {}
|
||||||
void reset() {
|
void reset() {
|
||||||
apid = SpacePacketBase::LIMIT_APID;
|
apid = ccsds::LIMIT_APID;
|
||||||
sourceSequenceCount = 0;
|
sourceSequenceCount = 0;
|
||||||
serviceType = 0;
|
serviceType = 0;
|
||||||
serviceSubtype = 0;
|
serviceSubtype = 0;
|
||||||
subCounter = 0;
|
subCounter = 0;
|
||||||
memset(rawTimestamp, 0, sizeof(rawTimestamp));
|
memset(rawTimestamp.data(), 0, rawTimestamp.size());
|
||||||
}
|
}
|
||||||
void setContent(TmPacketMinimal* packet) {
|
void setContent(PusTmReader* packet) {
|
||||||
apid = packet->getAPID();
|
apid = packet->getApid();
|
||||||
sourceSequenceCount = packet->getPacketSequenceCount();
|
sourceSequenceCount = packet->getSequenceCount();
|
||||||
serviceType = packet->getService();
|
serviceType = packet->getService();
|
||||||
serviceSubtype = packet->getSubService();
|
serviceSubtype = packet->getSubService();
|
||||||
subCounter = packet->getPacketSubcounter();
|
subCounter = packet->getMessageTypeCounter();
|
||||||
memset(rawTimestamp, 0, sizeof(rawTimestamp));
|
memset(rawTimestamp.data(), 0, rawTimestamp.size());
|
||||||
const uint8_t* pField = NULL;
|
// TODO: Fix all of this
|
||||||
uint32_t size = 0;
|
// const uint8_t* pField = NULL;
|
||||||
ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
|
// uint32_t size = 0;
|
||||||
if (result != returnvalue::OK) {
|
// auto* timeReader = packet->getTimeReader();
|
||||||
return;
|
// ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
|
||||||
}
|
// if (result != returnvalue::OK) {
|
||||||
if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE) {
|
// return;
|
||||||
// Shortcut to avoid converting CDS back and forth.
|
//}
|
||||||
memcpy(rawTimestamp, pField, size);
|
// if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE)
|
||||||
return;
|
// {
|
||||||
}
|
// Shortcut to avoid converting CDS back and forth.
|
||||||
timeval time = {0, 0};
|
// TODO: Fix
|
||||||
result = packet->getPacketTime(&time);
|
// memcpy(rawTimestamp, pField, size);
|
||||||
if (result != returnvalue::OK) {
|
// return;
|
||||||
return;
|
// }
|
||||||
}
|
// timeval time = {0, 0};
|
||||||
|
// result = packet->getPacketTime(&time);
|
||||||
CCSDSTime::CDS_short cdsFormat;
|
// if (result != returnvalue::OK) {
|
||||||
result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
|
// return;
|
||||||
if (result != returnvalue::OK) {
|
// }
|
||||||
return;
|
//
|
||||||
}
|
// CCSDSTime::CDS_short cdsFormat;
|
||||||
memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
|
// result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
|
||||||
|
// if (result != returnvalue::OK) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// TODO: Fix
|
||||||
|
// memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
|
||||||
}
|
}
|
||||||
void setContent(TmPacketInformation* content) {
|
void setContent(TmPacketInformation* content) {
|
||||||
apid = content->apid;
|
apid = content->apid;
|
||||||
@ -114,9 +126,10 @@ class TmPacketInformation : public SerializeIF {
|
|||||||
serviceType = content->serviceType;
|
serviceType = content->serviceType;
|
||||||
serviceSubtype = content->serviceSubtype;
|
serviceSubtype = content->serviceSubtype;
|
||||||
subCounter = content->subCounter;
|
subCounter = content->subCounter;
|
||||||
memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp));
|
// TODO: Fix
|
||||||
|
// memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp));
|
||||||
}
|
}
|
||||||
bool isValid() const { return (apid < SpacePacketBase::LIMIT_APID) ? true : false; }
|
bool isValid() const { return (apid < ccsds::LIMIT_APID) ? true : false; }
|
||||||
static void reset(TmPacketInformation* packet) { packet->reset(); }
|
static void reset(TmPacketInformation* packet) { packet->reset(); }
|
||||||
|
|
||||||
static bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) {
|
static bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) {
|
||||||
@ -216,7 +229,7 @@ class TmPacketInformation : public SerializeIF {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||||
return adapter.serialize(buffer, size, maxSize, streamEndianness);
|
return adapter.serialize(buffer, size, maxSize, streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +240,7 @@ class TmPacketInformation : public SerializeIF {
|
|||||||
size += SerializeAdapter::getSerializedSize(&serviceType);
|
size += SerializeAdapter::getSerializedSize(&serviceType);
|
||||||
size += SerializeAdapter::getSerializedSize(&serviceSubtype);
|
size += SerializeAdapter::getSerializedSize(&serviceSubtype);
|
||||||
size += SerializeAdapter::getSerializedSize(&subCounter);
|
size += SerializeAdapter::getSerializedSize(&subCounter);
|
||||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||||
size += adapter.getSerializedSize();
|
size += adapter.getSerializedSize();
|
||||||
return size;
|
return size;
|
||||||
};
|
};
|
||||||
@ -253,7 +266,7 @@ class TmPacketInformation : public SerializeIF {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||||
return adapter.deSerialize(buffer, size, streamEndianness);
|
return adapter.deSerialize(buffer, size, streamEndianness);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +276,6 @@ class TmPacketInformation : public SerializeIF {
|
|||||||
uint8_t serviceType;
|
uint8_t serviceType;
|
||||||
uint8_t serviceSubtype;
|
uint8_t serviceSubtype;
|
||||||
uint8_t subCounter;
|
uint8_t subCounter;
|
||||||
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE];
|
std::vector<uint8_t> rawTimestamp;
|
||||||
};
|
};
|
||||||
#endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */
|
#endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */
|
||||||
|
@ -100,6 +100,5 @@ ReturnValue_t PusTcCreator::setSerializableUserData(const SerializeIF &serializa
|
|||||||
void PusTcCreator::setup() {
|
void PusTcCreator::setup() {
|
||||||
spCreator.setPacketType(ccsds::PacketType::TC);
|
spCreator.setPacketType(ccsds::PacketType::TC);
|
||||||
spCreator.setSecHeaderFlag();
|
spCreator.setSecHeaderFlag();
|
||||||
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,6 @@ void PusTmCreator::setup() {
|
|||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
spCreator.setPacketType(ccsds::PacketType::TM);
|
spCreator.setPacketType(ccsds::PacketType::TM);
|
||||||
spCreator.setSecHeaderFlag();
|
spCreator.setSecHeaderFlag();
|
||||||
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
|
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
|
||||||
|
@ -11,7 +11,7 @@ class SourceSequenceCounter {
|
|||||||
SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {}
|
SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {}
|
||||||
void increment() { sequenceCount = (sequenceCount + 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void increment() { sequenceCount = (sequenceCount + 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
void decrement() { sequenceCount = (sequenceCount - 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void decrement() { sequenceCount = (sequenceCount - 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
uint16_t get() const { return this->sequenceCount; }
|
uint16_t get() { return this->sequenceCount; }
|
||||||
void reset(uint16_t toValue = 0) { sequenceCount = toValue % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void reset(uint16_t toValue = 0) { sequenceCount = toValue % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
SourceSequenceCounter& operator++(int) {
|
SourceSequenceCounter& operator++(int) {
|
||||||
this->increment();
|
this->increment();
|
||||||
|
@ -145,17 +145,13 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
|||||||
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
|
||||||
|
|
||||||
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
|
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
|
||||||
ReturnValue_t result = storeDownlinkData(&message);
|
storeDownlinkData(&message);
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
tmStore->deleteData(message.getStorageId());
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = tmStore->getData(message.getStorageId(), &data, &size);
|
result = tmStore->getData(message.getStorageId(), &data, &size);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
status = result;
|
status = result;
|
||||||
tmStore->deleteData(message.getStorageId());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,9 +159,9 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
status = result;
|
status = result;
|
||||||
} else {
|
} else {
|
||||||
|
tmStore->deleteData(message.getStorageId());
|
||||||
packetSentCounter++;
|
packetSentCounter++;
|
||||||
}
|
}
|
||||||
tmStore->deleteData(message.getStorageId());
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -325,12 +325,12 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
|
|||||||
// trickery here to calculate the raw values first
|
// trickery here to calculate the raw values first
|
||||||
int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8;
|
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 fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8;
|
||||||
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[9] << 8)) >> 8;
|
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8;
|
||||||
|
|
||||||
// Now scale to physical value in microtesla
|
// Now scale to physical value in microtesla
|
||||||
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;
|
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;
|
||||||
float fieldStrengthY = fieldStrengthRawY * scaleFactorY;
|
float fieldStrengthY = fieldStrengthRawY * scaleFactorX;
|
||||||
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorZ;
|
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX;
|
||||||
|
|
||||||
if (periodicPrintout) {
|
if (periodicPrintout) {
|
||||||
if (debugDivider.checkAndIncrement()) {
|
if (debugDivider.checkAndIncrement()) {
|
||||||
|
@ -183,6 +183,10 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
|
||||||
|
<< " bytes" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <fsfw_hal/linux/serial/SerialComIF.h>
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -31,7 +31,4 @@ int customSetup() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int customTeardown() {
|
int customTeardown() { return 0; }
|
||||||
ObjectManager::clear();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -9,9 +9,7 @@ DeviceHandlerCommander::DeviceHandlerCommander(object_id_t objectId)
|
|||||||
QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceHandlerCommander::~DeviceHandlerCommander() {
|
DeviceHandlerCommander::~DeviceHandlerCommander() {}
|
||||||
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerCommander::performOperation(uint8_t operationCode) {
|
ReturnValue_t DeviceHandlerCommander::performOperation(uint8_t operationCode) {
|
||||||
readCommandQueue();
|
readCommandQueue();
|
||||||
|
@ -1,38 +1,46 @@
|
|||||||
#include <fsfw/osal/osal.h>
|
|
||||||
|
#ifdef LINUX
|
||||||
|
|
||||||
|
/*
|
||||||
#include <fsfw/tasks/SemaphoreFactory.h>
|
#include <fsfw/tasks/SemaphoreFactory.h>
|
||||||
#include <fsfw/timemanager/Stopwatch.h>
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
|
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include "catch.hpp"
|
||||||
|
#include "core/CatchDefinitions.h"
|
||||||
|
|
||||||
// binary semaphores currently only supported on linux
|
TEST_CASE("Binary Semaphore Test" , "[BinSemaphore]") {
|
||||||
#ifdef FSFW_OSAL_LINUX
|
//perform set-up here
|
||||||
|
SemaphoreIF* binSemaph = SemaphoreFactory::instance()->
|
||||||
TEST_CASE("Binary Semaphore Test", "[BinSemaphore]") {
|
createBinarySemaphore();
|
||||||
// perform set-up here
|
REQUIRE(binSemaph != nullptr);
|
||||||
SemaphoreIF* binSemaph = SemaphoreFactory::instance()->createBinarySemaphore();
|
SECTION("Simple Test") {
|
||||||
REQUIRE(binSemaph != nullptr);
|
// set-up is run for each section
|
||||||
SECTION("Simple Test") {
|
REQUIRE(binSemaph->getSemaphoreCounter() == 1);
|
||||||
// set-up is run for each section
|
REQUIRE(binSemaph->release() ==
|
||||||
REQUIRE(binSemaph->getSemaphoreCounter() == 1);
|
static_cast<int>(SemaphoreIF::SEMAPHORE_NOT_OWNED));
|
||||||
REQUIRE(binSemaph->release() == static_cast<int>(SemaphoreIF::SEMAPHORE_NOT_OWNED));
|
REQUIRE(binSemaph->acquire(SemaphoreIF::POLLING) ==
|
||||||
REQUIRE(binSemaph->acquire(SemaphoreIF::POLLING) == returnvalue::OK);
|
returnvalue::OK);
|
||||||
{
|
{
|
||||||
// not precise enough on linux.. should use clock instead..
|
// not precise enough on linux.. should use clock instead..
|
||||||
// Stopwatch stopwatch(false);
|
//Stopwatch stopwatch(false);
|
||||||
// REQUIRE(binSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 5) ==
|
//REQUIRE(binSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 5) ==
|
||||||
// SemaphoreIF::SEMAPHORE_TIMEOUT);
|
// SemaphoreIF::SEMAPHORE_TIMEOUT);
|
||||||
// dur_millis_t time = stopwatch.stop();
|
//dur_millis_t time = stopwatch.stop();
|
||||||
// CHECK(time == 5);
|
//CHECK(time == 5);
|
||||||
}
|
}
|
||||||
REQUIRE(binSemaph->getSemaphoreCounter() == 0);
|
REQUIRE(binSemaph->getSemaphoreCounter() == 0);
|
||||||
REQUIRE(binSemaph->release() == returnvalue::OK);
|
REQUIRE(binSemaph->release() == returnvalue::OK);
|
||||||
}
|
}
|
||||||
SemaphoreFactory::instance()->deleteSemaphore(binSemaph);
|
SemaphoreFactory::instance()->deleteSemaphore(binSemaph);
|
||||||
// perform tear-down here
|
// perform tear-down here
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Counting Semaphore Test", "[CountingSemaph]") {
|
|
||||||
SECTION("Simple Test") {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
TEST_CASE("Counting Semaphore Test" , "[CountingSemaph]") {
|
||||||
|
SECTION("Simple Test") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace addresses {
|
namespace addresses {
|
||||||
/* Logical addresses have uint32_t datatype */
|
/* Logical addresses have uint32_t datatype */
|
||||||
enum LogicAddress : address_t {};
|
enum logicalAddresses : address_t {};
|
||||||
} // namespace addresses
|
} // namespace addresses
|
||||||
|
|
||||||
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */
|
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */
|
||||||
|
Reference in New Issue
Block a user