Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/KSat/fsfw into mueller/master

This commit is contained in:
Robin Müller 2020-12-15 14:41:07 +01:00
commit 3e41b202a1
179 changed files with 1344 additions and 1240 deletions

View File

@ -1,5 +1,8 @@
## Changes from ASTP 0.0.1 to 1.0.0 ## Changes from ASTP 0.0.1 to 1.0.0
### Host OSAL
- Bugfix in MessageQueue, which caused the sender not to be set properly
### FreeRTOS OSAL ### FreeRTOS OSAL
@ -11,3 +14,49 @@ a C file without issues
- It is now possible to change the message queue depth for the telecommand verification service (PUS1) - It is now possible to change the message queue depth for the telecommand verification service (PUS1)
- The same is possible for the event reporting service (PUS5) - The same is possible for the event reporting service (PUS5)
- PUS Health Service added, which allows to command and retrieve health via PUS packets - PUS Health Service added, which allows to command and retrieve health via PUS packets
### EnhancedControllerBase
- New base class for a controller which also implements HasActionsIF and HasLocalDataPoolIF
### Local Pool
- Interface of LocalPools has changed. LocalPool is not a template anymore. Instead the size and bucket number of the pools per page and the number of pages are passed to the ctor instead of two ctor arguments and a template parameter
### Parameter Service
- The API of the parameter service has been changed to prevent inconsistencies
between documentation and actual code and to clarify usage.
- The parameter ID now consists of:
1. Domain ID (1 byte)
2. Unique Identifier (1 byte)
3. Linear Index (2 bytes)
The linear index can be used for arrays as well as matrices.
The parameter load command now explicitely expects the ECSS PTC and PFC
information as well as the rows and column number. Rows and column will
default to one, which is equivalent to one scalar parameter (the most
important use-case)
### File System Interface
- A new interfaces specifies the functions for a software object which exposes the file system of a given hardware to use message based file handling (e.g. PUS commanding)
### Internal Error Reporter
- The new internal error reporter uses the local data pools. The pool IDs for
the exisiting three error values and the new error set will be hardcoded for
now, the the constructor for the internal error reporter just takes an object
ID for now.
### Device Handler Base
- There is an additional `PERFORM_OPERATION` step for the device handler base. It is important
that DHB users adapt their polling sequence tables to perform this step. This steps allows for aclear distinction between operation and communication steps
### Events
- makeEvent function: Now takes three input parameters instead of two and
allows setting a unique ID. Event.cpp source file removed, functions now
defined in header directly. Namespaces renamed. Functions declared `constexpr`
now

85
CMakeLists.txt Normal file
View File

@ -0,0 +1,85 @@
cmake_minimum_required(VERSION 3.13)
set(LIB_FSFW_NAME fsfw)
add_library(${LIB_FSFW_NAME})
# Set options for FSFW OSAL selection.
if(UNIX)
set(OS_FSFW "linux" CACHE STRING "OS abstraction layer used in the FSFW")
elseif(WIN32)
set(OS_FSFW "host" CACHE STRING "OS abstraction layer used in the FSFW")
endif()
set_property(CACHE OS_FSFW PROPERTY STRINGS host linux rtems freertos)
if(${OS_FSFW} STREQUAL host)
set(OS_FSFW_NAME "Host")
elseif(${OS_FSFW} STREQUAL linux)
set(OS_FSFW_NAME "Linux")
elseif(${OS_FSFW} STREQUAL freertos)
set(OS_FSFW_NAME "FreeRTOS")
elseif(${OS_FSFW} STREQUAL rtems)
set(OS_FSFW_NAME "RTEMS")
else()
message(WARNING "Invalid operating system for FSFW specified! Setting to host..")
set(OS_FSFW_NAME "Host")
set(OS_FSFW "host")
endif()
message(STATUS "Compiling FSFW for the ${OS_FSFW_NAME} operating system")
# Options to exclude parts of the FSFW from compilation.
option(FSFW_USE_RMAP "Compile with RMAP" ON)
option(FSFW_USE_DATALINKLAYER "Compile with Data Link Layer" ON)
add_subdirectory(action)
add_subdirectory(container)
add_subdirectory(controller)
add_subdirectory(coordinates)
add_subdirectory(datalinklayer)
add_subdirectory(datapool)
add_subdirectory(devicehandlers)
add_subdirectory(events)
add_subdirectory(fdir)
add_subdirectory(globalfunctions)
add_subdirectory(health)
add_subdirectory(internalError)
add_subdirectory(ipc)
add_subdirectory(memory)
add_subdirectory(modes)
add_subdirectory(monitoring)
add_subdirectory(objectmanager)
add_subdirectory(osal)
add_subdirectory(parameters)
add_subdirectory(power)
add_subdirectory(pus)
if(FSFW_USE_RMAP)
add_subdirectory(rmap)
endif()
add_subdirectory(serialize)
add_subdirectory(serviceinterface)
add_subdirectory(storagemanager)
add_subdirectory(subsystem)
add_subdirectory(tasks)
add_subdirectory(tcdistribution)
add_subdirectory(thermal)
add_subdirectory(timemanager)
add_subdirectory(tmstorage)
add_subdirectory(tmtcpacket)
add_subdirectory(tmtcservices)
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it.
# If this is not given, we include the default configuration and emit a warning.
if(NOT FSFW_CONFIG_PATH)
message(WARNING "Flight Software Framework configuration path not set!")
message(WARNING "Setting default configuration!")
add_subdirectory(defaultcfg/fsfwconfig)
endif()
# Required include paths to compile the FSFW
target_include_directories(${LIB_FSFW_NAME}
INTERFACE
${FSFW_CONFIG_PATH}
)

View File

@ -1,10 +1,11 @@
#ifndef FSFW_DEFAULTCFG_VERSION_H_ #ifndef FSFW_DEFAULTCFG_VERSION_H_
#define FSFW_DEFAULTCFG_VERSION_H_ #define FSFW_DEFAULTCFG_VERSION_H_
const char* const FSFW_VERSION_NAME = "fsfw"; const char* const FSFW_VERSION_NAME = "ASTP";
#define FSFW_VERSION 0 #define FSFW_VERSION 0
#define FSFW_SUBVERSION 0 #define FSFW_SUBVERSION 0
#define FSFW_REVISION 1

2
NOTICE
View File

@ -4,6 +4,8 @@ The initial version of the Flight Software Framework was developed during
the Flying Laptop Project by the Universität Stuttgart in coorporation the Flying Laptop Project by the Universität Stuttgart in coorporation
with Airbus Defence and Space GmbH. with Airbus Defence and Space GmbH.
The supreme FSFW Logo was designed by Markus Koller and Luise Trilsbach.
Copyrights in the Flight Software Framework are retained by their contributors. Copyrights in the Flight Software Framework are retained by their contributors.
No copyright assignment is required to contribute to the Flight Software Framework. No copyright assignment is required to contribute to the Flight Software Framework.

View File

@ -0,0 +1,4 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
ControllerBase.cpp
)

View File

@ -8,7 +8,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
size_t commandQueueDepth) : size_t commandQueueDepth) :
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
submode(SUBMODE_NONE), modeHelper(this), submode(SUBMODE_NONE), modeHelper(this),
healthHelper(this, setObjectId), hkSwitcher(this) { healthHelper(this, setObjectId) {
commandQueue = QueueFactory::instance()->createMessageQueue( commandQueue = QueueFactory::instance()->createMessageQueue(
commandQueueDepth); commandQueueDepth);
} }
@ -44,10 +44,6 @@ ReturnValue_t ControllerBase::initialize() {
return result; return result;
} }
result = hkSwitcher.initialize();
if (result != RETURN_OK) {
return result;
}
return RETURN_OK; return RETURN_OK;
} }
@ -107,7 +103,6 @@ void ControllerBase::announceMode(bool recursive) {
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) { ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
handleQueue(); handleQueue();
hkSwitcher.performOperation();
performControlOperation(); performControlOperation();
return RETURN_OK; return RETURN_OK;
} }

View File

@ -72,9 +72,6 @@ protected:
HealthHelper healthHelper; HealthHelper healthHelper;
// Is this still needed?
HkSwitchHelper hkSwitcher;
/** /**
* Pointer to the task which executes this component, * Pointer to the task which executes this component,
* is invalid before setTaskIF was called. * is invalid before setTaskIF was called.

View File

@ -97,7 +97,6 @@ ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) { ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
handleQueue(); handleQueue();
hkSwitcher.performOperation();
localPoolManager.performHkOperation(); localPoolManager.performHkOperation();
performControlOperation(); performControlOperation();
return RETURN_OK; return RETURN_OK;

View File

@ -19,12 +19,12 @@ class VirtualChannelReception;
class DataLinkLayer : public CCSDSReturnValuesIF { class DataLinkLayer : public CCSDSReturnValuesIF {
public: public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_1;
static const Event RF_AVAILABLE = MAKE_EVENT(0, SEVERITY::INFO); //!< A RF available signal was detected. P1: raw RFA state, P2: 0 static const Event RF_AVAILABLE = MAKE_EVENT(0, severity::INFO); //!< A RF available signal was detected. P1: raw RFA state, P2: 0
static const Event RF_LOST = MAKE_EVENT(1, SEVERITY::INFO); //!< A previously found RF available signal was lost. P1: raw RFA state, P2: 0 static const Event RF_LOST = MAKE_EVENT(1, severity::INFO); //!< A previously found RF available signal was lost. P1: raw RFA state, P2: 0
static const Event BIT_LOCK = MAKE_EVENT(2, SEVERITY::INFO); //!< A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0 static const Event BIT_LOCK = MAKE_EVENT(2, severity::INFO); //!< A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0
static const Event BIT_LOCK_LOST = MAKE_EVENT(3, SEVERITY::INFO); //!< A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0 static const Event BIT_LOCK_LOST = MAKE_EVENT(3, severity::INFO); //!< A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0
// static const Event RF_CHAIN_LOST = MAKE_EVENT(4, SEVERITY::INFO); //!< The CCSDS Board detected that either bit lock or RF available or both are lost. No parameters. // static const Event RF_CHAIN_LOST = MAKE_EVENT(4, severity::INFO); //!< The CCSDS Board detected that either bit lock or RF available or both are lost. No parameters.
static const Event FRAME_PROCESSING_FAILED = MAKE_EVENT(5, SEVERITY::LOW); //!< The CCSDS Board could not interpret a TC static const Event FRAME_PROCESSING_FAILED = MAKE_EVENT(5, severity::LOW); //!< The CCSDS Board could not interpret a TC
/** /**
* The Constructor sets the passed parameters and nothing else. * The Constructor sets the passed parameters and nothing else.
* @param set_frame_buffer The buffer in which incoming frame candidates are stored. * @param set_frame_buffer The buffer in which incoming frame candidates are stored.

View File

@ -9,9 +9,9 @@
MapPacketExtraction::MapPacketExtraction(uint8_t setMapId, MapPacketExtraction::MapPacketExtraction(uint8_t setMapId,
object_id_t setPacketDestination) : object_id_t setPacketDestination) :
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId),
bufferPosition(packetBuffer), packetDestination(setPacketDestination), bufferPosition(packetBuffer), packetDestination(setPacketDestination),
packetStore(NULL), tcQueueId(MessageQueueIF::NO_QUEUE) { tcQueueId(MessageQueueIF::NO_QUEUE) {
std::memset(packetBuffer, 0, sizeof(packetBuffer)); std::memset(packetBuffer, 0, sizeof(packetBuffer));
} }

View File

@ -1,5 +1,5 @@
#ifndef MAPPACKETEXTRACTION_H_ #ifndef FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
#define MAPPACKETEXTRACTION_H_ #define FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
#include "MapPacketExtractionIF.h" #include "MapPacketExtractionIF.h"
#include "../objectmanager/ObjectManagerIF.h" #include "../objectmanager/ObjectManagerIF.h"
@ -20,11 +20,12 @@ private:
static const uint32_t MAX_PACKET_SIZE = 4096; static const uint32_t MAX_PACKET_SIZE = 4096;
uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame. uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame.
uint8_t mapId; //!< MAP ID of this MAP Channel. uint8_t mapId; //!< MAP ID of this MAP Channel.
uint32_t packetLength; //!< Complete length of the current Space Packet. uint32_t packetLength = 0; //!< Complete length of the current Space Packet.
uint8_t* bufferPosition; //!< Position to write to in the internal Packet buffer. uint8_t* bufferPosition; //!< Position to write to in the internal Packet buffer.
uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer. uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer.
object_id_t packetDestination; object_id_t packetDestination;
StorageManagerIF* packetStore; //!< Pointer to the store where full TC packets are stored. //!< Pointer to the store where full TC packets are stored.
StorageManagerIF* packetStore = nullptr;
MessageQueueId_t tcQueueId; //!< QueueId to send found packets to the distributor. MessageQueueId_t tcQueueId; //!< QueueId to send found packets to the distributor.
/** /**
* Debug method to print the packet Buffer's content. * Debug method to print the packet Buffer's content.
@ -69,4 +70,4 @@ public:
uint8_t getMapId() const; uint8_t getMapId() const;
}; };
#endif /* MAPPACKETEXTRACTION_H_ */ #endif /* FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_ */

View File

