Merge remote-tracking branch 'upstream/development' into mueller/power-switcher-component-upstream
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
All checks were successful
fsfw/fsfw/pipeline/pr-development This commit looks good
This commit is contained in:
commit
eb494707af
14
CHANGELOG.md
14
CHANGELOG.md
@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Changes
|
||||
|
||||
- Bump C++ required version to C++17. Every project which uses the FSFW and every modern
|
||||
compiler supports it
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/622
|
||||
- HAL Linux SPI: Set the Clock Default State when setting new SPI speed
|
||||
and mode
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/573
|
||||
@ -28,6 +31,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
creation call. It allows passing context information and an arbitrary user argument into
|
||||
the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583
|
||||
- Clock:
|
||||
- `timeval` to `TimeOfDay_t`
|
||||
- Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/)
|
||||
- Moved the statics used by Clock in ClockCommon.cpp to this file
|
||||
- Better check for leap seconds
|
||||
- Added Unittests for Clock (only getter)
|
||||
|
||||
## Removed
|
||||
|
||||
@ -46,8 +55,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixed
|
||||
|
||||
- Move some CMake directives further up top so they are not ignored
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/621
|
||||
- Small bugfix in STM32 HAL for SPI
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/599
|
||||
- HAL GPIO: Improved error checking in `LinuxLibgpioIF::configureGpios(...)`. If a GPIO
|
||||
configuration fails, the function will exit prematurely with a dedicated error code
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/602
|
||||
|
||||
# [v4.0.0]
|
||||
|
||||
|
@ -1,5 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(LIB_FSFW_NAME fsfw)
|
||||
project(${LIB_FSFW_NAME})
|
||||
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
elseif(${CMAKE_CXX_STANDARD} LESS 17)
|
||||
message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++17 support")
|
||||
endif()
|
||||
|
||||
set(FSFW_VERSION 4)
|
||||
set(FSFW_SUBVERSION 0)
|
||||
set(FSFW_REVISION 0)
|
||||
@ -10,14 +20,15 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
set(FSFW_ETL_LIB_MAJOR_VERSION 20 CACHE STRING
|
||||
"ETL library major version requirement"
|
||||
)
|
||||
set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.2 CACHE STRING
|
||||
set(FSFW_ETL_LIB_VERSION ${FSFW_ETL_LIB_MAJOR_VERSION}.27.3 CACHE STRING
|
||||
"ETL library exact version requirement"
|
||||
)
|
||||
set(FSFW_ETL_LINK_TARGET etl::etl)
|
||||
|
||||
set(FSFW_CATCH2_LIB_MAJOR_VERSION 3 CACHE STRING
|
||||
"Catch2 library major version requirement"
|
||||
)
|
||||
set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview4 CACHE STRING
|
||||
set(FSFW_CATCH2_LIB_VERSION v${FSFW_CATCH2_LIB_MAJOR_VERSION}.0.0-preview5 CACHE STRING
|
||||
"Catch2 library exact version requirement"
|
||||
)
|
||||
|
||||
@ -54,11 +65,10 @@ option(FSFW_ADD_TMSTORAGE "Compile with tm storage components" OFF)
|
||||
# Contrib sources
|
||||
option(FSFW_ADD_SGP4_PROPAGATOR "Add SGP4 propagator code" OFF)
|
||||
|
||||
set(LIB_FSFW_NAME fsfw)
|
||||
|
||||
set(FSFW_TEST_TGT fsfw-tests)
|
||||
set(FSFW_DUMMY_TGT fsfw-dummy)
|
||||
|
||||
project(${LIB_FSFW_NAME})
|
||||
add_library(${LIB_FSFW_NAME})
|
||||
|
||||
if(FSFW_BUILD_UNITTESTS)
|
||||
@ -76,9 +86,7 @@ if(FSFW_BUILD_UNITTESTS)
|
||||
GIT_TAG ${FSFW_CATCH2_LIB_VERSION}
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(Catch2)
|
||||
#fixes regression -preview4, to be confirmed in later releases
|
||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
||||
list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2)
|
||||
endif()
|
||||
|
||||
set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg)
|
||||
@ -123,7 +131,22 @@ if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||
GIT_TAG ${FSFW_ETL_LIB_VERSION}
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(etl)
|
||||
list(APPEND FSFW_FETCH_CONTENT_TARGETS ${FSFW_ETL_LIB_NAME})
|
||||
endif()
|
||||
|
||||
# The documentation for FetchContent recommends declaring all the dependencies
|
||||
# before making them available. We make all declared dependency available here
|
||||
# after their declaration
|
||||
if(FSFW_FETCH_CONTENT_TARGETS)
|
||||
FetchContent_MakeAvailable(${FSFW_FETCH_CONTENT_TARGETS})
|
||||
if(TARGET ${FSFW_ETL_LIB_NAME})
|
||||
add_library(${FSFW_ETL_LINK_TARGET} ALIAS ${FSFW_ETL_LIB_NAME})
|
||||
endif()
|
||||
if(TARGET Catch2)
|
||||
# Fixes regression -preview4, to be confirmed in later releases
|
||||
# Related GitHub issue: https://github.com/catchorg/Catch2/issues/2417
|
||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(FSFW_CORE_INC_PATH "inc")
|
||||
@ -138,12 +161,6 @@ target_include_directories(${LIB_FSFW_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
elseif(${CMAKE_CXX_STANDARD} LESS 11)
|
||||
message(FATAL_ERROR "Compiling the FSFW requires a minimum of C++11 support")
|
||||
endif()
|
||||
|
||||
# Backwards comptability
|
||||
if(OS_FSFW AND NOT FSFW_OSAL)
|
||||
@ -387,7 +404,7 @@ target_compile_options(${LIB_FSFW_NAME} PRIVATE
|
||||
)
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
||||
${FSFW_ETL_LIB_NAME}
|
||||
${FSFW_ETL_LINK_TARGET}
|
||||
${FSFW_ADDITIONAL_LINK_LIBS}
|
||||
)
|
||||
|
||||
|
@ -6,3 +6,9 @@ RUN apt-get --yes upgrade
|
||||
#tzdata is a dependency, won't install otherwise
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping
|
||||
|
||||
RUN git clone https://github.com/catchorg/Catch2.git && \
|
||||
cd Catch2 && \
|
||||
git checkout v3.0.0-preview5 && \
|
||||
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
|
||||
cmake --build build/ --target install
|
||||
|
2
automation/Jenkinsfile
vendored
2
automation/Jenkinsfile
vendored
@ -3,7 +3,7 @@ pipeline {
|
||||
BUILDDIR = 'build-tests'
|
||||
}
|
||||
agent {
|
||||
docker { image 'fsfw-ci:d1'}
|
||||
docker { image 'fsfw-ci:d2'}
|
||||
}
|
||||
stages {
|
||||
stage('Clean') {
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "MgmLIS3MDLHandler.h"
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
|
||||
MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication,
|
||||
CookieIF *comCookie, uint32_t transitionDelay)
|
||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||
|
@ -12,9 +12,14 @@ if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
||||
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
||||
add_subdirectory(gpio)
|
||||
endif()
|
||||
add_subdirectory(spi)
|
||||
add_subdirectory(i2c)
|
||||
add_subdirectory(uart)
|
||||
# Adding those does not really make sense on Apple systems which
|
||||
# are generally host systems. It won't even compile as the headers
|
||||
# are missing
|
||||
if(NOT APPLE)
|
||||
add_subdirectory(i2c)
|
||||
add_subdirectory(spi)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(uio)
|
||||
|
@ -44,6 +44,7 @@ ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
for (auto& gpioConfig : mapToAdd) {
|
||||
auto& gpioType = gpioConfig.second->gpioType;
|
||||
switch (gpioType) {
|
||||
@ -55,7 +56,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
configureGpioByChip(gpioConfig.first, *regularGpio);
|
||||
result = configureGpioByChip(gpioConfig.first, *regularGpio);
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): {
|
||||
@ -63,7 +64,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
configureGpioByLabel(gpioConfig.first, *regularGpio);
|
||||
result = configureGpioByLabel(gpioConfig.first, *regularGpio);
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): {
|
||||
@ -71,7 +72,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
configureGpioByLineName(gpioConfig.first, *regularGpio);
|
||||
result = configureGpioByLineName(gpioConfig.first, *regularGpio);
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::CALLBACK): {
|
||||
@ -83,8 +84,11 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||
gpioCallback->initValue, gpioCallback->callbackArgs);
|
||||
}
|
||||
}
|
||||
if (result != RETURN_OK) {
|
||||
return GPIO_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId,
|
||||
|
@ -29,6 +29,8 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4);
|
||||
static constexpr ReturnValue_t GPIO_DUPLICATE_DETECTED =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 5);
|
||||
static constexpr ReturnValue_t GPIO_INIT_FAILED =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 6);
|
||||
|
||||
LinuxLibgpioIF(object_id_t objectId);
|
||||
virtual ~LinuxLibgpioIF();
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
||||
#include "SpiCookie.h"
|
||||
|
||||
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev,
|
||||
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed)
|
||||
|
@ -265,6 +265,7 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
|
||||
cfsetispeed(options, B230400);
|
||||
cfsetospeed(options, B230400);
|
||||
break;
|
||||
#ifndef __APPLE__
|
||||
case UartBaudRate::RATE_460800:
|
||||
cfsetispeed(options, B460800);
|
||||
cfsetospeed(options, B460800);
|
||||
@ -313,6 +314,7 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
|
||||
cfsetispeed(options, B4000000);
|
||||
cfsetospeed(options, B4000000);
|
||||
break;
|
||||
#endif // ! __APPLE__
|
||||
default:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
||||
|
@ -24,9 +24,7 @@ void UartCookie::setParityEven() { parity = Parity::EVEN; }
|
||||
|
||||
Parity UartCookie::getParity() const { return parity; }
|
||||
|
||||
void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) {
|
||||
bitsPerWord = bitsPerWord_;
|
||||
}
|
||||
void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
|
||||
|
||||
BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; }
|
||||
|
||||
|
@ -44,7 +44,7 @@ class HeaderSerializer : public SerializeIF, public PduHeaderIF {
|
||||
cfdp::WidthInBytes getLenEntityIds() const override;
|
||||
cfdp::WidthInBytes getLenSeqNum() const override;
|
||||
cfdp::SegmentMetadataFlag getSegmentMetadataFlag() const override;
|
||||
bool hasSegmentMetadataFlag() const;
|
||||
bool hasSegmentMetadataFlag() const override;
|
||||
void setSegmentationControl(cfdp::SegmentationControl);
|
||||
|
||||
void getSourceId(cfdp::EntityId& sourceId) const override;
|
||||
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
template <typename T, size_t MAX_SIZE, typename count_t = uint8_t>
|
||||
class FixedArrayList : public ArrayList<T, count_t> {
|
||||
#if !defined(_MSC_VER)
|
||||
#if !defined(_MSC_VER) && !defined(__clang__)
|
||||
static_assert(MAX_SIZE <= (std::pow(2, sizeof(count_t) * 8) - 1),
|
||||
"count_t is not large enough to hold MAX_SIZE");
|
||||
#endif
|
||||
|
@ -10,16 +10,23 @@ class HybridIterator : public LinkedElement<T>::Iterator, public ArrayList<T, co
|
||||
HybridIterator() {}
|
||||
|
||||
HybridIterator(typename LinkedElement<T>::Iterator *iter)
|
||||
: LinkedElement<T>::Iterator(*iter), value(iter->value), linked(true) {}
|
||||
: LinkedElement<T>::Iterator(*iter), linked(true) {
|
||||
if (iter != nullptr) {
|
||||
value = iter->value;
|
||||
}
|
||||
}
|
||||
|
||||
HybridIterator(LinkedElement<T> *start)
|
||||
: LinkedElement<T>::Iterator(start), value(start->value), linked(true) {}
|
||||
HybridIterator(LinkedElement<T> *start) : LinkedElement<T>::Iterator(start), linked(true) {
|
||||
if (start != nullptr) {
|
||||
value = start->value;
|
||||
}
|
||||
}
|
||||
|
||||
HybridIterator(typename ArrayList<T, count_t>::Iterator start,
|
||||
typename ArrayList<T, count_t>::Iterator end)
|
||||
: ArrayList<T, count_t>::Iterator(start), value(start.value), linked(false), end(end.value) {
|
||||
if (value == this->end) {
|
||||
value = NULL;
|
||||
value = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ class ControllerBase : public HasModesIF,
|
||||
virtual void performControlOperation() = 0;
|
||||
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) = 0;
|
||||
uint32_t *msToReachTheMode) override = 0;
|
||||
|
||||
const object_id_t parentId;
|
||||
|
||||
@ -80,9 +80,9 @@ class ControllerBase : public HasModesIF,
|
||||
|
||||
/** Mode helpers */
|
||||
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||
virtual void setToExternalControl();
|
||||
virtual void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
virtual void setToExternalControl() override;
|
||||
virtual void announceMode(bool recursive);
|
||||
/** HK helpers */
|
||||
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
||||
|
@ -109,7 +109,7 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF, public HasRetu
|
||||
*/
|
||||
virtual ReturnValue_t unlockDataPool() override;
|
||||
|
||||
virtual uint16_t getFillCount() const;
|
||||
virtual uint16_t getFillCount() const override;
|
||||
|
||||
/* SerializeIF implementations */
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||
|
@ -787,9 +787,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i
|
||||
// Serialize set packet into store.
|
||||
size_t size = 0;
|
||||
result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeId);
|
||||
return result;
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeId);
|
||||
return result;
|
||||
}
|
||||
if (expectedSize != size) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateSetStructurePacket",
|
||||
@ -806,8 +806,8 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, bool i
|
||||
}
|
||||
|
||||
result = hkQueue->reply(&reply);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeId);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -94,13 +94,14 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
const uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount) / 8.0);
|
||||
uint8_t *validityPtr = nullptr;
|
||||
#ifdef _MSC_VER
|
||||
/* Use a std::vector here because MSVC will (rightly) not create a fixed size array
|
||||
with a non constant size specifier */
|
||||
std::vector<uint8_t> validityMask(validityMaskSize);
|
||||
#if defined(_MSC_VER) || defined(__clang__)
|
||||
// Use a std::vector here because MSVC will (rightly) not create a fixed size array
|
||||
// with a non constant size specifier. The Apple compiler (LLVM) will not accept
|
||||
// the initialization of a variable sized array
|
||||
std::vector<uint8_t> validityMask(validityMaskSize, 0);
|
||||
validityPtr = validityMask.data();
|
||||
#else
|
||||
uint8_t validityMask[validityMaskSize] = {0};
|
||||
uint8_t validityMask[validityMaskSize] = {};
|
||||
validityPtr = validityMask;
|
||||
#endif
|
||||
uint8_t validBufferIndex = 0;
|
||||
|
@ -23,8 +23,8 @@ class LocalPoolObjectBase : public PoolVariableIF, public HasReturnvaluesIF, pub
|
||||
LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId, DataSetIF* dataSet = nullptr,
|
||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE);
|
||||
|
||||
void setReadWriteMode(pool_rwm_t newReadWriteMode);
|
||||
pool_rwm_t getReadWriteMode() const;
|
||||
void setReadWriteMode(pool_rwm_t newReadWriteMode) override;
|
||||
pool_rwm_t getReadWriteMode() const override;
|
||||
|
||||
bool isValid() const override;
|
||||
void setValid(bool valid) override;
|
||||
|
@ -458,16 +458,15 @@ size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) {
|
||||
DeviceCommandId_t replyId = NO_COMMAND_ID;
|
||||
DeviceCommandMap::iterator command = cookieInfo.pendingCommand;
|
||||
if (command->second.useAlternativeReplyId) {
|
||||
replyId = command->second.alternativeReplyId;
|
||||
}
|
||||
else {
|
||||
replyId = commandId;
|
||||
replyId = command->second.alternativeReplyId;
|
||||
} else {
|
||||
replyId = commandId;
|
||||
}
|
||||
DeviceReplyIter iter = deviceReplyMap.find(replyId);
|
||||
if (iter != deviceReplyMap.end()) {
|
||||
if (iter->second.delayCycles != 0) {
|
||||
return iter->second.replyLen;
|
||||
}
|
||||
if (iter->second.delayCycles != 0) {
|
||||
return iter->second.replyLen;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* @param counter Specifies which Action to perform
|
||||
* @return RETURN_OK for successful execution
|
||||
*/
|
||||
virtual ReturnValue_t performOperation(uint8_t counter);
|
||||
virtual ReturnValue_t performOperation(uint8_t counter) override;
|
||||
|
||||
/**
|
||||
* @brief Initializes the device handler
|
||||
@ -173,7 +173,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* Calls fillCommandAndReplyMap().
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t initialize();
|
||||
virtual ReturnValue_t initialize() override;
|
||||
|
||||
/**
|
||||
* @brief Intialization steps performed after all tasks have been created.
|
||||
@ -1058,11 +1058,11 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* @param parameter1 Optional parameter 1
|
||||
* @param parameter2 Optional parameter 2
|
||||
*/
|
||||
void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
||||
void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) override;
|
||||
/**
|
||||
* Same as triggerEvent, but for forwarding if object is used as proxy.
|
||||
*/
|
||||
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const;
|
||||
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override;
|
||||
|
||||
/**
|
||||
* Checks if current mode is transitional mode.
|
||||
|
@ -25,7 +25,7 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
|
||||
: BinaryTree<SerializeableMatcherIF<T>>(root.element), maxDepth(maxDepth) {}
|
||||
MatchTree() : BinaryTree<SerializeableMatcherIF<T>>(), maxDepth(-1) {}
|
||||
virtual ~MatchTree() {}
|
||||
virtual bool match(T number) { return matchesTree(number); }
|
||||
virtual bool match(T number) override { return matchesTree(number); }
|
||||
bool matchesTree(T number) {
|
||||
iterator iter = this->begin();
|
||||
if (iter == this->end()) {
|
||||
@ -179,6 +179,9 @@ class MatchTree : public SerializeableMatcherIF<T>, public BinaryTree<Serializea
|
||||
virtual ReturnValue_t cleanUpElement(iterator position) { return HasReturnvaluesIF::RETURN_OK; }
|
||||
|
||||
bool matchSubtree(iterator iter, T number) {
|
||||
if (iter == nullptr) {
|
||||
return false;
|
||||
}
|
||||
bool isMatch = iter->match(number);
|
||||
if (isMatch) {
|
||||
if (iter.left() == this->end()) {
|
||||
|
@ -15,7 +15,7 @@ class RangeMatcher : public SerializeableMatcherIF<T> {
|
||||
RangeMatcher(T lowerBound, T upperBound, bool inverted = false)
|
||||
: inverted(inverted), lowerBound(lowerBound), upperBound(upperBound) {}
|
||||
|
||||
bool match(T input) {
|
||||
bool match(T input) override {
|
||||
if (inverted) {
|
||||
return !doMatch(input);
|
||||
} else {
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "MessageQueueBase.h"
|
||||
|
||||
MessageQueueBase::MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest,
|
||||
MqArgs* args): id(id) {
|
||||
MessageQueueBase::MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* args)
|
||||
: id(id) {
|
||||
this->defaultDest = defaultDest;
|
||||
if(args != nullptr) {
|
||||
if (args != nullptr) {
|
||||
this->args = *args;
|
||||
}
|
||||
}
|
||||
@ -23,35 +23,25 @@ ReturnValue_t MessageQueueBase::reply(MessageQueueMessageIF* message) {
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueBase::receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t* receivedFrom) {
|
||||
MessageQueueId_t* receivedFrom) {
|
||||
ReturnValue_t status = this->receiveMessage(message);
|
||||
*receivedFrom = this->last;
|
||||
return status;
|
||||
}
|
||||
|
||||
MessageQueueId_t MessageQueueBase::getLastPartner() const {
|
||||
return last;
|
||||
}
|
||||
MessageQueueId_t MessageQueueBase::getLastPartner() const { return last; }
|
||||
|
||||
MessageQueueId_t MessageQueueBase::getId() const {
|
||||
return id;
|
||||
}
|
||||
MessageQueueId_t MessageQueueBase::getId() const { return id; }
|
||||
|
||||
MqArgs& MessageQueueBase::getMqArgs() {
|
||||
return args;
|
||||
}
|
||||
MqArgs& MessageQueueBase::getMqArgs() { return args; }
|
||||
|
||||
void MessageQueueBase::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
||||
this->defaultDest = defaultDestination;
|
||||
}
|
||||
|
||||
MessageQueueId_t MessageQueueBase::getDefaultDestination() const {
|
||||
return defaultDest;
|
||||
}
|
||||
MessageQueueId_t MessageQueueBase::getDefaultDestination() const { return defaultDest; }
|
||||
|
||||
bool MessageQueueBase::isDefaultDestinationSet() const {
|
||||
return (defaultDest != NO_QUEUE);
|
||||
}
|
||||
bool MessageQueueBase::isDefaultDestinationSet() const { return (defaultDest != NO_QUEUE); }
|
||||
|
||||
ReturnValue_t MessageQueueBase::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
bool ignoreFault) {
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_
|
||||
#define FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_
|
||||
|
||||
#include <fsfw/ipc/definitions.h>
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <fsfw/ipc/definitions.h>
|
||||
|
||||
class MessageQueueBase: public MessageQueueIF {
|
||||
public:
|
||||
class MessageQueueBase : public MessageQueueIF {
|
||||
public:
|
||||
MessageQueueBase(MessageQueueId_t id, MessageQueueId_t defaultDest, MqArgs* mqArgs);
|
||||
virtual ~MessageQueueBase();
|
||||
|
||||
@ -17,25 +17,24 @@ public:
|
||||
virtual MessageQueueId_t getDefaultDestination() const override;
|
||||
virtual bool isDefaultDestinationSet() const override;
|
||||
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
bool ignoreFault) override;
|
||||
bool ignoreFault) override;
|
||||
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t* receivedFrom) override;
|
||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) override;
|
||||
MessageQueueId_t* receivedFrom) override;
|
||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) override;
|
||||
|
||||
// OSAL specific, forward the abstract function
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) = 0;
|
||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) = 0;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
MessageQueueId_t id = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t last = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t defaultDest = MessageQueueIF::NO_QUEUE;
|
||||
MqArgs args = {};
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_IPC_MESSAGEQUEUEBASE_H_ */
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_IPC_MESSAGEQUEUEIF_H_
|
||||
|
||||
#include <fsfw/ipc/definitions.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
@ -45,7 +46,8 @@ class MessageQueueIF {
|
||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) = 0;
|
||||
|
||||
/**
|
||||
* @brief This function reads available messages from the message queue and returns the sender.
|
||||
* @brief This function reads available messages from the message queue and returns the
|
||||
* sender.
|
||||
* @details
|
||||
* It works identically to the other receiveMessage call, but in addition
|
||||
* returns the sender's queue id.
|
||||
|
@ -34,7 +34,7 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
||||
SerializeElement<T> limitValue;
|
||||
SerializeElement<ReturnValue_t> oldState;
|
||||
SerializeElement<ReturnValue_t> newState;
|
||||
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE];
|
||||
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE] = {};
|
||||
SerializeElement<SerialBufferAdapter<uint8_t>> timestampSerializer;
|
||||
TimeStamperIF* timeStamper;
|
||||
MonitoringReportContent()
|
||||
@ -46,7 +46,6 @@ class MonitoringReportContent : public SerialLinkedListAdapter<SerializeIF> {
|
||||
limitValue(0),
|
||||
oldState(0),
|
||||
newState(0),
|
||||
rawTimestamp({0}),
|
||||
timestampSerializer(rawTimestamp, sizeof(rawTimestamp)),
|
||||
timeStamper(NULL) {
|
||||
setAllNext();
|
||||
|
@ -48,9 +48,9 @@ class SystemObject : public SystemObjectIF {
|
||||
virtual ~SystemObject();
|
||||
object_id_t getObjectId() const override;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual ReturnValue_t checkObjectConnections();
|
||||
virtual ReturnValue_t checkObjectConnections() override;
|
||||
|
||||
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const;
|
||||
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override;
|
||||
};
|
||||
|
||||
#endif /* FSFW_OBJECTMANAGER_SYSTEMOBJECT_H_ */
|
||||
|
@ -16,11 +16,13 @@
|
||||
//! Debugging preprocessor define.
|
||||
#define FSFW_UDP_RECV_WIRETAPPING_ENABLED 0
|
||||
|
||||
const timeval UdpTcPollingTask::DEFAULT_TIMEOUT = {0, 500000};
|
||||
|
||||
UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBridge,
|
||||
size_t maxRecvSize, double timeoutSeconds)
|
||||
: SystemObject(objectId), tmtcBridgeId(tmtcUdpBridge) {
|
||||
if (frameSize > 0) {
|
||||
this->frameSize = frameSize;
|
||||
if (maxRecvSize > 0) {
|
||||
this->frameSize = maxRecvSize;
|
||||
} else {
|
||||
this->frameSize = DEFAULT_MAX_RECV_SIZE;
|
||||
}
|
||||
@ -31,22 +33,20 @@ UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBrid
|
||||
receptionBuffer.resize(this->frameSize);
|
||||
|
||||
if (timeoutSeconds == -1) {
|
||||
receptionTimeout = DEFAULT_TIMEOUT;
|
||||
receptionTimeout = UdpTcPollingTask::DEFAULT_TIMEOUT;
|
||||
} else {
|
||||
receptionTimeout = timevalOperations::toTimeval(timeoutSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
UdpTcPollingTask::~UdpTcPollingTask() {}
|
||||
|
||||
ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) {
|
||||
[[noreturn]] ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) {
|
||||
/* Sender Address is cached here. */
|
||||
struct sockaddr senderAddress;
|
||||
struct sockaddr senderAddress {};
|
||||
socklen_t senderAddressSize = sizeof(senderAddress);
|
||||
|
||||
/* Poll for new UDP datagrams in permanent loop. */
|
||||
while (true) {
|
||||
int bytesReceived =
|
||||
ssize_t bytesReceived =
|
||||
recvfrom(this->serverSocket, reinterpret_cast<char*>(receptionBuffer.data()), frameSize,
|
||||
receptionFlags, &senderAddress, &senderAddressSize);
|
||||
if (bytesReceived == SOCKET_ERROR) {
|
||||
@ -70,7 +70,6 @@ ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) {
|
||||
}
|
||||
tmtcBridge->checkAndSetClientAddress(senderAddress);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
|
||||
@ -155,7 +154,7 @@ void UdpTcPollingTask::setTimeout(double timeoutSeconds) {
|
||||
#endif
|
||||
}
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
timeval tval;
|
||||
timeval tval {};
|
||||
tval = timevalOperations::toTimeval(timeoutSeconds);
|
||||
int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(receptionTimeout));
|
||||
if (result == -1) {
|
||||
|
@ -21,11 +21,11 @@ class UdpTcPollingTask : public TcpIpBase, public SystemObject, public Executabl
|
||||
public:
|
||||
static constexpr size_t DEFAULT_MAX_RECV_SIZE = 1500;
|
||||
//! 0.5 default milliseconds timeout for now.
|
||||
static constexpr timeval DEFAULT_TIMEOUT = {0, 500};
|
||||
static const timeval DEFAULT_TIMEOUT;
|
||||
|
||||
UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUdpBridge, size_t maxRecvSize = 0,
|
||||
double timeoutSeconds = -1);
|
||||
virtual ~UdpTcPollingTask();
|
||||
~UdpTcPollingTask() override = default;
|
||||
|
||||
/**
|
||||
* Turn on optional timeout for UDP polling. In the default mode,
|
||||
@ -34,9 +34,9 @@ class UdpTcPollingTask : public TcpIpBase, public SystemObject, public Executabl
|
||||
*/
|
||||
void setTimeout(double timeoutSeconds);
|
||||
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||
[[noreturn]] ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
protected:
|
||||
StorageManagerIF* tcStore = nullptr;
|
||||
@ -51,7 +51,7 @@ class UdpTcPollingTask : public TcpIpBase, public SystemObject, public Executabl
|
||||
std::vector<uint8_t> receptionBuffer;
|
||||
|
||||
size_t frameSize = 0;
|
||||
timeval receptionTimeout;
|
||||
timeval receptionTimeout{};
|
||||
|
||||
ReturnValue_t handleSuccessfullTcRead(size_t bytesRead);
|
||||
};
|
||||
|
@ -20,13 +20,13 @@
|
||||
const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
||||
|
||||
UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
std::string udpServerPort, object_id_t tmStoreId,
|
||||
const std::string& udpServerPort_, object_id_t tmStoreId,
|
||||
object_id_t tcStoreId)
|
||||
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||
if (udpServerPort == "") {
|
||||
this->udpServerPort = DEFAULT_SERVER_PORT;
|
||||
if (udpServerPort_.empty()) {
|
||||
udpServerPort = DEFAULT_SERVER_PORT;
|
||||
} else {
|
||||
this->udpServerPort = udpServerPort;
|
||||
udpServerPort = udpServerPort_;
|
||||
}
|
||||
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
@ -117,7 +117,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
||||
tcpip::printAddress(&clientAddress);
|
||||
#endif
|
||||
|
||||
int bytesSent = sendto(serverSocket, reinterpret_cast<const char *>(data), dataLen, flags,
|
||||
ssize_t bytesSent = sendto(serverSocket, reinterpret_cast<const char *>(data), dataLen, flags,
|
||||
&clientAddress, clientAddressLen);
|
||||
if (bytesSent == SOCKET_ERROR) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -150,7 +150,7 @@ void UdpTmTcBridge::checkAndSetClientAddress(sockaddr &newAddress) {
|
||||
clientAddressLen = sizeof(clientAddress);
|
||||
}
|
||||
|
||||
void UdpTmTcBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs) {
|
||||
this->timeoutType = timeoutType;
|
||||
this->mutexTimeoutMs = timeoutMs;
|
||||
void UdpTmTcBridge::setMutexProperties(MutexIF::TimeoutType timeoutType_, dur_millis_t timeoutMs) {
|
||||
timeoutType = timeoutType_;
|
||||
mutexTimeoutMs = timeoutMs;
|
||||
}
|
||||
|
@ -29,10 +29,10 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase {
|
||||
/* The ports chosen here should not be used by any other process. */
|
||||
static const std::string DEFAULT_SERVER_PORT;
|
||||
|
||||
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort = "",
|
||||
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, const std::string& udpServerPort = "",
|
||||
object_id_t tmStoreId = objects::TM_STORE,
|
||||
object_id_t tcStoreId = objects::TC_STORE);
|
||||
virtual ~UdpTmTcBridge();
|
||||
~UdpTmTcBridge() override;
|
||||
|
||||
/**
|
||||
* Set properties of internal mutex.
|
||||
@ -46,12 +46,12 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase {
|
||||
std::string getUdpPort() const;
|
||||
|
||||
protected:
|
||||
virtual ReturnValue_t sendTm(const uint8_t* data, size_t dataLen) override;
|
||||
ReturnValue_t sendTm(const uint8_t* data, size_t dataLen) override;
|
||||
|
||||
private:
|
||||
std::string udpServerPort;
|
||||
|
||||
struct sockaddr clientAddress;
|
||||
struct sockaddr clientAddress = {};
|
||||
socklen_t clientAddressLen = 0;
|
||||
|
||||
//! Access to the client address is mutex protected as it is set by another task.
|
||||
|
@ -11,9 +11,6 @@
|
||||
// TODO sanitize input?
|
||||
// TODO much of this code can be reused for tick-only systems
|
||||
|
||||
uint16_t Clock::leapSeconds = 0;
|
||||
MutexIF* Clock::timeMutex = nullptr;
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void) { return 1000; }
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_
|
||||
|
||||
#include <fsfw/ipc/MessageQueueBase.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "TaskManagement.h"
|
||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||
|
@ -1,24 +1,27 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
Clock.cpp
|
||||
FixedTimeslotTask.cpp
|
||||
MessageQueue.cpp
|
||||
Mutex.cpp
|
||||
MutexFactory.cpp
|
||||
PeriodicTask.cpp
|
||||
QueueFactory.cpp
|
||||
QueueMapManager.cpp
|
||||
SemaphoreFactory.cpp
|
||||
TaskFactory.cpp
|
||||
taskHelpers.cpp
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
Clock.cpp
|
||||
FixedTimeslotTask.cpp
|
||||
MessageQueue.cpp
|
||||
Mutex.cpp
|
||||
MutexFactory.cpp
|
||||
PeriodicTask.cpp
|
||||
QueueFactory.cpp
|
||||
QueueMapManager.cpp
|
||||
SemaphoreFactory.cpp
|
||||
TaskFactory.cpp
|
||||
taskHelpers.cpp
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
rt
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
if(NOT APPLE)
|
||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
||||
rt
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "fsfw/ipc/MutexGuard.h"
|
||||
#include "fsfw/platform.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
@ -11,9 +12,6 @@
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
uint16_t Clock::leapSeconds = 0;
|
||||
MutexIF* Clock::timeMutex = NULL;
|
||||
|
||||
using SystemClock = std::chrono::system_clock;
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void) {
|
||||
@ -127,6 +125,13 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
|
||||
auto fraction = now - seconds;
|
||||
time_t tt = SystemClock::to_time_t(now);
|
||||
ReturnValue_t result = checkOrCreateClockMutex();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
MutexGuard helper(timeMutex);
|
||||
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||
// Therefore we have to use a Mutex here
|
||||
struct tm* timeInfo;
|
||||
timeInfo = gmtime(&tt);
|
||||
time->year = timeInfo->tm_year + 1900;
|
||||
|
@ -1,17 +1,17 @@
|
||||
#ifndef FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_
|
||||
#define FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_
|
||||
|
||||
#include "fsfw/ipc/MessageQueueBase.h"
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||
#include "fsfw/ipc/MessageQueueBase.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||
#include "fsfw/ipc/MutexIF.h"
|
||||
#include "fsfw/ipc/definitions.h"
|
||||
#include "fsfw/timemanager/Clock.h"
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
/**
|
||||
* @brief This class manages sending and receiving of
|
||||
* message queue messages.
|
||||
|
@ -1,29 +1,29 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
Clock.cpp
|
||||
BinarySemaphore.cpp
|
||||
CountingSemaphore.cpp
|
||||
FixedTimeslotTask.cpp
|
||||
InternalErrorCodes.cpp
|
||||
MessageQueue.cpp
|
||||
Mutex.cpp
|
||||
MutexFactory.cpp
|
||||
PeriodicPosixTask.cpp
|
||||
PosixThread.cpp
|
||||
QueueFactory.cpp
|
||||
SemaphoreFactory.cpp
|
||||
TaskFactory.cpp
|
||||
tcpipHelpers.cpp
|
||||
unixUtility.cpp
|
||||
)
|
||||
Clock.cpp
|
||||
BinarySemaphore.cpp
|
||||
CountingSemaphore.cpp
|
||||
FixedTimeslotTask.cpp
|
||||
InternalErrorCodes.cpp
|
||||
MessageQueue.cpp
|
||||
Mutex.cpp
|
||||
MutexFactory.cpp
|
||||
PeriodicPosixTask.cpp
|
||||
PosixThread.cpp
|
||||
QueueFactory.cpp
|
||||
SemaphoreFactory.cpp
|
||||
TaskFactory.cpp
|
||||
tcpipHelpers.cpp
|
||||
unixUtility.cpp
|
||||
)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
target_link_libraries(${LIB_FSFW_NAME} PUBLIC
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
if(NOT APPLE)
|
||||
target_link_libraries(${LIB_FSFW_NAME} PUBLIC
|
||||
rt
|
||||
)
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME} INTERFACE
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
)
|
||||
endif()
|
||||
|
@ -8,11 +8,9 @@
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "fsfw/ipc/MutexGuard.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
uint16_t Clock::leapSeconds = 0;
|
||||
MutexIF* Clock::timeMutex = NULL;
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void) {
|
||||
uint32_t ticks = sysconf(_SC_CLK_TCK);
|
||||
return ticks;
|
||||
@ -117,7 +115,13 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
// TODO errno
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t result = checkOrCreateClockMutex();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
MutexGuard helper(timeMutex);
|
||||
// gmtime writes its output in a global buffer which is not Thread Safe
|
||||
// Therefore we have to use a Mutex here
|
||||
struct tm* timeInfo;
|
||||
timeInfo = gmtime(&timeUnix.tv_sec);
|
||||
time->year = timeInfo->tm_year + 1900;
|
||||
|
@ -61,8 +61,7 @@ class MessageQueue : public MessageQueueBase {
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
||||
ReturnValue_t flush(uint32_t* count) override;
|
||||
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) override;
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -6,9 +6,6 @@
|
||||
#include "fsfw/ipc/MutexGuard.h"
|
||||
#include "fsfw/osal/rtems/RtemsBasic.h"
|
||||
|
||||
uint16_t Clock::leapSeconds = 0;
|
||||
MutexIF* Clock::timeMutex = nullptr;
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void) {
|
||||
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
|
||||
return static_cast<uint32_t>(ticks_per_second);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
||||
|
||||
#include <fsfw/ipc/MessageQueueBase.h>
|
||||
|
||||
#include "RtemsBasic.h"
|
||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
@ -52,8 +53,8 @@ class MessageQueue : public MessageQueueBase {
|
||||
// Implement non-generic MessageQueueIF functions not handled by MessageQueueBase
|
||||
ReturnValue_t flush(uint32_t* count) override;
|
||||
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom = NO_QUEUE,
|