Merge branch 'mueller/timeman-update' of https://egit.irs.uni-stuttgart.de/KSat/fsfw into mueller/timeman-update
This commit is contained in:
commit
5a4f453aaa
114
CMakeLists.txt
114
CMakeLists.txt
@ -3,30 +3,42 @@ 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")
|
||||
if(NOT OS_FSFW)
|
||||
message(STATUS "No OS for FSFW via OS_FSFW set. Assuming host OS")
|
||||
# Assume host OS and autodetermine from OS_FSFW
|
||||
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()
|
||||
|
||||
endif()
|
||||
|
||||
message(STATUS "Compiling FSFW for the ${OS_FSFW_NAME} operating system")
|
||||
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")
|
||||
target_link_libraries(${LIB_FSFW_NAME} ${LIB_OS_NAME})
|
||||
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)
|
||||
@ -36,8 +48,14 @@ add_subdirectory(action)
|
||||
add_subdirectory(container)
|
||||
add_subdirectory(controller)
|
||||
add_subdirectory(coordinates)
|
||||
add_subdirectory(datalinklayer)
|
||||
|
||||
if(FSFW_USE_DATALINKLAYER)
|
||||
add_subdirectory(datalinklayer)
|
||||
endif()
|
||||
|
||||
add_subdirectory(datapool)
|
||||
add_subdirectory(datapoollocal)
|
||||
add_subdirectory(housekeeping)
|
||||
add_subdirectory(devicehandlers)
|
||||
add_subdirectory(events)
|
||||
add_subdirectory(fdir)
|
||||
@ -55,7 +73,7 @@ add_subdirectory(power)
|
||||
add_subdirectory(pus)
|
||||
|
||||
if(FSFW_USE_RMAP)
|
||||
add_subdirectory(rmap)
|
||||
add_subdirectory(rmap)
|
||||
endif()
|
||||
|
||||
add_subdirectory(serialize)
|
||||
@ -73,13 +91,53 @@ 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)
|
||||
message(WARNING "Flight Software Framework configuration path not set!")
|
||||
message(WARNING "Setting default configuration!")
|
||||
add_subdirectory(defaultcfg/fsfwconfig)
|
||||
endif()
|
||||
|
||||
# FSFW might be part of a possibly complicated folder structure, so we
|
||||
# extract the absolute path of the fsfwconfig folder.
|
||||
if(IS_ABSOLUTE ${FSFW_CONFIG_PATH})
|
||||
set(FSFW_CONFIG_PATH_ABSOLUTE ${FSFW_CONFIG_PATH})
|
||||
else()
|
||||
get_filename_component(FSFW_CONFIG_PATH_ABSOLUTE
|
||||
${FSFW_CONFIG_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(WARNING_FLAGS
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wshadow=local
|
||||
-Wimplicit-fallthrough=1
|
||||
-Wno-unused-parameter
|
||||
-Wno-psabi
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(COMPILER_FLAGS "/permissive-")
|
||||
endif()
|
||||
|
||||
# Required include paths to compile the FSFW
|
||||
target_include_directories(${LIB_FSFW_NAME}
|
||||
INTERFACE
|
||||
${FSFW_CONFIG_PATH}
|
||||
target_include_directories(${LIB_FSFW_NAME} INTERFACE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${FSFW_CONFIG_PATH_ABSOLUTE}
|
||||
)
|
||||
|
||||
# Includes path required to compile FSFW itself as well
|
||||
# We assume that the fsfwconfig folder uses include relative to the project
|
||||
# root here!
|
||||
target_include_directories(${LIB_FSFW_NAME} PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${FSFW_CONFIG_PATH_ABSOLUTE}
|
||||
)
|
||||
|
||||
# Machine specific options can be set with the ABI_FLAGS variable.
|
||||
target_compile_options(${LIB_FSFW_NAME} PRIVATE
|
||||
${WARNING_FLAGS}
|
||||
${COMPILER_FLAGS}
|
||||
${ABI_FLAGS}
|
||||
)
|
||||
|
@ -1,7 +1,9 @@
|
||||
#ifndef SGP4PROPAGATOR_H_
|
||||
#define SGP4PROPAGATOR_H_
|
||||
|
||||
#ifndef WIN32
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "../contrib/sgp4/sgp4unit.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
|
@ -1,11 +1,6 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
ControllerSet.cpp
|
||||
DataPool.cpp
|
||||
DataPoolAdmin.cpp
|
||||
DataPoolParameterWrapper.cpp
|
||||
DataSet.cpp
|
||||
HkSwitchHelper.cpp
|
||||
PoolDataSetBase.cpp
|
||||
PoolEntry.cpp
|
||||
PoolRawAccess.cpp
|
||||
)
|
@ -59,6 +59,11 @@ uint16_t PoolDataSetBase::getFillCount() const {
|
||||
|
||||
ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
if(registeredVariables[count] == nullptr) {
|
||||
// configuration error.
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
// These checks are often performed by the respective
|
||||
// variable implementation too, but I guess a double check does not hurt.
|
||||
if (registeredVariables[count]->getReadWriteMode() !=
|
||||
|
8
datapoollocal/CMakeLists.txt
Normal file
8
datapoollocal/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
LocalDataPoolManager.cpp
|
||||
LocalDataSet.cpp
|
||||
LocalPoolDataSetBase.cpp
|
||||
LocalPoolObjectBase.cpp
|
||||
SharedLocalDataSet.cpp
|
||||
)
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -15,12 +15,6 @@
|
||||
//! Can be used to enable additional debugging printouts for developing the FSFW
|
||||
#define FSFW_PRINT_VERBOSITY_LEVEL 0
|
||||
|
||||
//! Defines the FIFO depth of each commanding service base which
|
||||
//! also determines how many commands a CSB service can handle in one cycle
|
||||
//! simulataneously. This will increase the required RAM for
|
||||
//! each CSB service !
|
||||
#define FSFW_CSB_FIFO_DEPTH 6
|
||||
|
||||
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
|
||||
//! additional output which requires the translation files translateObjects
|
||||
//! and translateEvents (and their compiled source files)
|
||||
@ -29,8 +23,8 @@
|
||||
#if FSFW_OBJ_EVENT_TRANSLATION == 1
|
||||
//! Specify whether info events are printed too.
|
||||
#define FSFW_DEBUG_INFO 1
|
||||
#include <translateObjects.h>
|
||||
#include <translateEvents.h>
|
||||
#include "objects/translateObjects.h"
|
||||
#include "events/translateEvents.h"
|
||||
#else
|
||||
#endif
|
||||
|
||||
@ -50,6 +44,12 @@ static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 8;
|
||||
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
|
||||
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
|
||||
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
||||
|
||||
//! Defines the FIFO depth of each commanding service base which
|
||||
//! also determines how many commands a CSB service can handle in one cycle
|
||||
//! simulataneously. This will increase the required RAM for
|
||||
//! each CSB service !
|
||||
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
#include "OBSWVersion.h"
|
||||
|
||||
#include "objects/systemObjectList.h"
|
||||
#include "events/subsystemIdRanges.h"
|
||||
#include "returnvalues/classIds.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace config {
|
||||
#endif
|
||||
|
@ -1,6 +1,5 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
Event.cpp
|
||||
EventManager.cpp
|
||||
EventMessage.cpp
|
||||
)
|
||||
|
@ -2,7 +2,12 @@
|
||||
#define TIMEVALOPERATIONS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
timeval& operator+=(timeval& lhs, const timeval& rhs);
|
||||
|
||||
|
5
housekeeping/CMakeLists.txt
Normal file
5
housekeeping/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
HousekeepingMessage.cpp
|
||||
PeriodicHousekeepingHelper.cpp
|
||||
)
|
@ -1,4 +1,4 @@
|
||||
#include "../ipc/CommandMessageCleaner.h"
|
||||
#include "CommandMessageCleaner.h"
|
||||
|
||||
#include "../devicehandlers/DeviceHandlerMessage.h"
|
||||
#include "../health/HealthMessage.h"
|
||||
@ -7,11 +7,12 @@
|
||||
#include "../monitoring/MonitoringMessage.h"
|
||||
#include "../subsystem/modes/ModeSequenceMessage.h"
|
||||
#include "../tmstorage/TmStoreMessage.h"
|
||||
#include "../housekeeping/HousekeepingMessage.h"
|
||||
#include "../parameters/ParameterMessage.h"
|
||||
|
||||
void CommandMessageCleaner::clearCommandMessage(CommandMessage* message) {
|
||||
switch(message->getMessageType()){
|
||||
case messagetypes::MODE_COMMAND:
|
||||
case messagetypes::MODE_COMMAND:
|
||||
ModeMessage::clear(message);
|
||||
break;
|
||||
case messagetypes::HEALTH_COMMAND:
|
||||
@ -38,6 +39,9 @@ void CommandMessageCleaner::clearCommandMessage(CommandMessage* message) {
|
||||
case messagetypes::PARAMETER:
|
||||
ParameterMessage::clear(message);
|
||||
break;
|
||||
case messagetypes::HOUSEKEEPING:
|
||||
HousekeepingMessage::clear(message);
|
||||
break;
|
||||
default:
|
||||
messagetypes::clearMissionMessage(message);
|
||||
break;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_
|
||||
#define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_
|
||||
|
||||
#include <fsfw/ipc/messageQueueDefinitions.h>
|
||||
#include "messageQueueDefinitions.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef FRAMEWORK_IPC_MUTEXFACTORY_H_
|
||||
#define FRAMEWORK_IPC_MUTEXFACTORY_H_
|
||||
#ifndef FSFW_IPC_MUTEXFACTORY_H_
|
||||
#define FSFW_IPC_MUTEXFACTORY_H_
|
||||
|
||||
#include "MutexIF.h"
|
||||
/**
|
||||
@ -31,4 +31,4 @@ private:
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_IPC_MUTEXFACTORY_H_ */
|
||||
#endif /* FSFW_IPC_MUTEXFACTORY_H_ */
|
||||
|
@ -16,8 +16,8 @@ public:
|
||||
<< timeoutMs << " milliseconds!" << std::endl;
|
||||
}
|
||||
else if(status != HasReturnvaluesIF::RETURN_OK){
|
||||
sif::error << "MutexHelper: Lock of Mutex failed with code " <<
|
||||
status << std::endl;
|
||||
sif::error << "MutexHelper: Lock of Mutex failed with code "
|
||||
<< status << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ protected:
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
LocalPoolVar<T> poolVariable;
|
||||
LocalPoolVariable<T> poolVariable;
|
||||
};
|
||||
|
||||
#endif /* FSFW_MONITORING_MONITORBASE_H_ */
|
||||
|
@ -22,9 +22,23 @@
|
||||
#else
|
||||
#error "Can't decide which end is which!"
|
||||
#endif
|
||||
#else
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
|
||||
#define BYTE_ORDER_SYSTEM LITTLE_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER_SYSTEM BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#error __BYTE_ORDER__ not defined
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
30
osal/FreeRTOS/CMakeLists.txt
Normal file
30
osal/FreeRTOS/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
Clock.cpp
|
||||
FixedTimeslotTask.cpp
|
||||
BinarySemaphore.cpp
|
||||
BinSemaphUsingTask.cpp
|
||||
CountingSemaphore.cpp
|
||||
CountingSemaphUsingTask.cpp
|
||||
MessageQueue.cpp
|
||||
Mutex.cpp
|
||||
MutexFactory.cpp
|
||||
PeriodicTask.cpp
|
||||
QueueFactory.cpp
|
||||
SemaphoreFactory.cpp
|
||||
TaskFactory.cpp
|
||||
Timekeeper.cpp
|
||||
TaskManagement.cpp
|
||||
)
|
||||
|
||||
# FreeRTOS is required to link the FSFW now. It is recommended to compile
|
||||
# FreeRTOS as a static library and set LIB_OS_NAME to the target name of the
|
||||
# library.
|
||||
if(NOT LIB_OS_NAME)
|
||||
message(FATAL_ERROR
|
||||
"FreeRTOS needs to be linked as a target and "
|
||||
"LIB_OS_NAME needs to be set to the target"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${LIB_FSWFW_NAME} ${LIB_OS_NAME})
|
@ -13,9 +13,9 @@ target_sources(${LIB_FSFW_NAME}
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
add_definitions(-pthread)
|
||||
target_link_libraries(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
rt
|
||||
pthread
|
||||
)
|
||||
endif()
|
@ -1,4 +1,4 @@
|
||||
#include "../../osal/linux/BinarySemaphore.h"
|
||||
#include "BinarySemaphore.h"
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
extern "C" {
|
||||
|
@ -76,25 +76,25 @@ timeval Clock::getUptime() {
|
||||
|
||||
ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
//TODO This is not posix compatible and delivers only seconds precision
|
||||
// is the OS not called Linux?
|
||||
//Linux specific file read but more precise
|
||||
// Linux specific file read but more precise.
|
||||
double uptimeSeconds;
|
||||
if(std::ifstream("/proc/uptime",std::ios::in) >> uptimeSeconds){
|
||||
uptime->tv_sec = uptimeSeconds;
|
||||
uptime->tv_usec = uptimeSeconds *(double) 1e6 - (uptime->tv_sec *1e6);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
//TODO This is not posix compatible and delivers only seconds precision
|
||||
// I suggest this is moved into another clock function which will
|
||||
// deliver second precision later.
|
||||
// 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;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
//}
|
||||
|
||||
ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
timeval uptime;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "../../objectmanager/ObjectManagerIF.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <fcntl.h> /* For O_* constants */
|
||||
#include <sys/stat.h> /* For mode constants */
|
||||
#include <cstring>
|
||||
|
@ -1,10 +1,9 @@
|
||||
#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"
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
class Mutex : public MutexIF {
|
||||
public:
|
||||
Mutex();
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "../../ipc/MutexFactory.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#include "../../ipc/MutexFactory.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 "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "PosixThread.h"
|
||||
|
||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
|
||||
@ -149,8 +151,10 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
|
||||
|
||||
status = pthread_attr_setstack(&attributes, stackPointer, stackSize);
|
||||
if(status != 0){
|
||||
sif::error << "Posix Thread attribute setStack failed with: " <<
|
||||
strerror(status) << std::endl;
|
||||
sif::error << "PosixThread::createTask: pthread_attr_setstack "
|
||||
" failed with: " << strerror(status) << std::endl;
|
||||
sif::error << "Make sure the specified stack size is valid and is "
|
||||
"larger than the minimum allowed stack size." << std::endl;
|
||||
}
|
||||
|
||||
status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED);
|
||||
|
@ -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 "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 "Timer.h"
|
||||
|
||||
|
||||
Timer::Timer() {
|
||||
sigevent sigEvent;
|
||||
|
@ -119,7 +119,7 @@ void TcWinUdpPollingTask::setTimeout(double timeoutSeconds) {
|
||||
int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO,
|
||||
reinterpret_cast<const char*>(&timeoutMs), sizeof(DWORD));
|
||||
if(result == -1) {
|
||||
sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting "
|
||||
sif::error << "TcWinUdpPollingTask::TcSocketPollingTask: Setting "
|
||||
"receive timeout failed with " << strerror(errno) << std::endl;
|
||||
}
|
||||
}
|
||||
@ -128,17 +128,22 @@ void TcWinUdpPollingTask::handleReadError() {
|
||||
int error = WSAGetLastError();
|
||||
switch(error) {
|
||||
case(WSANOTINITIALISED): {
|
||||
sif::info << "TmTcWinUdpBridge::handleReadError: WSANOTINITIALISED: "
|
||||
sif::info << "TcWinUdpPollingTask::handleReadError: WSANOTINITIALISED: "
|
||||
<< "WSAStartup(...) call " << "necessary" << std::endl;
|
||||
break;
|
||||
}
|
||||
case(WSAEFAULT): {
|
||||
sif::info << "TmTcWinUdpBridge::handleReadError: WSADEFAULT: "
|
||||
sif::info << "TcWinUdpPollingTask::handleReadError: WSADEFAULT: "
|
||||
<< "Bad address " << std::endl;
|
||||
break;
|
||||
}
|
||||
case(WSAEINVAL): {
|
||||
sif::info << "TcWinUdpPollingTask::handleReadError: WSAEINVAL: "
|
||||
<< "Invalid input parameters. " << std::endl;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::info << "TmTcWinUdpBridge::handleReadError: Error code: "
|
||||
sif::info << "TcWinUdpPollingTask::handleReadError: Error code: "
|
||||
<< error << std::endl;
|
||||
break;
|
||||
}
|
||||
|
295
pus/Service3Housekeeping.cpp
Normal file
295
pus/Service3Housekeeping.cpp
Normal file
@ -0,0 +1,295 @@
|
||||
#include "Service3Housekeeping.h"
|
||||
#include "servicepackets/Service3Packets.h"
|
||||
#include "../datapoollocal/HasLocalDataPoolIF.h"
|
||||
|
||||
|
||||
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid,
|
||||
uint8_t serviceId):
|
||||
CommandingServiceBase(objectId, apid, serviceId,
|
||||
NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS) {}
|
||||
|
||||
Service3Housekeeping::~Service3Housekeeping() {}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::isValidSubservice(uint8_t subservice) {
|
||||
switch(static_cast<Subservice>(subservice)) {
|
||||
case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION:
|
||||
case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION:
|
||||
case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
|
||||
case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
|
||||
case Subservice::REPORT_HK_REPORT_STRUCTURES:
|
||||
case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES :
|
||||
case Subservice::GENERATE_ONE_PARAMETER_REPORT:
|
||||
case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT:
|
||||
case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL:
|
||||
case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL:
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
// Telemetry or invalid subservice.
|
||||
case Subservice::HK_DEFINITIONS_REPORT:
|
||||
case Subservice::DIAGNOSTICS_DEFINITION_REPORT:
|
||||
case Subservice::HK_REPORT:
|
||||
case Subservice::DIAGNOSTICS_REPORT:
|
||||
default:
|
||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::getMessageQueueAndObject(uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen,
|
||||
MessageQueueId_t *id, object_id_t *objectId) {
|
||||
ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen);
|
||||
if(result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return checkInterfaceAndAcquireMessageQueue(id,objectId);
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::checkAndAcquireTargetID(
|
||||
object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) {
|
||||
if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen,
|
||||
SerializeIF::Endianness::BIG) != HasReturnvaluesIF::RETURN_OK) {
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::checkInterfaceAndAcquireMessageQueue(
|
||||
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
|
||||
// check HasLocalDataPoolIF property of target
|
||||
HasLocalDataPoolIF* possibleTarget =
|
||||
objectManager->get<HasLocalDataPoolIF>(*objectId);
|
||||
if(possibleTarget == nullptr){
|
||||
return CommandingServiceBase::INVALID_OBJECT;
|
||||
}
|
||||
*messageQueueToSet = possibleTarget->getCommandQueue();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t Service3Housekeeping::prepareCommand(CommandMessage* message,
|
||||
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
|
||||
uint32_t *state, object_id_t objectId) {
|
||||
switch(static_cast<Subservice>(subservice)) {
|
||||
case Subservice::ENABLE_PERIODIC_HK_REPORT_GENERATION:
|
||||
return prepareReportingTogglingCommand(message, objectId, true, false,
|
||||
tcData, tcDataLen);
|
||||
case Subservice::DISABLE_PERIODIC_HK_REPORT_GENERATION:
|
||||
return prepareReportingTogglingCommand(message, objectId, false, false,
|
||||
tcData, tcDataLen);
|
||||
case Subservice::ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
|
||||
return prepareReportingTogglingCommand(message, objectId, true, true,
|
||||
tcData, tcDataLen);
|
||||
case Subservice::DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION:
|
||||
return prepareReportingTogglingCommand(message, objectId, false, true,
|
||||
tcData, tcDataLen);
|
||||
case Subservice::REPORT_HK_REPORT_STRUCTURES:
|
||||
return prepareStructureReportingCommand(message, objectId, false, tcData,
|
||||
tcDataLen);
|
||||
case Subservice::REPORT_DIAGNOSTICS_REPORT_STRUCTURES:
|
||||
return prepareStructureReportingCommand(message, objectId, true, tcData,
|
||||
tcDataLen);
|
||||
case Subservice::GENERATE_ONE_PARAMETER_REPORT:
|
||||
return prepareOneShotReportCommand(message, objectId, false,
|
||||
tcData, tcDataLen);
|
||||
case Subservice::GENERATE_ONE_DIAGNOSTICS_REPORT:
|
||||
return prepareOneShotReportCommand(message, objectId, true,
|
||||
tcData, tcDataLen);
|
||||
case Subservice::MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL:
|
||||
return prepareCollectionIntervalModificationCommand(message, objectId,
|
||||
false, tcData, tcDataLen);
|
||||
case Subservice::MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL:
|
||||
return prepareCollectionIntervalModificationCommand(message, objectId,
|
||||
true, tcData, tcDataLen);
|
||||
case Subservice::HK_DEFINITIONS_REPORT:
|
||||
case Subservice::DIAGNOSTICS_DEFINITION_REPORT:
|
||||
case Subservice::HK_REPORT:
|
||||
case Subservice::DIAGNOSTICS_REPORT:
|
||||
// Those are telemetry packets.
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
default:
|
||||
// should never happen, subservice was already checked.
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::prepareReportingTogglingCommand(
|
||||
CommandMessage *command, object_id_t objectId,
|
||||
bool enableReporting, bool isDiagnostics,
|
||||
const uint8_t* tcData, size_t tcDataLen) {
|
||||
if(tcDataLen < sizeof(sid_t)) {
|
||||
// TC data should consist of object ID and set ID.
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
|
||||
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
|
||||
HousekeepingMessage::setToggleReportingCommand(command, targetSid,
|
||||
enableReporting, isDiagnostics);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::prepareStructureReportingCommand(
|
||||
CommandMessage *command, object_id_t objectId, bool isDiagnostics,
|
||||
const uint8_t* tcData, size_t tcDataLen) {
|
||||
if(tcDataLen < sizeof(sid_t)) {
|
||||
// TC data should consist of object ID and set ID.
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
|
||||
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
|
||||
HousekeepingMessage::setStructureReportingCommand(command, targetSid,
|
||||
isDiagnostics);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::prepareOneShotReportCommand(
|
||||
CommandMessage *command, object_id_t objectId, bool isDiagnostics,
|
||||
const uint8_t *tcData, size_t tcDataLen) {
|
||||
if(tcDataLen < sizeof(sid_t)) {
|
||||
// TC data should consist of object ID and set ID.
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
|
||||
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
|
||||
HousekeepingMessage::setOneShotReportCommand(command, targetSid,
|
||||
isDiagnostics);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::prepareCollectionIntervalModificationCommand(
|
||||
CommandMessage *command, object_id_t objectId, bool isDiagnostics,
|
||||
const uint8_t *tcData, size_t tcDataLen) {
|
||||
if(tcDataLen < sizeof(sid_t) + sizeof(float)) {
|
||||
// SID plus the size of the new collection intervL.
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
|
||||
sid_t targetSid = buildSid(objectId, &tcData, &tcDataLen);
|
||||
float newCollectionInterval = 0;
|
||||
SerializeAdapter::deSerialize(&newCollectionInterval, &tcData, &tcDataLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(command,
|
||||
targetSid, newCollectionInterval, isDiagnostics);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
|
||||
Command_t previousCommand, uint32_t *state,
|
||||
CommandMessage* optionalNextCommand, object_id_t objectId,
|
||||
bool *isStep) {
|
||||
Command_t command = reply->getCommand();
|
||||
switch(command) {
|
||||
|
||||
case(HousekeepingMessage::HK_REPORT): {
|
||||
ReturnValue_t result = generateHkReply(reply,
|
||||
static_cast<uint8_t>(Subservice::HK_REPORT));
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
|
||||
case(HousekeepingMessage::DIAGNOSTICS_REPORT): {
|
||||
ReturnValue_t result = generateHkReply(reply,
|
||||
static_cast<uint8_t>(Subservice::DIAGNOSTICS_REPORT));
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
|
||||
case(HousekeepingMessage::HK_DEFINITIONS_REPORT): {
|
||||
return generateHkReply(reply, static_cast<uint8_t>(
|
||||
Subservice::HK_DEFINITIONS_REPORT));
|
||||
break;
|
||||
}
|
||||
case(HousekeepingMessage::DIAGNOSTICS_DEFINITION_REPORT): {
|
||||
return generateHkReply(reply, static_cast<uint8_t>(
|
||||
Subservice::DIAGNOSTICS_DEFINITION_REPORT));
|
||||
break;
|
||||
}
|
||||
|
||||
case(HousekeepingMessage::HK_REQUEST_SUCCESS): {
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
|
||||
case(HousekeepingMessage::HK_REQUEST_FAILURE): {
|
||||
failureParameter1 = objectId;
|
||||
ReturnValue_t error = HasReturnvaluesIF::RETURN_FAILED;
|
||||
HousekeepingMessage::getHkRequestFailureReply(reply,&error);
|
||||
failureParameter2 = error;
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
|
||||
default:
|
||||
sif::error << "Service3Housekeeping::handleReply: Invalid reply with "
|
||||
<< "reply command " << command << "!" << std::endl;
|
||||
return CommandingServiceBase::INVALID_REPLY;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void Service3Housekeeping::handleUnrequestedReply(
|
||||
CommandMessage* reply) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
Command_t command = reply->getCommand();
|
||||
|
||||
switch(command) {
|
||||
|
||||
case(HousekeepingMessage::DIAGNOSTICS_REPORT): {
|
||||
result = generateHkReply(reply,
|
||||
static_cast<uint8_t>(Subservice::DIAGNOSTICS_REPORT));
|
||||
break;
|
||||
}
|
||||
|
||||
case(HousekeepingMessage::HK_REPORT): {
|
||||
result = generateHkReply(reply,
|
||||
static_cast<uint8_t>(Subservice::HK_REPORT));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
sif::error << "Service3Housekeeping::handleUnrequestedReply: Invalid "
|
||||
<< "reply with " << "reply command " << command << "!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
// Configuration error
|
||||
sif::debug << "Service3Housekeeping::handleUnrequestedReply:"
|
||||
<< "Could not generate reply!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueId_t Service3Housekeeping::getHkQueue() const {
|
||||
return commandQueue->getId();
|
||||
}
|
||||
|
||||
ReturnValue_t Service3Housekeeping::generateHkReply(
|
||||
const CommandMessage* hkMessage, uint8_t subserviceId) {
|
||||
store_address_t storeId;
|
||||
|
||||
sid_t sid = HousekeepingMessage::getHkDataReply(hkMessage, &storeId);
|
||||
auto resultPair = IPCStore->getData(storeId);
|
||||
if(resultPair.first != HasReturnvaluesIF::RETURN_OK) {
|
||||
return resultPair.first;
|
||||
}
|
||||
|
||||
HkPacket hkPacket(sid, resultPair.second.data(), resultPair.second.size());
|
||||
return sendTmPacket(static_cast<uint8_t>(subserviceId),
|
||||
hkPacket.hkData, hkPacket.hkSize, nullptr, 0);
|
||||
}
|
||||
|
||||
sid_t Service3Housekeeping::buildSid(object_id_t objectId,
|
||||
const uint8_t** tcData, size_t* tcDataLen) {
|
||||
sid_t targetSid;
|
||||
targetSid.objectId = objectId;
|
||||
// skip deserialization of object ID, was already done.
|
||||
*tcData += sizeof(object_id_t);
|
||||
*tcDataLen -= sizeof(object_id_t);
|
||||
// size check is expected to be performed beforehand!
|
||||
SerializeAdapter::deSerialize(&targetSid.ownerSetId, tcData, tcDataLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
return targetSid;
|
||||
}
|
105
pus/Service3Housekeeping.h
Normal file
105
pus/Service3Housekeeping.h
Normal file
@ -0,0 +1,105 @@
|
||||
#ifndef FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_
|
||||
#define FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_
|
||||
|
||||
#include "../housekeeping/AcceptsHkPacketsIF.h"
|
||||
#include "../housekeeping/HousekeepingMessage.h"
|
||||
#include "../tmtcservices/CommandingServiceBase.h"
|
||||
|
||||
/**
|
||||
* @brief Manges spacecraft housekeeping reports and
|
||||
* sends pool variables (temperature, GPS data ...) to ground.
|
||||
*
|
||||
* @details Full Documentation: ECSS-E70-41A or ECSS-E-ST-70-41C.
|
||||
* Implementation based on PUS-C
|
||||
*
|
||||
* The housekeeping service type provides means to control and adapt the
|
||||
* spacecraft reporting plan according to the mission phases.
|
||||
* The housekeeping service type provides the visibility of any
|
||||
* on-board parameters assembled in housekeeping parameter report structures
|
||||
* or diagnostic parameter report structures as required for the mission.
|
||||
* The parameter report structures used by the housekeeping service can
|
||||
* be predefined on-board or created when needed.
|
||||
*
|
||||
* @author R. Mueller
|
||||
* @ingroup pus_services
|
||||
*/
|
||||
class Service3Housekeeping: public CommandingServiceBase,
|
||||
public AcceptsHkPacketsIF {
|
||||
public:
|
||||