@ -13,7 +13,7 @@ class HkSwitchHelper: public ExecutableObjectIF, public CommandsActionsIF {
public: public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HK; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HK;
static const Event SWITCHING_TM_FAILED = MAKE_EVENT(1, SEVERITY::LOW); //!< Commanding the HK Service failed, p1: error code, p2 action: 0 disable / 1 enable static const Event SWITCHING_TM_FAILED = MAKE_EVENT(1, severity::LOW); //!< Commanding the HK Service failed, p1: error code, p2 action: 0 disable / 1 enable
HkSwitchHelper(EventReportingProxyIF *eventProxy); HkSwitchHelper(EventReportingProxyIF *eventProxy);
virtual ~HkSwitchHelper(); virtual ~HkSwitchHelper();

View File

@ -48,7 +48,7 @@ class HousekeepingPacketUpdate;
* @author R. Mueller * @author R. Mueller
*/ */
class LocalDataPoolManager { class LocalDataPoolManager {
template<typename T> friend class LocalPoolVar; template<typename T> friend class LocalPoolVariable;
template<typename T, uint16_t vecSize> friend class LocalPoolVector; template<typename T, uint16_t vecSize> friend class LocalPoolVector;
friend class LocalPoolDataSetBase; friend class LocalPoolDataSetBase;
friend void (Factory::setStaticFrameworkObjectIds)(); friend void (Factory::setStaticFrameworkObjectIds)();

View File

@ -22,10 +22,10 @@
* @ingroup data_pool * @ingroup data_pool
*/ */
template<typename T> template<typename T>
class LocalPoolVar: public LocalPoolObjectBase { class LocalPoolVariable: public LocalPoolObjectBase {
public: public:
//! Default ctor is forbidden. //! Default ctor is forbidden.
LocalPoolVar() = delete; LocalPoolVariable() = delete;
/** /**
* This constructor is used by the data creators to have pool variable * This constructor is used by the data creators to have pool variable
@ -43,7 +43,7 @@ public:
* If nullptr, the variable is not registered. * If nullptr, the variable is not registered.
* @param setReadWriteMode Specify the read-write mode of the pool variable. * @param setReadWriteMode Specify the read-write mode of the pool variable.
*/ */
LocalPoolVar(HasLocalDataPoolIF* hkOwner, lp_id_t poolId, LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE); pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
@ -64,7 +64,7 @@ public:
* @param setReadWriteMode Specify the read-write mode of the pool variable. * @param setReadWriteMode Specify the read-write mode of the pool variable.
* *
*/ */
LocalPoolVar(object_id_t poolOwner, lp_id_t poolId, LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
DataSetIF* dataSet = nullptr, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE); pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
/** /**
@ -73,10 +73,10 @@ public:
* @param dataSet * @param dataSet
* @param setReadWriteMode * @param setReadWriteMode
*/ */
LocalPoolVar(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr, LocalPoolVariable(gp_id_t globalPoolId, DataSetIF* dataSet = nullptr,
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE); pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
virtual~ LocalPoolVar() {}; virtual~ LocalPoolVariable() {};
/** /**
* @brief This is the local copy of the data pool entry. * @brief This is the local copy of the data pool entry.
@ -118,23 +118,23 @@ public:
ReturnValue_t commit(dur_millis_t lockTimeout = MutexIF::BLOCKING) override; ReturnValue_t commit(dur_millis_t lockTimeout = MutexIF::BLOCKING) override;
LocalPoolVar<T> &operator=(const T& newValue); LocalPoolVariable<T> &operator=(const T& newValue);
LocalPoolVar<T> &operator=(const LocalPoolVar<T>& newPoolVariable); LocalPoolVariable<T> &operator=(const LocalPoolVariable<T>& newPoolVariable);
//! Explicit type conversion operator. Allows casting the class to //! Explicit type conversion operator. Allows casting the class to
//! its template type to perform operations on value. //! its template type to perform operations on value.
explicit operator T() const; explicit operator T() const;
bool operator==(const LocalPoolVar<T>& other) const; bool operator==(const LocalPoolVariable<T>& other) const;
bool operator==(const T& other) const; bool operator==(const T& other) const;
bool operator!=(const LocalPoolVar<T>& other) const; bool operator!=(const LocalPoolVariable<T>& other) const;
bool operator!=(const T& other) const; bool operator!=(const T& other) const;
bool operator<(const LocalPoolVar<T>& other) const; bool operator<(const LocalPoolVariable<T>& other) const;
bool operator<(const T& other) const; bool operator<(const T& other) const;
bool operator>(const LocalPoolVar<T>& other) const; bool operator>(const LocalPoolVariable<T>& other) const;
bool operator>(const T& other) const; bool operator>(const T& other) const;
protected: protected:
@ -160,7 +160,7 @@ protected:
// std::ostream is the type for object std::cout // std::ostream is the type for object std::cout
template <typename U> template <typename U>
friend std::ostream& operator<< (std::ostream &out, friend std::ostream& operator<< (std::ostream &out,
const LocalPoolVar<U> &var); const LocalPoolVariable<U> &var);
private: private:
}; };
@ -168,18 +168,18 @@ private:
#include "LocalPoolVariable.tpp" #include "LocalPoolVariable.tpp"
template<class T> template<class T>
using lp_var_t = LocalPoolVar<T>; using lp_var_t = LocalPoolVariable<T>;
using lp_bool_t = LocalPoolVar<uint8_t>; using lp_bool_t = LocalPoolVariable<uint8_t>;
using lp_uint8_t = LocalPoolVar<uint8_t>; using lp_uint8_t = LocalPoolVariable<uint8_t>;
using lp_uint16_t = LocalPoolVar<uint16_t>; using lp_uint16_t = LocalPoolVariable<uint16_t>;
using lp_uint32_t = LocalPoolVar<uint32_t>; using lp_uint32_t = LocalPoolVariable<uint32_t>;
using lp_uint64_t = LocalPoolVar<uint64_t>; using lp_uint64_t = LocalPoolVariable<uint64_t>;
using lp_int8_t = LocalPoolVar<int8_t>; using lp_int8_t = LocalPoolVariable<int8_t>;
using lp_int16_t = LocalPoolVar<int16_t>; using lp_int16_t = LocalPoolVariable<int16_t>;
using lp_int32_t = LocalPoolVar<int32_t>; using lp_int32_t = LocalPoolVariable<int32_t>;
using lp_int64_t = LocalPoolVar<int64_t>; using lp_int64_t = LocalPoolVariable<int64_t>;
using lp_float_t = LocalPoolVar<float>; using lp_float_t = LocalPoolVariable<float>;
using lp_double_t = LocalPoolVar<double>; using lp_double_t = LocalPoolVariable<double>;
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ */ #endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ */

View File

@ -6,32 +6,32 @@
#endif #endif
template<typename T> template<typename T>
inline LocalPoolVar<T>::LocalPoolVar(HasLocalDataPoolIF* hkOwner, inline LocalPoolVariable<T>::LocalPoolVariable(HasLocalDataPoolIF* hkOwner,
lp_id_t poolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode): lp_id_t poolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {} LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
template<typename T> template<typename T>
inline LocalPoolVar<T>::LocalPoolVar(object_id_t poolOwner, lp_id_t poolId, inline LocalPoolVariable<T>::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
DataSetIF *dataSet, pool_rwm_t setReadWriteMode): DataSetIF *dataSet, pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {} LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
template<typename T> template<typename T>
inline LocalPoolVar<T>::LocalPoolVar(gp_id_t globalPoolId, DataSetIF *dataSet, inline LocalPoolVariable<T>::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF *dataSet,
pool_rwm_t setReadWriteMode): pool_rwm_t setReadWriteMode):
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
dataSet, setReadWriteMode){} dataSet, setReadWriteMode){}
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::read(dur_millis_t lockTimeout) { inline ReturnValue_t LocalPoolVariable<T>::read(dur_millis_t lockTimeout) {
MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING, MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
lockTimeout); lockTimeout);
return readWithoutLock(); return readWithoutLock();
} }
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::readWithoutLock() { inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_WRITE) { if(readWriteMode == pool_rwm_t::VAR_WRITE) {
sif::debug << "LocalPoolVar: Invalid read write " sif::debug << "LocalPoolVar: Invalid read write "
"mode for read() call." << std::endl; "mode for read() call." << std::endl;
@ -53,14 +53,14 @@ inline ReturnValue_t LocalPoolVar<T>::readWithoutLock() {
} }
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::commit(dur_millis_t lockTimeout) { inline ReturnValue_t LocalPoolVariable<T>::commit(dur_millis_t lockTimeout) {
MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING, MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
lockTimeout); lockTimeout);
return commitWithoutLock(); return commitWithoutLock();
} }
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::commitWithoutLock() { inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
if(readWriteMode == pool_rwm_t::VAR_READ) { if(readWriteMode == pool_rwm_t::VAR_READ) {
sif::debug << "LocalPoolVar: Invalid read write " sif::debug << "LocalPoolVar: Invalid read write "
"mode for commit() call." << std::endl; "mode for commit() call." << std::endl;
@ -81,88 +81,88 @@ inline ReturnValue_t LocalPoolVar<T>::commitWithoutLock() {
} }
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::serialize(uint8_t** buffer, size_t* size, inline ReturnValue_t LocalPoolVariable<T>::serialize(uint8_t** buffer, size_t* size,
const size_t max_size, SerializeIF::Endianness streamEndianness) const { const size_t max_size, SerializeIF::Endianness streamEndianness) const {
return SerializeAdapter::serialize(&value, return SerializeAdapter::serialize(&value,
buffer, size ,max_size, streamEndianness); buffer, size ,max_size, streamEndianness);
} }
template<typename T> template<typename T>
inline size_t LocalPoolVar<T>::getSerializedSize() const { inline size_t LocalPoolVariable<T>::getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&value); return SerializeAdapter::getSerializedSize(&value);
} }
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::deSerialize(const uint8_t** buffer, inline ReturnValue_t LocalPoolVariable<T>::deSerialize(const uint8_t** buffer,
size_t* size, SerializeIF::Endianness streamEndianness) { size_t* size, SerializeIF::Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
} }
template<typename T> template<typename T>
inline std::ostream& operator<< (std::ostream &out, inline std::ostream& operator<< (std::ostream &out,
const LocalPoolVar<T> &var) { const LocalPoolVariable<T> &var) {
out << var.value; out << var.value;
return out; return out;
} }
template<typename T> template<typename T>
inline LocalPoolVar<T>::operator T() const { inline LocalPoolVariable<T>::operator T() const {
return value; return value;
} }
template<typename T> template<typename T>
inline LocalPoolVar<T> & LocalPoolVar<T>::operator=(const T& newValue) { inline LocalPoolVariable<T> & LocalPoolVariable<T>::operator=(const T& newValue) {
value = newValue; value = newValue;
return *this; return *this;
} }
template<typename T> template<typename T>
inline LocalPoolVar<T>& LocalPoolVar<T>::operator =( inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator =(
const LocalPoolVar<T>& newPoolVariable) { const LocalPoolVariable<T>& newPoolVariable) {
value = newPoolVariable.value; value = newPoolVariable.value;
return *this; return *this;
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator ==(const LocalPoolVar<T> &other) const { inline bool LocalPoolVariable<T>::operator ==(const LocalPoolVariable<T> &other) const {
return this->value == other.value; return this->value == other.value;
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator ==(const T &other) const { inline bool LocalPoolVariable<T>::operator ==(const T &other) const {
return this->value == other; return this->value == other;
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator !=(const LocalPoolVar<T> &other) const { inline bool LocalPoolVariable<T>::operator !=(const LocalPoolVariable<T> &other) const {
return not (*this == other); return not (*this == other);
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator !=(const T &other) const { inline bool LocalPoolVariable<T>::operator !=(const T &other) const {
return not (*this == other); return not (*this == other);
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator <(const LocalPoolVar<T> &other) const { inline bool LocalPoolVariable<T>::operator <(const LocalPoolVariable<T> &other) const {
return this->value < other.value; return this->value < other.value;
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator <(const T &other) const { inline bool LocalPoolVariable<T>::operator <(const T &other) const {
return this->value < other; return this->value < other;
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator >(const LocalPoolVar<T> &other) const { inline bool LocalPoolVariable<T>::operator >(const LocalPoolVariable<T> &other) const {
return not (*this < other); return not (*this < other);
} }
template<typename T> template<typename T>
inline bool LocalPoolVar<T>::operator >(const T &other) const { inline bool LocalPoolVariable<T>::operator >(const T &other) const {
return not (*this < other); return not (*this < other);
} }

View File

@ -27,13 +27,11 @@
#define FSFW_OBJ_EVENT_TRANSLATION 0 #define FSFW_OBJ_EVENT_TRANSLATION 0
#if FSFW_OBJ_EVENT_TRANSLATION == 1 #if FSFW_OBJ_EVENT_TRANSLATION == 1
#define FSFW_DEBUG_OUTPUT 1
//! Specify whether info events are printed too. //! Specify whether info events are printed too.
#define FSFW_DEBUG_INFO 1 #define FSFW_DEBUG_INFO 1
#include <translateObjects.h> #include <translateObjects.h>
#include <translateEvents.h> #include <translateEvents.h>
#else #else
#define FSFW_DEBUG_OUTPUT 0
#endif #endif
//! When using the newlib nano library, C99 support for stdio facilities //! When using the newlib nano library, C99 support for stdio facilities

View File

@ -113,7 +113,7 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
doGetRead(); doGetRead();
// This will be performed after datasets have been updated by the // This will be performed after datasets have been updated by the
// custom device implementation. // custom device implementation.
hkManager.performHkOperation(); hkManager.performHkOperation();
break; break;
default: default:
break; break;
@ -693,7 +693,7 @@ void DeviceHandlerBase::doGetRead() {
void DeviceHandlerBase::parseReply(const uint8_t* receivedData, void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
size_t receivedDataLen) { size_t receivedDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
DeviceCommandId_t foundId = 0xffffffff; DeviceCommandId_t foundId = DeviceHandlerIF::NO_COMMAND;
size_t foundLen = 0; size_t foundLen = 0;
// The loop may not execute more often than the number of received bytes // The loop may not execute more often than the number of received bytes
// (worst case). This approach avoids infinite loops due to buggy // (worst case). This approach avoids infinite loops due to buggy
@ -1453,3 +1453,9 @@ dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const {
return pstIntervalMs; return pstIntervalMs;
} }
DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
if(cookieInfo.pendingCommand != deviceCommandMap.end()) {
return cookieInfo.pendingCommand->first;
}
return DeviceHandlerIF::NO_COMMAND;
}

View File

@ -234,7 +234,7 @@ protected:
* - If the device does not change the mode, the mode will be changed to * - If the device does not change the mode, the mode will be changed to
* _MODE_POWER_DOWN, when the timeout (from getTransitionDelay()) * _MODE_POWER_DOWN, when the timeout (from getTransitionDelay())
* has passed. * has passed.
* 0xffffffff *
* #transitionFailure can be set to a failure code indicating the reason * #transitionFailure can be set to a failure code indicating the reason
* for a failed transition * for a failed transition
*/ */
@ -734,15 +734,27 @@ protected:
//! before setTaskIF was called. //! before setTaskIF was called.
PeriodicTaskIF* executingTask = nullptr; PeriodicTaskIF* executingTask = nullptr;
static object_id_t powerSwitcherId; //!< Object which switches power on and off. //!< Object which switches power on and off.
static object_id_t powerSwitcherId;
static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default. //!< Object which receives RAW data by default.
static object_id_t rawDataReceiverId;
//!< Object which may be the root cause of an identified fault.
static object_id_t defaultFdirParentId;
/**
* Helper function to get pending command. This is useful for devices
* like SPI sensors to identify the last sent command.
* @return
*/
DeviceCommandId_t getPendingCommand() const;
static object_id_t defaultFdirParentId; //!< Object which may be the root cause of an identified fault.
/** /**
* Helper function to report a missed reply * Helper function to report a missed reply
* *
* Can be overwritten by children to act on missed replies or to fake reporting Id. * Can be overwritten by children to act on missed replies or to fake
* reporting Id.
* *
* @param id of the missed reply * @param id of the missed reply
*/ */
@ -849,15 +861,18 @@ protected:
/** /**
* Build the device command to send for raw mode. * Build the device command to send for raw mode.
* *
* This is only called in @c MODE_RAW. It is for the rare case that in raw mode packets * This is only called in @c MODE_RAW. It is for the rare case that in
* are to be sent by the handler itself. It is NOT needed for the raw commanding service. * raw mode packets are to be sent by the handler itself. It is NOT needed
* Its only current use is in the STR handler which gets its raw packets from a different * for the raw commanding service. Its only current use is in the STR
* source. * handler which gets its raw packets from a different source.
* Also it can be used for transitional commands, to get the device ready for @c MODE_RAW * Also it can be used for transitional commands, to get the device ready
* for @c MODE_RAW
* *
* As it is almost never used, there is a default implementation returning @c NOTHING_TO_SEND. * As it is almost never used, there is a default implementation
* returning @c NOTHING_TO_SEND.
* *
* #rawPacket and #rawPacketLen must be set by this method to the packet to be sent. * #rawPacket and #rawPacketLen must be set by this method to the packet
* to be sent.
* *
* @param[out] id the device command id built * @param[out] id the device command id built
* @return * @return
@ -870,7 +885,9 @@ protected:
* Returns the delay cycle count of a reply. * Returns the delay cycle count of a reply.
* A count != 0 indicates that the command is already executed. * A count != 0 indicates that the command is already executed.
* @param deviceCommand The command to look for * @param deviceCommand The command to look for
* @return The current delay count. If the command does not exist (should never happen) it returns 0. * @return
* The current delay count. If the command does not exist (should never
* happen) it returns 0.
*/ */
uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand); uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand);
@ -880,20 +897,22 @@ protected:
* It gets space in the #IPCStore, copies data there, then sends a raw reply * It gets space in the #IPCStore, copies data there, then sends a raw reply
* containing the store address. * containing the store address.
* *
* This method is virtual, as the STR has a different channel to send raw replies * This method is virtual, as the STR has a different channel to send
* and overwrites it accordingly. * raw replies and overwrites it accordingly.
* *
* @param data data to send * @param data data to send
* @param len length of @c data * @param len length of @c data
* @param sendTo the messageQueueId of the one to send to * @param sendTo the messageQueueId of the one to send to
* @param isCommand marks the raw data as a command, the message then will be of type raw_command * @param isCommand marks the raw data as a command, the message then
* will be of type raw_command
*/ */
virtual void replyRawData(const uint8_t *data, size_t len, virtual void replyRawData(const uint8_t *data, size_t len,
MessageQueueId_t sendTo, bool isCommand = false); MessageQueueId_t sendTo, bool isCommand = false);
/** /**
* Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping is active and if so, * Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping
* does not send the Data as the wiretapping will have sent it already * is active and if so, does not send the data as the wiretapping will have
* sent it already
*/ */
void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len); void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len);
@ -905,17 +924,19 @@ protected:
/** /**
* Enable the reply checking for a command * Enable the reply checking for a command
* *
* Is only called, if the command was sent (ie the getWriteReply was successful). * Is only called, if the command was sent (i.e. the getWriteReply was
* Must ensure that all replies are activated and correctly linked to the command that initiated it. * successful). Must ensure that all replies are activated and correctly
* The default implementation looks for a reply with the same id as the command id in the replyMap or * linked to the command that initiated it.
* uses the alternativeReplyId if flagged so. * The default implementation looks for a reply with the same id as the
* When found, copies maxDelayCycles to delayCycles in the reply information and sets the command to * command id in the replyMap or uses the alternativeReplyId if flagged so.
* expect one reply. * When found, copies maxDelayCycles to delayCycles in the reply information
* and sets the command to expect one reply.
* *
* Can be overwritten by the child, if a command activates multiple replies * Can be overwritten by the child, if a command activates multiple replies
* or replyId differs from commandId. * or replyId differs from commandId.
* Notes for child implementations: * Notes for child implementations:
* - If the command was not found in the reply map, NO_REPLY_EXPECTED MUST be returned. * - If the command was not found in the reply map,
* NO_REPLY_EXPECTED MUST be returned.
* - A failure code may be returned if something went fundamentally wrong. * - A failure code may be returned if something went fundamentally wrong.
* *
* @param deviceCommand * @param deviceCommand
@ -931,17 +952,20 @@ protected:
* get the state of the PCDU switches in the datapool * get the state of the PCDU switches in the datapool
* *
* @return * @return
* - @c PowerSwitchIF::SWITCH_ON if all switches specified by #switches are on * - @c PowerSwitchIF::SWITCH_ON if all switches specified
* - @c PowerSwitchIF::SWITCH_OFF one of the switches specified by #switches are off * by #switches are on
* - @c PowerSwitchIF::RETURN_FAILED if an error occured * - @c PowerSwitchIF::SWITCH_OFF one of the switches specified by
* #switches are off
* - @c PowerSwitchIF::RETURN_FAILED if an error occured
*/ */
ReturnValue_t getStateOfSwitches(void); ReturnValue_t getStateOfSwitches(void);
/** /**
* set all datapool variables that are update periodically in normal mode invalid * @brief Set all datapool variables that are update periodically in
* * normal mode invalid
* Child classes should provide an implementation which sets all those variables invalid * @details TODO: Use local pools
* which are set periodically during any normal mode. * Child classes should provide an implementation which sets all those
* variables invalid which are set periodically during any normal mode.
*/ */
virtual void setNormalDatapoolEntriesInvalid() = 0; virtual void setNormalDatapoolEntriesInvalid() = 0;
@ -951,11 +975,12 @@ protected:
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
/** /**
* Children can overwrite this function to suppress checking of the command Queue * Children can overwrite this function to suppress checking of the
* command Queue
* *
* This can be used when the child does not want to receive a command in a certain * This can be used when the child does not want to receive a command in
* situation. Care must be taken that checking is not permanentely disabled as this * a certain situation. Care must be taken that checking is not
* would render the handler unusable. * permanentely disabled as this would render the handler unusable.
* *
* @return whether checking the queue should NOT be done * @return whether checking the queue should NOT be done
*/ */
@ -994,17 +1019,20 @@ protected:
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, virtual void forwardEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) const; uint32_t parameter2 = 0) const;
/** /**
* Checks state of switches in conjunction with mode and triggers an event if they don't fit. * Checks state of switches in conjunction with mode and triggers an event
* if they don't fit.
*/ */
virtual void checkSwitchState(); virtual void checkSwitchState();
/** /**
* Reserved for the rare case where a device needs to perform additional operation cyclically in OFF mode. * Reserved for the rare case where a device needs to perform additional
* operation cyclically in OFF mode.
*/ */
virtual void doOffActivity(); virtual void doOffActivity();
/** /**
* Reserved for the rare case where a device needs to perform additional operation cyclically in ON mode. * Reserved for the rare case where a device needs to perform additional
* operation cyclically in ON mode.
*/ */
virtual void doOnActivity(); virtual void doOnActivity();
@ -1045,9 +1073,10 @@ private:
/** /**
* Information about a cookie. * Information about a cookie.
* *
* This is stored in a map for each cookie, to not only track the state, but also information * This is stored in a map for each cookie, to not only track the state,
* about the sent command. Tracking this information is needed as * but also information about the sent command. Tracking this information
* the state of a commandId (waiting for reply) is done when a RMAP write reply is received. * is needed as the state of a commandId (waiting for reply) is done when a
* write reply is received.
*/ */
struct CookieInfo { struct CookieInfo {
CookieState_t state; CookieState_t state;
@ -1104,10 +1133,14 @@ private:
/** /**
* Handle the device handler mode. * Handle the device handler mode.
* *
* - checks whether commands are valid for the current mode, rejects them accordingly * - checks whether commands are valid for the current mode, rejects
* - checks whether commanded mode transitions are required and calls handleCommandedModeTransition() * them accordingly
* - does the necessary action for the current mode or calls doChildStateMachine in modes @c MODE_TO_ON and @c MODE_TO_OFF * - checks whether commanded mode transitions are required and calls
* - actions that happen in transitions (eg setting a timeout) are handled in setMode() * handleCommandedModeTransition()
* - does the necessary action for the current mode or calls
* doChildStateMachine in modes @c MODE_TO_ON and @c MODE_TO_OFF
* - actions that happen in transitions (e.g. setting a timeout) are
* handled in setMode()
*/ */
void doStateMachine(void); void doStateMachine(void);
@ -1117,16 +1150,17 @@ private:
/** /**
* Decrement the counter for the timout of replies. * Decrement the counter for the timout of replies.
* *
* This is called at the beginning of each cycle. It checks whether a reply has timed out (that means a reply was expected * This is called at the beginning of each cycle. It checks whether a
* but not received). * reply has timed out (that means a reply was expected but not received).
*/ */
void decrementDeviceReplyMap(void); void decrementDeviceReplyMap(void);
/** /**
* Convenience function to handle a reply. * Convenience function to handle a reply.
* *
* Called after scanForReply() has found a packet. Checks if the found id is in the #deviceCommandMap, if so, * Called after scanForReply() has found a packet. Checks if the found ID
* calls interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) for further action. * is in the #deviceCommandMap, if so, calls
* #interpretDeviceReply for further action.
* *
* It also resets the timeout counter for the command id. * It also resets the timeout counter for the command id.
* *
@ -1186,7 +1220,7 @@ private:
* @param[out] len * @param[out] len
* @return * @return
* - @c RETURN_OK @c data is valid * - @c RETURN_OK @c data is valid
* - @c RETURN_FAILED IPCStore is NULL * - @c RETURN_FAILED IPCStore is nullptr
* - the return value from the IPCStore if it was not @c RETURN_OK * - the return value from the IPCStore if it was not @c RETURN_OK
*/ */
ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data,

View File

@ -191,7 +191,7 @@ void DeviceHandlerFailureIsolation::triggerEvent(Event event, uint32_t parameter
uint32_t parameter2) { uint32_t parameter2) {
//Do not throw error events if fdirState != none. //Do not throw error events if fdirState != none.
//This will still forward MODE and HEALTH INFO events in any case. //This will still forward MODE and HEALTH INFO events in any case.
if (fdirState == NONE || EVENT::getSeverity(event) == SEVERITY::INFO) { if (fdirState == NONE || event::getSeverity(event) == severity::INFO) {
FailureIsolationBase::triggerEvent(event, parameter1, parameter2); FailureIsolationBase::triggerEvent(event, parameter1, parameter2);
} }
} }
@ -201,7 +201,7 @@ bool DeviceHandlerFailureIsolation::isFdirActionInProgress() {
} }
void DeviceHandlerFailureIsolation::startRecovery(Event reason) { void DeviceHandlerFailureIsolation::startRecovery(Event reason) {
throwFdirEvent(FDIR_STARTS_RECOVERY, EVENT::getEventId(reason)); throwFdirEvent(FDIR_STARTS_RECOVERY, event::getEventId(reason));
setOwnerHealth(HasHealthIF::NEEDS_RECOVERY); setOwnerHealth(HasHealthIF::NEEDS_RECOVERY);
setFdirState(RECOVERY_ONGOING); setFdirState(RECOVERY_ONGOING);
} }
@ -228,7 +228,7 @@ ReturnValue_t DeviceHandlerFailureIsolation::getParameter(uint8_t domainId,
} }
void DeviceHandlerFailureIsolation::setFaulty(Event reason) { void DeviceHandlerFailureIsolation::setFaulty(Event reason) {
throwFdirEvent(FDIR_TURNS_OFF_DEVICE, EVENT::getEventId(reason)); throwFdirEvent(FDIR_TURNS_OFF_DEVICE, event::getEventId(reason));
setOwnerHealth(HasHealthIF::FAULTY); setOwnerHealth(HasHealthIF::FAULTY);
setFdirState(AWAIT_SHUTDOWN); setFdirState(AWAIT_SHUTDOWN);
} }

View File

@ -95,17 +95,17 @@ public:
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5; static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW); static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, severity::LOW);
static const Event DEVICE_SENDING_COMMAND_FAILED = MAKE_EVENT(1, SEVERITY::LOW); static const Event DEVICE_SENDING_COMMAND_FAILED = MAKE_EVENT(1, severity::LOW);
static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, SEVERITY::LOW); static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, severity::LOW);
static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, SEVERITY::LOW); static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, severity::LOW);
static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, SEVERITY::LOW); static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW);
static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, SEVERITY::LOW); static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, severity::LOW);
static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, SEVERITY::LOW); static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, severity::LOW);
static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, SEVERITY::LOW); static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, severity::LOW);
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, SEVERITY::LOW); //!< Indicates a SW bug in child class. static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW); //!< Indicates a SW bug in child class.
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW); static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH); static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;

