Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/KSat/fsfw into mueller/master
This commit is contained in:
commit
3e41b202a1
49
CHANGELOG
49
CHANGELOG
@ -1,5 +1,8 @@
|
||||
## 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
|
||||
|
||||
@ -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)
|
||||
- The same is possible for the event reporting service (PUS5)
|
||||
- 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
85
CMakeLists.txt
Normal 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}
|
||||
)
|
@ -1,10 +1,11 @@
|
||||
#ifndef 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_SUBVERSION 0
|
||||
#define FSFW_REVISION 1
|
||||
|
||||
|
||||
|
||||
|
2
NOTICE
2
NOTICE
@ -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
|
||||
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.
|
||||
No copyright assignment is required to contribute to the Flight Software Framework.
|
||||
|
||||
|
4
controller/CMakeLists.txt
Normal file
4
controller/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
ControllerBase.cpp
|
||||
)
|
@ -8,7 +8,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||
size_t commandQueueDepth) :
|
||||
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
|
||||
submode(SUBMODE_NONE), modeHelper(this),
|
||||
healthHelper(this, setObjectId), hkSwitcher(this) {
|
||||
healthHelper(this, setObjectId) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
commandQueueDepth);
|
||||
}
|
||||
@ -44,10 +44,6 @@ ReturnValue_t ControllerBase::initialize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = hkSwitcher.initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
@ -107,7 +103,6 @@ void ControllerBase::announceMode(bool recursive) {
|
||||
|
||||
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
||||
handleQueue();
|
||||
hkSwitcher.performOperation();
|
||||
performControlOperation();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
@ -72,9 +72,6 @@ protected:
|
||||
|
||||
HealthHelper healthHelper;
|
||||
|
||||
// Is this still needed?
|
||||
HkSwitchHelper hkSwitcher;
|
||||
|
||||
/**
|
||||
* Pointer to the task which executes this component,
|
||||
* is invalid before setTaskIF was called.
|
||||
|
@ -97,7 +97,6 @@ ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
|
||||
|
||||
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
|
||||
handleQueue();
|
||||
hkSwitcher.performOperation();
|
||||
localPoolManager.performHkOperation();
|
||||
performControlOperation();
|
||||
return RETURN_OK;
|
||||
|
@ -19,12 +19,12 @@ class VirtualChannelReception;
|
||||
class DataLinkLayer : public CCSDSReturnValuesIF {
|
||||
public:
|
||||
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_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_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 FRAME_PROCESSING_FAILED = MAKE_EVENT(5, SEVERITY::LOW); //!< The CCSDS Board could not interpret a TC
|
||||
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 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 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
|
||||
/**
|
||||
* The Constructor sets the passed parameters and nothing else.
|
||||
* @param set_frame_buffer The buffer in which incoming frame candidates are stored.
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
MapPacketExtraction::MapPacketExtraction(uint8_t setMapId,
|
||||
object_id_t setPacketDestination) :
|
||||
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0),
|
||||
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId),
|
||||
bufferPosition(packetBuffer), packetDestination(setPacketDestination),
|
||||
packetStore(NULL), tcQueueId(MessageQueueIF::NO_QUEUE) {
|
||||
tcQueueId(MessageQueueIF::NO_QUEUE) {
|
||||
std::memset(packetBuffer, 0, sizeof(packetBuffer));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef MAPPACKETEXTRACTION_H_
|
||||
#define MAPPACKETEXTRACTION_H_
|
||||
#ifndef FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
|
||||
#define FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
|
||||
|
||||
#include "MapPacketExtractionIF.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
@ -20,11 +20,12 @@ private:
|
||||
static const uint32_t MAX_PACKET_SIZE = 4096;
|
||||
uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame.
|
||||
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 packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer.
|
||||
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.
|
||||
/**
|
||||
* Debug method to print the packet Buffer's content.
|
||||
@ -69,4 +70,4 @@ public:
|
||||
uint8_t getMapId() const;
|
||||
};
|
||||
|
||||
#endif /* MAPPACKETEXTRACTION_H_ */
|
||||
#endif /* FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_ */
|
||||
|
@ -13,7 +13,7 @@ class HkSwitchHelper: public ExecutableObjectIF, public CommandsActionsIF {
|
||||
public:
|
||||
|
||||
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);
|
||||
virtual ~HkSwitchHelper();
|
||||
|
@ -48,7 +48,7 @@ class HousekeepingPacketUpdate;
|
||||
* @author R. Mueller
|
||||
*/
|
||||
class LocalDataPoolManager {
|
||||
template<typename T> friend class LocalPoolVar;
|
||||
template<typename T> friend class LocalPoolVariable;
|
||||
template<typename T, uint16_t vecSize> friend class LocalPoolVector;
|
||||
friend class LocalPoolDataSetBase;
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
|
@ -22,10 +22,10 @@
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
template<typename T>
|
||||
class LocalPoolVar: public LocalPoolObjectBase {
|
||||
class LocalPoolVariable: public LocalPoolObjectBase {
|
||||
public:
|
||||
//! Default ctor is forbidden.
|
||||
LocalPoolVar() = delete;
|
||||
LocalPoolVariable() = delete;
|
||||
|
||||
/**
|
||||
* This constructor is used by the data creators to have pool variable
|
||||
@ -43,7 +43,7 @@ public:
|
||||
* If nullptr, the variable is not registered.
|
||||
* @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,
|
||||
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.
|
||||
*
|
||||
*/
|
||||
LocalPoolVar(object_id_t poolOwner, lp_id_t poolId,
|
||||
LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId,
|
||||
DataSetIF* dataSet = nullptr,
|
||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||
/**
|
||||
@ -73,10 +73,10 @@ public:
|
||||
* @param dataSet
|
||||
* @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);
|
||||
|
||||
virtual~ LocalPoolVar() {};
|
||||
virtual~ LocalPoolVariable() {};
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
|
||||
LocalPoolVar<T> &operator=(const T& newValue);
|
||||
LocalPoolVar<T> &operator=(const LocalPoolVar<T>& newPoolVariable);
|
||||
LocalPoolVariable<T> &operator=(const T& newValue);
|
||||
LocalPoolVariable<T> &operator=(const LocalPoolVariable<T>& newPoolVariable);
|
||||
|
||||
//! Explicit type conversion operator. Allows casting the class to
|
||||
//! its template type to perform operations on value.
|
||||
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 LocalPoolVar<T>& other) const;
|
||||
bool operator!=(const LocalPoolVariable<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 LocalPoolVar<T>& other) const;
|
||||
bool operator>(const LocalPoolVariable<T>& other) const;
|
||||
bool operator>(const T& other) const;
|
||||
|
||||
protected:
|
||||
@ -160,7 +160,7 @@ protected:
|
||||
// std::ostream is the type for object std::cout
|
||||
template <typename U>
|
||||
friend std::ostream& operator<< (std::ostream &out,
|
||||
const LocalPoolVar<U> &var);
|
||||
const LocalPoolVariable<U> &var);
|
||||
|
||||
private:
|
||||
};
|
||||
@ -168,18 +168,18 @@ private:
|
||||
#include "LocalPoolVariable.tpp"
|
||||
|
||||
template<class T>
|
||||
using lp_var_t = LocalPoolVar<T>;
|
||||
using lp_var_t = LocalPoolVariable<T>;
|
||||
|
||||
using lp_bool_t = LocalPoolVar<uint8_t>;
|
||||
using lp_uint8_t = LocalPoolVar<uint8_t>;
|
||||
using lp_uint16_t = LocalPoolVar<uint16_t>;
|
||||
using lp_uint32_t = LocalPoolVar<uint32_t>;
|
||||
using lp_uint64_t = LocalPoolVar<uint64_t>;
|
||||
using lp_int8_t = LocalPoolVar<int8_t>;
|
||||
using lp_int16_t = LocalPoolVar<int16_t>;
|
||||
using lp_int32_t = LocalPoolVar<int32_t>;
|
||||
using lp_int64_t = LocalPoolVar<int64_t>;
|
||||
using lp_float_t = LocalPoolVar<float>;
|
||||
using lp_double_t = LocalPoolVar<double>;
|
||||
using lp_bool_t = LocalPoolVariable<uint8_t>;
|
||||
using lp_uint8_t = LocalPoolVariable<uint8_t>;
|
||||
using lp_uint16_t = LocalPoolVariable<uint16_t>;
|
||||
using lp_uint32_t = LocalPoolVariable<uint32_t>;
|
||||
using lp_uint64_t = LocalPoolVariable<uint64_t>;
|
||||
using lp_int8_t = LocalPoolVariable<int8_t>;
|
||||
using lp_int16_t = LocalPoolVariable<int16_t>;
|
||||
using lp_int32_t = LocalPoolVariable<int32_t>;
|
||||
using lp_int64_t = LocalPoolVariable<int64_t>;
|
||||
using lp_float_t = LocalPoolVariable<float>;
|
||||
using lp_double_t = LocalPoolVariable<double>;
|
||||
|
||||
#endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ */
|
||||
|
@ -6,32 +6,32 @@
|
||||
#endif
|
||||
|
||||
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):
|
||||
LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {}
|
||||
|
||||
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):
|
||||
LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {}
|
||||
|
||||
|
||||
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):
|
||||
LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId,
|
||||
dataSet, setReadWriteMode){}
|
||||
|
||||
|
||||
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,
|
||||
lockTimeout);
|
||||
return readWithoutLock();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t LocalPoolVar<T>::readWithoutLock() {
|
||||
inline ReturnValue_t LocalPoolVariable<T>::readWithoutLock() {
|
||||
if(readWriteMode == pool_rwm_t::VAR_WRITE) {
|
||||
sif::debug << "LocalPoolVar: Invalid read write "
|
||||
"mode for read() call." << std::endl;
|
||||
@ -53,14 +53,14 @@ inline ReturnValue_t LocalPoolVar<T>::readWithoutLock() {
|
||||
}
|
||||
|
||||
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,
|
||||
lockTimeout);
|
||||
return commitWithoutLock();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t LocalPoolVar<T>::commitWithoutLock() {
|
||||
inline ReturnValue_t LocalPoolVariable<T>::commitWithoutLock() {
|
||||
if(readWriteMode == pool_rwm_t::VAR_READ) {
|
||||
sif::debug << "LocalPoolVar: Invalid read write "
|
||||
"mode for commit() call." << std::endl;
|
||||
@ -81,88 +81,88 @@ inline ReturnValue_t LocalPoolVar<T>::commitWithoutLock() {
|
||||
}
|
||||
|
||||
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 {
|
||||
return SerializeAdapter::serialize(&value,
|
||||
buffer, size ,max_size, streamEndianness);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline size_t LocalPoolVar<T>::getSerializedSize() const {
|
||||
inline size_t LocalPoolVariable<T>::getSerializedSize() const {
|
||||
return SerializeAdapter::getSerializedSize(&value);
|
||||
}
|
||||
|
||||
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) {
|
||||
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::ostream& operator<< (std::ostream &out,
|
||||
const LocalPoolVar<T> &var) {
|
||||
const LocalPoolVariable<T> &var) {
|
||||
out << var.value;
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline LocalPoolVar<T>::operator T() const {
|
||||
inline LocalPoolVariable<T>::operator T() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline LocalPoolVar<T> & LocalPoolVar<T>::operator=(const T& newValue) {
|
||||
inline LocalPoolVariable<T> & LocalPoolVariable<T>::operator=(const T& newValue) {
|
||||
value = newValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline LocalPoolVar<T>& LocalPoolVar<T>::operator =(
|
||||
const LocalPoolVar<T>& newPoolVariable) {
|
||||
inline LocalPoolVariable<T>& LocalPoolVariable<T>::operator =(
|
||||
const LocalPoolVariable<T>& newPoolVariable) {
|
||||
value = newPoolVariable.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,11 @@
|
||||
#define FSFW_OBJ_EVENT_TRANSLATION 0
|
||||
|
||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||
#define FSFW_DEBUG_OUTPUT 1
|
||||
//! Specify whether info events are printed too.
|
||||
#define FSFW_DEBUG_INFO 1
|
||||
#include <translateObjects.h>
|
||||
#include <translateEvents.h>
|
||||
#else
|
||||
#define FSFW_DEBUG_OUTPUT 0
|
||||
#endif
|
||||
|
||||
//! When using the newlib nano library, C99 support for stdio facilities
|
||||
|
@ -693,7 +693,7 @@ void DeviceHandlerBase::doGetRead() {
|
||||
void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
|
||||
size_t receivedDataLen) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
DeviceCommandId_t foundId = 0xffffffff;
|
||||
DeviceCommandId_t foundId = DeviceHandlerIF::NO_COMMAND;
|
||||
size_t foundLen = 0;
|
||||
// The loop may not execute more often than the number of received bytes
|
||||
// (worst case). This approach avoids infinite loops due to buggy
|
||||
@ -1453,3 +1453,9 @@ dur_millis_t DeviceHandlerBase::getPeriodicOperationFrequency() const {
|
||||
return pstIntervalMs;
|
||||
}
|
||||
|
||||
DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
||||
if(cookieInfo.pendingCommand != deviceCommandMap.end()) {
|
||||
return cookieInfo.pendingCommand->first;
|
||||
}
|
||||
return DeviceHandlerIF::NO_COMMAND;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ protected:
|
||||
* - If the device does not change the mode, the mode will be changed to
|
||||
* _MODE_POWER_DOWN, when the timeout (from getTransitionDelay())
|
||||
* has passed.
|
||||
* 0xffffffff
|
||||
*
|
||||
* #transitionFailure can be set to a failure code indicating the reason
|
||||
* for a failed transition
|
||||
*/
|
||||
@ -734,15 +734,27 @@ protected:
|
||||
//! before setTaskIF was called.
|
||||
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
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@ -849,15 +861,18 @@ protected:
|
||||
/**
|
||||
* 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
|
||||
* are to be sent by the handler itself. It is NOT needed for the raw commanding service.
|
||||
* Its only current use is in the STR 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
|
||||
* This is only called in @c MODE_RAW. It is for the rare case that in
|
||||
* raw mode packets are to be sent by the handler itself. It is NOT needed
|
||||
* for the raw commanding service. Its only current use is in the STR
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
* @return
|
||||
@ -870,7 +885,9 @@ protected:
|
||||
* Returns the delay cycle count of a reply.
|
||||
* A count != 0 indicates that the command is already executed.
|
||||
* @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);
|
||||
|
||||
@ -880,20 +897,22 @@ protected:
|
||||
* It gets space in the #IPCStore, copies data there, then sends a raw reply
|
||||
* containing the store address.
|
||||
*
|
||||
* This method is virtual, as the STR has a different channel to send raw replies
|
||||
* and overwrites it accordingly.
|
||||
* This method is virtual, as the STR has a different channel to send
|
||||
* raw replies and overwrites it accordingly.
|
||||
*
|
||||
* @param data data to send
|
||||
* @param len length of @c data
|
||||
* @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,
|
||||
MessageQueueId_t sendTo, bool isCommand = false);
|
||||
|
||||
/**
|
||||
* Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping is active and if so,
|
||||
* does not send the Data as the wiretapping will have sent it already
|
||||
* Calls replyRawData() with #defaultRawReceiver, but checks if wiretapping
|
||||
* 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);
|
||||
|
||||
@ -905,17 +924,19 @@ protected:
|
||||
/**
|
||||
* Enable the reply checking for a command
|
||||
*
|
||||
* Is only called, if the command was sent (ie the getWriteReply was successful).
|
||||
* Must ensure that all replies are activated and correctly linked to the command that initiated it.
|
||||
* The default implementation looks for a reply with the same id as the command id in the replyMap or
|
||||
* uses the alternativeReplyId if flagged so.
|
||||
* When found, copies maxDelayCycles to delayCycles in the reply information and sets the command to
|
||||
* expect one reply.
|
||||
* Is only called, if the command was sent (i.e. the getWriteReply was
|
||||
* successful). Must ensure that all replies are activated and correctly
|
||||
* linked to the command that initiated it.
|
||||
* The default implementation looks for a reply with the same id as the
|
||||
* command id in the replyMap or uses the alternativeReplyId if flagged so.
|
||||
* 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
|
||||
* or replyId differs from commandId.
|
||||
* 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.
|
||||
*
|
||||
* @param deviceCommand
|
||||
@ -931,17 +952,20 @@ protected:
|
||||
* get the state of the PCDU switches in the datapool
|
||||
*
|
||||
* @return
|
||||
* - @c PowerSwitchIF::SWITCH_ON if all switches specified by #switches are on
|
||||
* - @c PowerSwitchIF::SWITCH_OFF one of the switches specified by #switches are off
|
||||
* - @c PowerSwitchIF::SWITCH_ON if all switches specified
|
||||
* by #switches are on
|
||||
* - @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);
|
||||
|
||||
/**
|
||||
* set all datapool variables that are update periodically in normal mode invalid
|
||||
*
|
||||
* Child classes should provide an implementation which sets all those variables invalid
|
||||
* which are set periodically during any normal mode.
|
||||
* @brief Set all datapool variables that are update periodically in
|
||||
* normal mode invalid
|
||||
* @details TODO: Use local pools
|
||||
* Child classes should provide an implementation which sets all those
|
||||
* variables invalid which are set periodically during any normal mode.
|
||||
*/
|
||||
virtual void setNormalDatapoolEntriesInvalid() = 0;
|
||||
|
||||
@ -951,11 +975,12 @@ protected:
|
||||
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
|
||||
* situation. Care must be taken that checking is not permanentely disabled as this
|
||||
* would render the handler unusable.
|
||||
* This can be used when the child does not want to receive a command in
|
||||
* a certain situation. Care must be taken that checking is not
|
||||
* permanentely disabled as this would render the handler unusable.
|
||||
*
|
||||
* @return whether checking the queue should NOT be done
|
||||
*/
|
||||
@ -994,17 +1019,20 @@ protected:
|
||||
virtual void forwardEvent(Event event, uint32_t parameter1 = 0,
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
@ -1045,9 +1073,10 @@ private:
|
||||
/**
|
||||
* Information about a cookie.
|
||||
*
|
||||
* This is stored in a map for each cookie, to not only track the state, but also information
|
||||
* about the sent command. Tracking this information is needed as
|
||||
* the state of a commandId (waiting for reply) is done when a RMAP write reply is received.
|
||||
* This is stored in a map for each cookie, to not only track the state,
|
||||
* but also information about the sent command. Tracking this information
|
||||
* is needed as the state of a commandId (waiting for reply) is done when a
|
||||
* write reply is received.
|
||||
*/
|
||||
struct CookieInfo {
|
||||
CookieState_t state;
|
||||
@ -1104,10 +1133,14 @@ private:
|
||||
/**
|
||||
* Handle the device handler mode.
|
||||
*
|
||||
* - checks whether commands are valid for the current mode, rejects them accordingly
|
||||
* - checks whether commanded mode transitions are required and calls 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 (eg setting a timeout) are handled in setMode()
|
||||
* - checks whether commands are valid for the current mode, rejects
|
||||
* them accordingly
|
||||
* - checks whether commanded mode transitions are required and calls
|
||||
* 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);
|
||||
|
||||
@ -1117,16 +1150,17 @@ private:
|
||||
/**
|
||||
* 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
|
||||
* but not received).
|
||||
* This is called at the beginning of each cycle. It checks whether a
|
||||
* reply has timed out (that means a reply was expected but not received).
|
||||
*/
|
||||
void decrementDeviceReplyMap(void);
|
||||
|
||||
/**
|
||||
* Convenience function to handle a reply.
|
||||
*
|
||||
* Called after scanForReply() has found a packet. Checks if the found id is in the #deviceCommandMap, if so,
|
||||
* calls interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) for further action.
|
||||
* Called after scanForReply() has found a packet. Checks if the found ID
|
||||
* is in the #deviceCommandMap, if so, calls
|
||||
* #interpretDeviceReply for further action.
|
||||
*
|
||||
* It also resets the timeout counter for the command id.
|
||||
*
|
||||
@ -1186,7 +1220,7 @@ private:
|
||||
* @param[out] len
|
||||
* @return
|
||||
* - @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
|
||||
*/
|
||||
ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data,
|
||||
|
@ -191,7 +191,7 @@ void DeviceHandlerFailureIsolation::triggerEvent(Event event, uint32_t parameter
|
||||
uint32_t parameter2) {
|
||||
//Do not throw error events if fdirState != none.
|
||||
//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);
|
||||
}
|
||||
}
|
||||
@ -201,7 +201,7 @@ bool DeviceHandlerFailureIsolation::isFdirActionInProgress() {
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::startRecovery(Event reason) {
|
||||
throwFdirEvent(FDIR_STARTS_RECOVERY, EVENT::getEventId(reason));
|
||||
throwFdirEvent(FDIR_STARTS_RECOVERY, event::getEventId(reason));
|
||||
setOwnerHealth(HasHealthIF::NEEDS_RECOVERY);
|
||||
setFdirState(RECOVERY_ONGOING);
|
||||
}
|
||||
@ -228,7 +228,7 @@ ReturnValue_t DeviceHandlerFailureIsolation::getParameter(uint8_t domainId,
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::setFaulty(Event reason) {
|
||||
throwFdirEvent(FDIR_TURNS_OFF_DEVICE, EVENT::getEventId(reason));
|
||||
throwFdirEvent(FDIR_TURNS_OFF_DEVICE, event::getEventId(reason));
|
||||
setOwnerHealth(HasHealthIF::FAULTY);
|
||||
setFdirState(AWAIT_SHUTDOWN);
|
||||
}
|
||||
|
@ -95,17 +95,17 @@ public:
|
||||
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 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_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, 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_MISSED_REPLY = MAKE_EVENT(5, 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 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_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH);
|
||||
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_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, 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_MISSED_REPLY = MAKE_EVENT(5, 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 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_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
||||
|
||||
|
8
events/CMakeLists.txt
Normal file
8
events/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
Event.cpp
|
||||
EventManager.cpp
|
||||
EventMessage.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(eventmatching)
|
@ -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;
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fwSubsystemIdRanges.h"
|
||||
//could be move to more suitable location
|
||||
// could be moved to more suitable location
|
||||
#include <events/subsystemIdRanges.h>
|
||||
|
||||
typedef uint16_t EventId_t;
|
||||
@ -13,33 +13,28 @@ typedef uint8_t EventSeverity_t;
|
||||
|
||||
typedef uint32_t Event;
|
||||
|
||||
namespace EVENT {
|
||||
EventId_t getEventId(Event event);
|
||||
namespace event {
|
||||
|
||||
EventSeverity_t getSeverity(Event event);
|
||||
|
||||
Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId,
|
||||
EventSeverity_t eventSeverity);
|
||||
constexpr EventId_t getEventId(Event event) {
|
||||
return (event & 0xFFFF);
|
||||
}
|
||||
|
||||
namespace SEVERITY {
|
||||
static const EventSeverity_t INFO = 1;
|
||||
static const EventSeverity_t LOW = 2;
|
||||
static const EventSeverity_t MEDIUM = 3;
|
||||
static const EventSeverity_t HIGH = 4;
|
||||
constexpr EventSeverity_t getSeverity(Event event) {
|
||||
return ((event >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
//Unfortunately, this does not work nicely because of the inability to define static classes in headers.
|
||||
//struct Event {
|
||||
// Event(uint8_t domain, uint8_t counter, EventSeverity_t severity) :
|
||||
// id(domain*100+counter), severity(severity) {
|
||||
// }
|
||||
// EventId_t id;
|
||||
// EventSeverity_t severity;
|
||||
// static const EventSeverity_t INFO = 1;
|
||||
// static const EventSeverity_t LOW = 2;
|
||||
// static const EventSeverity_t MEDIUM = 3;
|
||||
// static const EventSeverity_t HIGH = 4;
|
||||
//};
|
||||
constexpr Event makeEvent(uint8_t subsystemId, uint8_t uniqueEventId,
|
||||
EventSeverity_t eventSeverity) {
|
||||
return (eventSeverity << 16) + (subsystemId * 100) + uniqueEventId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace severity {
|
||||
static constexpr EventSeverity_t INFO = 1;
|
||||
static constexpr EventSeverity_t LOW = 2;
|
||||
static constexpr EventSeverity_t MEDIUM = 3;
|
||||
static constexpr EventSeverity_t HIGH = 4;
|
||||
}
|
||||
|
||||
#endif /* EVENTOBJECT_EVENT_H_ */
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "EventManager.h"
|
||||
#include "EventMessage.h"
|
||||
|
||||
#include <FSFWConfig.h>
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../ipc/QueueFactory.h"
|
||||
@ -9,7 +11,6 @@
|
||||
// objects registering for certain events.
|
||||
// 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.
|
||||
// This should be configurable..
|
||||
const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
||||
{fsfwconfig::FSFW_EVENTMGMR_MATCHTREE_NODES,
|
||||
sizeof(EventMatchTree::Node)},
|
||||
@ -113,12 +114,12 @@ ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener,
|
||||
return result;
|
||||
}
|
||||
|
||||
#if FSFW_DEBUG_OUTPUT == 1
|
||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||
|
||||
void EventManager::printEvent(EventMessage* message) {
|
||||
const char *string = 0;
|
||||
switch (message->getSeverity()) {
|
||||
case SEVERITY::INFO:
|
||||
case severity::INFO:
|
||||
#if DEBUG_INFO_EVENT == 1
|
||||
string = translateObject(message->getReporter());
|
||||
sif::info << "EVENT: ";
|
||||
|
@ -1,18 +1,20 @@
|
||||
#ifndef EVENTMANAGER_H_
|
||||
#define EVENTMANAGER_H_
|
||||
#ifndef FSFW_EVENT_EVENTMANAGER_H_
|
||||
#define FSFW_EVENT_EVENTMANAGER_H_
|
||||
|
||||
#include "eventmatching/EventMatchTree.h"
|
||||
#include "EventManagerIF.h"
|
||||
#include "eventmatching/EventMatchTree.h"
|
||||
|
||||
#include <FSFWConfig.h>
|
||||
|
||||
#include "../objectmanager/SystemObject.h"
|
||||
#include "../storagemanager/LocalPool.h"
|
||||
#include "../tasks/ExecutableObjectIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../ipc/MutexIF.h"
|
||||
#include <FSFWConfig.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#if FSFW_DEBUG_OUTPUT == 1
|
||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||
// forward declaration, should be implemented by mission
|
||||
extern const char* translateObject(object_id_t object);
|
||||
extern const char* translateEvents(Event event);
|
||||
@ -59,7 +61,7 @@ protected:
|
||||
|
||||
void notifyListeners(EventMessage *message);
|
||||
|
||||
#if FSFW_DEBUG_OUTPUT == 1
|
||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||
void printEvent(EventMessage *message);
|
||||
#endif
|
||||
|
||||
@ -68,4 +70,4 @@ protected:
|
||||
void unlockMutex();
|
||||
};
|
||||
|
||||
#endif /* EVENTMANAGER_H_ */
|
||||
#endif /* FSFW_EVENT_EVENTMANAGER_H_ */
|
||||
|
@ -48,7 +48,7 @@ void EventMessage::setMessageId(uint8_t id) {
|
||||
EventSeverity_t EventMessage::getSeverity() {
|
||||
Event event;
|
||||
memcpy(&event, getData(), sizeof(Event));
|
||||
return EVENT::getSeverity(event);
|
||||
return event::getSeverity(event);
|
||||
}
|
||||
|
||||
void EventMessage::setSeverity(EventSeverity_t severity) {
|
||||
@ -61,7 +61,7 @@ void EventMessage::setSeverity(EventSeverity_t severity) {
|
||||
EventId_t EventMessage::getEventId() {
|
||||
Event event;
|
||||
memcpy(&event, getData(), sizeof(Event));
|
||||
return EVENT::getEventId(event);
|
||||
return event::getEventId(event);
|
||||
}
|
||||
|
||||
void EventMessage::setEventId(EventId_t eventId) {
|
||||
|
7
events/eventmatching/CMakeLists.txt
Normal file
7
events/eventmatching/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
EventIdRangeMatcher.cpp
|
||||
EventMatchTree.cpp
|
||||
ReporterRangeMatcher.cpp
|
||||
SeverityRangeMatcher.cpp
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
#ifndef FRAMEWORK_EVENTS_FWSUBSYSTEMIDRANGES_H_
|
||||
#define FRAMEWORK_EVENTS_FWSUBSYSTEMIDRANGES_H_
|
||||
#ifndef FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_
|
||||
#define FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_
|
||||
|
||||
namespace SUBSYSTEM_ID {
|
||||
enum {
|
||||
@ -27,4 +27,4 @@ enum {
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_EVENTS_FWSUBSYSTEMIDRANGES_H_ */
|
||||
#endif /* FSFW_EVENTS_FWSUBSYSTEMIDRANGES_H_ */
|
||||
|
@ -139,7 +139,7 @@ void FailureIsolationBase::triggerEvent(Event event, uint32_t parameter1,
|
||||
uint32_t parameter2) {
|
||||
//With this mechanism, all events are disabled for a certain device.
|
||||
//That's not so good for visibility.
|
||||
if (isFdirDisabledForSeverity(EVENT::getSeverity(event))) {
|
||||
if (isFdirDisabledForSeverity(event::getSeverity(event))) {
|
||||
return;
|
||||
}
|
||||
EventMessage message(event, ownerId, parameter1, parameter2);
|
||||
@ -148,7 +148,7 @@ void FailureIsolationBase::triggerEvent(Event event, uint32_t parameter1,
|
||||
}
|
||||
|
||||
bool FailureIsolationBase::isFdirDisabledForSeverity(EventSeverity_t severity) {
|
||||
if ((owner != NULL) && (severity != SEVERITY::INFO)) {
|
||||
if ((owner != NULL) && (severity != severity::INFO)) {
|
||||
if (owner->getHealth() == HasHealthIF::EXTERNAL_CONTROL) {
|
||||
//External control disables handling of fault messages.
|
||||
return true;
|
||||
|
@ -14,9 +14,9 @@ class FailureIsolationBase: public HasReturnvaluesIF,
|
||||
public HasParametersIF {
|
||||
public:
|
||||
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_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_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_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||
|
||||
FailureIsolationBase(object_id_t owner,
|
||||
object_id_t parent = objects::NO_OBJECT,
|
||||
|
12
globalfunctions/CMakeLists.txt
Normal file
12
globalfunctions/CMakeLists.txt
Normal 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)
|
@ -1,4 +1,4 @@
|
||||
#include "../globalfunctions/Type.h"
|
||||
#include "Type.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
|
||||
Type::Type() :
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef TYPE_H_
|
||||
#define TYPE_H_
|
||||
#ifndef FSFW_GLOBALFUNCTIONS_TYPE_H_
|
||||
#define FSFW_GLOBALFUNCTIONS_TYPE_H_
|
||||
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
@ -97,4 +97,4 @@ struct PodTypeConversion<double> {
|
||||
static const Type::ActualType_t type = Type::DOUBLE;
|
||||
};
|
||||
|
||||
#endif /* TYPE_H_ */
|
||||
#endif /* FSFW_GLOBALFUNCTIONS_TYPE_H_ */
|
||||
|
4
globalfunctions/math/CMakeLists.txt
Normal file
4
globalfunctions/math/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
QuaternionOperations.cpp
|
||||
)
|
@ -21,13 +21,13 @@ public:
|
||||
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
|
||||
static const Event HEALTH_INFO = MAKE_EVENT(6, SEVERITY::INFO);
|
||||
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, SEVERITY::INFO);
|
||||
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, SEVERITY::LOW);
|
||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, SEVERITY::LOW); //!< Assembly overwrites health information of children to keep satellite alive.
|
||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, SEVERITY::MEDIUM); //!< Someone starts a recovery of a component (typically power-cycle). No parameters.
|
||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, SEVERITY::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1: 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, SEVERITY::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
|
||||
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
||||
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
||||
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep satellite alive.
|
||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically power-cycle). No parameters.
|
||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1: 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
|
||||
|
||||
virtual ~HasHealthIF() {
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_IPC_COMMANDMESSAGE_H_
|
||||
|
||||
#include "CommandMessageIF.h"
|
||||
|
||||
#include "MessageQueueMessage.h"
|
||||
#include "FwMessageTypes.h"
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef FSFW_IPC_MESSAGEQUEUESENDERIF_H_
|
||||
#define FSFW_IPC_MESSAGEQUEUESENDERIF_H_
|
||||
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../ipc/MessageQueueMessageIF.h"
|
||||
#include "MessageQueueIF.h"
|
||||
#include "MessageQueueMessageIF.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
|
||||
class MessageQueueSenderIF {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef FRAMEWORK_IPC_MUTEXFACTORY_H_
|
||||
#define FRAMEWORK_IPC_MUTEXFACTORY_H_
|
||||
#ifndef FSFW_IPC_MUTEXFACTORY_H_
|
||||
#define FSFW_IPC_MUTEXFACTORY_H_
|
||||
|
||||
#include "../ipc/MutexIF.h"
|
||||
#include "MutexIF.h"
|
||||
/**
|
||||
* Creates Mutex.
|
||||
* 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_ */
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "MessageQueueIF.h"
|
||||
#include "MessageQueueMessage.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
|
@ -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_ */
|
@ -18,14 +18,14 @@ public:
|
||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||
|
||||
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 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 MODE_TRANSITION_FAILED = MAKE_EVENT(3, SEVERITY::LOW);
|
||||
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 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 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 FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||
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 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 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_OFF = 0; //!< The device is powered off. The only command accepted in this mode is a mode change to on.
|
||||
|
@ -72,7 +72,7 @@ protected:
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
LocalPoolVar<T> poolVariable;
|
||||
LocalPoolVariable<T> poolVariable;
|
||||
};
|
||||
|
||||
#endif /* FSFW_MONITORING_MONITORBASE_H_ */
|
||||
|
@ -15,10 +15,10 @@ public:
|
||||
static const uint8_t LIMIT_TYPE_OBJECT = 128;
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_2;
|
||||
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_ABOVE_HIGH_LIMIT = MAKE_EVENT(3, SEVERITY::LOW);
|
||||
static const Event VALUE_OUT_OF_RANGE = MAKE_EVENT(4, 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_ABOVE_HIGH_LIMIT = MAKE_EVENT(3, 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 ReturnValue_t UNCHECKED = MAKE_RETURN_CODE(1);
|
||||
|
@ -2,6 +2,9 @@
|
||||
#include "TaskManagement.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
|
||||
tskKERNEL_VERSION_MAJOR > 8
|
||||
|
||||
BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() {
|
||||
handle = TaskManagement::getCurrentTaskHandle();
|
||||
if(handle == nullptr) {
|
||||
@ -97,3 +100,6 @@ uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR(
|
||||
higherPriorityTaskWoken);
|
||||
return notificationValue;
|
||||
}
|
||||
|
||||
#endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
|
||||
tskKERNEL_VERSION_MAJOR > 8 */
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
// todo: does not work for older FreeRTOS version, so we should
|
||||
// actually check whether tskKERNEL_VERSION_MAJOR is larger than.. 7 or 8 ?
|
||||
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
|
||||
tskKERNEL_VERSION_MAJOR > 8
|
||||
|
||||
/**
|
||||
* @brief Binary Semaphore implementation using the task notification value.
|
||||
@ -90,4 +90,7 @@ protected:
|
||||
TaskHandle_t handle;
|
||||
};
|
||||
|
||||
#endif /* (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
|
||||
tskKERNEL_VERSION_MAJOR > 8 */
|
||||
|
||||
#endif /* FSFW_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "../../osal/FreeRTOS/BinarySemaphore.h"
|
||||
#include "../../osal/FreeRTOS/TaskManagement.h"
|
||||
#include "BinarySemaphore.h"
|
||||
#include "TaskManagement.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
BinarySemaphore::BinarySemaphore() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
|
||||
#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
|
||||
#ifndef FSFW_OSAL_FREERTOS_BINARYSEMPAHORE_H_
|
||||
#define FSFW_OSAL_FREERTOS_BINARYSEMPAHORE_H_
|
||||
|
||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../../tasks/SemaphoreIF.h"
|
||||
@ -104,4 +104,4 @@ protected:
|
||||
SemaphoreHandle_t handle;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */
|
||||
#endif /* FSFW_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "Timekeeper.h"
|
||||
|
||||
#include "../../timemanager/Clock.h"
|
||||
#include "../../globalfunctions/timevalOperations.h"
|
||||
#include "../../osal/FreeRTOS/Timekeeper.h"
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
@ -1,7 +1,11 @@
|
||||
#include "../../osal/FreeRTOS/CountingSemaphUsingTask.h"
|
||||
#include "../../osal/FreeRTOS/TaskManagement.h"
|
||||
#include "CountingSemaphUsingTask.h"
|
||||
#include "TaskManagement.h"
|
||||
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
#if (tskKERNEL_VERSION_MAJOR == 8 && tskKERNEL_VERSION_MINOR > 2) || \
|
||||
tskKERNEL_VERSION_MAJOR > 8
|
||||
|
||||
CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount,
|
||||
uint8_t initCount): maxCount(maxCount) {
|
||||
if(initCount > maxCount) {
|
||||
@ -112,3 +116,5 @@ uint8_t CountingSemaphoreUsingTask::getSemaphoreCounterFromISR(
|
||||
uint8_t CountingSemaphoreUsingTask::getMaxCount() const {
|
||||
return maxCount;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,13 +1,14 @@
|
||||
#ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
|
||||
#define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
|
||||
#ifndef FSFW_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
|
||||
#define FSFW_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
|
||||
|
||||
#include "../../osal/FreeRTOS/CountingSemaphUsingTask.h"
|
||||
#include "CountingSemaphUsingTask.h"
|
||||
#include "../../tasks/SemaphoreIF.h"
|
||||
|
||||
extern "C" {
|
||||
#include <freertos/FreeRTOS.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
|
||||
@ -102,4 +103,7 @@ private:
|
||||
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_ */
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "../../osal/FreeRTOS/CountingSemaphore.h"
|
||||
#include "CountingSemaphore.h"
|
||||
#include "TaskManagement.h"
|
||||
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../../osal/FreeRTOS/TaskManagement.h"
|
||||
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef 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.
|
||||
|
@ -114,38 +114,24 @@ void FixedTimeslotTask::taskFunctionality() {
|
||||
intervalMs = this->pst.getIntervalToPreviousSlotMs();
|
||||
interval = pdMS_TO_TICKS(intervalMs);
|
||||
|
||||
checkMissedDeadline(xLastWakeTime, interval);
|
||||
|
||||
#if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || \
|
||||
tskKERNEL_VERSION_MAJOR > 10
|
||||
BaseType_t wasDelayed = xTaskDelayUntil(&xLastWakeTime, interval);
|
||||
if(wasDelayed == pdFALSE) {
|
||||
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() {
|
||||
if(deadlineMissedFunc != nullptr) {
|
||||
this->deadlineMissedFunc();
|
||||
|
@ -93,8 +93,6 @@ protected:
|
||||
*/
|
||||
void taskFunctionality(void);
|
||||
|
||||
void checkMissedDeadline(const TickType_t xLastWakeTime,
|
||||
const TickType_t interval);
|
||||
void handleMissedDeadline();
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_
|
||||
#define FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_
|
||||
#ifndef FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
|
||||
#define FSFW_OSAL_FREERTOS_FREERTOSTASKIF_H_
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
@ -8,6 +8,34 @@ class FreeRTOSTaskIF {
|
||||
public:
|
||||
virtual~ FreeRTOSTaskIF() {}
|
||||
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_ */
|
||||
|
@ -1,10 +1,11 @@
|
||||
#ifndef FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
|
||||
#define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
|
||||
|
||||
#include "TaskManagement.h"
|
||||
|
||||
#include "../../internalError/InternalErrorReporterIF.h"
|
||||
#include "../../ipc/MessageQueueIF.h"
|
||||
#include "../../ipc/MessageQueueMessageIF.h"
|
||||
#include "../../osal/FreeRTOS/TaskManagement.h"
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/queue.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "../../osal/FreeRTOS/Mutex.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "Mutex.h"
|
||||
|
||||
#include "../../ipc/MutexFactory.h"
|
||||
#include "../../osal/FreeRTOS/Mutex.h"
|
||||
|
||||
|
||||
//TODO: Different variant than the lazy loading in QueueFactory.
|
||||
//What's better and why? -> one is on heap the other on bss/data
|
||||
|
@ -80,10 +80,18 @@ void PeriodicTask::taskFunctionality() {
|
||||
object->performOperation();
|
||||
}
|
||||
|
||||
checkMissedDeadline(xLastWakeTime, xPeriod);
|
||||
|
||||
#if (tskKERNEL_VERSION_MAJOR == 10 && tskKERNEL_VERSION_MINOR >= 4) || \
|
||||
tskKERNEL_VERSION_MAJOR > 10
|
||||
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;
|
||||
}
|
||||
|
||||
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() {
|
||||
return handle;
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
|
||||
TaskHandle_t getTaskHandle() override;
|
||||
protected:
|
||||
|
||||
bool started;
|
||||
TaskHandle_t handle;
|
||||
|
||||
@ -118,8 +119,6 @@ protected:
|
||||
*/
|
||||
void taskFunctionality(void);
|
||||
|
||||
void checkMissedDeadline(const TickType_t xLastWakeTime,
|
||||
const TickType_t interval);
|
||||
void handleMissedDeadline();
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "MessageQueue.h"
|
||||
|
||||
#include "../../ipc/MessageQueueSenderIF.h"
|
||||
#include "../../ipc/QueueFactory.h"
|
||||
|
||||
#include "../../osal/FreeRTOS/MessageQueue.h"
|
||||
|
||||
|
||||
QueueFactory* QueueFactory::factoryInstance = nullptr;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "../../osal/FreeRTOS/TaskManagement.h"
|
||||
#include "TaskManagement.h"
|
||||
|
||||
void TaskManagement::vRequestContextSwitchFromTask() {
|
||||
vTaskDelay(0);
|
||||
@ -22,3 +22,4 @@ size_t TaskManagement::getTaskStackHighWatermark(
|
||||
TaskHandle_t task) {
|
||||
return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
|
||||
}
|
||||
|
||||
|
@ -3,17 +3,16 @@
|
||||
|
||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
extern "C" {
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
}
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* Architecture dependant portmacro.h function call.
|
||||
* Should be implemented in bsp.
|
||||
*/
|
||||
extern void vRequestContextSwitchFromISR();
|
||||
extern "C" void vRequestContextSwitchFromISR();
|
||||
|
||||
/*!
|
||||
* Used by functions to tell if they are being called from
|
||||
@ -27,26 +26,25 @@ enum class CallContext {
|
||||
};
|
||||
|
||||
|
||||
class TaskManagement {
|
||||
public:
|
||||
namespace TaskManagement {
|
||||
/**
|
||||
* @brief In this function, a function dependant on the portmacro.h header
|
||||
* 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
|
||||
* to unblock and a context switch is required.
|
||||
*/
|
||||
static void requestContextSwitch(CallContext callContext);
|
||||
void requestContextSwitch(CallContext callContext);
|
||||
|
||||
/**
|
||||
* If task preemption in FreeRTOS is disabled, a context switch
|
||||
* can be requested manually by calling this function.
|
||||
*/
|
||||
static void vRequestContextSwitchFromTask(void);
|
||||
void vRequestContextSwitchFromTask(void);
|
||||
|
||||
/**
|
||||
* @return The current task handle
|
||||
*/
|
||||
static TaskHandle_t getCurrentTaskHandle();
|
||||
TaskHandle_t getCurrentTaskHandle();
|
||||
|
||||
/**
|
||||
* Get returns the minimum amount of remaining stack space in words
|
||||
@ -57,8 +55,8 @@ public:
|
||||
* @return Smallest value of stack remaining since the task was started in
|
||||
* words.
|
||||
*/
|
||||
static size_t getTaskStackHighWatermark(
|
||||
TaskHandle_t task = nullptr);
|
||||
size_t getTaskStackHighWatermark(TaskHandle_t task = nullptr);
|
||||
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "../../osal/FreeRTOS/Timekeeper.h"
|
||||
#include "Timekeeper.h"
|
||||
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include <FreeRTOSConfig.h>
|
||||
|
||||
Timekeeper * Timekeeper::myinstance = nullptr;
|
||||
|
||||
|
@ -106,11 +106,6 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
uint32_t Clock::getUptimeSeconds() {
|
||||
timeval uptime = getUptime();
|
||||
return uptime.tv_sec;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
// do some magic with chrono (C++20!)
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include "FixedTimeslotTask.h"
|
||||
#include "Mutex.h"
|
||||
#include "../../osal/host/FixedTimeslotTask.h"
|
||||
|
||||
#include "../../ipc/MutexFactory.h"
|
||||
#include "../../osal/host/Mutex.h"
|
||||
#include "../../osal/host/FixedTimeslotTask.h"
|
||||
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../../tasks/ExecutableObjectIF.h"
|
||||
|
||||
@ -33,18 +35,18 @@ FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority,
|
||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||
ABOVE_NORMAL_PRIORITY_CLASS);
|
||||
if(result != 0) {
|
||||
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with "
|
||||
<< "code " << GetLastError() << std::endl;
|
||||
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
|
||||
<< GetLastError() << std::endl;
|
||||
}
|
||||
result = SetThreadPriority(
|
||||
reinterpret_cast<HANDLE>(mainThread.native_handle()),
|
||||
THREAD_PRIORITY_NORMAL);
|
||||
if(result != 0) {
|
||||
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with "
|
||||
"code " << GetLastError() << std::endl;
|
||||
sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
|
||||
<< GetLastError() << std::endl;
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
@ -58,8 +60,7 @@ FixedTimeslotTask::~FixedTimeslotTask(void) {
|
||||
}
|
||||
|
||||
void FixedTimeslotTask::taskEntryPoint(void* argument) {
|
||||
FixedTimeslotTask *originalTask(
|
||||
reinterpret_cast<FixedTimeslotTask*>(argument));
|
||||
FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(argument));
|
||||
|
||||
if (not originalTask->started) {
|
||||
// we have to suspend/block here until the task is started.
|
||||
@ -115,7 +116,8 @@ void FixedTimeslotTask::taskFunctionality() {
|
||||
if (not pollingSeqTable.slotFollowsImmediately()) {
|
||||
// we need to wait before executing the current slot
|
||||
// this gives us the time to wait:
|
||||
interval = chron_ms(this->pollingSeqTable.getIntervalToPreviousSlotMs());
|
||||
interval = chron_ms(
|
||||
this->pollingSeqTable.getIntervalToPreviousSlotMs());
|
||||
delayForInterval(¤tStartTime, interval);
|
||||
//TODO deadline missed check
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ protected:
|
||||
//!< Typedef for the List of objects.
|
||||
typedef std::vector<ExecutableObjectIF*> ObjectList;
|
||||
std::thread mainThread;
|
||||
std::atomic<bool> terminateThread = false;
|
||||
std::atomic<bool> terminateThread { false };
|
||||
|
||||
//! Polling sequence table which contains the object to execute
|
||||
//! and information like the timeslots and the passed execution step.
|
||||
|
@ -34,7 +34,7 @@ ReturnValue_t MessageQueue::sendToDefaultFrom(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());
|
||||
} else {
|
||||
return MessageQueueIF::NO_REPLY_PARTNER;
|
||||
@ -106,6 +106,7 @@ bool MessageQueue::isDefaultDestinationSet() const {
|
||||
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault) {
|
||||
message->setSender(sentFrom);
|
||||
if(message->getMessageSize() > message->getMaximumMessageSize()) {
|
||||
// Actually, this should never happen or an error will be emitted
|
||||
// in MessageQueueMessage.
|
||||
@ -126,7 +127,6 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||
// TODO: Better returnvalue
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
if(targetQueue->messageQueue.size() < targetQueue->messageDepth) {
|
||||
MutexHelper mutexLock(targetQueue->queueLock,
|
||||
MutexIF::TimeoutType::WAITING, 20);
|
||||
@ -145,7 +145,6 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
||||
else {
|
||||
return MessageQueueIF::FULL;
|
||||
}
|
||||
message->setSender(sentFrom);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -4,21 +4,18 @@
|
||||
Mutex::Mutex() {}
|
||||
|
||||
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||
if(timeoutMs == MutexIF::BLOCKING) {
|
||||
if(timeoutType == MutexIF::BLOCKING) {
|
||||
mutex.lock();
|
||||
locked = true;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
else if(timeoutMs == MutexIF::POLLING) {
|
||||
else if(timeoutType == MutexIF::POLLING) {
|
||||
if(mutex.try_lock()) {
|
||||
locked = true;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
}
|
||||
else if(timeoutMs > MutexIF::POLLING){
|
||||
auto chronoMs = std::chrono::milliseconds(timeoutMs);
|
||||
if(mutex.try_lock_for(chronoMs)) {
|
||||
locked = true;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
}
|
||||
@ -26,11 +23,7 @@ ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
|
||||
}
|
||||
|
||||
ReturnValue_t Mutex::unlockMutex() {
|
||||
if(not locked) {
|
||||
return MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX;
|
||||
}
|
||||
mutex.unlock();
|
||||
locked = false;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef FSFW_OSAL_HOST_MUTEX_H_
|
||||
#define FSFW_OSAL_HOST_MUTEX_H_
|
||||
#ifndef FSFW_OSAL_HOSTED_MUTEX_H_
|
||||
#define FSFW_OSAL_HOSTED_MUTEX_H_
|
||||
|
||||
#include "../../ipc/MutexIF.h"
|
||||
|
||||
@ -22,8 +22,8 @@ public:
|
||||
|
||||
std::timed_mutex* getMutexHandle();
|
||||
private:
|
||||
bool locked = false;
|
||||
//bool locked = false;
|
||||
std::timed_mutex mutex;
|
||||
};
|
||||
|
||||
#endif /* FSFW_OSAL_HOST_MUTEX_H_ */
|
||||
#endif /* FSFW_OSAL_HOSTED_MUTEX_H_ */
|
||||
|
@ -89,6 +89,10 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) {
|
||||
}
|
||||
|
||||
void PeriodicTask::taskFunctionality() {
|
||||
for (const auto& object: objectList) {
|
||||
object->initializeAfterTaskCreation();
|
||||
}
|
||||
|
||||
std::chrono::milliseconds periodChrono(static_cast<uint32_t>(period*1000));
|
||||
auto currentStartTime {
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
@ -96,10 +100,6 @@ void PeriodicTask::taskFunctionality() {
|
||||
};
|
||||
auto nextStartTime { currentStartTime };
|
||||
|
||||
for (const auto& object: objectList) {
|
||||
object->initializeAfterTaskCreation();
|
||||
}
|
||||
|
||||
/* Enter the loop that defines the task behavior. */
|
||||
for (;;) {
|
||||
if(terminateThread.load()) {
|
||||
@ -109,10 +109,6 @@ void PeriodicTask::taskFunctionality() {
|
||||
object->performOperation();
|
||||
}
|
||||
if(not delayForInterval(¤tStartTime, periodChrono)) {
|
||||
#ifdef DEBUG
|
||||
sif::warning << "PeriodicTask: " << taskName <<
|
||||
" missed deadline!\n" << std::flush;
|
||||
#endif
|
||||
if(deadlineMissedFunc != nullptr) {
|
||||
this->deadlineMissedFunc();
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ protected:
|
||||
//!< Typedef for the List of objects.
|
||||
typedef std::vector<ExecutableObjectIF*> ObjectList;
|
||||
std::thread mainThread;
|
||||
std::atomic<bool> terminateThread = false;
|
||||
std::atomic<bool> terminateThread { false };
|
||||
|
||||
/**
|
||||
* @brief This attribute holds a list of objects to be executed.
|
||||
|
@ -1,7 +1,11 @@
|
||||
|
||||
#include "MessageQueue.h"
|
||||
#include "../../ipc/QueueFactory.h"
|
||||
|
||||
#include "../../ipc/MessageQueueSenderIF.h"
|
||||
#include "../../ipc/MessageQueueMessageIF.h"
|
||||
#include "../../ipc/QueueFactory.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
QueueFactory* QueueFactory::factoryInstance = nullptr;
|
||||
|
@ -44,16 +44,8 @@ MessageQueueIF* QueueMapManager::getMessageQueue(
|
||||
return queueIter->second;
|
||||
}
|
||||
else {
|
||||
if(messageQueueId == MessageQueueIF::NO_QUEUE) {
|
||||
sif::error << "QueueMapManager::getQueueHandle: Configuration"
|
||||
<< " error, NO_QUEUE was passed to this function!"
|
||||
<< std::endl;
|
||||
}
|
||||
else {
|
||||
sif::warning << "QueueMapManager::getQueueHandle: The ID "
|
||||
<< messageQueueId << " does not exists in the map."
|
||||
<< std::endl;
|
||||
}
|
||||
sif::warning << "QueueMapManager::getQueueHandle: The ID " <<
|
||||
messageQueueId << " does not exists in the map" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "../../osal/linux/BinarySemaphore.h"
|
||||
#include "BinarySemaphore.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
extern "C" {
|
||||
|
25
osal/linux/CMakeLists.txt
Normal file
25
osal/linux/CMakeLists.txt
Normal 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
|
||||
)
|
@ -1,4 +1,3 @@
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../../timemanager/Clock.h"
|
||||
|
||||
@ -86,15 +85,16 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
uint32_t Clock::getUptimeSeconds() {
|
||||
//TODO This is not posix compatible and delivers only seconds precision
|
||||
struct sysinfo sysInfo;
|
||||
int result = sysinfo(&sysInfo);
|
||||
if(result != 0){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return sysInfo.uptime;
|
||||
}
|
||||
// Wait for new FSFW Clock function delivering seconds uptime.
|
||||
//uint32_t Clock::getUptimeSeconds() {
|
||||
// //TODO This is not posix compatible and delivers only seconds precision
|
||||
// struct sysinfo sysInfo;
|
||||
// int result = sysinfo(&sysInfo);
|
||||
// if(result != 0){
|
||||
// return HasReturnvaluesIF::RETURN_FAILED;
|
||||
// }
|
||||
// return sysInfo.uptime;
|
||||
//}
|
||||
|
||||
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
timeval uptime;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "../../osal/linux/Mutex.h"
|
||||
#include "Mutex.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../../timemanager/Clock.h"
|
||||
|
||||
|
@ -1,12 +1,8 @@
|
||||
#ifndef OS_LINUX_MUTEX_H_
|
||||
#define OS_LINUX_MUTEX_H_
|
||||
#ifndef FSFW_OSAL_LINUX_MUTEX_H_
|
||||
#define FSFW_OSAL_LINUX_MUTEX_H_
|
||||
|
||||
#include "../../ipc/MutexIF.h"
|
||||
|
||||
extern "C" {
|
||||
#include <pthread.h>
|
||||
}
|
||||
|
||||
|
||||
class Mutex : public MutexIF {
|
||||
public:
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "Mutex.h"
|
||||
|
||||
#include "../../ipc/MutexFactory.h"
|
||||
#include "../../osal/linux/Mutex.h"
|
||||
|
||||
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
|
||||
MutexFactory* MutexFactory::factoryInstance = new MutexFactory();
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "PosixThread.h"
|
||||
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../../osal/linux/PosixThread.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "../../tasks/SemaphoreFactory.h"
|
||||
#include "BinarySemaphore.h"
|
||||
#include "CountingSemaphore.h"
|
||||
|
||||
#include "../../tasks/SemaphoreFactory.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "../../osal/linux/FixedTimeslotTask.h"
|
||||
#include "../../osal/linux/PeriodicPosixTask.h"
|
||||
#include "FixedTimeslotTask.h"
|
||||
#include "PeriodicPosixTask.h"
|
||||
|
||||
#include "../../tasks/TaskFactory.h"
|
||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "Timer.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include <errno.h>
|
||||
#include "../../osal/linux/Timer.h"
|
||||
|
||||
|
||||
Timer::Timer() {
|
||||
sigevent sigEvent;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <rtems/score/todimpl.h>
|
||||
|
||||
uint16_t Clock::leapSeconds = 0;
|
||||
MutexIF* Clock::timeMutex = NULL;
|
||||
MutexIF* Clock::timeMutex = nullptr;
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void){
|
||||
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).
|
||||
//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
|
||||
_TOD_Set(&newTime,NULL);
|
||||
_TOD_Set(&newTime,nullptr);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
||||
|
||||
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
|
||||
//SHOULDDO: works not for dates in the past (might have less leap seconds)
|
||||
if (timeMutex == NULL) {
|
||||
if (timeMutex == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
@ -157,40 +157,34 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
|
||||
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
MutexHelper helper(timeMutex);
|
||||
|
||||
|
||||
leapSeconds = leapSeconds_;
|
||||
|
||||
result = timeMutex->unlockMutex();
|
||||
return result;
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
||||
if(timeMutex==NULL){
|
||||
if(timeMutex==nullptr){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
MutexHelper helper(timeMutex);
|
||||
|
||||
*leapSeconds_ = leapSeconds;
|
||||
|
||||
result = timeMutex->unlockMutex();
|
||||
return result;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::checkOrCreateClockMutex(){
|
||||
if(timeMutex==NULL){
|
||||
if(timeMutex==nullptr){
|
||||
MutexFactory* mutexFactory = MutexFactory::instance();
|
||||
if (mutexFactory == NULL) {
|
||||
if (mutexFactory == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
timeMutex = mutexFactory->createMutex();
|
||||
if (timeMutex == NULL) {
|
||||
if (timeMutex == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const {
|
||||
}
|
||||
|
||||
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,
|
||||
size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
|
@ -12,8 +12,8 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
|
||||
// return INVALID_WORKSPACE_ADDRESS;
|
||||
case INTERNAL_ERROR_TOO_LITTLE_WORKSPACE:
|
||||
return TOO_LITTLE_WORKSPACE;
|
||||
case INTERNAL_ERROR_WORKSPACE_ALLOCATION:
|
||||
return WORKSPACE_ALLOCATION;
|
||||
// case INTERNAL_ERROR_WORKSPACE_ALLOCATION:
|
||||
// return WORKSPACE_ALLOCATION;
|
||||
// case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL:
|
||||
// return INTERRUPT_STACK_TOO_SMALL;
|
||||
case INTERNAL_ERROR_THREAD_EXITTED:
|
||||
|
@ -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();
|
||||
}
|
@ -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_ */
|
@ -1,14 +1,15 @@
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../../objectmanager/ObjectManagerIF.h"
|
||||
#include "MessageQueue.h"
|
||||
#include "RtemsBasic.h"
|
||||
#include <cstring>
|
||||
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_status_code status = rtems_message_queue_create(name, message_depth,
|
||||
max_message_size, 0, &(this->id));
|
||||
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:"
|
||||
<< (uint32_t) status << std::endl;
|
||||
this->id = 0;
|
||||
@ -20,15 +21,15 @@ MessageQueue::~MessageQueue() {
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage* message, bool ignoreFault) {
|
||||
MessageQueueMessageIF* message, bool 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());
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
|
||||
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
|
||||
if (this->lastPartner != 0) {
|
||||
return sendMessage(this->lastPartner, message, this->getId());
|
||||
} 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) {
|
||||
ReturnValue_t status = this->receiveMessage(message);
|
||||
*receivedFrom = this->lastPartner;
|
||||
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,
|
||||
message->getBuffer(), &(message->messageSize),
|
||||
message->getBuffer(),&size,
|
||||
RTEMS_NO_WAIT, 1);
|
||||
if (status == RTEMS_SUCCESSFUL) {
|
||||
message->setMessageSize(size);
|
||||
this->lastPartner = message->getSender();
|
||||
//Check size of incoming message.
|
||||
if (message->messageSize < message->getMinimumMessageSize()) {
|
||||
if (message->getMessageSize() < message->getMinimumMessageSize()) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
} else {
|
||||
//No message was received. Keep lastPartner anyway, I might send something later.
|
||||
//But still, delete packet content.
|
||||
memset(message->getData(), 0, message->MAX_DATA_SIZE);
|
||||
memset(message->getData(), 0, message->getMaximumMessageSize());
|
||||
}
|
||||
return convertReturnCode(status);
|
||||
}
|
||||
@ -79,20 +82,20 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,
|
||||
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault) {
|
||||
|
||||
message->setSender(sentFrom);
|
||||
rtems_status_code result = rtems_message_queue_send(sendTo,
|
||||
message->getBuffer(), message->messageSize);
|
||||
message->getBuffer(), message->getMessageSize());
|
||||
|
||||
//TODO: Check if we're in ISR.
|
||||
if (result != RTEMS_SUCCESSFUL && !ignoreFault) {
|
||||
if (internalErrorReporter == NULL) {
|
||||
if (internalErrorReporter == nullptr) {
|
||||
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||
objects::INTERNAL_ERROR_REPORTER);
|
||||
}
|
||||
if (internalErrorReporter != NULL) {
|
||||
if (internalErrorReporter != nullptr) {
|
||||
internalErrorReporter->queueMessageNotSent();
|
||||
}
|
||||
}
|
||||
@ -105,7 +108,7 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message,
|
||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
||||
}
|
||||
|
@ -1,14 +1,5 @@
|
||||
/**
|
||||
* @file 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_
|
||||
#ifndef FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
||||
#define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
||||
|
||||
#include "../../internalError/InternalErrorReporterIF.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.
|
||||
*/
|
||||
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.
|
||||
* @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.
|
||||
* @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.
|
||||
* @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.
|
||||
* @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.
|
||||
@ -84,7 +75,7 @@ public:
|
||||
* @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.
|
||||
*/
|
||||
ReturnValue_t receiveMessage(MessageQueueMessage* message,
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t *receivedFrom);
|
||||
|
||||
/**
|
||||
@ -95,7 +86,7 @@ public:
|
||||
* message's content is cleared and the function returns immediately.
|
||||
* @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.
|
||||
* @param count The number of flushed messages.
|
||||
@ -121,7 +112,7 @@ public:
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
* \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.
|
||||
* 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.
|
||||
*/
|
||||
@ -178,4 +169,4 @@ private:
|
||||
static ReturnValue_t convertReturnCode(rtems_status_code inValue);
|
||||
};
|
||||
|
||||
#endif /* MESSAGEQUEUE_H_ */
|
||||
#endif /* FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_ */
|
||||
|
@ -30,7 +30,7 @@ ReturnValue_t MultiObjectTask::startTask() {
|
||||
rtems_status_code status = rtems_task_start(id, MultiObjectTask::taskEntryPoint,
|
||||
rtems_task_argument((void *) this));
|
||||
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;
|
||||
}
|
||||
switch(status){
|
||||
@ -63,8 +63,8 @@ void MultiObjectTask::taskFunctionality() {
|
||||
char nameSpace[8] = { 0 };
|
||||
char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace),
|
||||
nameSpace);
|
||||
error << "ObjectTask: " << ptr << " Deadline missed." << std::endl;
|
||||
if (this->deadlineMissedFunc != NULL) {
|
||||
sif::error << "ObjectTask: " << ptr << " Deadline missed." << std::endl;
|
||||
if (this->deadlineMissedFunc != nullptr) {
|
||||
this->deadlineMissedFunc();
|
||||
}
|
||||
}
|
||||
@ -74,12 +74,13 @@ void MultiObjectTask::taskFunctionality() {
|
||||
ReturnValue_t MultiObjectTask::addComponent(object_id_t object) {
|
||||
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
|
||||
object);
|
||||
if (newObject == NULL) {
|
||||
if (newObject == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
objectList.push_back(newObject);
|
||||
ReturnValue_t result = newObject->initializeAfterTaskCreation();
|
||||
return result;
|
||||
newObject->setTaskIF(this);
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
uint32_t MultiObjectTask::getPeriodMs() const {
|
||||
|
@ -1,11 +1,5 @@
|
||||
/**
|
||||
* @file MultiObjectTask.h
|
||||
* @brief This file defines the MultiObjectTask class.
|
||||
* @date 30.01.2014
|
||||
* @author baetz
|
||||
*/
|
||||
#ifndef MULTIOBJECTTASK_H_
|
||||
#define MULTIOBJECTTASK_H_
|
||||
#ifndef FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_
|
||||
#define FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_
|
||||
|
||||
#include "../../objectmanager/ObjectManagerIF.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
|
||||
* multiple objects that implement the ExecutableObjectIF interface. The objects must be
|
||||
* added prior to starting the task.
|
||||
*
|
||||
* @author baetz
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
class MultiObjectTask: public TaskBase, public PeriodicTaskIF {
|
||||
@ -63,11 +57,11 @@ public:
|
||||
* @param object Id of the object to add.
|
||||
* @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:
|
||||
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.
|
||||
/**
|
||||
@ -86,7 +80,7 @@ protected:
|
||||
/**
|
||||
* @brief The pointer to the deadline-missed function.
|
||||
* @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
|
||||
* of the periodic task.
|
||||
*/
|
||||
@ -110,4 +104,4 @@ protected:
|
||||
void taskFunctionality(void);
|
||||
};
|
||||
|
||||
#endif /* MULTIOBJECTTASK_H_ */
|
||||
#endif /* FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_ */
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "Mutex.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
const uint32_t MutexIF::NO_TIMEOUT = RTEMS_NO_TIMEOUT;
|
||||
uint8_t Mutex::count = 0;
|
||||
|
||||
Mutex::Mutex() :
|
||||
@ -11,7 +10,7 @@ Mutex::Mutex() :
|
||||
RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0,
|
||||
&mutexId);
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -19,13 +18,28 @@ Mutex::Mutex() :
|
||||
Mutex::~Mutex() {
|
||||
rtems_status_code status = rtems_semaphore_delete(mutexId);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
error << "Mutex: deletion for id " << mutexId
|
||||
sif::error << "Mutex: deletion for id " << mutexId
|
||||
<< " failed with " << status << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
|
||||
rtems_status_code status = rtems_semaphore_obtain(mutexId, RTEMS_WAIT, timeoutMs);
|
||||
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType =
|
||||
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){
|
||||
case RTEMS_SUCCESSFUL:
|
||||
//semaphore obtained successfully
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef OS_RTEMS_MUTEX_H_
|
||||
#define OS_RTEMS_MUTEX_H_
|
||||
#ifndef FSFW_OSAL_RTEMS_MUTEX_H_
|
||||
#define FSFW_OSAL_RTEMS_MUTEX_H_
|
||||
|
||||
#include "../../ipc/MutexIF.h"
|
||||
#include "RtemsBasic.h"
|
||||
@ -8,11 +8,11 @@ class Mutex : public MutexIF {
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
ReturnValue_t lockMutex(uint32_t timeoutMs);
|
||||
ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs = 0);
|
||||
ReturnValue_t unlockMutex();
|
||||
private:
|
||||
rtems_id mutexId;
|
||||
static uint8_t count;
|
||||
};
|
||||
|
||||
#endif /* OS_RTEMS_MUTEX_H_ */
|
||||
#endif /* FSFW_OSAL_RTEMS_MUTEX_H_ */
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "Mutex.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() {
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include "../../tasks/FixedSequenceSlot.h"
|
||||
#include "../../objectmanager/SystemObjectIF.h"
|
||||
#include "../../osal/rtems/PollingTask.h"
|
||||
#include "../../osal/rtems/RtemsBasic.h"
|
||||
#include "../../objectmanager/ObjectManagerIF.h"
|
||||
#include "PollingTask.h"
|
||||
#include "RtemsBasic.h"
|
||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include <rtems/bspIo.h>
|
||||
@ -34,14 +35,14 @@ rtems_task PollingTask::taskEntryPoint(rtems_task_argument argument) {
|
||||
PollingTask *originalTask(reinterpret_cast<PollingTask*>(argument));
|
||||
//The task's functionality is called.
|
||||
originalTask->taskFunctionality();
|
||||
debug << "Polling task " << originalTask->getId()
|
||||
sif::debug << "Polling task " << originalTask->getId()
|
||||
<< " returned from taskFunctionality." << std::endl;
|
||||
}
|
||||
|
||||
void PollingTask::missedDeadlineCounter() {
|
||||
PollingTask::deadlineMissedCount++;
|
||||
if (PollingTask::deadlineMissedCount % 10 == 0) {
|
||||
error << "PST missed " << PollingTask::deadlineMissedCount
|
||||
sif::error << "PST missed " << PollingTask::deadlineMissedCount
|
||||
<< " deadlines." << std::endl;
|
||||
}
|
||||
}
|
||||
@ -50,7 +51,7 @@ ReturnValue_t PollingTask::startTask() {
|
||||
rtems_status_code status = rtems_task_start(id, PollingTask::taskEntryPoint,
|
||||
rtems_task_argument((void *) this));
|
||||
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;
|
||||
}
|
||||
switch(status){
|
||||
@ -68,8 +69,9 @@ ReturnValue_t PollingTask::startTask() {
|
||||
|
||||
ReturnValue_t PollingTask::addSlot(object_id_t componentId,
|
||||
uint32_t slotTimeMs, int8_t executionStep) {
|
||||
if (objectManager->get<ExecutableObjectIF>(componentId) != nullptr) {
|
||||
pst.addSlot(componentId, slotTimeMs, executionStep, this);
|
||||
ExecutableObjectIF* object = objectManager->get<ExecutableObjectIF>(componentId);
|
||||
if (object != nullptr) {
|
||||
pst.addSlot(componentId, slotTimeMs, executionStep, object, this);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -82,7 +84,7 @@ uint32_t PollingTask::getPeriodMs() const {
|
||||
return pst.getLengthMs();
|
||||
}
|
||||
|
||||
ReturnValue_t PollingTask::checkAndInitializeSequence() const {
|
||||
ReturnValue_t PollingTask::checkSequence() const {
|
||||
return pst.checkSequence();
|
||||
}
|
||||
|
||||
@ -90,11 +92,10 @@ ReturnValue_t PollingTask::checkAndInitializeSequence() const {
|
||||
|
||||
void PollingTask::taskFunctionality() {
|
||||
// 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.
|
||||
rtems_interval interval = RtemsBasic::convertMsToTicks(
|
||||
(*it)->pollingTimeMs);
|
||||
rtems_interval interval = RtemsBasic::convertMsToTicks(it->pollingTimeMs);
|
||||
TaskBase::setAndStartPeriod(interval,&periodId);
|
||||
//The task's "infinite" inner loop is entered.
|
||||
while (1) {
|
||||
@ -107,7 +108,7 @@ void PollingTask::taskFunctionality() {
|
||||
//If the deadline was missed, the deadlineMissedFunc is called.
|
||||
rtems_status_code status = TaskBase::restartPeriod(interval,periodId);
|
||||
if (status == RTEMS_TIMEOUT) {
|
||||
if (this->deadlineMissedFunc != NULL) {
|
||||
if (this->deadlineMissedFunc != nullptr) {
|
||||
this->deadlineMissedFunc();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef POLLINGTASK_H_
|
||||
#define POLLINGTASK_H_
|
||||
#ifndef FSFW_OSAL_RTEMS_POLLINGTASK_H_
|
||||
#define FSFW_OSAL_RTEMS_POLLINGTASK_H_
|
||||
|
||||
#include "../../tasks/FixedSlotSequence.h"
|
||||
#include "../../tasks/FixedTimeslotTaskIF.h"
|
||||
@ -42,7 +42,7 @@ class PollingTask: public TaskBase, public FixedTimeslotTaskIF {
|
||||
|
||||
uint32_t getPeriodMs() const;
|
||||
|
||||
ReturnValue_t checkAndInitializeSequence() const;
|
||||
ReturnValue_t checkSequence() const;
|
||||
|
||||
ReturnValue_t sleepFor(uint32_t ms);
|
||||
protected:
|
||||
@ -82,4 +82,4 @@ protected:
|
||||
void taskFunctionality( void );
|
||||
};
|
||||
|
||||
#endif /* POLLINGTASK_H_ */
|
||||
#endif /* FSFW_OSAL_RTEMS_POLLINGTASK_H_ */
|
||||
|
@ -1,16 +1,17 @@
|
||||
#include "../../ipc/QueueFactory.h"
|
||||
#include "../../ipc/MessageQueueSenderIF.h"
|
||||
#include "MessageQueue.h"
|
||||
#include "RtemsBasic.h"
|
||||
|
||||
QueueFactory* QueueFactory::factoryInstance = NULL;
|
||||
QueueFactory* QueueFactory::factoryInstance = nullptr;
|
||||
|
||||
|
||||
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
|
||||
message->setSender(sentFrom);
|
||||
rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(),
|
||||
message->messageSize);
|
||||
message->getMessageSize());
|
||||
switch(result){
|
||||
case RTEMS_SUCCESSFUL:
|
||||
//message sent successfully
|
||||
@ -37,7 +38,7 @@ ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
||||
}
|
||||
|
||||
QueueFactory* QueueFactory::instance() {
|
||||
if (factoryInstance == NULL) {
|
||||
if (factoryInstance == nullptr) {
|
||||
factoryInstance = new QueueFactory;
|
||||
}
|
||||
return factoryInstance;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef OS_RTEMS_RTEMSBASIC_H_
|
||||
#define OS_RTEMS_RTEMSBASIC_H_
|
||||
#ifndef FSFW_OSAL_RTEMS_RTEMSBASIC_H_
|
||||
#define FSFW_OSAL_RTEMS_RTEMSBASIC_H_
|
||||
|
||||
#include "../../returnvalues/HasReturnvaluesIF.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
Loading…
Reference in New Issue
Block a user