Merge remote-tracking branch 'upstream/development' into updates_fixes_pus_time_service
fsfw/fsfw/pipeline/pr-development This commit looks good Details

This commit is contained in:
Robin Müller 2023-02-07 12:11:29 +01:00
commit 46230e6c6d
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
22 changed files with 275 additions and 97 deletions

View File

@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval - `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
seconds instead of uptime. seconds instead of uptime.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726 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 - DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
to false correctly because the `read` and `write` calls were missing. to false correctly because the `read` and `write` calls were missing.
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead - PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
@ -36,6 +39,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Added ## Added
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice. - `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. - `DleParser` helper class to parse DLE encoded packets from a byte stream.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711 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.

View File

@ -1,45 +1,87 @@
pipeline { pipeline {
environment { environment {
BUILDDIR = 'cmake-build-tests' BUILDDIR_HOST = 'cmake-build-tests-host'
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' args '--network host --sysctl fs.mqueue.msg_max=100'
} }
} }
stages { stages {
stage('Clean') { stage('Host') {
steps { stages{
sh 'rm -rf $BUILDDIR' stage('Clean') {
} steps {
} sh 'rm -rf $BUILDDIR_HOST'
stage('Configure') { }
steps { }
dir(BUILDDIR) { stage('Configure') {
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..' steps {
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('Build') { stage('Linux') {
steps { stages{
dir(BUILDDIR) { stage('Clean') {
sh 'cmake --build . -j4' steps {
sh 'rm -rf $BUILDDIR_LINUX'
}
} }
} stage('Configure') {
} steps {
stage('Unittests') { dir(BUILDDIR_LINUX) {
steps { sh 'cmake -DFSFW_OSAL=linux -DFSFW_BUILD_TESTS=ON -DFSFW_CICD_BUILD=ON ..'
dir(BUILDDIR) { }
sh 'cmake --build . -- fsfw-tests_coverage -j4' }
} }
} stage('Build') {
} steps {
stage('Valgrind') { dir(BUILDDIR_LINUX) {
steps { sh 'cmake --build . -j4'
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'
}
}
} }
} }
} }

View File

@ -23,6 +23,7 @@ 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);
} }
@ -61,9 +62,14 @@ 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);
} }

View File

@ -31,6 +31,7 @@ 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,

View File

@ -18,6 +18,7 @@ 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;

View File

@ -23,7 +23,7 @@ FailureIsolationBase::~FailureIsolationBase() {
#endif #endif
return; return;
} }
manager->unsubscribeFromAllEvents(eventQueue->getId(), ownerId); manager->unregisterListener(eventQueue->getId());
QueueFactory::instance()->deleteMessageQueue(eventQueue); QueueFactory::instance()->deleteMessageQueue(eventQueue);
} }

View File

@ -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() {} virtual ~MatchTree() { clear(); }
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,6 +176,45 @@ 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) {

View File

@ -6,8 +6,6 @@
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();
} }

View File