8
events/CMakeLists.txt Normal file
View File

@ -0,0 +1,8 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Event.cpp
EventManager.cpp
EventMessage.cpp
)
add_subdirectory(eventmatching)

View File

@ -1,16 +0,0 @@
#include "Event.h"
namespace EVENT {
EventId_t getEventId(Event event) {
return (event & 0xFFFF);
}
EventSeverity_t getSeverity(Event event) {
return ((event >> 16) & 0xFF);
}
Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId,
EventSeverity_t eventSeverity) {
return (eventSeverity << 16) + (subsystemId * 100) + uniqueEventId;
}
}

View File

@ -3,7 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include "fwSubsystemIdRanges.h" #include "fwSubsystemIdRanges.h"
//could be move to more suitable location // could be moved to more suitable location
#include <events/subsystemIdRanges.h> #include <events/subsystemIdRanges.h>
typedef uint16_t EventId_t; typedef uint16_t EventId_t;
@ -13,33 +13,28 @@ typedef uint8_t EventSeverity_t;
typedef uint32_t Event; typedef uint32_t Event;
namespace EVENT { namespace event {
EventId_t getEventId(Event event);
EventSeverity_t getSeverity(Event event); constexpr EventId_t getEventId(Event event) {
return (event & 0xFFFF);
Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId,
EventSeverity_t eventSeverity);
} }
namespace SEVERITY { constexpr EventSeverity_t getSeverity(Event event) {
static const EventSeverity_t INFO = 1; return ((event >> 16) & 0xFF);
static const EventSeverity_t LOW = 2;
static const EventSeverity_t MEDIUM = 3;
static const EventSeverity_t HIGH = 4;
} }
//Unfortunately, this does not work nicely because of the inability to define static classes in headers. constexpr Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId,
//struct Event { EventSeverity_t eventSeverity) {
// Event(uint8_t domain, uint8_t counter, EventSeverity_t severity) : return (eventSeverity << 16) + (subsystemId * 100) + uniqueEventId;
// id(domain*100+counter), severity(severity) { }
// }
// EventId_t id; }
// EventSeverity_t severity;
// static const EventSeverity_t INFO = 1; namespace severity {
// static const EventSeverity_t LOW = 2; static constexpr EventSeverity_t INFO = 1;
// static const EventSeverity_t MEDIUM = 3; static constexpr EventSeverity_t LOW = 2;
// static const EventSeverity_t HIGH = 4; static constexpr EventSeverity_t MEDIUM = 3;
//}; static constexpr EventSeverity_t HIGH = 4;
}
#endif /* EVENTOBJECT_EVENT_H_ */ #endif /* EVENTOBJECT_EVENT_H_ */

