diff --git a/CMakeLists.txt b/CMakeLists.txt index 669283c74..02849ca44 100644 --- a/CMakeLists.txt +++ b/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} ) diff --git a/coordinates/Sgp4Propagator.h b/coordinates/Sgp4Propagator.h index 3949547e1..f813c6f4d 100644 --- a/coordinates/Sgp4Propagator.h +++ b/coordinates/Sgp4Propagator.h @@ -1,7 +1,9 @@ #ifndef SGP4PROPAGATOR_H_ #define SGP4PROPAGATOR_H_ +#ifndef WIN32 #include +#endif #include "../contrib/sgp4/sgp4unit.h" #include "../returnvalues/HasReturnvaluesIF.h" diff --git a/datapool/CMakeLists.txt b/datapool/CMakeLists.txt index e741f6a13..0d53e1ba1 100644 --- a/datapool/CMakeLists.txt +++ b/datapool/CMakeLists.txt @@ -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 ) \ No newline at end of file diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp index 1acd3fd3b..cb2348f72 100644 --- a/datapool/PoolDataSetBase.cpp +++ b/datapool/PoolDataSetBase.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() != diff --git a/datapoollocal/CMakeLists.txt b/datapoollocal/CMakeLists.txt new file mode 100644 index 000000000..c6b187cd2 --- /dev/null +++ b/datapoollocal/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + LocalDataPoolManager.cpp + LocalDataSet.cpp + LocalPoolDataSetBase.cpp + LocalPoolObjectBase.cpp + SharedLocalDataSet.cpp +) \ No newline at end of file diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 95d483032..c4024cf9e 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -48,7 +48,7 @@ class HousekeepingPacketUpdate; * @author R. Mueller */ class LocalDataPoolManager { - template friend class LocalPoolVar; + template friend class LocalPoolVariable; template friend class LocalPoolVector; friend class LocalPoolDataSetBase; friend void (Factory::setStaticFrameworkObjectIds)(); diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index c18d54433..7b7e443e1 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -22,10 +22,10 @@ * @ingroup data_pool */ template -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 &operator=(const T& newValue); - LocalPoolVar &operator=(const LocalPoolVar& newPoolVariable); + LocalPoolVariable &operator=(const T& newValue); + LocalPoolVariable &operator=(const LocalPoolVariable& 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& other) const; + bool operator==(const LocalPoolVariable& other) const; bool operator==(const T& other) const; - bool operator!=(const LocalPoolVar& other) const; + bool operator!=(const LocalPoolVariable& other) const; bool operator!=(const T& other) const; - bool operator<(const LocalPoolVar& other) const; + bool operator<(const LocalPoolVariable& other) const; bool operator<(const T& other) const; - bool operator>(const LocalPoolVar& other) const; + bool operator>(const LocalPoolVariable& other) const; bool operator>(const T& other) const; protected: @@ -160,7 +160,7 @@ protected: // std::ostream is the type for object std::cout template friend std::ostream& operator<< (std::ostream &out, - const LocalPoolVar &var); + const LocalPoolVariable &var); private: }; @@ -168,18 +168,18 @@ private: #include "LocalPoolVariable.tpp" template -using lp_var_t = LocalPoolVar; +using lp_var_t = LocalPoolVariable; -using lp_bool_t = LocalPoolVar; -using lp_uint8_t = LocalPoolVar; -using lp_uint16_t = LocalPoolVar; -using lp_uint32_t = LocalPoolVar; -using lp_uint64_t = LocalPoolVar; -using lp_int8_t = LocalPoolVar; -using lp_int16_t = LocalPoolVar; -using lp_int32_t = LocalPoolVar; -using lp_int64_t = LocalPoolVar; -using lp_float_t = LocalPoolVar; -using lp_double_t = LocalPoolVar; +using lp_bool_t = LocalPoolVariable; +using lp_uint8_t = LocalPoolVariable; +using lp_uint16_t = LocalPoolVariable; +using lp_uint32_t = LocalPoolVariable; +using lp_uint64_t = LocalPoolVariable; +using lp_int8_t = LocalPoolVariable; +using lp_int16_t = LocalPoolVariable; +using lp_int32_t = LocalPoolVariable; +using lp_int64_t = LocalPoolVariable; +using lp_float_t = LocalPoolVariable; +using lp_double_t = LocalPoolVariable; #endif /* FSFW_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ */ diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index b9f7b906e..48649ad58 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -6,32 +6,32 @@ #endif template -inline LocalPoolVar::LocalPoolVar(HasLocalDataPoolIF* hkOwner, +inline LocalPoolVariable::LocalPoolVariable(HasLocalDataPoolIF* hkOwner, lp_id_t poolId, DataSetIF* dataSet, pool_rwm_t setReadWriteMode): LocalPoolObjectBase(poolId, hkOwner, dataSet, setReadWriteMode) {} template -inline LocalPoolVar::LocalPoolVar(object_id_t poolOwner, lp_id_t poolId, +inline LocalPoolVariable::LocalPoolVariable(object_id_t poolOwner, lp_id_t poolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode): LocalPoolObjectBase(poolOwner, poolId, dataSet, setReadWriteMode) {} template -inline LocalPoolVar::LocalPoolVar(gp_id_t globalPoolId, DataSetIF *dataSet, +inline LocalPoolVariable::LocalPoolVariable(gp_id_t globalPoolId, DataSetIF *dataSet, pool_rwm_t setReadWriteMode): LocalPoolObjectBase(globalPoolId.objectId, globalPoolId.localPoolId, dataSet, setReadWriteMode){} template -inline ReturnValue_t LocalPoolVar::read(dur_millis_t lockTimeout) { +inline ReturnValue_t LocalPoolVariable::read(dur_millis_t lockTimeout) { MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING, lockTimeout); return readWithoutLock(); } template -inline ReturnValue_t LocalPoolVar::readWithoutLock() { +inline ReturnValue_t LocalPoolVariable::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::readWithoutLock() { } template -inline ReturnValue_t LocalPoolVar::commit(dur_millis_t lockTimeout) { +inline ReturnValue_t LocalPoolVariable::commit(dur_millis_t lockTimeout) { MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING, lockTimeout); return commitWithoutLock(); } template -inline ReturnValue_t LocalPoolVar::commitWithoutLock() { +inline ReturnValue_t LocalPoolVariable::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::commitWithoutLock() { } template -inline ReturnValue_t LocalPoolVar::serialize(uint8_t** buffer, size_t* size, +inline ReturnValue_t LocalPoolVariable::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 -inline size_t LocalPoolVar::getSerializedSize() const { +inline size_t LocalPoolVariable::getSerializedSize() const { return SerializeAdapter::getSerializedSize(&value); } template -inline ReturnValue_t LocalPoolVar::deSerialize(const uint8_t** buffer, +inline ReturnValue_t LocalPoolVariable::deSerialize(const uint8_t** buffer, size_t* size, SerializeIF::Endianness streamEndianness) { return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); } template inline std::ostream& operator<< (std::ostream &out, - const LocalPoolVar &var) { + const LocalPoolVariable &var) { out << var.value; return out; } template -inline LocalPoolVar::operator T() const { +inline LocalPoolVariable::operator T() const { return value; } template -inline LocalPoolVar & LocalPoolVar::operator=(const T& newValue) { +inline LocalPoolVariable & LocalPoolVariable::operator=(const T& newValue) { value = newValue; return *this; } template -inline LocalPoolVar& LocalPoolVar::operator =( - const LocalPoolVar& newPoolVariable) { +inline LocalPoolVariable& LocalPoolVariable::operator =( + const LocalPoolVariable& newPoolVariable) { value = newPoolVariable.value; return *this; } template -inline bool LocalPoolVar::operator ==(const LocalPoolVar &other) const { +inline bool LocalPoolVariable::operator ==(const LocalPoolVariable &other) const { return this->value == other.value; } template -inline bool LocalPoolVar::operator ==(const T &other) const { +inline bool LocalPoolVariable::operator ==(const T &other) const { return this->value == other; } template -inline bool LocalPoolVar::operator !=(const LocalPoolVar &other) const { +inline bool LocalPoolVariable::operator !=(const LocalPoolVariable &other) const { return not (*this == other); } template -inline bool LocalPoolVar::operator !=(const T &other) const { +inline bool LocalPoolVariable::operator !=(const T &other) const { return not (*this == other); } template -inline bool LocalPoolVar::operator <(const LocalPoolVar &other) const { +inline bool LocalPoolVariable::operator <(const LocalPoolVariable &other) const { return this->value < other.value; } template -inline bool LocalPoolVar::operator <(const T &other) const { +inline bool LocalPoolVariable::operator <(const T &other) const { return this->value < other; } template -inline bool LocalPoolVar::operator >(const LocalPoolVar &other) const { +inline bool LocalPoolVariable::operator >(const LocalPoolVariable &other) const { return not (*this < other); } template -inline bool LocalPoolVar::operator >(const T &other) const { +inline bool LocalPoolVariable::operator >(const T &other) const { return not (*this < other); } diff --git a/defaultcfg/fsfwconfig/FSFWConfig.h b/defaultcfg/fsfwconfig/FSFWConfig.h index 7e19235cd..e1815d050 100644 --- a/defaultcfg/fsfwconfig/FSFWConfig.h +++ b/defaultcfg/fsfwconfig/FSFWConfig.h @@ -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 -#include +#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_ */ diff --git a/defaultcfg/fsfwconfig/OBSWConfig.h b/defaultcfg/fsfwconfig/OBSWConfig.h index a9f576386..8ad2cb675 100644 --- a/defaultcfg/fsfwconfig/OBSWConfig.h +++ b/defaultcfg/fsfwconfig/OBSWConfig.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 diff --git a/events/CMakeLists.txt b/events/CMakeLists.txt index 9e63deb89..4e935167a 100644 --- a/events/CMakeLists.txt +++ b/events/CMakeLists.txt @@ -1,6 +1,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE - Event.cpp EventManager.cpp EventMessage.cpp ) diff --git a/globalfunctions/timevalOperations.h b/globalfunctions/timevalOperations.h index 3977d5d96..db68f3304 100644 --- a/globalfunctions/timevalOperations.h +++ b/globalfunctions/timevalOperations.h @@ -2,7 +2,12 @@ #define TIMEVALOPERATIONS_H_ #include + +#ifdef WIN32 +#include +#else #include +#endif timeval& operator+=(timeval& lhs, const timeval& rhs); diff --git a/housekeeping/CMakeLists.txt b/housekeeping/CMakeLists.txt new file mode 100644 index 000000000..fecad2e3d --- /dev/null +++ b/housekeeping/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + HousekeepingMessage.cpp + PeriodicHousekeepingHelper.cpp +) \ No newline at end of file diff --git a/ipc/CommandMessageCleaner.cpp b/ipc/CommandMessageCleaner.cpp index 6a99b4d2d..6a3640699 100644 --- a/ipc/CommandMessageCleaner.cpp +++ b/ipc/CommandMessageCleaner.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; diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index b5a30c086..33e01e7d0 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ #define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ -#include +#include "messageQueueDefinitions.h" #include #include diff --git a/ipc/MutexFactory.h b/ipc/MutexFactory.h index f8133d814..db505ff94 100644 --- a/ipc/MutexFactory.h +++ b/ipc/MutexFactory.h @@ -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_ */ diff --git a/ipc/MutexHelper.h b/ipc/MutexHelper.h index 3dc369213..97001ade9 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexHelper.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; } } diff --git a/monitoring/MonitorBase.h b/monitoring/MonitorBase.h index 530a38409..967f0f62f 100644 --- a/monitoring/MonitorBase.h +++ b/monitoring/MonitorBase.h @@ -72,7 +72,7 @@ protected: return HasReturnvaluesIF::RETURN_OK; } - LocalPoolVar poolVariable; + LocalPoolVariable poolVariable; }; #endif /* FSFW_MONITORING_MONITORBASE_H_ */ diff --git a/osal/Endiness.h b/osal/Endiness.h index 65cc0a10f..9d3fdef0f 100644 --- a/osal/Endiness.h +++ b/osal/Endiness.h @@ -22,9 +22,23 @@ #else #error "Can't decide which end is which!" #endif +#else + +#ifdef WIN32 +#include +#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 diff --git a/osal/FreeRTOS/CMakeLists.txt b/osal/FreeRTOS/CMakeLists.txt new file mode 100644 index 000000000..95462010f --- /dev/null +++ b/osal/FreeRTOS/CMakeLists.txt @@ -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}) \ No newline at end of file diff --git a/osal/host/CMakeLists.txt b/osal/host/CMakeLists.txt index d73e6f275..aa32990be 100644 --- a/osal/host/CMakeLists.txt +++ b/osal/host/CMakeLists.txt @@ -13,9 +13,9 @@ target_sources(${LIB_FSFW_NAME} ) if(UNIX) - add_definitions(-pthread) target_link_libraries(${LIB_FSFW_NAME} PRIVATE rt + pthread ) endif() \ No newline at end of file diff --git a/osal/linux/BinarySemaphore.cpp b/osal/linux/BinarySemaphore.cpp index 8c0eeae71..b81fa1090 100644 --- a/osal/linux/BinarySemaphore.cpp +++ b/osal/linux/BinarySemaphore.cpp @@ -1,4 +1,4 @@ -#include "../../osal/linux/BinarySemaphore.h" +#include "BinarySemaphore.h" #include "../../serviceinterface/ServiceInterfaceStream.h" extern "C" { diff --git a/osal/linux/Clock.cpp b/osal/linux/Clock.cpp index 4de18f83b..6cddda35b 100644 --- a/osal/linux/Clock.cpp +++ b/osal/linux/Clock.cpp @@ -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; diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index bc14374ac..cfadb7931 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -3,6 +3,7 @@ #include "../../objectmanager/ObjectManagerIF.h" #include + #include /* For O_* constants */ #include /* For mode constants */ #include diff --git a/osal/linux/Mutex.h b/osal/linux/Mutex.h index ecb47a336..cfce407f7 100644 --- a/osal/linux/Mutex.h +++ b/osal/linux/Mutex.h @@ -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 - class Mutex : public MutexIF { public: Mutex(); diff --git a/osal/linux/MutexFactory.cpp b/osal/linux/MutexFactory.cpp index 8c2faf888..80211f8bc 100644 --- a/osal/linux/MutexFactory.cpp +++ b/osal/linux/MutexFactory.cpp @@ -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(); diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index ddb1f74f6..55d74de3e 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -1,5 +1,7 @@ -#include "../../serviceinterface/ServiceInterfaceStream.h" #include "PosixThread.h" + +#include "../../serviceinterface/ServiceInterfaceStream.h" + #include #include @@ -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); diff --git a/osal/linux/SemaphoreFactory.cpp b/osal/linux/SemaphoreFactory.cpp index e4710933e..cfb5f12dd 100644 --- a/osal/linux/SemaphoreFactory.cpp +++ b/osal/linux/SemaphoreFactory.cpp @@ -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; diff --git a/osal/linux/TaskFactory.cpp b/osal/linux/TaskFactory.cpp index f507c7671..d18a03161 100644 --- a/osal/linux/TaskFactory.cpp +++ b/osal/linux/TaskFactory.cpp @@ -1,5 +1,6 @@ #include "FixedTimeslotTask.h" #include "PeriodicPosixTask.h" + #include "../../tasks/TaskFactory.h" #include "../../returnvalues/HasReturnvaluesIF.h" diff --git a/osal/linux/Timer.cpp b/osal/linux/Timer.cpp index ee964baa0..bae631d72 100644 --- a/osal/linux/Timer.cpp +++ b/osal/linux/Timer.cpp @@ -1,6 +1,7 @@ +#include "Timer.h" #include "../../serviceinterface/ServiceInterfaceStream.h" #include -#include "Timer.h" + Timer::Timer() { sigevent sigEvent; diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index 7b54bb2cf..06deafd10 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -119,7 +119,7 @@ void TcWinUdpPollingTask::setTimeout(double timeoutSeconds) { int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&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; } diff --git a/pus/Service3Housekeeping.cpp b/pus/Service3Housekeeping.cpp new file mode 100644 index 000000000..175af026b --- /dev/null +++ b/pus/Service3Housekeeping.cpp @@ -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)) { + 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(*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)) { + 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(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(Subservice::DIAGNOSTICS_REPORT)); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return CommandingServiceBase::EXECUTION_COMPLETE; + } + + case(HousekeepingMessage::HK_DEFINITIONS_REPORT): { + return generateHkReply(reply, static_cast( + Subservice::HK_DEFINITIONS_REPORT)); + break; + } + case(HousekeepingMessage::DIAGNOSTICS_DEFINITION_REPORT): { + return generateHkReply(reply, static_cast( + 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(Subservice::DIAGNOSTICS_REPORT)); + break; + } + + case(HousekeepingMessage::HK_REPORT): { + result = generateHkReply(reply, + static_cast(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(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; +} diff --git a/pus/Service3Housekeeping.h b/pus/Service3Housekeeping.h new file mode 100644 index 000000000..269710ef3 --- /dev/null +++ b/pus/Service3Housekeeping.h @@ -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: + static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4; + static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60; + + Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId); + virtual~ Service3Housekeeping(); +protected: + /* CSB abstract functions implementation . See CSB documentation. */ + ReturnValue_t isValidSubservice(uint8_t subservice) override; + ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) override; + ReturnValue_t prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) override; + ReturnValue_t handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) override; + + virtual MessageQueueId_t getHkQueue() const; +private: + enum class Subservice { + ENABLE_PERIODIC_HK_REPORT_GENERATION = 5, //!< [EXPORT] : [TC] + DISABLE_PERIODIC_HK_REPORT_GENERATION = 6, //!< [EXPORT] : [TC] + + ENABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION = 7, //!< [EXPORT] : [TC] + DISABLE_PERIODIC_DIAGNOSTICS_REPORT_GENERATION = 8, //!< [EXPORT] : [TC] + + //! [EXPORT] : [TC] Report HK structure by supplying SID + REPORT_HK_REPORT_STRUCTURES = 9, + //! [EXPORT] : [TC] Report Diagnostics structure by supplying SID + REPORT_DIAGNOSTICS_REPORT_STRUCTURES = 11, + + //! [EXPORT] : [TM] Report corresponding to Subservice 9 TC + HK_DEFINITIONS_REPORT = 10, + //! [EXPORT] : [TM] Report corresponding to Subservice 11 TC + DIAGNOSTICS_DEFINITION_REPORT = 12, + + //! [EXPORT] : [TM] Core packet. Contains Housekeeping data + HK_REPORT = 25, + //! [EXPORT] : [TM] Core packet. Contains diagnostics data + DIAGNOSTICS_REPORT = 26, + + /* PUS-C */ + GENERATE_ONE_PARAMETER_REPORT = 27, //!< [EXPORT] : [TC] + GENERATE_ONE_DIAGNOSTICS_REPORT = 28, //!< [EXPORT] : [TC] + + MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL = 31, //!< [EXPORT] : [TC] + MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = 32, //!< [EXPORT] : [TC] + }; + + ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId); + + ReturnValue_t generateHkReply(const CommandMessage* hkMessage, + uint8_t subserviceId); + ReturnValue_t prepareReportingTogglingCommand(CommandMessage* command, + object_id_t objectId, bool enableReporting, bool isDiagnostics, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t prepareStructureReportingCommand(CommandMessage* command, + object_id_t objectId, bool isDiagnostics, const uint8_t* tcData, + size_t tcDataLen); + ReturnValue_t prepareOneShotReportCommand(CommandMessage* command, + object_id_t objectId, bool isDiagnostics, const uint8_t* tcData, + size_t tcDataLen); + ReturnValue_t prepareCollectionIntervalModificationCommand( + CommandMessage* command, object_id_t objectId, bool isDiagnostics, + const uint8_t* tcData, size_t tcDataLen); + + void handleUnrequestedReply(CommandMessage* reply) override; + sid_t buildSid(object_id_t objectId, const uint8_t** tcData, + size_t* tcDataLen); +}; + +#endif /* FSFW_PUS_SERVICE3HOUSEKEEPINGSERVICE_H_ */ diff --git a/pus/servicepackets/Service3Packets.h b/pus/servicepackets/Service3Packets.h new file mode 100644 index 000000000..05732e11b --- /dev/null +++ b/pus/servicepackets/Service3Packets.h @@ -0,0 +1,21 @@ +#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_ +#define FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_ + +#include +#include + +/** + * @brief Subservices 25 and 26: TM packets + * @ingroup spacepackets + */ +class HkPacket { //!< [EXPORT] : [SUBSERVICE] 25, 26 +public: + sid_t sid; //!< [EXPORT] : [COMMENT] Structure ID (SID) of housekeeping data. + const uint8_t* hkData; //!< [EXPORT] : [MAXSIZE] Deduced size + size_t hkSize; //!< [EXPORT] : [IGNORE] + + HkPacket(sid_t sid, const uint8_t* data, size_t size): + sid(sid), hkData(data), hkSize(size) {} +}; + +#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE3PACKETS_H_ */ diff --git a/storagemanager/CMakeLists.txt b/storagemanager/CMakeLists.txt index 57c921952..b8138cae7 100644 --- a/storagemanager/CMakeLists.txt +++ b/storagemanager/CMakeLists.txt @@ -2,4 +2,6 @@ target_sources(${LIB_FSFW_NAME} PRIVATE ConstStorageAccessor.cpp StorageAccessor.cpp + LocalPool.cpp + PoolManager.cpp ) \ No newline at end of file diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp deleted file mode 100644 index 5e61efe45..000000000 --- a/storagemanager/LocalPool.tpp +++ /dev/null @@ -1,305 +0,0 @@ -#ifndef FSFW_STORAGEMANAGER_LOCALPOOL_TPP_ -#define FSFW_STORAGEMANAGER_LOCALPOOL_TPP_ - -#ifndef FSFW_STORAGEMANAGER_LOCALPOOL_H_ -#error Include LocalPool.h before LocalPool.tpp! -#endif - -template -inline LocalPool::LocalPool(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS], bool registered, - bool spillsToHigherPools) : - SystemObject(setObjectId, registered), internalErrorReporter(nullptr), - spillsToHigherPools(spillsToHigherPools) -{ - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - this->element_sizes[n] = element_sizes[n]; - this->n_elements[n] = n_elements[n]; - store[n] = new uint8_t[n_elements[n] * element_sizes[n]]; - size_list[n] = new uint32_t[n_elements[n]]; - memset(store[n], 0x00, (n_elements[n] * element_sizes[n])); - //TODO checkme - memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); - } -} - - -template -inline ReturnValue_t LocalPool::findEmpty(uint16_t pool_index, - uint16_t* element) { - ReturnValue_t status = DATA_STORAGE_FULL; - for (uint16_t foundElement = 0; foundElement < n_elements[pool_index]; - foundElement++) { - if (size_list[pool_index][foundElement] == STORAGE_FREE) { - *element = foundElement; - status = RETURN_OK; - break; - } - } - return status; -} - -template -inline void LocalPool::write(store_address_t packet_id, - const uint8_t* data, size_t size) { - uint8_t* ptr; - uint32_t packet_position = getRawPosition(packet_id); - - //check size? -> Not necessary, because size is checked before calling this function. - ptr = &store[packet_id.pool_index][packet_position]; - memcpy(ptr, data, size); - size_list[packet_id.pool_index][packet_id.packet_index] = size; -} - -//Returns page size of 0 in case store_index is illegal -template -inline uint32_t LocalPool::getPageSize(uint16_t pool_index) { - if (pool_index < NUMBER_OF_POOLS) { - return element_sizes[pool_index]; - } else { - return 0; - } -} - -template -inline ReturnValue_t LocalPool::getPoolIndex( - size_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex) { - for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) { - //debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << - // n << ", Element Size: " << element_sizes[n] << std::endl; - if (element_sizes[n] >= packet_size) { - *poolIndex = n; - return RETURN_OK; - } - } - return DATA_TOO_LARGE; -} - -template -inline uint32_t LocalPool::getRawPosition( - store_address_t packet_id) { - return packet_id.packet_index * element_sizes[packet_id.pool_index]; -} - -template -inline ReturnValue_t LocalPool::reserveSpace( - const uint32_t size, store_address_t* address, bool ignoreFault) { - ReturnValue_t status = getPoolIndex(size, &address->pool_index); - if (status != RETURN_OK) { - sif::error << "LocalPool( " << std::hex << getObjectId() << std::dec - << " )::reserveSpace: Packet too large." << std::endl; - return status; - } - status = findEmpty(address->pool_index, &address->packet_index); - while (status != RETURN_OK && spillsToHigherPools) { - status = getPoolIndex(size, &address->pool_index, address->pool_index + 1); - if (status != RETURN_OK) { - //We don't find any fitting pool anymore. - break; - } - status = findEmpty(address->pool_index, &address->packet_index); - } - if (status == RETURN_OK) { - // if (getObjectId() == objects::IPC_STORE && address->pool_index >= 3) { - // debug << "Reserve: Pool: " << std::dec << address->pool_index << - // " Index: " << address->packet_index << std::endl; - // } - - size_list[address->pool_index][address->packet_index] = size; - } else { - if (!ignoreFault and internalErrorReporter != nullptr) { - internalErrorReporter->storeFull(); - } - // error << "LocalPool( " << std::hex << getObjectId() << std::dec - // << " )::reserveSpace: Packet store is full." << std::endl; - } - return status; -} - -template -inline LocalPool::~LocalPool(void) { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - delete[] store[n]; - delete[] size_list[n]; - } -} - -template -inline ReturnValue_t LocalPool::addData( - store_address_t* storageId, const uint8_t* data, size_t size, - bool ignoreFault) { - ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); - if (status == RETURN_OK) { - write(*storageId, data, size); - } - return status; -} - -template -inline ReturnValue_t LocalPool::getFreeElement( - store_address_t* storageId, const size_t size, - uint8_t** p_data, bool ignoreFault) { - ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); - if (status == RETURN_OK) { - *p_data = &store[storageId->pool_index][getRawPosition(*storageId)]; - } else { - *p_data = NULL; - } - return status; -} - -template -inline ConstAccessorPair LocalPool::getData( - store_address_t storeId) { - uint8_t* tempData = nullptr; - ConstStorageAccessor constAccessor(storeId, this); - ReturnValue_t status = modifyData(storeId, &tempData, &constAccessor.size_); - constAccessor.constDataPointer = tempData; - return ConstAccessorPair(status, std::move(constAccessor)); -} - -template -inline ReturnValue_t LocalPool::getData(store_address_t storeId, - ConstStorageAccessor& storeAccessor) { - uint8_t* tempData = nullptr; - ReturnValue_t status = modifyData(storeId, &tempData, &storeAccessor.size_); - storeAccessor.assignStore(this); - storeAccessor.constDataPointer = tempData; - return status; -} - -template -inline ReturnValue_t LocalPool::getData( - store_address_t packet_id, const uint8_t** packet_ptr, size_t* size) { - uint8_t* tempData = nullptr; - ReturnValue_t status = modifyData(packet_id, &tempData, size); - *packet_ptr = tempData; - return status; -} - -template -inline AccessorPair LocalPool::modifyData( - store_address_t storeId) { - StorageAccessor accessor(storeId, this); - ReturnValue_t status = modifyData(storeId, &accessor.dataPointer, - &accessor.size_); - accessor.assignConstPointer(); - return AccessorPair(status, std::move(accessor)); -} - -template -inline ReturnValue_t LocalPool::modifyData( - store_address_t storeId, StorageAccessor& storeAccessor) { - storeAccessor.assignStore(this); - ReturnValue_t status = modifyData(storeId, &storeAccessor.dataPointer, - &storeAccessor.size_); - storeAccessor.assignConstPointer(); - return status; -} - -template -inline ReturnValue_t LocalPool::modifyData( - store_address_t packet_id, uint8_t** packet_ptr, size_t* size) { - ReturnValue_t status = RETURN_FAILED; - if (packet_id.pool_index >= NUMBER_OF_POOLS) { - return ILLEGAL_STORAGE_ID; - } - if ((packet_id.packet_index >= n_elements[packet_id.pool_index])) { - return ILLEGAL_STORAGE_ID; - } - if (size_list[packet_id.pool_index][packet_id.packet_index] - != STORAGE_FREE) { - uint32_t packet_position = getRawPosition(packet_id); - *packet_ptr = &store[packet_id.pool_index][packet_position]; - *size = size_list[packet_id.pool_index][packet_id.packet_index]; - status = RETURN_OK; - } else { - status = DATA_DOES_NOT_EXIST; - } - return status; -} - -template -inline ReturnValue_t LocalPool::deleteData( - store_address_t packet_id) { - //if (getObjectId() == objects::IPC_STORE && packet_id.pool_index >= 3) { - // debug << "Delete: Pool: " << std::dec << packet_id.pool_index << " Index: " - // << packet_id.packet_index << std::endl; - //} - ReturnValue_t status = RETURN_OK; - uint32_t page_size = getPageSize(packet_id.pool_index); - if ((page_size != 0) - && (packet_id.packet_index < n_elements[packet_id.pool_index])) { - uint16_t packet_position = getRawPosition(packet_id); - uint8_t* ptr = &store[packet_id.pool_index][packet_position]; - memset(ptr, 0, page_size); - //Set free list - size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE; - } else { - //pool_index or packet_index is too large - sif::error << "LocalPool:deleteData failed." << std::endl; - status = ILLEGAL_STORAGE_ID; - } - return status; -} - -template -inline void LocalPool::clearStore() { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - //TODO checkme - memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); - } -} - -template -inline ReturnValue_t LocalPool::deleteData(uint8_t* ptr, - size_t size, store_address_t* storeId) { - store_address_t localId; - ReturnValue_t result = ILLEGAL_ADDRESS; - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - //Not sure if new allocates all stores in order. so better be careful. - if ((store[n] <= ptr) && (&store[n][n_elements[n]*element_sizes[n]]) > ptr) { - localId.pool_index = n; - uint32_t deltaAddress = ptr - store[n]; - // Getting any data from the right "block" is ok. - // This is necessary, as IF's sometimes don't point to the first - // element of an object. - localId.packet_index = deltaAddress / element_sizes[n]; - result = deleteData(localId); - //if (deltaAddress % element_sizes[n] != 0) { - // error << "Pool::deleteData: address not aligned!" << std::endl; - //} - break; - } - } - if (storeId != NULL) { - *storeId = localId; - } - return result; -} - -template -inline ReturnValue_t LocalPool::initialize() { - ReturnValue_t result = SystemObject::initialize(); - if (result != RETURN_OK) { - return result; - } - internalErrorReporter = objectManager->get( - objects::INTERNAL_ERROR_REPORTER); - if (internalErrorReporter == nullptr){ - return ObjectManagerIF::INTERNAL_ERR_REPORTER_UNINIT; - } - - //Check if any pool size is large than the maximum allowed. - for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) { - if (element_sizes[count] >= STORAGE_FREE) { - sif::error << "LocalPool::initialize: Pool is too large! " - "Max. allowed size is: " << (STORAGE_FREE - 1) << std::endl; - return StorageManagerIF::POOL_TOO_LARGE; - } - } - return RETURN_OK; -} - -#endif /* FSFW_STORAGEMANAGER_LOCALPOOL_TPP_ */ diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp deleted file mode 100644 index 2be44ece2..000000000 --- a/storagemanager/PoolManager.tpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ -#define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ - -#ifndef FSFW_STORAGEMANAGER_POOLMANAGER_H_ -#error Include PoolManager.h before PoolManager.tpp! -#endif - -template -inline PoolManager::PoolManager(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS]) : - LocalPool(setObjectId, element_sizes, n_elements, true) { - mutex = MutexFactory::instance()->createMutex(); -} - -template -inline PoolManager::~PoolManager(void) { - MutexFactory::instance()->deleteMutex(mutex); -} - -template -inline ReturnValue_t PoolManager::reserveSpace( - const uint32_t size, store_address_t* address, bool ignoreFault) { - MutexHelper mutexHelper(mutex,MutexIF::WAITING, mutexTimeoutMs); - ReturnValue_t status = LocalPool::reserveSpace(size, - address,ignoreFault); - return status; -} - -template -inline ReturnValue_t PoolManager::deleteData( - store_address_t packet_id) { - // debug << "PoolManager( " << translateObject(getObjectId()) << - // " )::deleteData from store " << packet_id.pool_index << - // ". id is "<< packet_id.packet_index << std::endl; - MutexHelper mutexHelper(mutex,MutexIF::WAITING, mutexTimeoutMs); - ReturnValue_t status = LocalPool::deleteData(packet_id); - return status; -} - -template -inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, - size_t size, store_address_t* storeId) { - MutexHelper mutexHelper(mutex,MutexIF::WAITING, mutexTimeoutMs); - ReturnValue_t status = LocalPool::deleteData(buffer, - size, storeId); - return status; -} - -template -inline void PoolManager::setMutexTimeout( - uint32_t mutexTimeoutMs) { - this->mutexTimeout = mutexTimeoutMs; -} - -#endif /* FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ */ diff --git a/thermal/CMakeLists.txt b/thermal/CMakeLists.txt index 67664fbe5..ad5327214 100644 --- a/thermal/CMakeLists.txt +++ b/thermal/CMakeLists.txt @@ -1,10 +1,10 @@ target_sources(${LIB_FSFW_NAME} PRIVATE AbstractTemperatureSensor.cpp - CoreComponent.cpp Heater.cpp RedundantHeater.cpp + ThermalComponentCore.cpp ThermalComponent.cpp ThermalModule.cpp - ThermalMonitor.cpp + ThermalMonitorReporter.cpp ) diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 61e40d19c..6400d284c 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -7,7 +7,12 @@ #include "../globalfunctions/timevalOperations.h" #include + +#ifdef WIN32 +#include +#else #include +#endif class Clock { public: diff --git a/unittest/core/CatchFactory.cpp b/unittest/core/CatchFactory.cpp new file mode 100644 index 000000000..3177212f4 --- /dev/null +++ b/unittest/core/CatchFactory.cpp @@ -0,0 +1,56 @@ +#include "CatchFactory.h" + +#include +#include + +#include +#include +#include + +/** + * @brief Produces system objects. + * @details + * Build tasks by using SystemObject Interface (Interface). + * Header files of all tasks must be included + * Please note that an object has to implement the system object interface + * if the interface validity is checked or retrieved later by using the + * get(object_id) function from the ObjectManagerIF. + * + * Framework objects are created first. + * + * @ingroup init + */ +void Factory::produce(void) { + setStaticFrameworkObjectIds(); + new EventManager(objects::EVENT_MANAGER); + new HealthTable(objects::HEALTH_TABLE); + new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER); + + { + PoolManager::LocalPoolConfig poolCfg = { + {100, 16}, {50, 32}, {25, 64} , {15, 128}, {5, 1024} + }; + new PoolManager(objects::TC_STORE, poolCfg); + } + + { + PoolManager::LocalPoolConfig poolCfg = { + {100, 16}, {50, 32}, {25, 64} , {15, 128}, {5, 1024} + }; + new PoolManager(objects::TM_STORE, poolCfg); + } + + { + PoolManager::LocalPoolConfig poolCfg = { + {100, 16}, {50, 32}, {25, 64} , {15, 128}, {5, 1024} + }; + new PoolManager(objects::IPC_STORE, poolCfg); + } + +} + +void Factory::setStaticFrameworkObjectIds() { + +} + + diff --git a/unittest/testcfg/CatchFactory.h b/unittest/core/CatchFactory.h similarity index 71% rename from unittest/testcfg/CatchFactory.h rename to unittest/core/CatchFactory.h index 84f9207e2..f06e7ae55 100644 --- a/unittest/testcfg/CatchFactory.h +++ b/unittest/core/CatchFactory.h @@ -1,5 +1,5 @@ -#ifndef FACTORY_H_ -#define FACTORY_H_ +#ifndef FSFW_CATCHFACTORY_H_ +#define FSFW_CATCHFACTORY_H_ #include @@ -13,4 +13,4 @@ namespace Factory { } -#endif /* FACTORY_H_ */ +#endif /* FSFW_CATCHFACTORY_H_ */ diff --git a/unittest/core/CatchSetup.cpp b/unittest/core/CatchSetup.cpp index cb5bd33ed..c93cf0323 100644 --- a/unittest/core/CatchSetup.cpp +++ b/unittest/core/CatchSetup.cpp @@ -1,6 +1,5 @@ +#include #include "CatchDefinitions.h" -#include "CatchFactory.h" - #include #ifdef GCOV @@ -10,15 +9,11 @@ #include "../../objectmanager/ObjectManager.h" #include "../../objectmanager/ObjectManagerIF.h" #include "../../storagemanager/StorageManagerIF.h" -#include "../../datapool/DataPool.h" #include "../../serviceinterface/ServiceInterfaceStream.h" /* Global instantiations normally done in main.cpp */ /* Initialize Data Pool */ -//namespace glob { -DataPool dataPool(datapool::dataPoolInit); -//} namespace sif { diff --git a/unittest/testcfg/CatchFactory.cpp b/unittest/testcfg/CatchFactory.cpp deleted file mode 100644 index c74a8126d..000000000 --- a/unittest/testcfg/CatchFactory.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "CatchFactory.h" - -#include -#include - -#include -#include -#include - -/** - * @brief Produces system objects. - * @details - * Build tasks by using SystemObject Interface (Interface). - * Header files of all tasks must be included - * Please note that an object has to implement the system object interface - * if the interface validity is checked or retrieved later by using the - * get(object_id) function from the ObjectManagerIF. - * - * Framework objects are created first. - * - * @ingroup init - */ -void Factory::produce(void) { - setStaticFrameworkObjectIds(); - new EventManager(objects::EVENT_MANAGER); - new HealthTable(objects::HEALTH_TABLE); - //new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER); - - { - static constexpr uint8_t NUMBER_OF_POOLS = 5; - const uint16_t element_sizes[NUMBER_OF_POOLS] = {16, 32, 64, 128, 1024}; - const uint16_t n_elements[NUMBER_OF_POOLS] = {100, 50, 25, 15, 5}; - new PoolManager(objects::TC_STORE, element_sizes, - n_elements); - } - - { - static constexpr uint8_t NUMBER_OF_POOLS = 5; - const uint16_t element_sizes[NUMBER_OF_POOLS] = {16, 32, 64, 128, 1024}; - const uint16_t n_elements[NUMBER_OF_POOLS] = {100, 50, 25, 15, 5}; - new PoolManager(objects::TM_STORE, element_sizes, - n_elements); - } - - { - static constexpr uint8_t NUMBER_OF_POOLS = 6; - const uint16_t element_sizes[NUMBER_OF_POOLS] = {32, 64, 512, - 1024, 2048, 4096}; - const uint16_t n_elements[NUMBER_OF_POOLS] = {200, 100, 50, 25, 15, 5}; - new PoolManager(objects::IPC_STORE, element_sizes, - n_elements); - } - -} - -void Factory::setStaticFrameworkObjectIds() { - -} - - diff --git a/unittest/testcfg/FSFWConfig.h b/unittest/testcfg/FSFWConfig.h index 599345602..6b0def902 100644 --- a/unittest/testcfg/FSFWConfig.h +++ b/unittest/testcfg/FSFWConfig.h @@ -1,44 +1,55 @@ #ifndef CONFIG_FSFWCONFIG_H_ #define CONFIG_FSFWCONFIG_H_ -#include +#include +#include //! Used to determine whether C++ ostreams are used //! Those can lead to code bloat. #define FSFW_CPP_OSTREAM_ENABLED 1 -//! Reduced printout to further decrese code size +//! Reduced printout to further decrease code size //! Be careful, this also turns off most diagnostic prinouts! -#define FSFW_REDUCED_PRINTOUT 0 +#define FSFW_ENHANCED_PRINTOUT 0 -//! Can be used to enable debugging printouts for developing the FSFW -#define FSFW_DEBUGGING 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 +//! Can be used to enable additional debugging printouts for developing the FSFW +#define FSFW_PRINT_VERBOSITY_LEVEL 0 //! If FSFW_OBJ_EVENT_TRANSLATION is set to one, //! additional output which requires the translation files translateObjects //! and translateEvents (and their compiled source files) #define FSFW_OBJ_EVENT_TRANSLATION 0 -//! If -DDEBUG is supplied in the build defines, there will be -//! additional output which requires the translation files translateObjects -//! and translateEvents (and their compiles source files) #if FSFW_OBJ_EVENT_TRANSLATION == 1 //! Specify whether info events are printed too. -#define FSFW_DEBUG_INFO 1 -#include -#include +#define FSFW_DEBUG_INFO 1 +#include "objects/translateObjects.h" +#include "events/translateEvents.h" #else #endif //! When using the newlib nano library, C99 support for stdio facilities //! will not be provided. This define should be set to 1 if this is the case. -#define FSFW_NO_C99_IO 1 +#define FSFW_NO_C99_IO 1 +//! Specify whether a special mode store is used for Subsystem components. +#define FSFW_USE_MODESTORE 0 + +namespace fsfwconfig { +//! Default timestamp size. The default timestamp will be an eight byte CDC +//! short timestamp. +static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 8; + +//! Configure the allocated pool sizes for the event manager. +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 = 3; +} #endif /* CONFIG_FSFWCONFIG_H_ */ diff --git a/unittest/testcfg/Makefile-FSFW-Tests b/unittest/testcfg/Makefile-FSFW-Tests index 2017d2bd8..550fd1dee 100644 --- a/unittest/testcfg/Makefile-FSFW-Tests +++ b/unittest/testcfg/Makefile-FSFW-Tests @@ -15,7 +15,7 @@ SHELL = /bin/sh # (can be overriden by adding CHIP=chip and BOARD=board to the command-line) # Unit Test can only be run on host machine for now (Linux) FRAMEWORK_PATH = fsfw -FILE_ROOT = $(FRAMEWORK_PATH)/unittest +TEST_FILE_ROOT = $(FRAMEWORK_PATH)/unittest BOARD = unittest LINUX = 1 OS_FSFW = linux @@ -58,9 +58,10 @@ endif UNIT_TEST = 1 # General folder paths -CONFIG_PATH = $(FILE_ROOT)/config -UNIT_TEST_PATH = $(FILE_ROOT)/tests -CORE_PATH = $(FILE_ROOT)/core +CONFIG_PATH = testcfg +# Core copy has to be copied as well. +CORE_PATH = core +UNIT_TEST_PATH = $(TEST_FILE_ROOT)/tests # Output file basename BASENAME = fsfw @@ -154,8 +155,8 @@ include $(S)/$(notdir $S).mk endef $(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE))) -INCLUDES += $(FILE_ROOT) -INCLUDES += $(FILE_ROOT)/catch2/ +INCLUDES += $(TEST_FILE_ROOT) +INCLUDES += $(TEST_FILE_ROOT)/catch2/ #------------------------------------------------------------------------------- # Source Files diff --git a/unittest/testcfg/testcfg.mk b/unittest/testcfg/testcfg.mk index 31d3b60a5..fca2f7327 100644 --- a/unittest/testcfg/testcfg.mk +++ b/unittest/testcfg/testcfg.mk @@ -6,11 +6,3 @@ CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp) CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp) INCLUDES += $(CURRENTPATH) -INCLUDES += $(CURRENTPATH)/objects -INCLUDES += $(CURRENTPATH)/ipc -INCLUDES += $(CURRENTPATH)/pollingsequence -INCLUDES += $(CURRENTPATH)/returnvalues -INCLUDES += $(CURRENTPATH)/tmtc -INCLUDES += $(CURRENTPATH)/events -INCLUDES += $(CURRENTPATH)/devices -INCLUDES += $(CURRENTPATH)/cdatapool