@ -7,14 +7,17 @@
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth) InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
: SystemObject(setObjectId), : SystemObject(setObjectId),
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
poolManager(this, commandQueue), poolManager(this, commandQueue),
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID), internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
internalErrorDataset(this) { internalErrorDataset(this) {
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
mutex = MutexFactory::instance()->createMutex(); 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) { void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
this->diagnosticPrintout = enable; this->diagnosticPrintout = enable;

View File

@ -23,9 +23,17 @@ 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() {
for (auto const& iter : objectList) { teardown = true;
delete iter.second; 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) { 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

View File

@ -24,12 +24,17 @@ class ObjectManager : public ObjectManagerIF {
using produce_function_t = void (*)(void* args); 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. * 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>
@ -66,6 +71,9 @@ 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

View File

@ -1,10 +1,13 @@
# 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)
@ -13,16 +16,17 @@ 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(WARNING "The OS_FSFW variable was not set. Assuming host OS..") message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
# Not set. Assumuing this is a host build, try to determine host OS # Not set. Assumuing this is a host build, try to determine host OS
if(WIN32) if(WIN32)
add_subdirectory(host) add_subdirectory(host)
add_subdirectory(windows) add_subdirectory(windows)
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.")
@ -31,3 +35,5 @@ else()
endif() endif()
add_subdirectory(common) add_subdirectory(common)
configure_file(osal.h.in ${CMAKE_BINARY_DIR}/fsfw/osal/osal.h)

View File

@ -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,
size_t receptionBufferSize, size_t ringBufferSize, TcpTmTcServer::TcpConfig cfg, size_t receptionBufferSize,
std::string customTcpServerPort, ReceptionModes receptionMode) size_t ringBufferSize, ReceptionModes receptionMode)
: SystemObject(objectId), : SystemObject(objectId),
tmtcBridgeId(tmtcTcpBridge), tmtcBridgeId(tmtcTcpBridge),
receptionMode(receptionMode), receptionMode(receptionMode),
tcpConfig(std::move(customTcpServerPort)), tcpConfig(cfg),
receptionBuffer(receptionBufferSize), receptionBuffer(receptionBufferSize),
ringBuffer(ringBufferSize, true) {} ringBuffer(ringBufferSize, true) {}
@ -91,6 +91,15 @@ 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) {

View File

@ -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:
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 * Passed to the recv call
@ -63,8 +63,24 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
*/ */
int tcpTmFlags = 0; 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; static const std::string DEFAULT_SERVER_PORT;
@ -80,10 +96,9 @@ 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(object_id_t objectId, object_id_t tmtcTcpBridge, TcpTmTcServer::TcpConfig cfg,
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;

View File

@ -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\n", queueCounter++); sprintf(name, "/FSFW_MQ%u", 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)

36
src/fsfw/osal/osal.h.in Normal file
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
}
};

View File

@ -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: " << std::hex << objectId << std::dec << std::endl; sif::error << "Object ID: 0x" << 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;

View File

@ -329,8 +329,8 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
// 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 * scaleFactorX; float fieldStrengthY = fieldStrengthRawY * scaleFactorY;
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX; float fieldStrengthZ = fieldStrengthRawZ * scaleFactorZ;
if (periodicPrintout) { if (periodicPrintout) {
if (debugDivider.checkAndIncrement()) { if (debugDivider.checkAndIncrement()) {

View File

@ -180,10 +180,6 @@ 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;
} }

View File

@ -31,4 +31,7 @@ int customSetup() {
return 0; return 0;
} }
int customTeardown() { return 0; } int customTeardown() {
ObjectManager::clear();
return 0;
}

View File

@ -9,7 +9,9 @@ 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();

View File

@ -1,46 +1,38 @@
#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 "catch.hpp" #include <catch2/catch_test_macros.hpp>
#include "core/CatchDefinitions.h"
TEST_CASE("Binary Semaphore Test" , "[BinSemaphore]") { // binary semaphores currently only supported on linux
//perform set-up here #ifdef FSFW_OSAL_LINUX
SemaphoreIF* binSemaph = SemaphoreFactory::instance()->
createBinarySemaphore(); TEST_CASE("Binary Semaphore Test", "[BinSemaphore]") {
REQUIRE(binSemaph != nullptr); // perform set-up here
SECTION("Simple Test") { SemaphoreIF* binSemaph = SemaphoreFactory::instance()->createBinarySemaphore();
// set-up is run for each section REQUIRE(binSemaph != nullptr);
REQUIRE(binSemaph->getSemaphoreCounter() == 1); SECTION("Simple Test") {
REQUIRE(binSemaph->release() == // set-up is run for each section
static_cast<int>(SemaphoreIF::SEMAPHORE_NOT_OWNED)); REQUIRE(binSemaph->getSemaphoreCounter() == 1);
REQUIRE(binSemaph->acquire(SemaphoreIF::POLLING) == REQUIRE(binSemaph->release() == static_cast<int>(SemaphoreIF::SEMAPHORE_NOT_OWNED));
result::OK); REQUIRE(binSemaph->acquire(SemaphoreIF::POLLING) == 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() == result::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]") {
TEST_CASE("Counting Semaphore Test" , "[CountingSemaph]") { SECTION("Simple Test") {}
SECTION("Simple Test") {
}
} }
*/
#endif #endif