View File

@ -1,4 +1,6 @@
#include "EventManager.h" #include "EventManager.h"
#include "EventMessage.h"
#include <FSFWConfig.h> #include <FSFWConfig.h>
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
#include "../ipc/QueueFactory.h" #include "../ipc/QueueFactory.h"
@ -9,7 +11,6 @@
// objects registering for certain events. // objects registering for certain events.
// Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher. // Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher.
// So a good guess is 75 to a max of 100 pools required for each, which fits well. // So a good guess is 75 to a max of 100 pools required for each, which fits well.
// This should be configurable..
const LocalPool::LocalPoolConfig EventManager::poolConfig = { const LocalPool::LocalPoolConfig EventManager::poolConfig = {
{fsfwconfig::FSFW_EVENTMGMR_MATCHTREE_NODES, {fsfwconfig::FSFW_EVENTMGMR_MATCHTREE_NODES,
sizeof(EventMatchTree::Node)}, sizeof(EventMatchTree::Node)},
@ -113,12 +114,12 @@ ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener,
return result; return result;
} }
#if FSFW_DEBUG_OUTPUT == 1 #if FSFW_OBJ_EVENT_TRANSLATION == 1
void EventManager::printEvent(EventMessage* message) { void EventManager::printEvent(EventMessage* message) {
const char *string = 0; const char *string = 0;
switch (message->getSeverity()) { switch (message->getSeverity()) {
case SEVERITY::INFO: case severity::INFO:
#if DEBUG_INFO_EVENT == 1 #if DEBUG_INFO_EVENT == 1
string = translateObject(message->getReporter()); string = translateObject(message->getReporter());
sif::info << "EVENT: "; sif::info << "EVENT: ";

View File

@ -1,18 +1,20 @@
#ifndef EVENTMANAGER_H_ #ifndef FSFW_EVENT_EVENTMANAGER_H_
#define EVENTMANAGER_H_ #define FSFW_EVENT_EVENTMANAGER_H_
#include "eventmatching/EventMatchTree.h"
#include "EventManagerIF.h" #include "EventManagerIF.h"
#include "eventmatching/EventMatchTree.h"
#include <FSFWConfig.h>
#include "../objectmanager/SystemObject.h" #include "../objectmanager/SystemObject.h"
#include "../storagemanager/LocalPool.h" #include "../storagemanager/LocalPool.h"
#include "../tasks/ExecutableObjectIF.h" #include "../tasks/ExecutableObjectIF.h"
#include "../ipc/MessageQueueIF.h" #include "../ipc/MessageQueueIF.h"
#include "../ipc/MutexIF.h" #include "../ipc/MutexIF.h"
#include <FSFWConfig.h>
#include <map> #include <map>
#if FSFW_DEBUG_OUTPUT == 1 #if FSFW_OBJ_EVENT_TRANSLATION == 1
// forward declaration, should be implemented by mission // forward declaration, should be implemented by mission
extern const char* translateObject(object_id_t object); extern const char* translateObject(object_id_t object);
extern const char* translateEvents(Event event); extern const char* translateEvents(Event event);
@ -59,7 +61,7 @@ protected:
void notifyListeners(EventMessage *message); void notifyListeners(EventMessage *message);
#if FSFW_DEBUG_OUTPUT == 1 #if FSFW_OBJ_EVENT_TRANSLATION == 1
void printEvent(EventMessage *message); void printEvent(EventMessage *message);
#endif #endif
@ -68,4 +70,4 @@ protected:
void unlockMutex(); void unlockMutex();
}; };
#endif /* EVENTMANAGER_H_ */ #endif /* FSFW_EVENT_EVENTMANAGER_H_ */

View File

@ -48,7 +48,7 @@ void EventMessage::setMessageId(uint8_t id) {
EventSeverity_t EventMessage::getSeverity() { EventSeverity_t EventMessage::getSeverity() {
Event event; Event event;
memcpy(&event, getData(), sizeof(Event)); memcpy(&event, getData(), sizeof(Event));
return EVENT::getSeverity(event); return event::getSeverity(event);
} }
void EventMessage::setSeverity(EventSeverity_t severity) { void EventMessage::setSeverity(EventSeverity_t severity) {
@ -61,7 +61,7 @@ void EventMessage::setSeverity(EventSeverity_t severity) {
EventId_t EventMessage::getEventId() { EventId_t EventMessage::getEventId() {
Event event; Event event;
memcpy(&event, getData(), sizeof(Event)); memcpy(&event, getData(), sizeof(Event));
return EVENT::getEventId(event); return event::getEventId(event);
} }
void EventMessage::setEventId(EventId_t eventId) { void EventMessage::setEventId(EventId_t eventId) {

View File

@ -0,0 +1,7 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
EventIdRangeMatcher.cpp
EventMatchTree.cpp
ReporterRangeMatcher.cpp
SeverityRangeMatcher.cpp
)

View File

@ -1,5 +1,5 @@
#ifndef FRAMEWORK_EVENTS_FWSUBSYSTEMIDRANGES_H_ #ifndef FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_
#define FRAMEWORK_EVENTS_FWSUBSYSTEMIDRANGES_H_ #define FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_
namespace SUBSYSTEM_ID { namespace SUBSYSTEM_ID {
enum { enum {
@ -27,4 +27,4 @@ enum {
#endif /* FRAMEWORK_EVENTS_FWSUBSYSTEMIDRANGES_H_ */ #endif /* FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ */

View File

@ -139,7 +139,7 @@ void FailureIsolationBase::triggerEvent(Event event, uint32_t parameter1,
uint32_t parameter2) { uint32_t parameter2) {
//With this mechanism, all events are disabled for a certain device. //With this mechanism, all events are disabled for a certain device.
//That's not so good for visibility. //That's not so good for visibility.
if (isFdirDisabledForSeverity(EVENT::getSeverity(event))) { if (isFdirDisabledForSeverity(event::getSeverity(event))) {
return; return;
} }
EventMessage message(event, ownerId, parameter1, parameter2); EventMessage message(event, ownerId, parameter1, parameter2);
@ -148,7 +148,7 @@ void FailureIsolationBase::triggerEvent(Event event, uint32_t parameter1,
} }
bool FailureIsolationBase::isFdirDisabledForSeverity(EventSeverity_t severity) { bool FailureIsolationBase::isFdirDisabledForSeverity(EventSeverity_t severity) {
if ((owner != NULL) && (severity != SEVERITY::INFO)) { if ((owner != NULL) && (severity != severity::INFO)) {
if (owner->getHealth() == HasHealthIF::EXTERNAL_CONTROL) { if (owner->getHealth() == HasHealthIF::EXTERNAL_CONTROL) {
//External control disables handling of fault messages. //External control disables handling of fault messages.
return true; return true;

View File

@ -14,9 +14,9 @@ class FailureIsolationBase: public HasReturnvaluesIF,
public HasParametersIF { public HasParametersIF {
public: public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, SEVERITY::INFO); //!< FDIR has an internal state, which changed from par2 (oldState) to par1 (newState). static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, SEVERITY::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery. static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, SEVERITY::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery. static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
FailureIsolationBase(object_id_t owner, FailureIsolationBase(object_id_t owner,
object_id_t parent = objects::NO_OBJECT, object_id_t parent = objects::NO_OBJECT,

View File

@ -0,0 +1,12 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
arrayprinter.cpp
AsciiConverter.cpp
CRC.cpp
DleEncoder.cpp
PeriodicOperationDivider.cpp
timevalOperations.cpp
Type.cpp
)
add_subdirectory(math)

View File

@ -1,4 +1,4 @@
#include "../globalfunctions/Type.h" #include "Type.h"
#include "../serialize/SerializeAdapter.h" #include "../serialize/SerializeAdapter.h"
Type::Type() : Type::Type() :

View File

@ -1,5 +1,5 @@
#ifndef TYPE_H_ #ifndef FSFW_GLOBALFUNCTIONS_TYPE_H_
#define TYPE_H_ #define FSFW_GLOBALFUNCTIONS_TYPE_H_
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../serialize/SerializeIF.h" #include "../serialize/SerializeIF.h"
@ -97,4 +97,4 @@ struct PodTypeConversion<double> {
static const Type::ActualType_t type = Type::DOUBLE; static const Type::ActualType_t type = Type::DOUBLE;
}; };
#endif /* TYPE_H_ */ #endif /* FSFW_GLOBALFUNCTIONS_TYPE_H_ */

View File

@ -0,0 +1,4 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
QuaternionOperations.cpp
)

View File

@ -21,13 +21,13 @@ public:
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2); static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
static const Event HEALTH_INFO = MAKE_EVENT(6, SEVERITY::INFO); static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, SEVERITY::INFO); static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, SEVERITY::LOW); static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, SEVERITY::LOW); //!< Assembly overwrites health information of children to keep satellite alive. static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep satellite alive.
static const Event TRYING_RECOVERY = MAKE_EVENT(10, SEVERITY::MEDIUM); //!< Someone starts a recovery of a component (typically power-cycle). No parameters. static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically power-cycle). No parameters.
static const Event RECOVERY_STEP = MAKE_EVENT(11, SEVERITY::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1: 0 for the first, 1 for the second event. P2: 0 static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1: 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_DONE = MAKE_EVENT(12, SEVERITY::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters. static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
virtual ~HasHealthIF() { virtual ~HasHealthIF() {
} }

View File

@ -2,6 +2,7 @@
#define FSFW_IPC_COMMANDMESSAGE_H_ #define FSFW_IPC_COMMANDMESSAGE_H_
#include "CommandMessageIF.h" #include "CommandMessageIF.h"
#include "MessageQueueMessage.h" #include "MessageQueueMessage.h"
#include "FwMessageTypes.h" #include "FwMessageTypes.h"

View File

@ -1,8 +1,8 @@
#ifndef FSFW_IPC_MESSAGEQUEUESENDERIF_H_ #ifndef FSFW_IPC_MESSAGEQUEUESENDERIF_H_
#define FSFW_IPC_MESSAGEQUEUESENDERIF_H_ #define FSFW_IPC_MESSAGEQUEUESENDERIF_H_
#include "../ipc/MessageQueueIF.h" #include "MessageQueueIF.h"
#include "../ipc/MessageQueueMessageIF.h" #include "MessageQueueMessageIF.h"
#include "../objectmanager/ObjectManagerIF.h" #include "../objectmanager/ObjectManagerIF.h"
class MessageQueueSenderIF { class MessageQueueSenderIF {

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_IPC_MUTEXFACTORY_H_ #ifndef FSFW_IPC_MUTEXFACTORY_H_
#define FRAMEWORK_IPC_MUTEXFACTORY_H_ #define FSFW_IPC_MUTEXFACTORY_H_
#include "../ipc/MutexIF.h" #include "MutexIF.h"
/** /**
* Creates Mutex. * Creates Mutex.
* This class is a "singleton" interface, i.e. it provides an * This class is a "singleton" interface, i.e. it provides an
@ -31,4 +31,4 @@ private:
#endif /* FRAMEWORK_IPC_MUTEXFACTORY_H_ */ #endif /* FSFW_IPC_MUTEXFACTORY_H_ */

View File

@ -3,6 +3,7 @@
#include "MessageQueueIF.h" #include "MessageQueueIF.h"
#include "MessageQueueMessage.h" #include "MessageQueueMessage.h"
#include <cstdint> #include <cstdint>
/** /**

View File

@ -1,22 +0,0 @@
#ifndef FRAMEWORK_MEMORY_MEMORYPROXYIF_H_
#define FRAMEWORK_MEMORY_MEMORYPROXYIF_H_
#include "../memory/AcceptsMemoryMessagesIF.h"
/**
* This was a nice idea to transparently forward incoming messages to another object.
* But it doesn't work like that.
*/
class MemoryProxyIF : public AcceptsMemoryMessagesIF {
public:
virtual MessageQueueId_t getProxyQueue() const = 0;
MessageQueueId_t getCommandQueue() const {
return getProxyQueue();
}
virtual ~MemoryProxyIF() {}
};
#endif /* FRAMEWORK_MEMORY_MEMORYPROXYIF_H_ */

View File

@ -18,14 +18,14 @@ public:
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04); static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
static const Event CHANGING_MODE = MAKE_EVENT(0, SEVERITY::INFO); //!< An object announces changing the mode. p1: target mode. p2: target submode static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode. p2: target submode
static const Event MODE_INFO = MAKE_EVENT(1, SEVERITY::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
static const Event FALLBACK_FAILED = MAKE_EVENT(2, SEVERITY::HIGH); static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, SEVERITY::LOW); static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, SEVERITY::HIGH); static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, SEVERITY::LOW); //!< Indicates a bug or configuration failure: Object is in a mode it should never be in. static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a mode it should never be in.
static const Event FORCING_MODE = MAKE_EVENT(6, SEVERITY::MEDIUM); //!< The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, SEVERITY::LOW); //!< A mode command was rejected by the called object. Par1: called object id, Par2: return code. static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1: called object id, Par2: return code.
static const Mode_t MODE_ON = 1; //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted static const Mode_t MODE_ON = 1; //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in this mode is a mode change to on. static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in this mode is a mode change to on.

View File

@ -72,7 +72,7 @@ protected:
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
LocalPoolVar<T> poolVariable; LocalPoolVariable<T> poolVariable;
}; };
#endif /* FSFW_MONITORING_MONITORBASE_H_ */ #endif /* FSFW_MONITORING_MONITORBASE_H_ */

View File

@ -15,10 +15,10 @@ public:
static const uint8_t LIMIT_TYPE_OBJECT = 128; static const uint8_t LIMIT_TYPE_OBJECT = 128;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_2; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_2;
static const Event MONITOR_CHANGED_STATE = MAKE_EVENT(1, SEVERITY::LOW); static const Event MONITOR_CHANGED_STATE = MAKE_EVENT(1, severity::LOW);
static const Event VALUE_BELOW_LOW_LIMIT = MAKE_EVENT(2, SEVERITY::LOW); static const Event VALUE_BELOW_LOW_LIMIT = MAKE_EVENT(2, severity::LOW);
static const Event VALUE_ABOVE_HIGH_LIMIT = MAKE_EVENT(3, SEVERITY::LOW); static const Event VALUE_ABOVE_HIGH_LIMIT = MAKE_EVENT(3, severity::LOW);
static const Event VALUE_OUT_OF_RANGE = MAKE_EVENT(4, SEVERITY::LOW); static const Event VALUE_OUT_OF_RANGE = MAKE_EVENT(4, severity::LOW);
static const uint8_t INTERFACE_ID = CLASS_ID::LIMITS_IF; static const uint8_t INTERFACE_ID = CLASS_ID::LIMITS_IF;
static const ReturnValue_t UNCHECKED = MAKE_RETURN_CODE(1); static const ReturnValue_t UNCHECKED = MAKE_RETURN_CODE(1);

View File

@ -2,6 +2,9 @@
#include "TaskManagement.h" #include "TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8
BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() {
handle = TaskManagement::getCurrentTaskHandle(); handle = TaskManagement::getCurrentTaskHandle();
if(handle == nullptr) { if(handle == nullptr) {
@ -97,3 +100,6 @@ uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR(
higherPriorityTaskWoken); higherPriorityTaskWoken);
return notificationValue; return notificationValue;
} }
#endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8 */

View File

@ -7,8 +7,8 @@
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
// todo: does not work for older FreeRTOS version, so we should #if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
// actually check whether tskKERNEL_VERSION_MAJOR is larger than.. 7 or 8 ? tskKERNEL_VERSION_MAJOR > 8
/** /**
* @brief Binary Semaphore implementation using the task notification value. * @brief Binary Semaphore implementation using the task notification value.
@ -90,4 +90,7 @@ protected:
TaskHandle_t handle; TaskHandle_t handle;
}; };
#endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8 */
#endif /* FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ #endif /* FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */

View File

@ -1,5 +1,5 @@
#include "../../osal/FreeRTOS/BinarySemaphore.h" #include "BinarySemaphore.h"
#include "../../osal/FreeRTOS/TaskManagement.h" #include "TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
BinarySemaphore::BinarySemaphore() { BinarySemaphore::BinarySemaphore() {

View File

@ -1,5 +1,5 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ #ifndef FSFW_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ #define FSFW_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
#include "../../tasks/SemaphoreIF.h" #include "../../tasks/SemaphoreIF.h"
@ -104,4 +104,4 @@ protected:
SemaphoreHandle_t handle; SemaphoreHandle_t handle;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */ #endif /* FSFW_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */

View File

@ -1,6 +1,7 @@
#include "Timekeeper.h"
#include "../../timemanager/Clock.h" #include "../../timemanager/Clock.h"
#include "../../globalfunctions/timevalOperations.h" #include "../../globalfunctions/timevalOperations.h"
#include "../../osal/FreeRTOS/Timekeeper.h"
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>

View File

@ -1,7 +1,11 @@
#include "../../osal/FreeRTOS/CountingSemaphUsingTask.h" #include "CountingSemaphUsingTask.h"
#include "../../osal/FreeRTOS/TaskManagement.h" #include "TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8
CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount, CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount,
uint8_t initCount): maxCount(maxCount) { uint8_t initCount): maxCount(maxCount) {
if(initCount > maxCount) { if(initCount > maxCount) {
@ -112,3 +116,5 @@ uint8_t CountingSemaphoreUsingTask::getSemaphoreCounterFromISR(
uint8_t CountingSemaphoreUsingTask::getMaxCount() const { uint8_t CountingSemaphoreUsingTask::getMaxCount() const {
return maxCount; return maxCount;
} }
#endif

View File

@ -1,13 +1,14 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ #ifndef FSFW_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
#define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ #define FSFW_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
#include "../../osal/FreeRTOS/CountingSemaphUsingTask.h" #include "CountingSemaphUsingTask.h"
#include "../../tasks/SemaphoreIF.h" #include "../../tasks/SemaphoreIF.h"
extern "C" {
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
}
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8
/** /**
* @brief Couting Semaphore implementation which uses the notification value * @brief Couting Semaphore implementation which uses the notification value
@ -102,4 +103,7 @@ private:
const uint8_t maxCount; const uint8_t maxCount;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */ #endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
tskKERNEL_VERSION_MAJOR > 8 */
#endif /* FSFW_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */

View File

@ -1,6 +1,7 @@
#include "../../osal/FreeRTOS/CountingSemaphore.h" #include "CountingSemaphore.h"
#include "TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../osal/FreeRTOS/TaskManagement.h"
#include <freertos/semphr.h> #include <freertos/semphr.h>

View File

@ -1,6 +1,7 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ #ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_
#define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ #define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_
#include "../../osal/FreeRTOS/BinarySemaphore.h"
#include "BinarySemaphore.h"
/** /**
* @brief Counting semaphores, which can be acquire more than once. * @brief Counting semaphores, which can be acquire more than once.

View File

@ -114,38 +114,24 @@ void FixedTimeslotTask::taskFunctionality() {
intervalMs = this->pst.getIntervalToPreviousSlotMs(); intervalMs = this->pst.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs); interval = pdMS_TO_TICKS(intervalMs);
checkMissedDeadline(xLastWakeTime, interval); #if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || \
tskKERNEL_VERSION_MAJOR > 10
// Wait for the interval. This exits immediately if a deadline was BaseType_t wasDelayed = xTaskDelayUntil(&xLastWakeTime, interval);
// missed while also updating the last wake time. if(wasDelayed == pdFALSE) {
vTaskDelayUntil(&xLastWakeTime, interval); handleMissedDeadline();
}
#else
if(checkMissedDeadline(xLastWakeTime, interval)) {
handleMissedDeadline();
}
// Wait for the interval. This exits immediately if a deadline was
// missed while also updating the last wake time.
vTaskDelayUntil(&xLastWakeTime, interval);
#endif
} }
} }
} }
void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
void FixedTimeslotTask::handleMissedDeadline() { void FixedTimeslotTask::handleMissedDeadline() {
if(deadlineMissedFunc != nullptr) { if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();

View File

@ -93,8 +93,6 @@ protected:
*/ */
void taskFunctionality(void); void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline(); void handleMissedDeadline();
}; };

View File

@ -1,13 +1,41 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ #ifndef FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
#define FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ #define FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
class FreeRTOSTaskIF { class FreeRTOSTaskIF {
public: public:
virtual~ FreeRTOSTaskIF() {} virtual~ FreeRTOSTaskIF() {}
virtual TaskHandle_t getTaskHandle() = 0; virtual TaskHandle_t getTaskHandle() = 0;
protected:
bool checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or
(currentTickCount > timeToWake)) {
return true;
}
}
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and
(currentTickCount > timeToWake)) {
return true;
}
return false;
}
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ */ #endif /* FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_ */

View File

@ -1,10 +1,11 @@
#ifndef FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_ #ifndef FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
#define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_ #define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
#include "TaskManagement.h"
#include "../../internalError/InternalErrorReporterIF.h" #include "../../internalError/InternalErrorReporterIF.h"
#include "../../ipc/MessageQueueIF.h" #include "../../ipc/MessageQueueIF.h"
#include "../../ipc/MessageQueueMessageIF.h" #include "../../ipc/MessageQueueMessageIF.h"
#include "../../osal/FreeRTOS/TaskManagement.h"
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/queue.h> #include <freertos/queue.h>

View File

@ -1,4 +1,4 @@
#include "../../osal/FreeRTOS/Mutex.h" #include "Mutex.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"

View File

@ -1,5 +1,7 @@
#include "Mutex.h"
#include "../../ipc/MutexFactory.h" #include "../../ipc/MutexFactory.h"
#include "../../osal/FreeRTOS/Mutex.h"
//TODO: Different variant than the lazy loading in QueueFactory. //TODO: Different variant than the lazy loading in QueueFactory.
//What's better and why? -> one is on heap the other on bss/data //What's better and why? -> one is on heap the other on bss/data

View File

@ -80,10 +80,18 @@ void PeriodicTask::taskFunctionality() {
object->performOperation(); object->performOperation();
} }
checkMissedDeadline(xLastWakeTime, xPeriod); #if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || \
tskKERNEL_VERSION_MAJOR > 10
vTaskDelayUntil(&xLastWakeTime, xPeriod); BaseType_t wasDelayed = xTaskDelayUntil(&xLastWakeTime, xPeriod);
if(wasDelayed == pdFALSE) {
handleMissedDeadline();
}
#else
if(checkMissedDeadline(xLastWakeTime, xPeriod)) {
handleMissedDeadline();
}
vTaskDelayUntil(&xLastWakeTime, xPeriod);
#endif
} }
} }
@ -105,29 +113,6 @@ uint32_t PeriodicTask::getPeriodMs() const {
return period * 1000; return period * 1000;
} }
void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
TaskHandle_t PeriodicTask::getTaskHandle() { TaskHandle_t PeriodicTask::getTaskHandle() {
return handle; return handle;
} }

View File

@ -71,6 +71,7 @@ public:
TaskHandle_t getTaskHandle() override; TaskHandle_t getTaskHandle() override;
protected: protected:
bool started; bool started;
TaskHandle_t handle; TaskHandle_t handle;
@ -118,8 +119,6 @@ protected:
*/ */
void taskFunctionality(void); void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline(); void handleMissedDeadline();
}; };

View File

@ -1,8 +1,8 @@
#include "MessageQueue.h"
#include "../../ipc/MessageQueueSenderIF.h" #include "../../ipc/MessageQueueSenderIF.h"
#include "../../ipc/QueueFactory.h" #include "../../ipc/QueueFactory.h"
#include "../../osal/FreeRTOS/MessageQueue.h"
QueueFactory* QueueFactory::factoryInstance = nullptr; QueueFactory* QueueFactory::factoryInstance = nullptr;

View File

@ -1,4 +1,4 @@
#include "../../osal/FreeRTOS/TaskManagement.h" #include "TaskManagement.h"
void TaskManagement::vRequestContextSwitchFromTask() { void TaskManagement::vRequestContextSwitchFromTask() {
vTaskDelay(0); vTaskDelay(0);
@ -22,3 +22,4 @@ size_t TaskManagement::getTaskStackHighWatermark(
TaskHandle_t task) { TaskHandle_t task) {
return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t); return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
} }

View File

@ -3,17 +3,16 @@
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
extern "C" {
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
}
#include <cstdint> #include <cstdint>
/** /**
* Architecture dependant portmacro.h function call. * Architecture dependant portmacro.h function call.
* Should be implemented in bsp. * Should be implemented in bsp.
*/ */
extern void vRequestContextSwitchFromISR(); extern "C" void vRequestContextSwitchFromISR();
/*! /*!
* Used by functions to tell if they are being called from * Used by functions to tell if they are being called from
@ -27,38 +26,37 @@ enum class CallContext {
}; };
class TaskManagement { namespace TaskManagement {
public: /**
/** * @brief In this function, a function dependant on the portmacro.h header
* @brief In this function, a function dependant on the portmacro.h header * function calls to request a context switch can be specified.
* function calls to request a context switch can be specified. * This can be used if sending to the queue from an ISR caused a task
* This can be used if sending to the queue from an ISR caused a task * to unblock and a context switch is required.
* to unblock and a context switch is required. */
*/ void requestContextSwitch(CallContext callContext);
static void requestContextSwitch(CallContext callContext);
/** /**
* If task preemption in FreeRTOS is disabled, a context switch * If task preemption in FreeRTOS is disabled, a context switch
* can be requested manually by calling this function. * can be requested manually by calling this function.
*/ */
static void vRequestContextSwitchFromTask(void); void vRequestContextSwitchFromTask(void);
/** /**
* @return The current task handle * @return The current task handle
*/ */
static TaskHandle_t getCurrentTaskHandle(); TaskHandle_t getCurrentTaskHandle();
/**
* Get returns the minimum amount of remaining stack space in words
* that was a available to the task since the task started executing.
* Please note that the actual value in bytes depends
* on the stack depth type.
* E.g. on a 32 bit machine, a value of 200 means 800 bytes.
* @return Smallest value of stack remaining since the task was started in
* words.
*/
size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
/**
* Get returns the minimum amount of remaining stack space in words
* that was a available to the task since the task started executing.
* Please note that the actual value in bytes depends
* on the stack depth type.
* E.g. on a 32 bit machine, a value of 200 means 800 bytes.
* @return Smallest value of stack remaining since the task was started in
* words.
*/
static size_t getTaskStackHighWatermark(
TaskHandle_t task = nullptr);
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */

View File

@ -1,6 +1,6 @@
#include "../../osal/FreeRTOS/Timekeeper.h" #include "Timekeeper.h"
#include "FreeRTOSConfig.h" #include <FreeRTOSConfig.h>
Timekeeper * Timekeeper::myinstance = nullptr; Timekeeper * Timekeeper::myinstance = nullptr;

View File

@ -106,11 +106,6 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint32_t Clock::getUptimeSeconds() {
timeval uptime = getUptime();
return uptime.tv_sec;
}
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
// do some magic with chrono (C++20!) // do some magic with chrono (C++20!)

View File

@ -1,7 +1,9 @@
#include "FixedTimeslotTask.h" #include "../../osal/host/FixedTimeslotTask.h"
#include "Mutex.h"
#include "../../ipc/MutexFactory.h" #include "../../ipc/MutexFactory.h"
#include "../../osal/host/Mutex.h"
#include "../../osal/host/FixedTimeslotTask.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../tasks/ExecutableObjectIF.h" #include "../../tasks/ExecutableObjectIF.h"
@ -33,18 +35,18 @@ FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority,
reinterpret_cast<HANDLE>(mainThread.native_handle()), reinterpret_cast<HANDLE>(mainThread.native_handle()),
ABOVE_NORMAL_PRIORITY_CLASS); ABOVE_NORMAL_PRIORITY_CLASS);
if(result != 0) { if(result != 0) {
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with " sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
<< "code " << GetLastError() << std::endl; << GetLastError() << std::endl;
} }
result = SetThreadPriority( result = SetThreadPriority(
reinterpret_cast<HANDLE>(mainThread.native_handle()), reinterpret_cast<HANDLE>(mainThread.native_handle()),
THREAD_PRIORITY_NORMAL); THREAD_PRIORITY_NORMAL);
if(result != 0) { if(result != 0) {
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with " sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
"code " << GetLastError() << std::endl; << GetLastError() << std::endl;
} }
#elif defined(LINUX) #elif defined(LINUX)
// we can just copy and paste the code from linux here. // TODO: we can just copy and paste the code from the linux OSAL here.
#endif #endif
} }
@ -58,8 +60,7 @@ FixedTimeslotTask::~FixedTimeslotTask(void) {
} }
void FixedTimeslotTask::taskEntryPoint(void* argument) { void FixedTimeslotTask::taskEntryPoint(void* argument) {
FixedTimeslotTask *originalTask( FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(argument));
reinterpret_cast<FixedTimeslotTask*>(argument));
if (not originalTask->started) { if (not originalTask->started) {
// we have to suspend/block here until the task is started. // we have to suspend/block here until the task is started.
@ -114,8 +115,9 @@ void FixedTimeslotTask::taskFunctionality() {
this->pollingSeqTable.executeAndAdvance(); this->pollingSeqTable.executeAndAdvance();
if (not pollingSeqTable.slotFollowsImmediately()) { if (not pollingSeqTable.slotFollowsImmediately()) {
// we need to wait before executing the current slot // we need to wait before executing the current slot
//this gives us the time to wait: // this gives us the time to wait:
interval = chron_ms(this->pollingSeqTable.getIntervalToPreviousSlotMs()); interval = chron_ms(
this->pollingSeqTable.getIntervalToPreviousSlotMs());
delayForInterval(&currentStartTime, interval); delayForInterval(&currentStartTime, interval);
//TODO deadline missed check //TODO deadline missed check
} }

View File

@ -74,7 +74,7 @@ protected:
//!< Typedef for the List of objects. //!< Typedef for the List of objects.
typedef std::vector<ExecutableObjectIF*> ObjectList; typedef std::vector<ExecutableObjectIF*> ObjectList;
std::thread mainThread; std::thread mainThread;
std::atomic<bool> terminateThread = false; std::atomic<bool> terminateThread { false };
//! Polling sequence table which contains the object to execute //! Polling sequence table which contains the object to execute
//! and information like the timeslots and the passed execution step. //! and information like the timeslots and the passed execution step.

View File

@ -34,7 +34,7 @@ ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
} }
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
if (this->lastPartner != 0) { if (this->lastPartner != MessageQueueIF::NO_QUEUE) {
return sendMessageFrom(this->lastPartner, message, this->getId()); return sendMessageFrom(this->lastPartner, message, this->getId());
} else { } else {
return MessageQueueIF::NO_REPLY_PARTNER; return MessageQueueIF::NO_REPLY_PARTNER;
@ -106,6 +106,7 @@ bool MessageQueue::isDefaultDestinationSet() const {
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom, MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) { bool ignoreFault) {
message->setSender(sentFrom);
if(message->getMessageSize() > message->getMaximumMessageSize()) { if(message->getMessageSize() > message->getMaximumMessageSize()) {
// Actually, this should never happen or an error will be emitted // Actually, this should never happen or an error will be emitted
// in MessageQueueMessage. // in MessageQueueMessage.
@ -126,7 +127,6 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
// TODO: Better returnvalue // TODO: Better returnvalue
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { if(targetQueue->messageQueue.size() < targetQueue->messageDepth) {
MutexHelper mutexLock(targetQueue->queueLock, MutexHelper mutexLock(targetQueue->queueLock,
MutexIF::TimeoutType::WAITING, 20); MutexIF::TimeoutType::WAITING, 20);
@ -145,7 +145,6 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
else { else {
return MessageQueueIF::FULL; return MessageQueueIF::FULL;
} }
message->setSender(sentFrom);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -4,21 +4,18 @@
Mutex::Mutex() {} Mutex::Mutex() {}
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) { ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
if(timeoutMs == MutexIF::BLOCKING) { if(timeoutType == MutexIF::BLOCKING) {
mutex.lock(); mutex.lock();
locked = true;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else if(timeoutMs == MutexIF::POLLING) { else if(timeoutType == MutexIF::POLLING) {
if(mutex.try_lock()) { if(mutex.try_lock()) {
locked = true;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
} }
else if(timeoutMs > MutexIF::POLLING){ else if(timeoutMs > MutexIF::POLLING){
auto chronoMs = std::chrono::milliseconds(timeoutMs); auto chronoMs = std::chrono::milliseconds(timeoutMs);
if(mutex.try_lock_for(chronoMs)) { if(mutex.try_lock_for(chronoMs)) {
locked = true;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
} }
@ -26,11 +23,7 @@ ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
} }
ReturnValue_t Mutex::unlockMutex() { ReturnValue_t Mutex::unlockMutex() {
if(not locked) {
return MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX;
}
mutex.unlock(); mutex.unlock();
locked = false;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -1,5 +1,5 @@
#ifndef FSFW_OSAL_HOST_MUTEX_H_ #ifndef FSFW_OSAL_HOSTED_MUTEX_H_
#define FSFW_OSAL_HOST_MUTEX_H_ #define FSFW_OSAL_HOSTED_MUTEX_H_
#include "../../ipc/MutexIF.h" #include "../../ipc/MutexIF.h"
@ -22,8 +22,8 @@ public:
std::timed_mutex* getMutexHandle(); std::timed_mutex* getMutexHandle();
private: private:
bool locked = false; //bool locked = false;
std::timed_mutex mutex; std::timed_mutex mutex;
}; };
#endif /* FSFW_OSAL_HOST_MUTEX_H_ */ #endif /* FSFW_OSAL_HOSTED_MUTEX_H_ */

View File

@ -89,16 +89,16 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) {
} }
void PeriodicTask::taskFunctionality() { void PeriodicTask::taskFunctionality() {
for (const auto& object: objectList) {
object->initializeAfterTaskCreation();
}
std::chrono::milliseconds periodChrono(static_cast<uint32_t>(period*1000)); std::chrono::milliseconds periodChrono(static_cast<uint32_t>(period*1000));
auto currentStartTime { auto currentStartTime {
std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()) std::chrono::system_clock::now().time_since_epoch())
}; };
auto nextStartTime{ currentStartTime }; auto nextStartTime { currentStartTime };
for (const auto& object: objectList) {
object->initializeAfterTaskCreation();
}
/* Enter the loop that defines the task behavior. */ /* Enter the loop that defines the task behavior. */
for (;;) { for (;;) {
@ -109,10 +109,6 @@ void PeriodicTask::taskFunctionality() {
object->performOperation(); object->performOperation();
} }
if(not delayForInterval(&currentStartTime, periodChrono)) { if(not delayForInterval(&currentStartTime, periodChrono)) {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << taskName <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) { if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();
} }

View File

@ -69,7 +69,7 @@ protected:
//!< Typedef for the List of objects. //!< Typedef for the List of objects.
typedef std::vector<ExecutableObjectIF*> ObjectList; typedef std::vector<ExecutableObjectIF*> ObjectList;
std::thread mainThread; std::thread mainThread;
std::atomic<bool> terminateThread = false; std::atomic<bool> terminateThread { false };
/** /**
* @brief This attribute holds a list of objects to be executed. * @brief This attribute holds a list of objects to be executed.

View File

@ -1,7 +1,11 @@
#include "MessageQueue.h" #include "MessageQueue.h"
#include "../../ipc/QueueFactory.h"
#include "../../ipc/MessageQueueSenderIF.h" #include "../../ipc/MessageQueueSenderIF.h"
#include "../../ipc/MessageQueueMessageIF.h"
#include "../../ipc/QueueFactory.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include <cstring> #include <cstring>
QueueFactory* QueueFactory::factoryInstance = nullptr; QueueFactory* QueueFactory::factoryInstance = nullptr;

View File

@ -44,17 +44,9 @@ MessageQueueIF* QueueMapManager::getMessageQueue(
return queueIter->second; return queueIter->second;
} }
else { else {
if(messageQueueId == MessageQueueIF::NO_QUEUE) { sif::warning << "QueueMapManager::getQueueHandle: The ID " <<
sif::error << "QueueMapManager::getQueueHandle: Configuration" messageQueueId << " does not exists in the map" << std::endl;
<< " error, NO_QUEUE was passed to this function!" return nullptr;
<< std::endl;
}
else {
sif::warning << "QueueMapManager::getQueueHandle: The ID "
<< messageQueueId << " does not exists in the map."
<< std::endl;
}
return nullptr;
} }
} }

View File

@ -1,4 +1,4 @@
#include "../../osal/linux/BinarySemaphore.h" #include "BinarySemaphore.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
extern "C" { extern "C" {

25
osal/linux/CMakeLists.txt Normal file
View File

@ -0,0 +1,25 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
Clock.cpp
BinarySemaphore.cpp
CountingSemaphore.cpp
FixedTimeslotTask.cpp
InternalErrorCodes.cpp
MessageQueue.cpp
Mutex.cpp
MutexFactory.cpp
PeriodicPosixTask.cpp
PosixThread.cpp
QueueFactory.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
TcUnixUdpPollingTask.cpp
TmTcUnixUdpBridge.cpp
Timer.cpp
)
target_link_libraries(${LIB_FSFW_NAME}
PRIVATE
rt
pthread
)

View File

@ -1,4 +1,3 @@
#include <fsfw/timemanager/Stopwatch.h>
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../timemanager/Clock.h" #include "../../timemanager/Clock.h"
@ -86,15 +85,16 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint32_t Clock::getUptimeSeconds() { // Wait for new FSFW Clock function delivering seconds uptime.
//TODO This is not posix compatible and delivers only seconds precision //uint32_t Clock::getUptimeSeconds() {
struct sysinfo sysInfo; // //TODO This is not posix compatible and delivers only seconds precision
int result = sysinfo(&sysInfo); // struct sysinfo sysInfo;
if(result != 0){ // int result = sysinfo(&sysInfo);
return HasReturnvaluesIF::RETURN_FAILED; // if(result != 0){
} // return HasReturnvaluesIF::RETURN_FAILED;
return sysInfo.uptime; // }
} // return sysInfo.uptime;
//}
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
timeval uptime; timeval uptime;

View File

@ -1,4 +1,4 @@
#include "../../osal/linux/Mutex.h" #include "Mutex.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../timemanager/Clock.h" #include "../../timemanager/Clock.h"

View File

@ -1,12 +1,8 @@
#ifndef OS_LINUX_MUTEX_H_ #ifndef FSFW_OSAL_LINUX_MUTEX_H_
#define OS_LINUX_MUTEX_H_ #define FSFW_OSAL_LINUX_MUTEX_H_
#include "../../ipc/MutexIF.h" #include "../../ipc/MutexIF.h"
extern "C" {
#include <pthread.h> #include <pthread.h>
}
class Mutex : public MutexIF { class Mutex : public MutexIF {
public: public:

View File

@ -1,5 +1,6 @@
#include "Mutex.h"
#include "../../ipc/MutexFactory.h" #include "../../ipc/MutexFactory.h"
#include "../../osal/linux/Mutex.h"
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why? //TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
MutexFactory* MutexFactory::factoryInstance = new MutexFactory(); MutexFactory* MutexFactory::factoryInstance = new MutexFactory();

View File

@ -1,5 +1,7 @@
#include "PosixThread.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../osal/linux/PosixThread.h"
#include <cstring> #include <cstring>
#include <errno.h> #include <errno.h>

View File

@ -1,6 +1,7 @@
#include "../../tasks/SemaphoreFactory.h"
#include "BinarySemaphore.h" #include "BinarySemaphore.h"
#include "CountingSemaphore.h" #include "CountingSemaphore.h"
#include "../../tasks/SemaphoreFactory.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr;

View File

@ -1,5 +1,6 @@
#include "../../osal/linux/FixedTimeslotTask.h" #include "FixedTimeslotTask.h"
#include "../../osal/linux/PeriodicPosixTask.h" #include "PeriodicPosixTask.h"
#include "../../tasks/TaskFactory.h" #include "../../tasks/TaskFactory.h"
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"

View File

@ -1,6 +1,7 @@
#include "Timer.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include <errno.h> #include <errno.h>
#include "../../osal/linux/Timer.h"
Timer::Timer() { Timer::Timer() {
sigevent sigEvent; sigevent sigEvent;

View File

@ -3,7 +3,7 @@
#include <rtems/score/todimpl.h> #include <rtems/score/todimpl.h>
uint16_t Clock::leapSeconds = 0; uint16_t Clock::leapSeconds = 0;
MutexIF* Clock::timeMutex = NULL; MutexIF* Clock::timeMutex = nullptr;
uint32_t Clock::getTicksPerSecond(void){ uint32_t Clock::getTicksPerSecond(void){
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second(); rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
@ -40,7 +40,7 @@ ReturnValue_t Clock::setClock(const timeval* time) {
//SHOULDDO: Not sure if we need to protect this call somehow (by thread lock or something). //SHOULDDO: Not sure if we need to protect this call somehow (by thread lock or something).
//Uli: rtems docu says you can call this from an ISR, not sure if this means no protetion needed //Uli: rtems docu says you can call this from an ISR, not sure if this means no protetion needed
//TODO Second parameter is ISR_lock_Context //TODO Second parameter is ISR_lock_Context
_TOD_Set(&newTime,NULL); _TOD_Set(&newTime,nullptr);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -131,7 +131,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
//SHOULDDO: works not for dates in the past (might have less leap seconds) //SHOULDDO: works not for dates in the past (might have less leap seconds)
if (timeMutex == NULL) { if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -157,40 +157,34 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); MutexHelper helper(timeMutex);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
leapSeconds = leapSeconds_; leapSeconds = leapSeconds_;
result = timeMutex->unlockMutex();
return result; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if(timeMutex==NULL){ if(timeMutex==nullptr){
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); MutexHelper helper(timeMutex);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*leapSeconds_ = leapSeconds; *leapSeconds_ = leapSeconds;
result = timeMutex->unlockMutex(); return HasReturnvaluesIF::RETURN_OK;
return result;
} }
ReturnValue_t Clock::checkOrCreateClockMutex(){ ReturnValue_t Clock::checkOrCreateClockMutex(){
if(timeMutex==NULL){ if(timeMutex==nullptr){
MutexFactory* mutexFactory = MutexFactory::instance(); MutexFactory* mutexFactory = MutexFactory::instance();
if (mutexFactory == NULL) { if (mutexFactory == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
timeMutex = mutexFactory->createMutex(); timeMutex = mutexFactory->createMutex();
if (timeMutex == NULL) { if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }

View File

@ -158,7 +158,7 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const {
} }
ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer,
int32_t* size, Endianness streamEndianness) { size_t* size, Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer, ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer,
size, streamEndianness); size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {

View File

@ -12,8 +12,8 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
// return INVALID_WORKSPACE_ADDRESS; // return INVALID_WORKSPACE_ADDRESS;
case INTERNAL_ERROR_TOO_LITTLE_WORKSPACE: case INTERNAL_ERROR_TOO_LITTLE_WORKSPACE:
return TOO_LITTLE_WORKSPACE; return TOO_LITTLE_WORKSPACE;
case INTERNAL_ERROR_WORKSPACE_ALLOCATION: // case INTERNAL_ERROR_WORKSPACE_ALLOCATION:
return WORKSPACE_ALLOCATION; // return WORKSPACE_ALLOCATION;
// case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL: // case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL:
// return INTERRUPT_STACK_TOO_SMALL; // return INTERRUPT_STACK_TOO_SMALL;
case INTERNAL_ERROR_THREAD_EXITTED: case INTERNAL_ERROR_THREAD_EXITTED:

View File

@ -1,86 +0,0 @@
#include "Interrupt.h"
extern "C" {
#include <bsp_flp/hw_timer/hw_timer.h>
#include <bsp_flp/hw_uart/hw_uart.h>
}
#include "RtemsBasic.h"
ReturnValue_t Interrupt::enableInterrupt(InterruptNumber_t interruptNumber) {
volatile uint32_t* irqMask = hw_irq_mask;
uint32_t expectedValue = *irqMask | (1 << interruptNumber);
*irqMask = expectedValue;
uint32_t tempValue = *irqMask;
if (tempValue == expectedValue) {
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t Interrupt::setInterruptServiceRoutine(IsrHandler_t handler,
InterruptNumber_t interrupt, IsrHandler_t* oldHandler) {
IsrHandler_t oldHandler_local;
if (oldHandler == NULL) {
oldHandler = &oldHandler_local;
}
//+ 0x10 comes because of trap type assignment to IRQs in UT699 processor
rtems_status_code status = rtems_interrupt_catch(handler, interrupt + 0x10,
oldHandler);
switch(status){
case RTEMS_SUCCESSFUL:
//ISR established successfully
return HasReturnvaluesIF::RETURN_OK;
case RTEMS_INVALID_NUMBER:
//illegal vector number
return HasReturnvaluesIF::RETURN_FAILED;
case RTEMS_INVALID_ADDRESS:
//illegal ISR entry point or invalid old_isr_handler
return HasReturnvaluesIF::RETURN_FAILED;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t Interrupt::disableInterrupt(InterruptNumber_t interruptNumber) {
//TODO Not implemented
return HasReturnvaluesIF::RETURN_FAILED;
}
//SHOULDDO: Make default values (edge, polarity) settable?
ReturnValue_t Interrupt::enableGpioInterrupt(InterruptNumber_t interrupt) {
volatile uint32_t* irqMask = hw_irq_mask;
uint32_t expectedValue = *irqMask | (1 << interrupt);
*irqMask = expectedValue;
uint32_t tempValue = *irqMask;
if (tempValue == expectedValue) {
volatile hw_gpio_port_t* ioPorts = hw_gpio_port;
ioPorts->direction &= ~(1 << interrupt); //Direction In
ioPorts->interrupt_edge |= 1 << interrupt; //Edge triggered
ioPorts->interrupt_polarity |= 1 << interrupt; //Trigger on rising edge
ioPorts->interrupt_mask |= 1 << interrupt; //Enable
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t Interrupt::disableGpioInterrupt(InterruptNumber_t interrupt) {
volatile uint32_t* irqMask = hw_irq_mask;
uint32_t expectedValue = *irqMask & ~(1 << interrupt);
*irqMask = expectedValue;
uint32_t tempValue = *irqMask;
if (tempValue == expectedValue) {
//Disable gpio IRQ
volatile hw_gpio_port_t* ioPorts = hw_gpio_port;
ioPorts->interrupt_mask &= ~(1 << interrupt);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
bool Interrupt::isInterruptInProgress() {
return rtems_interrupt_is_in_progress();
}

View File

@ -1,50 +0,0 @@
#ifndef OS_RTEMS_INTERRUPT_H_
#define OS_RTEMS_INTERRUPT_H_
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <cstring>
#include <rtems.h>
typedef rtems_isr_entry IsrHandler_t;
typedef rtems_isr IsrReturn_t;
typedef rtems_vector_number InterruptNumber_t;
class Interrupt {
public:
virtual ~Interrupt(){};
/**
* Establishes a new interrupt service routine.
* @param handler The service routine to establish
* @param interrupt The interrupt (NOT trap type) the routine shall react to.
* @return RETURN_OK on success. Otherwise, the OS failure code is returned.
*/
static ReturnValue_t setInterruptServiceRoutine(IsrHandler_t handler,
InterruptNumber_t interrupt, IsrHandler_t *oldHandler = NULL);
static ReturnValue_t enableInterrupt(InterruptNumber_t interruptNumber);
static ReturnValue_t disableInterrupt(InterruptNumber_t interruptNumber);
/**
* Enables the interrupt given.
* The function tests, if the InterruptMask register was written successfully.
* @param interrupt The interrupt to enable.
* @return RETURN_OK if the interrupt was set successfully. RETURN_FAILED else.
*/
static ReturnValue_t enableGpioInterrupt(InterruptNumber_t interrupt);
/**
* Disables the interrupt given.
* @param interrupt The interrupt to disable.
* @return RETURN_OK if the interrupt was set successfully. RETURN_FAILED else.
*/
static ReturnValue_t disableGpioInterrupt(InterruptNumber_t interrupt);
/**
* Checks if the current executing context is an ISR.
* @return true if handling an interrupt, false else.
*/
static bool isInterruptInProgress();
};
#endif /* OS_RTEMS_INTERRUPT_H_ */

View File

@ -1,14 +1,15 @@
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "MessageQueue.h" #include "MessageQueue.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
#include <cstring> #include <cstring>
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(NULL) { id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
rtems_name name = ('Q' << 24) + (queueCounter++ << 8); rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
rtems_status_code status = rtems_message_queue_create(name, message_depth, rtems_status_code status = rtems_message_queue_create(name, message_depth,
max_message_size, 0, &(this->id)); max_message_size, 0, &(this->id));
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "MessageQueue::MessageQueue: Creating Queue " << std::hex sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
<< name << std::dec << " failed with status:" << name << std::dec << " failed with status:"
<< (uint32_t) status << std::endl; << (uint32_t) status << std::endl;
this->id = 0; this->id = 0;
@ -20,15 +21,15 @@ MessageQueue::~MessageQueue() {
} }
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, bool ignoreFault) { MessageQueueMessageIF* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
} }
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessage* message) { ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
return sendToDefaultFrom(message, this->getId()); return sendToDefaultFrom(message, this->getId());
} }
ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
if (this->lastPartner != 0) { if (this->lastPartner != 0) {
return sendMessage(this->lastPartner, message, this->getId()); return sendMessage(this->lastPartner, message, this->getId());
} else { } else {
@ -36,27 +37,29 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
} }
} }
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t* receivedFrom) { MessageQueueId_t* receivedFrom) {
ReturnValue_t status = this->receiveMessage(message); ReturnValue_t status = this->receiveMessage(message);
*receivedFrom = this->lastPartner; *receivedFrom = this->lastPartner;
return status; return status;
} }
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
size_t size = 0;
rtems_status_code status = rtems_message_queue_receive(id, rtems_status_code status = rtems_message_queue_receive(id,
message->getBuffer(), &(message->messageSize), message->getBuffer(),&size,
RTEMS_NO_WAIT, 1); RTEMS_NO_WAIT, 1);
if (status == RTEMS_SUCCESSFUL) { if (status == RTEMS_SUCCESSFUL) {
message->setMessageSize(size);
this->lastPartner = message->getSender(); this->lastPartner = message->getSender();
//Check size of incoming message. //Check size of incoming message.
if (message->messageSize < message->getMinimumMessageSize()) { if (message->getMessageSize() < message->getMinimumMessageSize()) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} else { } else {
//No message was received. Keep lastPartner anyway, I might send something later. //No message was received. Keep lastPartner anyway, I might send something later.
//But still, delete packet content. //But still, delete packet content.
memset(message->getData(), 0, message->MAX_DATA_SIZE); memset(message->getData(), 0, message->getMaximumMessageSize());
} }
return convertReturnCode(status); return convertReturnCode(status);
} }
@ -79,20 +82,20 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
} }
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessage* message, MessageQueueId_t sentFrom, MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) { bool ignoreFault) {
message->setSender(sentFrom); message->setSender(sentFrom);
rtems_status_code result = rtems_message_queue_send(sendTo, rtems_status_code result = rtems_message_queue_send(sendTo,
message->getBuffer(), message->messageSize); message->getBuffer(), message->getMessageSize());
//TODO: Check if we're in ISR. //TODO: Check if we're in ISR.
if (result != RTEMS_SUCCESSFUL && !ignoreFault) { if (result != RTEMS_SUCCESSFUL && !ignoreFault) {
if (internalErrorReporter == NULL) { if (internalErrorReporter == nullptr) {
internalErrorReporter = objectManager->get<InternalErrorReporterIF>( internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER); objects::INTERNAL_ERROR_REPORTER);
} }
if (internalErrorReporter != NULL) { if (internalErrorReporter != nullptr) {
internalErrorReporter->queueMessageNotSent(); internalErrorReporter->queueMessageNotSent();
} }
} }
@ -105,7 +108,7 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
return returnCode; return returnCode;
} }
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message, ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
MessageQueueId_t sentFrom, bool ignoreFault) { MessageQueueId_t sentFrom, bool ignoreFault) {
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
} }

View File

@ -1,14 +1,5 @@
/** #ifndef FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
* @file MessageQueue.h #define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
*
* @date 10/02/2012
* @author Bastian Baetz
*
* @brief This file contains the definition of the MessageQueue class.
*/
#ifndef MESSAGEQUEUE_H_
#define MESSAGEQUEUE_H_
#include "../../internalError/InternalErrorReporterIF.h" #include "../../internalError/InternalErrorReporterIF.h"
#include "../../ipc/MessageQueueIF.h" #include "../../ipc/MessageQueueIF.h"
@ -60,14 +51,14 @@ public:
* @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
*/ */
ReturnValue_t sendMessage(MessageQueueId_t sendTo, ReturnValue_t sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, bool ignoreFault = false ); MessageQueueMessageIF* message, bool ignoreFault = false );
/** /**
* @brief This operation sends a message to the default destination. * @brief This operation sends a message to the default destination.
* @details As in the sendMessage method, this function uses the sendToDefault call of the * @details As in the sendMessage method, this function uses the sendToDefault call of the
* MessageQueueSender parent class and adds its queue id as "sentFrom" information. * MessageQueueSender parent class and adds its queue id as "sentFrom" information.
* @param message A pointer to a previously created message, which is sent. * @param message A pointer to a previously created message, which is sent.
*/ */
ReturnValue_t sendToDefault( MessageQueueMessage* message ); ReturnValue_t sendToDefault( MessageQueueMessageIF* message );
/** /**
* @brief This operation sends a message to the last communication partner. * @brief This operation sends a message to the last communication partner.
* @details This operation simplifies answering an incoming message by using the stored * @details This operation simplifies answering an incoming message by using the stored
@ -75,7 +66,7 @@ public:
* (i.e. lastPartner is zero), an error code is returned. * (i.e. lastPartner is zero), an error code is returned.
* @param message A pointer to a previously created message, which is sent. * @param message A pointer to a previously created message, which is sent.
*/ */
ReturnValue_t reply( MessageQueueMessage* message ); ReturnValue_t reply( MessageQueueMessageIF* message );
/** /**
* @brief This function reads available messages from the message queue and returns the sender. * @brief This function reads available messages from the message queue and returns the sender.
@ -84,7 +75,7 @@ public:
* @param message A pointer to a message in which the received data is stored. * @param message A pointer to a message in which the received data is stored.
* @param receivedFrom A pointer to a queue id in which the sender's id is stored. * @param receivedFrom A pointer to a queue id in which the sender's id is stored.
*/ */
ReturnValue_t receiveMessage(MessageQueueMessage* message, ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t *receivedFrom); MessageQueueId_t *receivedFrom);
/** /**
@ -95,7 +86,7 @@ public:
* message's content is cleared and the function returns immediately. * message's content is cleared and the function returns immediately.
* @param message A pointer to a message in which the received data is stored. * @param message A pointer to a message in which the received data is stored.
*/ */
ReturnValue_t receiveMessage(MessageQueueMessage* message); ReturnValue_t receiveMessage(MessageQueueMessageIF* message);
/** /**
* Deletes all pending messages in the queue. * Deletes all pending messages in the queue.
* @param count The number of flushed messages. * @param count The number of flushed messages.
@ -121,7 +112,7 @@ public:
* This variable is set to zero by default. * This variable is set to zero by default.
* \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. * \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
*/ */
virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
/** /**
* \brief The sendToDefault method sends a queue message to the default destination. * \brief The sendToDefault method sends a queue message to the default destination.
* \details In all other aspects, it works identical to the sendMessage method. * \details In all other aspects, it works identical to the sendMessage method.
@ -129,7 +120,7 @@ public:
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message.
* This variable is set to zero by default. * This variable is set to zero by default.
*/ */
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
/** /**
* \brief This method is a simple setter for the default destination. * \brief This method is a simple setter for the default destination.
*/ */
@ -178,4 +169,4 @@ private:
static ReturnValue_t convertReturnCode(rtems_status_code inValue); static ReturnValue_t convertReturnCode(rtems_status_code inValue);
}; };
#endif /* MESSAGEQUEUE_H_ */ #endif /* FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_ */

View File

@ -30,7 +30,7 @@ ReturnValue_t MultiObjectTask::startTask() {
rtems_status_code status = rtems_task_start(id, MultiObjectTask::taskEntryPoint, rtems_status_code status = rtems_task_start(id, MultiObjectTask::taskEntryPoint,
rtems_task_argument((void *) this)); rtems_task_argument((void *) this));
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "ObjectTask::startTask for " << std::hex << this->getId() sif::error << "ObjectTask::startTask for " << std::hex << this->getId()
<< std::dec << " failed." << std::endl; << std::dec << " failed." << std::endl;
} }
switch(status){ switch(status){
@ -63,8 +63,8 @@ void MultiObjectTask::taskFunctionality() {
char nameSpace[8] = { 0 }; char nameSpace[8] = { 0 };
char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace), char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace),
nameSpace); nameSpace);
error << "ObjectTask: " << ptr << " Deadline missed." << std::endl; sif::error << "ObjectTask: " << ptr << " Deadline missed." << std::endl;
if (this->deadlineMissedFunc != NULL) { if (this->deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();
} }
} }
@ -74,12 +74,13 @@ void MultiObjectTask::taskFunctionality() {
ReturnValue_t MultiObjectTask::addComponent(object_id_t object) { ReturnValue_t MultiObjectTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>( ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object); object);
if (newObject == NULL) { if (newObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
objectList.push_back(newObject); objectList.push_back(newObject);
ReturnValue_t result = newObject->initializeAfterTaskCreation(); newObject->setTaskIF(this);
return result;
return HasReturnvaluesIF::RETURN_OK;
} }
uint32_t MultiObjectTask::getPeriodMs() const { uint32_t MultiObjectTask::getPeriodMs() const {

View File

@ -1,11 +1,5 @@
/** #ifndef FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_
* @file MultiObjectTask.h #define FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_
* @brief This file defines the MultiObjectTask class.
* @date 30.01.2014
* @author baetz
*/
#ifndef MULTIOBJECTTASK_H_
#define MULTIOBJECTTASK_H_
#include "../../objectmanager/ObjectManagerIF.h" #include "../../objectmanager/ObjectManagerIF.h"
#include "../../tasks/PeriodicTaskIF.h" #include "../../tasks/PeriodicTaskIF.h"
@ -21,7 +15,7 @@ class ExecutableObjectIF;
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute * @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
* multiple objects that implement the ExecutableObjectIF interface. The objects must be * multiple objects that implement the ExecutableObjectIF interface. The objects must be
* added prior to starting the task. * added prior to starting the task.
* * @author baetz
* @ingroup task_handling * @ingroup task_handling
*/ */
class MultiObjectTask: public TaskBase, public PeriodicTaskIF { class MultiObjectTask: public TaskBase, public PeriodicTaskIF {
@ -63,11 +57,11 @@ public:
* @param object Id of the object to add. * @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/ */
ReturnValue_t addComponent(object_id_t object); ReturnValue_t addComponent(object_id_t object) override;
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms); ReturnValue_t sleepFor(uint32_t ms) override;
protected: protected:
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects. typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.
/** /**
@ -86,7 +80,7 @@ protected:
/** /**
* @brief The pointer to the deadline-missed function. * @brief The pointer to the deadline-missed function.
* @details This pointer stores the function that is executed if the task's deadline is missed. * @details This pointer stores the function that is executed if the task's deadline is missed.
* So, each may react individually on a timing failure. The pointer may be NULL, * So, each may react individually on a timing failure. The pointer may be nullptr,
* then nothing happens on missing the deadline. The deadline is equal to the next execution * then nothing happens on missing the deadline. The deadline is equal to the next execution
* of the periodic task. * of the periodic task.
*/ */
@ -110,4 +104,4 @@ protected:
void taskFunctionality(void); void taskFunctionality(void);
}; };
#endif /* MULTIOBJECTTASK_H_ */ #endif /* FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_ */

View File

@ -1,7 +1,6 @@
#include "Mutex.h" #include "Mutex.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
const uint32_t MutexIF::NO_TIMEOUT = RTEMS_NO_TIMEOUT;
uint8_t Mutex::count = 0; uint8_t Mutex::count = 0;
Mutex::Mutex() : Mutex::Mutex() :
@ -11,7 +10,7 @@ Mutex::Mutex() :
RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0, RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0,
&mutexId); &mutexId);
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "Mutex: creation with name, id " << mutexName << ", " << mutexId sif::error << "Mutex: creation with name, id " << mutexName << ", " << mutexId
<< " failed with " << status << std::endl; << " failed with " << status << std::endl;
} }
} }
@ -19,13 +18,28 @@ Mutex::Mutex() :
Mutex::~Mutex() { Mutex::~Mutex() {
rtems_status_code status = rtems_semaphore_delete(mutexId); rtems_status_code status = rtems_semaphore_delete(mutexId);
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "Mutex: deletion for id " << mutexId sif::error << "Mutex: deletion for id " << mutexId
<< " failed with " << status << std::endl; << " failed with " << status << std::endl;
} }
} }
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType =
rtems_status_code status = rtems_semaphore_obtain(mutexId, RTEMS_WAIT, timeoutMs); TimeoutType::BLOCKING, uint32_t timeoutMs) {
rtems_status_code status = RTEMS_INVALID_ID;
if(timeoutMs == MutexIF::TimeoutType::BLOCKING) {
status = rtems_semaphore_obtain(mutexId,
RTEMS_WAIT, RTEMS_NO_TIMEOUT);
}
else if(timeoutMs == MutexIF::TimeoutType::POLLING) {
timeoutMs = RTEMS_NO_TIMEOUT;
status = rtems_semaphore_obtain(mutexId,
RTEMS_NO_WAIT, 0);
}
else {
status = rtems_semaphore_obtain(mutexId,
RTEMS_WAIT, timeoutMs);
}
switch(status){ switch(status){
case RTEMS_SUCCESSFUL: case RTEMS_SUCCESSFUL:
//semaphore obtained successfully //semaphore obtained successfully

View File

@ -1,5 +1,5 @@
#ifndef OS_RTEMS_MUTEX_H_ #ifndef FSFW_OSAL_RTEMS_MUTEX_H_
#define OS_RTEMS_MUTEX_H_ #define FSFW_OSAL_RTEMS_MUTEX_H_
#include "../../ipc/MutexIF.h" #include "../../ipc/MutexIF.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
@ -8,11 +8,11 @@ class Mutex : public MutexIF {
public: public:
Mutex(); Mutex();
~Mutex(); ~Mutex();
ReturnValue_t lockMutex(uint32_t timeoutMs); ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs = 0);
ReturnValue_t unlockMutex(); ReturnValue_t unlockMutex();
private: private:
rtems_id mutexId; rtems_id mutexId;
static uint8_t count; static uint8_t count;
}; };
#endif /* OS_RTEMS_MUTEX_H_ */ #endif /* FSFW_OSAL_RTEMS_MUTEX_H_ */

View File

@ -2,7 +2,6 @@
#include "Mutex.h" #include "Mutex.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
MutexFactory* MutexFactory::factoryInstance = new MutexFactory(); MutexFactory* MutexFactory::factoryInstance = new MutexFactory();
MutexFactory::MutexFactory() { MutexFactory::MutexFactory() {

View File

@ -1,7 +1,8 @@
#include "../../tasks/FixedSequenceSlot.h" #include "../../tasks/FixedSequenceSlot.h"
#include "../../objectmanager/SystemObjectIF.h" #include "../../objectmanager/SystemObjectIF.h"
#include "../../osal/rtems/PollingTask.h" #include "../../objectmanager/ObjectManagerIF.h"
#include "../../osal/rtems/RtemsBasic.h" #include "PollingTask.h"
#include "RtemsBasic.h"
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include <rtems/bspIo.h> #include <rtems/bspIo.h>
@ -34,14 +35,14 @@ rtems_task PollingTask::taskEntryPoint(rtems_task_argument argument) {
PollingTask *originalTask(reinterpret_cast<PollingTask*>(argument)); PollingTask *originalTask(reinterpret_cast<PollingTask*>(argument));
//The task's functionality is called. //The task's functionality is called.
originalTask->taskFunctionality(); originalTask->taskFunctionality();
debug << "Polling task " << originalTask->getId() sif::debug << "Polling task " << originalTask->getId()
<< " returned from taskFunctionality." << std::endl; << " returned from taskFunctionality." << std::endl;
} }
void PollingTask::missedDeadlineCounter() { void PollingTask::missedDeadlineCounter() {
PollingTask::deadlineMissedCount++; PollingTask::deadlineMissedCount++;
if (PollingTask::deadlineMissedCount % 10 == 0) { if (PollingTask::deadlineMissedCount % 10 == 0) {
error << "PST missed " << PollingTask::deadlineMissedCount sif::error << "PST missed " << PollingTask::deadlineMissedCount
<< " deadlines." << std::endl; << " deadlines." << std::endl;
} }
} }
@ -50,7 +51,7 @@ ReturnValue_t PollingTask::startTask() {
rtems_status_code status = rtems_task_start(id, PollingTask::taskEntryPoint, rtems_status_code status = rtems_task_start(id, PollingTask::taskEntryPoint,
rtems_task_argument((void *) this)); rtems_task_argument((void *) this));
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "PollingTask::startTask for " << std::hex << this->getId() sif::error << "PollingTask::startTask for " << std::hex << this->getId()
<< std::dec << " failed." << std::endl; << std::dec << " failed." << std::endl;
} }
switch(status){ switch(status){
@ -68,8 +69,9 @@ ReturnValue_t PollingTask::startTask() {
ReturnValue_t PollingTask::addSlot(object_id_t componentId, ReturnValue_t PollingTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) { uint32_t slotTimeMs, int8_t executionStep) {
if (objectManager->get<ExecutableObjectIF>(componentId) != nullptr) { ExecutableObjectIF* object = objectManager->get<ExecutableObjectIF>(componentId);
pst.addSlot(componentId, slotTimeMs, executionStep, this); if (object != nullptr) {
pst.addSlot(componentId, slotTimeMs, executionStep, object, this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -82,7 +84,7 @@ uint32_t PollingTask::getPeriodMs() const {
return pst.getLengthMs(); return pst.getLengthMs();
} }
ReturnValue_t PollingTask::checkAndInitializeSequence() const { ReturnValue_t PollingTask::checkSequence() const {
return pst.checkSequence(); return pst.checkSequence();
} }
@ -90,11 +92,10 @@ ReturnValue_t PollingTask::checkAndInitializeSequence() const {
void PollingTask::taskFunctionality() { void PollingTask::taskFunctionality() {
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry. // A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
std::list<FixedSequenceSlot*>::iterator it = pst.current; FixedSlotSequence::SlotListIter it = pst.current;
//The start time for the first entry is read. //The start time for the first entry is read.
rtems_interval interval = RtemsBasic::convertMsToTicks( rtems_interval interval = RtemsBasic::convertMsToTicks(it->pollingTimeMs);
(*it)->pollingTimeMs);
TaskBase::setAndStartPeriod(interval,&periodId); TaskBase::setAndStartPeriod(interval,&periodId);
//The task's "infinite" inner loop is entered. //The task's "infinite" inner loop is entered.
while (1) { while (1) {
@ -107,7 +108,7 @@ void PollingTask::taskFunctionality() {
//If the deadline was missed, the deadlineMissedFunc is called. //If the deadline was missed, the deadlineMissedFunc is called.
rtems_status_code status = TaskBase::restartPeriod(interval,periodId); rtems_status_code status = TaskBase::restartPeriod(interval,periodId);
if (status == RTEMS_TIMEOUT) { if (status == RTEMS_TIMEOUT) {
if (this->deadlineMissedFunc != NULL) { if (this->deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();
} }
} }

View File

@ -1,5 +1,5 @@
#ifndef POLLINGTASK_H_ #ifndef FSFW_OSAL_RTEMS_POLLINGTASK_H_
#define POLLINGTASK_H_ #define FSFW_OSAL_RTEMS_POLLINGTASK_H_
#include "../../tasks/FixedSlotSequence.h" #include "../../tasks/FixedSlotSequence.h"
#include "../../tasks/FixedTimeslotTaskIF.h" #include "../../tasks/FixedTimeslotTaskIF.h"
@ -42,7 +42,7 @@ class PollingTask: public TaskBase, public FixedTimeslotTaskIF {
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const;
ReturnValue_t checkAndInitializeSequence() const; ReturnValue_t checkSequence() const;
ReturnValue_t sleepFor(uint32_t ms); ReturnValue_t sleepFor(uint32_t ms);
protected: protected:
@ -82,4 +82,4 @@ protected:
void taskFunctionality( void ); void taskFunctionality( void );
}; };
#endif /* POLLINGTASK_H_ */ #endif /* FSFW_OSAL_RTEMS_POLLINGTASK_H_ */

View File

@ -1,16 +1,17 @@
#include "../../ipc/QueueFactory.h" #include "../../ipc/QueueFactory.h"
#include "../../ipc/MessageQueueSenderIF.h"
#include "MessageQueue.h" #include "MessageQueue.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
QueueFactory* QueueFactory::factoryInstance = NULL; QueueFactory* QueueFactory::factoryInstance = nullptr;
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) { MessageQueueMessageIF* message, MessageQueueId_t sentFrom,bool ignoreFault) {
//TODO add ignoreFault functionality //TODO add ignoreFault functionality
message->setSender(sentFrom); message->setSender(sentFrom);
rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(), rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(),
message->messageSize); message->getMessageSize());
switch(result){ switch(result){
case RTEMS_SUCCESSFUL: case RTEMS_SUCCESSFUL:
//message sent successfully //message sent successfully
@ -37,7 +38,7 @@ ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
} }
QueueFactory* QueueFactory::instance() { QueueFactory* QueueFactory::instance() {
if (factoryInstance == NULL) { if (factoryInstance == nullptr) {
factoryInstance = new QueueFactory; factoryInstance = new QueueFactory;
} }
return factoryInstance; return factoryInstance;

View File

@ -1,5 +1,5 @@
#ifndef OS_RTEMS_RTEMSBASIC_H_ #ifndef FSFW_OSAL_RTEMS_RTEMSBASIC_H_
#define OS_RTEMS_RTEMSBASIC_H_ #define FSFW_OSAL_RTEMS_RTEMSBASIC_H_
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
#include <rtems.h> #include <rtems.h>
@ -22,4 +22,4 @@ public:
} }
}; };
#endif /* OS_RTEMS_RTEMSBASIC_H_ */ #endif /* FSFW_OSAL_RTEMS_RTEMSBASIC_H_ */

Some files were not shown because too many files have changed in this diff Show More