Compare commits
15 Commits
mueller/up
...
mueller/cl
Author | SHA1 | Date | |
---|---|---|---|
a7eb165f34 | |||
dd1e26e719 | |||
a2c024b24c | |||
e90960a7b6 | |||
e2b3cdd6c4 | |||
1e7a39a8e1 | |||
28380deab0 | |||
c361751751 | |||
17a153485d | |||
fffe1f812f | |||
2a9300e947 | |||
13f3a312be | |||
9705bf5d40 | |||
5425360876 | |||
b904d33cfe |
7
.run/fsfw-tests_coverage.run.xml
Normal file
7
.run/fsfw-tests_coverage.run.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="fsfw-tests_coverage" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="fsfw-example-hosted" TARGET_NAME="fsfw-tests_coverage" CONFIG_NAME="Debug Unittest" RUN_TARGET_PROJECT_NAME="fsfw-example-hosted" RUN_TARGET_NAME="fsfw-tests">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
7
.run/fsfw.run.xml
Normal file
7
.run/fsfw.run.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="fsfw" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="fsfw-tests" TARGET_NAME="fsfw" CONFIG_NAME="Debug Unittest" RUN_TARGET_PROJECT_NAME="fsfw-tests" RUN_TARGET_NAME="fsfw-tests">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -19,6 +19,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- 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
|
||||
- GPIO HAL: `Direction`, `GpioOperation` and `Levels` are enum classes now, which prevents
|
||||
name clashes with Windows defines.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||
- New CMake option `FSFW_HAL_LINUX_ADD_LIBGPIOD` to specifically exclude `gpiod` code.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||
- HAL Devicehandlers: Periodic printout is run-time configurable now
|
||||
@ -85,7 +91,6 @@ PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/636
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||
- HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585
|
||||
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
||||
|
||||
### Time
|
||||
|
||||
@ -134,6 +139,7 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
||||
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
||||
Easiest solution for now: Keep this option OFF by default.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
||||
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
||||
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
||||
inside `fsfw/version.h`
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||
|
@ -183,10 +183,7 @@ if(FSFW_BUILD_UNITTESTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} Finding and/or providing etl library with version ${FSFW_ETL_LIB_MAJOR_VERSION}"
|
||||
)
|
||||
message(STATUS "${MSG_PREFIX} Finding and/or providing ETL library")
|
||||
|
||||
# Check whether the user has already installed ETL first
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
@ -194,7 +191,7 @@ find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
|
||||
"No ETL installation was found with find_package. Installing and providing "
|
||||
"etl with FindPackage")
|
||||
include(FetchContent)
|
||||
|
||||
|
@ -46,9 +46,9 @@ class GpioIF : public HasReturnvaluesIF {
|
||||
* an ouput or input gpio.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to read.
|
||||
* @param gpioState State of GPIO will be written to this reference
|
||||
* @param gpioState State of GPIO will be written to this pointer.
|
||||
*/
|
||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, gpio::Levels& gpioState) = 0;
|
||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
||||
};
|
||||
|
||||
#endif /* COMMON_GPIO_GPIOIF_H_ */
|
||||
|
@ -9,7 +9,7 @@ using gpioId_t = uint16_t;
|
||||
|
||||
namespace gpio {
|
||||
|
||||
enum class Levels : int { LOW = 0, HIGH = 1, FAILED = -1, NONE = 99 };
|
||||
enum class Levels : int { LOW = 0, HIGH = 1, NONE = 99 };
|
||||
|
||||
enum class Direction : int { IN = 0, OUT = 1 };
|
||||
|
||||
|
@ -252,7 +252,6 @@ ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(localpool::DataPool &l
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry<float>({0.0}));
|
||||
poolManager.subscribeForPeriodicPacket(dataset.getSid(), false, 10.0, false);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,6 @@ MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCom
|
||||
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
|
||||
}
|
||||
|
||||
MgmLIS3MDLHandler::~MgmLIS3MDLHandler() {}
|
||||
|
||||
void MgmLIS3MDLHandler::doStartUp() {
|
||||
switch (internalState) {
|
||||
case (InternalState::STATE_NONE): {
|
||||
@ -90,7 +88,7 @@ ReturnValue_t MgmLIS3MDLHandler::buildTransitionDeviceCommand(DeviceCommandId_t
|
||||
|
||||
uint8_t MgmLIS3MDLHandler::readCommand(uint8_t command, bool continuousCom) {
|
||||
command |= (1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
if (continuousCom) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
@ -98,7 +96,7 @@ uint8_t MgmLIS3MDLHandler::readCommand(uint8_t command, bool continuousCom) {
|
||||
|
||||
uint8_t MgmLIS3MDLHandler::writeCommand(uint8_t command, bool continuousCom) {
|
||||
command &= ~(1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
if (continuousCom) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
@ -375,16 +373,13 @@ float MgmLIS3MDLHandler::getSensitivityFactor(MGMLIS3MDL::Sensitivies sens) {
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::enableTemperatureSensor(const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
if (commandData == nullptr) {
|
||||
return INVALID_COMMAND_PARAMETER;
|
||||
}
|
||||
triggerEvent(CHANGE_OF_SETUP_PARAMETER);
|
||||
uint32_t size = 2;
|
||||
commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1);
|
||||
if (commandDataLen > 1) {
|
||||
return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
|
||||
}
|
||||
switch (commandData[0]) {
|
||||
switch (*commandData) {
|
||||
case (MGMLIS3MDL::ON): {
|
||||
commandBuffer[1] = registers[0] | (1 << 7);
|
||||
break;
|
||||
@ -475,7 +470,6 @@ ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool(localpool::DataPool &lo
|
||||
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Y, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Z, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(MGMLIS3MDL::TEMPERATURE_CELCIUS, new PoolEntry<float>({0.0}));
|
||||
poolManager.subscribeForPeriodicPacket(dataset.getSid(), false, 10.0, false);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
|
||||
MgmLIS3MDLHandler(uint32_t objectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||
uint32_t transitionDelay);
|
||||
virtual ~MgmLIS3MDLHandler();
|
||||
~MgmLIS3MDLHandler() override = default;
|
||||
|
||||
void enablePeriodicPrintouts(bool enable, uint8_t divider);
|
||||
/**
|
||||
@ -46,7 +46,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
void doShutDown() override;
|
||||
void doStartUp() override;
|
||||
void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
|
||||
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
||||
uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) override;
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
|
||||
@ -60,9 +60,9 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
* @param packet
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
void modeChanged(void) override;
|
||||
void modeChanged() override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
|
||||
@ -72,8 +72,6 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
static const uint8_t SINGLE_COMMAND_ANSWER_LEN = 2;
|
||||
|
||||
uint32_t transitionDelay;
|
||||
// Single SPI command has 2 bytes, first for adress, second for content
|
||||
size_t singleComandSize = 2;
|
||||
// Has the size for all adresses of the lis3mdl + the continous write bit
|
||||
uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1];
|
||||
|
||||
@ -88,7 +86,6 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
uint8_t registers[MGMLIS3MDL::NR_OF_CTRL_REGISTERS];
|
||||
|
||||
uint8_t statusRegister = 0;
|
||||
bool goToNormalMode = false;
|
||||
|
||||
enum class InternalState {
|
||||
@ -111,14 +108,14 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
* @param single command to set the read-bit at
|
||||
* @param boolean to select a continuous read bit, default = false
|
||||
*/
|
||||
uint8_t readCommand(uint8_t command, bool continuousCom = false);
|
||||
static uint8_t readCommand(uint8_t command, bool continuousCom = false);
|
||||
|
||||
/**
|
||||
* Sets the write bit for the command
|
||||
* @param single command to set the write-bit at
|
||||
* @param boolean to select a continuous write bit, default = false
|
||||
*/
|
||||
uint8_t writeCommand(uint8_t command, bool continuousCom = false);
|
||||
static uint8_t writeCommand(uint8_t command, bool continuousCom = false);
|
||||
|
||||
/**
|
||||
* This Method gets the full scale for the measurement range
|
||||
|
@ -312,7 +312,6 @@ ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &loc
|
||||
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_X, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Y, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Z, new PoolEntry<float>({0.0}));
|
||||
poolManager.subscribeForPeriodicPacket(primaryDataset.getSid(), false, 10.0, false);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -330,9 +329,9 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
|
||||
int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8;
|
||||
|
||||
// Now scale to physical value in microtesla
|
||||
float fieldStrengthX = fieldStrengthRawX * scaleFactorX;
|
||||
float fieldStrengthY = fieldStrengthRawY * scaleFactorX;
|
||||
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX;
|
||||
float fieldStrengthX = static_cast<float>(fieldStrengthRawX) * scaleFactorX;
|
||||
float fieldStrengthY = static_cast<float>(fieldStrengthRawY) * scaleFactorY;
|
||||
float fieldStrengthZ = static_cast<float>(fieldStrengthRawZ) * scaleFactorZ;
|
||||
|
||||
if (periodicPrintout) {
|
||||
if (debugDivider.checkAndIncrement()) {
|
||||
|
@ -72,7 +72,6 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
||||
RM3100::Rm3100PrimaryDataset primaryDataset;
|
||||
|
||||
uint8_t commandBuffer[10];
|
||||
uint8_t commandBufferLen = 0;
|
||||
|
||||
uint8_t cmmRegValue = RM3100::CMM_VALUE;
|
||||
uint8_t tmrcRegValue = RM3100::TMRC_DEFAULT_VALUE;
|
||||
@ -100,4 +99,4 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
||||
PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3);
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICEHANDLING_MGMRM3100HANDLER_H_ */
|
||||
#endif /* MISSION_DEVICES_MGMRM3100HANDLER_H_ */
|
||||
|
@ -32,8 +32,6 @@ ReturnValue_t CommandExecutor::execute() {
|
||||
} else if (state == States::PENDING) {
|
||||
return COMMAND_PENDING;
|
||||
}
|
||||
// Reset data in read vector
|
||||
std::memset(readVec.data(), 0, readVec.size());
|
||||
currentCmdFile = popen(currentCmd.c_str(), "r");
|
||||
if (currentCmdFile == nullptr) {
|
||||
lastError = errno;
|
||||
@ -207,5 +205,3 @@ ReturnValue_t CommandExecutor::executeBlocking() {
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
const std::vector<char>& CommandExecutor::getReadVector() const { return readVec; }
|
||||
|
@ -109,8 +109,6 @@ class CommandExecutor {
|
||||
*/
|
||||
void reset();
|
||||
|
||||
const std::vector<char>& getReadVector() const;
|
||||
|
||||
private:
|
||||
std::string currentCmd;
|
||||
bool blocking = true;
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
UnixFileGuard::UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
||||
UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags,
|
||||
std::string diagnosticPrefix)
|
||||
: fileDescriptor(fileDescriptor) {
|
||||
if (fileDescriptor == nullptr) {
|
||||
|
@ -15,7 +15,7 @@ class UnixFileGuard {
|
||||
|
||||
static constexpr ReturnValue_t OPEN_FILE_FAILED = 1;
|
||||
|
||||
UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
||||
UnixFileGuard(std::string device, int* fileDescriptor, int flags,
|
||||
std::string diagnosticPrefix = "");
|
||||
|
||||
virtual ~UnixFileGuard();
|
||||
|
@ -1,27 +0,0 @@
|
||||
#ifndef FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
||||
#define FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
||||
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief Additional abstraction layer for handling GPIOs.
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class Gpio {
|
||||
public:
|
||||
Gpio(gpioId_t gpioId, GpioIF* gpioIF) : gpioId(gpioId), gpioIF(gpioIF) {
|
||||
if (gpioIF == nullptr) {
|
||||
sif::error << "Gpio::Gpio: Invalid GpioIF" << std::endl;
|
||||
}
|
||||
}
|
||||
ReturnValue_t pullHigh() { return gpioIF->pullHigh(gpioId); }
|
||||
ReturnValue_t pullLow() { return gpioIF->pullLow(gpioId); }
|
||||
|
||||
private:
|
||||
gpioId_t gpioId = gpio::NO_GPIO;
|
||||
GpioIF* gpioIF = nullptr;
|
||||
};
|
||||
|
||||
#endif /* FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_ */
|
@ -294,7 +294,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegularBase& regul
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState) {
|
||||
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -313,10 +313,7 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState)
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
gpioState = static_cast<gpio::Levels>(gpiod_line_get_value(regularGpio->lineHandle));
|
||||
if (gpioState == gpio::Levels::FAILED) {
|
||||
return GPIO_GET_VALUE_FAILED;
|
||||
}
|
||||
*gpioState = gpiod_line_get_value(regularGpio->lineHandle);
|
||||
} else {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||
if (gpioCallback->callback == nullptr) {
|
||||
|
@ -31,16 +31,14 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 5);
|
||||
static constexpr ReturnValue_t GPIO_INIT_FAILED =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 6);
|
||||
// Will be returned if getting the line value failed. Error type will be set to errno in this case
|
||||
static constexpr ReturnValue_t GPIO_GET_VALUE_FAILED =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 7);
|
||||
|
||||
LinuxLibgpioIF(object_id_t objectId);
|
||||
virtual ~LinuxLibgpioIF();
|
||||
|
||||
ReturnValue_t addGpios(GpioCookie* gpioCookie) override;
|
||||
ReturnValue_t pullHigh(gpioId_t gpioId) override;
|
||||
ReturnValue_t pullLow(gpioId_t gpioId) override;
|
||||
ReturnValue_t readGpio(gpioId_t gpioId, gpio::Levels& gpioState) override;
|
||||
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
|
||||
|
||||
private:
|
||||
static const size_t MAX_CHIPNAME_LENGTH = 11;
|
||||
|
@ -170,20 +170,18 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
|
||||
int readLen = read(fd, replyBuffer, requestLen);
|
||||
if (readLen != static_cast<int>(requestLen)) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
if (readLen < 0) {
|
||||
sif::warning << "I2cComIF::requestReceiveMessage: Reading from I2C "
|
||||
<< "device failed with error code " << errno << " | " << strerror(errno)
|
||||
<< std::endl;
|
||||
} else {
|
||||
sif::warning << "I2cComIF::requestReceiveMessage: Read only " << readLen << " from "
|
||||
<< requestLen << " bytes" << std::endl;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
#if FSFW_VERBOSE_LEVEL >= 1 and FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C "
|
||||
<< "device failed with error code " << errno << ". Description"
|
||||
<< " of error: " << strerror(errno) << std::endl;
|
||||
sif::error << "I2cComIF::requestReceiveMessage: Read only " << readLen << " from " << requestLen
|
||||
<< " bytes" << std::endl;
|
||||
#endif
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
|
||||
<< " bytes" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "fsfw/ipc/MutexIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
|
||||
class ManualCsLockWrapper : public HasReturnvaluesIF {
|
||||
public:
|
||||
ManualCsLockWrapper(MutexIF* lock, GpioIF* gpioIF, SpiCookie* cookie,
|
||||
MutexIF::TimeoutType type = MutexIF::TimeoutType::BLOCKING,
|
||||
uint32_t timeoutMs = 0)
|
||||
: lock(lock), gpioIF(gpioIF), cookie(cookie), type(type), timeoutMs(timeoutMs) {
|
||||
if (cookie == nullptr) {
|
||||
// TODO: Error? Or maybe throw exception..
|
||||
return;
|
||||
}
|
||||
cookie->setCsLockManual(true);
|
||||
lockResult = lock->lockMutex(type, timeoutMs);
|
||||
if (lockResult != RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
gpioResult = gpioIF->pullLow(cookie->getChipSelectPin());
|
||||
}
|
||||
|
||||
~ManualCsLockWrapper() {
|
||||
if (gpioResult == RETURN_OK) {
|
||||
gpioIF->pullHigh(cookie->getChipSelectPin());
|
||||
}
|
||||
cookie->setCsLockManual(false);
|
||||
if (lockResult == RETURN_OK) {
|
||||
lock->unlockMutex();
|
||||
}
|
||||
}
|
||||
ReturnValue_t lockResult;
|
||||
ReturnValue_t gpioResult;
|
||||
|
||||
private:
|
||||
MutexIF* lock;
|
||||
GpioIF* gpioIF;
|
||||
SpiCookie* cookie;
|
||||
MutexIF::TimeoutType type;
|
||||
uint32_t timeoutMs = 0;
|
||||
};
|
@ -15,8 +15,8 @@
|
||||
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
||||
#include "fsfw_hal/linux/utility.h"
|
||||
|
||||
SpiComIF::SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF)
|
||||
: SystemObject(objectId), gpioComIF(gpioComIF), dev(std::move(devname)) {
|
||||
SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF)
|
||||
: SystemObject(objectId), gpioComIF(gpioComIF) {
|
||||
if (gpioComIF == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -27,7 +27,7 @@ SpiComIF::SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF)
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
}
|
||||
|
||||
csMutex = MutexFactory::instance()->createMutex();
|
||||
spiMutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
||||
@ -85,7 +85,8 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
||||
spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms);
|
||||
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
UnixFileGuard fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR,
|
||||
"SpiComIF::initializeInterface");
|
||||
if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
@ -181,7 +182,8 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
int retval = 0;
|
||||
/* Prepare transfer */
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
std::string device = spiCookie->getSpiDevice();
|
||||
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
return OPENING_FILE_FAILED;
|
||||
}
|
||||
@ -194,27 +196,20 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
|
||||
bool fullDuplex = spiCookie->isFullDuplex();
|
||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||
bool csLockManual = spiCookie->getCsLockManual();
|
||||
|
||||
MutexIF::TimeoutType csType;
|
||||
dur_millis_t csTimeout = 0;
|
||||
// Pull SPI CS low. For now, no support for active high given
|
||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
||||
spiCookie->getMutexParams(csType, csTimeout);
|
||||
result = csMutex->lockMutex(csType, csTimeout);
|
||||
/* Pull SPI CS low. For now, no support for active high given */
|
||||
if (gpioId != gpio::NO_GPIO) {
|
||||
result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||
if (result != RETURN_OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
||||
<< std::endl;
|
||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl;
|
||||
#else
|
||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex\n");
|
||||
#endif
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
updateLinePolarity(fileDescriptor);
|
||||
result = gpioComIF->pullLow(gpioId);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
@ -226,8 +221,6 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
updateLinePolarity(fileDescriptor);
|
||||
}
|
||||
|
||||
/* Execute transfer */
|
||||
@ -255,9 +248,9 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
}
|
||||
}
|
||||
|
||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
||||
if (gpioId != gpio::NO_GPIO) {
|
||||
gpioComIF->pullHigh(gpioId);
|
||||
result = csMutex->unlockMutex();
|
||||
result = spiMutex->unlockMutex();
|
||||
if (result != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::sendMessage: Failed to unlock mutex" << std::endl;
|
||||
@ -285,8 +278,9 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
|
||||
ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::string device = spiCookie->getSpiDevice();
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||
if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
return OPENING_FILE_FAILED;
|
||||
}
|
||||
@ -298,22 +292,12 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool csLockManual = spiCookie->getCsLockManual();
|
||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||
MutexIF::TimeoutType csType;
|
||||
dur_millis_t csTimeout = 0;
|
||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
||||
spiCookie->getMutexParams(csType, csTimeout);
|
||||
result = csMutex->lockMutex(csType, csTimeout);
|
||||
if (gpioId != gpio::NO_GPIO) {
|
||||
result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||
if (result != RETURN_OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
||||
#endif
|
||||
sif::error << "SpiComIF::getSendSuccess: Failed to lock mutex" << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
@ -331,9 +315,9 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||
result = HALF_DUPLEX_TRANSFER_FAILED;
|
||||
}
|
||||
|
||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
||||
if (gpioId != gpio::NO_GPIO) {
|
||||
gpioComIF->pullHigh(gpioId);
|
||||
result = csMutex->unlockMutex();
|
||||
result = spiMutex->unlockMutex();
|
||||
if (result != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::getSendSuccess: Failed to unlock mutex" << std::endl;
|
||||
@ -362,7 +346,15 @@ ReturnValue_t SpiComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
MutexIF* SpiComIF::getCsMutex() { return csMutex; }
|
||||
MutexIF* SpiComIF::getMutex(MutexIF::TimeoutType* timeoutType, uint32_t* timeoutMs) {
|
||||
if (timeoutType != nullptr) {
|
||||
*timeoutType = this->timeoutType;
|
||||
}
|
||||
if (timeoutMs != nullptr) {
|
||||
*timeoutMs = this->timeoutMs;
|
||||
}
|
||||
return spiMutex;
|
||||
}
|
||||
|
||||
void SpiComIF::performSpiWiretapping(SpiCookie* spiCookie) {
|
||||
if (spiCookie == nullptr) {
|
||||
@ -409,27 +401,11 @@ void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed)
|
||||
if (retval != 0) {
|
||||
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed");
|
||||
}
|
||||
}
|
||||
|
||||
void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const {
|
||||
uint8_t tmpMode = 0;
|
||||
int retval = ioctl(spiFd, SPI_IOC_RD_MODE, &tmpMode);
|
||||
if (retval != 0) {
|
||||
utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Reading SPI mode failed");
|
||||
}
|
||||
mode = static_cast<spi::SpiModes>(tmpMode);
|
||||
|
||||
retval = ioctl(spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
|
||||
if (retval != 0) {
|
||||
utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Getting SPI speed failed");
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& SpiComIF::getSpiDev() const { return dev; }
|
||||
|
||||
void SpiComIF::updateLinePolarity(int spiFd) {
|
||||
// This updates the SPI clock default polarity. Only setting the mode does not update
|
||||
// the line state, which can be an issue on mode switches because the clock line will
|
||||
// switch the state after the chip select is pulled low
|
||||
clockUpdateTransfer.len = 0;
|
||||
int retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer);
|
||||
retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer);
|
||||
if (retval != 0) {
|
||||
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed");
|
||||
}
|
||||
|
@ -22,17 +22,17 @@ class SpiCookie;
|
||||
*/
|
||||
class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
public:
|
||||
static constexpr uint8_t CLASS_ID = CLASS_ID::HAL_SPI;
|
||||
static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI;
|
||||
static constexpr ReturnValue_t OPENING_FILE_FAILED =
|
||||
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0);
|
||||
HasReturnvaluesIF::makeReturnCode(spiRetvalId, 0);
|
||||
/* Full duplex (ioctl) transfer failure */
|
||||
static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED =
|
||||
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1);
|
||||
HasReturnvaluesIF::makeReturnCode(spiRetvalId, 1);
|
||||
/* Half duplex (read/write) transfer failure */
|
||||
static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED =
|
||||
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2);
|
||||
HasReturnvaluesIF::makeReturnCode(spiRetvalId, 2);
|
||||
|
||||
SpiComIF(object_id_t objectId, std::string devname, GpioIF* gpioComIF);
|
||||
SpiComIF(object_id_t objectId, GpioIF* gpioComIF);
|
||||
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
@ -44,8 +44,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
* @brief This function returns the mutex which can be used to protect the spi bus when
|
||||
* the chip select must be driven from outside of the com if.
|
||||
*/
|
||||
MutexIF* getCsMutex();
|
||||
void setMutexParams(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
||||
MutexIF* getMutex(MutexIF::TimeoutType* timeoutType = nullptr, uint32_t* timeoutMs = nullptr);
|
||||
|
||||
/**
|
||||
* Perform a regular send operation using Linux iotcl. This is public so it can be used
|
||||
@ -60,20 +59,6 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
|
||||
GpioIF* getGpioInterface();
|
||||
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
||||
void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const;
|
||||
|
||||
/**
|
||||
* This updates the SPI clock default polarity. Only setting the mode does not update
|
||||
* the line state, which can be an issue on mode switches because the clock line will
|
||||
* switch the state after the chip select is pulled low.
|
||||
*
|
||||
* It is recommended to call this function after #setSpiSpeedAndMode and after locking the
|
||||
* CS mutex if the SPI bus has multiple SPI devices with different speed and SPI modes attached.
|
||||
* @param spiFd
|
||||
*/
|
||||
void updateLinePolarity(int spiFd);
|
||||
|
||||
const std::string& getSpiDev() const;
|
||||
void performSpiWiretapping(SpiCookie* spiCookie);
|
||||
|
||||
ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer);
|
||||
@ -85,14 +70,10 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
};
|
||||
|
||||
GpioIF* gpioComIF = nullptr;
|
||||
std::string dev = "";
|
||||
/**
|
||||
* Protects the chip select operations. Lock when GPIO is pulled low, unlock after it was
|
||||
* pulled high
|
||||
*/
|
||||
MutexIF* csMutex = nullptr;
|
||||
// MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||
// uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT;
|
||||
|
||||
MutexIF* spiMutex = nullptr;
|
||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||
uint32_t timeoutMs = 20;
|
||||
spi_ioc_transfer clockUpdateTransfer = {};
|
||||
|
||||
using SpiDeviceMap = std::unordered_map<address_t, SpiInstance>;
|
||||
|
@ -1,25 +1,26 @@
|
||||
#include "SpiCookie.h"
|
||||
|
||||
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize,
|
||||
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev,
|
||||
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed)
|
||||
: SpiCookie(spi::SpiComIfModes::REGULAR, spiAddress, chipSelect, spiDev, maxSize, spiMode,
|
||||
spiSpeed, nullptr, nullptr) {}
|
||||
|
||||
SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize,
|
||||
spi::SpiModes spiMode, uint32_t spiSpeed)
|
||||
: SpiCookie(spi::SpiComIfModes::REGULAR, spiAddress, chipSelect, maxSize, spiMode, spiSpeed,
|
||||
nullptr, nullptr) {}
|
||||
: SpiCookie(spiAddress, gpio::NO_GPIO, spiDev, maxSize, spiMode, spiSpeed) {}
|
||||
|
||||
SpiCookie::SpiCookie(address_t spiAddress, const size_t maxSize, spi::SpiModes spiMode,
|
||||
uint32_t spiSpeed)
|
||||
: SpiCookie(spiAddress, gpio::NO_GPIO, maxSize, spiMode, spiSpeed) {}
|
||||
|
||||
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize,
|
||||
spi::SpiModes spiMode, uint32_t spiSpeed,
|
||||
spi::send_callback_function_t callback, void* args)
|
||||
: SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, chipSelect, maxSize, spiMode, spiSpeed,
|
||||
callback, args) {}
|
||||
|
||||
SpiCookie::SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect,
|
||||
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev,
|
||||
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed,
|
||||
spi::send_callback_function_t callback, void* args)
|
||||
: SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, chipSelect, spiDev, maxSize, spiMode,
|
||||
spiSpeed, callback, args) {}
|
||||
|
||||
SpiCookie::SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect,
|
||||
std::string spiDev, const size_t maxSize, spi::SpiModes spiMode,
|
||||
uint32_t spiSpeed, spi::send_callback_function_t callback, void* args)
|
||||
: spiAddress(spiAddress),
|
||||
chipSelectPin(chipSelect),
|
||||
spiDevice(spiDev),
|
||||
comIfMode(comIfMode),
|
||||
maxSize(maxSize),
|
||||
spiMode(spiMode),
|
||||
@ -49,6 +50,8 @@ size_t SpiCookie::getMaxBufferSize() const { return maxSize; }
|
||||
|
||||
address_t SpiCookie::getSpiAddress() const { return spiAddress; }
|
||||
|
||||
std::string SpiCookie::getSpiDevice() const { return spiDevice; }
|
||||
|
||||
void SpiCookie::setThreeWireSpi(bool enable) { uncommonParameters.threeWireSpi = enable; }
|
||||
|
||||
void SpiCookie::setLsbFirst(bool enable) { uncommonParameters.lsbFirst = enable; }
|
||||
@ -104,17 +107,3 @@ void SpiCookie::getCallback(spi::send_callback_function_t* callback, void** args
|
||||
*callback = this->sendCallback;
|
||||
*args = this->callbackArgs;
|
||||
}
|
||||
|
||||
void SpiCookie::setCsLockManual(bool enable) { manualCsLock = enable; }
|
||||
|
||||
bool SpiCookie::getCsLockManual() const { return manualCsLock; }
|
||||
|
||||
void SpiCookie::getMutexParams(MutexIF::TimeoutType& csTimeoutType, dur_millis_t& csTimeout) const {
|
||||
csTimeoutType = this->csTimeoutType;
|
||||
csTimeout = this->csTimeout;
|
||||
}
|
||||
|
||||
void SpiCookie::setMutexParams(MutexIF::TimeoutType csTimeoutType, dur_millis_t csTimeout) {
|
||||
this->csTimeoutType = csTimeoutType;
|
||||
this->csTimeout = csTimeout;
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
#define LINUX_SPI_SPICOOKIE_H_
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <fsfw/ipc/MutexIF.h>
|
||||
#include <fsfw/timemanager/clockDefinitions.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "../../common/gpio/gpioDefinitions.h"
|
||||
@ -22,8 +20,6 @@
|
||||
*/
|
||||
class SpiCookie : public CookieIF {
|
||||
public:
|
||||
static constexpr dur_millis_t DEFAULT_MUTEX_TIMEOUT = 20;
|
||||
|
||||
/**
|
||||
* Each SPI device will have a corresponding cookie. The cookie is used by the communication
|
||||
* interface and contains device specific information like the largest expected size to be
|
||||
@ -33,22 +29,23 @@ class SpiCookie : public CookieIF {
|
||||
* @param spiDev
|
||||
* @param maxSize
|
||||
*/
|
||||
SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode,
|
||||
uint32_t spiSpeed);
|
||||
SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize,
|
||||
spi::SpiModes spiMode, uint32_t spiSpeed);
|
||||
|
||||
/**
|
||||
* Like constructor above, but without a dedicated GPIO CS. Can be used for hardware
|
||||
* slave select or if CS logic is performed with decoders.
|
||||
*/
|
||||
SpiCookie(address_t spiAddress, const size_t maxReplySize, spi::SpiModes spiMode,
|
||||
uint32_t spiSpeed);
|
||||
SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxReplySize,
|
||||
spi::SpiModes spiMode, uint32_t spiSpeed);
|
||||
|
||||
/**
|
||||
* Use the callback mode of the SPI communication interface. The user can pass the callback
|
||||
* function here or by using the setter function #setCallbackMode
|
||||
*/
|
||||
SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode,
|
||||
uint32_t spiSpeed, spi::send_callback_function_t callback, void* args);
|
||||
SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize,
|
||||
spi::SpiModes spiMode, uint32_t spiSpeed, spi::send_callback_function_t callback,
|
||||
void* args);
|
||||
|
||||
/**
|
||||
* Get the callback function
|
||||
@ -58,6 +55,7 @@ class SpiCookie : public CookieIF {
|
||||
void getCallback(spi::send_callback_function_t* callback, void** args);
|
||||
|
||||
address_t getSpiAddress() const;
|
||||
std::string getSpiDevice() const;
|
||||
gpioId_t getChipSelectPin() const;
|
||||
size_t getMaxBufferSize() const;
|
||||
|
||||
@ -141,42 +139,9 @@ class SpiCookie : public CookieIF {
|
||||
*/
|
||||
void activateCsDeselect(bool deselectCs, uint16_t delayUsecs);
|
||||
|
||||
void getMutexParams(MutexIF::TimeoutType& csTimeoutType, dur_millis_t& csTimeout) const;
|
||||
void setMutexParams(MutexIF::TimeoutType csTimeoutType, dur_millis_t csTimeout);
|
||||
|
||||
void setCsLockManual(bool enable);
|
||||
bool getCsLockManual() const;
|
||||
|
||||
spi_ioc_transfer* getTransferStructHandle();
|
||||
|
||||
private:
|
||||
address_t spiAddress;
|
||||
gpioId_t chipSelectPin;
|
||||
|
||||
spi::SpiComIfModes comIfMode;
|
||||
|
||||
// Required for regular mode
|
||||
const size_t maxSize;
|
||||
spi::SpiModes spiMode;
|
||||
/**
|
||||
* If this is set to true, the SPI ComIF will not perform any mutex locking for the
|
||||
* CS mechanism. The user is responsible to locking and unlocking the mutex for the
|
||||
* whole duration of the transfers.
|
||||
*/
|
||||
bool manualCsLock = false;
|
||||
uint32_t spiSpeed;
|
||||
bool halfDuplex = false;
|
||||
|
||||
MutexIF::TimeoutType csTimeoutType = MutexIF::TimeoutType::WAITING;
|
||||
dur_millis_t csTimeout = DEFAULT_MUTEX_TIMEOUT;
|
||||
|
||||
// Required for callback mode
|
||||
spi::send_callback_function_t sendCallback = nullptr;
|
||||
void* callbackArgs = nullptr;
|
||||
|
||||
struct spi_ioc_transfer spiTransferStruct = {};
|
||||
UncommonParameters uncommonParameters;
|
||||
|
||||
/**
|
||||
* Internal constructor which initializes every field
|
||||
* @param spiAddress
|
||||
@ -189,8 +154,27 @@ class SpiCookie : public CookieIF {
|
||||
* @param args
|
||||
*/
|
||||
SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect,
|
||||
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed,
|
||||
std::string spiDev, const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed,
|
||||
spi::send_callback_function_t callback, void* args);
|
||||
|
||||
address_t spiAddress;
|
||||
gpioId_t chipSelectPin;
|
||||
std::string spiDevice;
|
||||
|
||||
spi::SpiComIfModes comIfMode;
|
||||
|
||||
// Required for regular mode
|
||||
const size_t maxSize;
|
||||
spi::SpiModes spiMode;
|
||||
uint32_t spiSpeed;
|
||||
bool halfDuplex = false;
|
||||
|
||||
// Required for callback mode
|
||||
spi::send_callback_function_t sendCallback = nullptr;
|
||||
void* callbackArgs = nullptr;
|
||||
|
||||
struct spi_ioc_transfer spiTransferStruct = {};
|
||||
UncommonParameters uncommonParameters;
|
||||
};
|
||||
|
||||
#endif /* LINUX_SPI_SPICOOKIE_H_ */
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
#include <fsfw/serviceinterface.h>
|
||||
|
||||
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
||||
size_t maxReplyLen, UartModes uartMode)
|
||||
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
|
||||
UartBaudRate baudrate, size_t maxReplyLen)
|
||||
: handlerId(handlerId),
|
||||
deviceFile(deviceFile),
|
||||
uartMode(uartMode),
|
||||
|
@ -69,8 +69,8 @@ class UartCookie : public CookieIF {
|
||||
* 8 databits (number of bits transfered with one uart frame)
|
||||
* One stop bit
|
||||
*/
|
||||
UartCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
||||
size_t maxReplyLen, UartModes uartMode = UartModes::NON_CANONICAL);
|
||||
UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
|
||||
UartBaudRate baudrate, size_t maxReplyLen);
|
||||
|
||||
virtual ~UartCookie();
|
||||
|
||||
|
@ -3,12 +3,6 @@ if [[ ! -f README.md ]]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
folder_list=(
|
||||
"./src"
|
||||
"./hal"
|
||||
"./tests"
|
||||
)
|
||||
|
||||
cmake_fmt="cmake-format"
|
||||
file_selectors="-iname CMakeLists.txt"
|
||||
if command -v ${cmake_fmt} &> /dev/null; then
|
||||
@ -21,10 +15,9 @@ fi
|
||||
cpp_format="clang-format"
|
||||
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
|
||||
if command -v ${cpp_format} &> /dev/null; then
|
||||
for dir in ${folder_list[@]}; do
|
||||
echo "Auto-formatting ${dir} recursively"
|
||||
find ${dir} ${file_selectors} | xargs clang-format --style=file -i
|
||||
done
|
||||
find ./src ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
find ./hal ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
find ./tests ${file_selectors} | xargs ${cpp_format} --style=file -i
|
||||
else
|
||||
echo "No ${cpp_format} tool found, not formatting C++/C files"
|
||||
fi
|
||||
|
@ -6,7 +6,7 @@
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||
: owner(setOwner), queueToUse(useThisQueue) {}
|
||||
|
||||
ActionHelper::~ActionHelper() {}
|
||||
ActionHelper::~ActionHelper() = default;
|
||||
|
||||
ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
|
||||
if (command->getCommand() == ActionMessage::EXECUTE_ACTION) {
|
||||
@ -59,7 +59,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { queueToUse = queue; }
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
const uint8_t* dataPtr = NULL;
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef FSFW_ACTION_ACTIONHELPER_H_
|
||||
#define FSFW_ACTION_ACTIONHELPER_H_
|
||||
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
/**
|
||||
* @brief Action Helper is a helper class which handles action messages
|
||||
*
|
||||
|
@ -2,9 +2,9 @@
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
ActionMessage::ActionMessage() {}
|
||||
ActionMessage::ActionMessage() = default;
|
||||
|
||||
ActionMessage::~ActionMessage() {}
|
||||
ActionMessage::~ActionMessage() = default;
|
||||
|
||||
void ActionMessage::setCommand(CommandMessage* message, ActionId_t fid,
|
||||
store_address_t parameters) {
|
||||
@ -64,9 +64,8 @@ void ActionMessage::clear(CommandMessage* message) {
|
||||
switch (message->getCommand()) {
|
||||
case EXECUTE_ACTION:
|
||||
case DATA_REPLY: {
|
||||
StorageManagerIF* ipcStore =
|
||||
ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore != NULL) {
|
||||
auto* ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore != nullptr) {
|
||||
ipcStore->deleteData(getStoreId(message));
|
||||
}
|
||||
break;
|
||||
|
@ -2,14 +2,14 @@
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
|
||||
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner)
|
||||
: owner(setOwner), queueToUse(NULL), ipcStore(NULL), commandCount(0), lastTarget(0) {}
|
||||
: owner(setOwner), queueToUse(nullptr), ipcStore(nullptr), commandCount(0), lastTarget(0) {}
|
||||
|
||||
CommandActionHelper::~CommandActionHelper() {}
|
||||
CommandActionHelper::~CommandActionHelper() = default;
|
||||
|
||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||
SerializeIF *data) {
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == nullptr) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
store_address_t storeId;
|
||||
@ -29,11 +29,8 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId
|
||||
|
||||
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||
const uint8_t *data, uint32_t size) {
|
||||
// if (commandCount != 0) {
|
||||
// return CommandsFunctionsIF::ALREADY_COMMANDING;
|
||||
// }
|
||||
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == NULL) {
|
||||
auto *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
|
||||
if (receiver == nullptr) {
|
||||
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
|
||||
}
|
||||
store_address_t storeId;
|
||||
@ -59,12 +56,12 @@ ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionI
|
||||
|
||||
ReturnValue_t CommandActionHelper::initialize() {
|
||||
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (ipcStore == NULL) {
|
||||
if (ipcStore == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
queueToUse = owner->getCommandQueuePtr();
|
||||
if (queueToUse == NULL) {
|
||||
if (queueToUse == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
@ -104,7 +101,7 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
|
||||
uint8_t CommandActionHelper::getCommandCount() const { return commandCount; }
|
||||
|
||||
void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) {
|
||||
const uint8_t *data = NULL;
|
||||
const uint8_t *data = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(storeId, &data, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
|
@ -14,14 +14,14 @@ class CommandActionHelper {
|
||||
friend class CommandsActionsIF;
|
||||
|
||||
public:
|
||||
CommandActionHelper(CommandsActionsIF* owner);
|
||||
explicit CommandActionHelper(CommandsActionsIF* owner);
|
||||
virtual ~CommandActionHelper();
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
|
||||
const uint8_t* data = nullptr, uint32_t size = 0);
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
|
||||
uint32_t size);
|
||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
||||
ReturnValue_t initialize();
|
||||
ReturnValue_t handleReply(CommandMessage* reply);
|
||||
uint8_t getCommandCount() const;
|
||||
[[nodiscard]] uint8_t getCommandCount() const;
|
||||
|
||||
private:
|
||||
CommandsActionsIF* owner;
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||
#define FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "CommandActionHelper.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* Interface to separate commanding actions of other objects.
|
||||
@ -21,7 +21,7 @@ class CommandsActionsIF {
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
||||
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
||||
virtual ~CommandsActionsIF() {}
|
||||
virtual ~CommandsActionsIF() = default;
|
||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||
|
||||
protected:
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef FSFW_ACTION_HASACTIONSIF_H_
|
||||
#define FSFW_ACTION_HASACTIONSIF_H_
|
||||
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "ActionHelper.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* @brief
|
||||
@ -40,12 +40,12 @@ class HasActionsIF {
|
||||
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4);
|
||||
virtual ~HasActionsIF() {}
|
||||
virtual ~HasActionsIF() = default;
|
||||
/**
|
||||
* Function to get the MessageQueueId_t of the implementing object
|
||||
* @return MessageQueueId_t of the object
|
||||
*/
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
[[nodiscard]] virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
/**
|
||||
* Execute or initialize the execution of a certain function.
|
||||
* The ActionHelpers will execute this function and behave differently
|
||||
|
@ -3,7 +3,7 @@
|
||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue)
|
||||
: ActionHelper(setOwner, useThisQueue), isExecuting(false) {}
|
||||
|
||||
SimpleActionHelper::~SimpleActionHelper() {}
|
||||
SimpleActionHelper::~SimpleActionHelper() = default;
|
||||
|
||||
void SimpleActionHelper::step(ReturnValue_t result) {
|
||||
// STEP_OFFESET is subtracted to compensate for adding offset in base
|
||||
@ -38,7 +38,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId
|
||||
ActionMessage::setStepReply(&reply, actionId, 0, HasActionsIF::IS_BUSY);
|
||||
queueToUse->sendMessage(commandedBy, &reply);
|
||||
}
|
||||
const uint8_t* dataPtr = NULL;
|
||||
const uint8_t* dataPtr = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
|
@ -11,15 +11,15 @@
|
||||
class SimpleActionHelper : public ActionHelper {
|
||||
public:
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
virtual ~SimpleActionHelper();
|
||||
~SimpleActionHelper() override;
|
||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
ReturnValue_t reportData(SerializeIF* data);
|
||||
|
||||
protected:
|
||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress);
|
||||
virtual void resetHelper();
|
||||
store_address_t dataAddress) override;
|
||||
void resetHelper() override;
|
||||
|
||||
private:
|
||||
bool isExecuting;
|
||||
@ -28,4 +28,4 @@ class SimpleActionHelper : public ActionHelper {
|
||||
uint8_t stepCount = 0;
|
||||
};
|
||||
|
||||
#endif /* SIMPLEACTIONHELPER_H_ */
|
||||
#endif /* FSFW_ACTION_SIMPLEACTIONHELPER_H_ */
|
||||
|
@ -12,9 +12,7 @@ object_id_t CFDPHandler::packetDestination = 0;
|
||||
|
||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||
: SystemObject(setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(
|
||||
CFDP_HANDLER_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
||||
distributor = dist;
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,12 @@ AckInfo::AckInfo(cfdp::FileDirectives ackedDirective, cfdp::ConditionCode ackedC
|
||||
}
|
||||
}
|
||||
|
||||
AckInfo::AckInfo() = default;
|
||||
|
||||
cfdp::ConditionCode AckInfo::getAckedConditionCode() const { return ackedConditionCode; }
|
||||
|
||||
void AckInfo::setAckedConditionCode(cfdp::ConditionCode ackedConditionCode) {
|
||||
this->ackedConditionCode = ackedConditionCode;
|
||||
void AckInfo::setAckedConditionCode(cfdp::ConditionCode ackedConditionCode_) {
|
||||
ackedConditionCode = ackedConditionCode_;
|
||||
if (ackedDirective == cfdp::FileDirectives::FINISH) {
|
||||
this->directiveSubtypeCode = 0b0001;
|
||||
} else {
|
||||
@ -26,20 +28,18 @@ void AckInfo::setAckedConditionCode(cfdp::ConditionCode ackedConditionCode) {
|
||||
|
||||
cfdp::FileDirectives AckInfo::getAckedDirective() const { return ackedDirective; }
|
||||
|
||||
void AckInfo::setAckedDirective(cfdp::FileDirectives ackedDirective) {
|
||||
this->ackedDirective = ackedDirective;
|
||||
void AckInfo::setAckedDirective(cfdp::FileDirectives ackedDirective_) {
|
||||
ackedDirective = ackedDirective_;
|
||||
}
|
||||
|
||||
uint8_t AckInfo::getDirectiveSubtypeCode() const { return directiveSubtypeCode; }
|
||||
|
||||
void AckInfo::setDirectiveSubtypeCode(uint8_t directiveSubtypeCode) {
|
||||
this->directiveSubtypeCode = directiveSubtypeCode;
|
||||
void AckInfo::setDirectiveSubtypeCode(uint8_t directiveSubtypeCode_) {
|
||||
directiveSubtypeCode = directiveSubtypeCode_;
|
||||
}
|
||||
|
||||
cfdp::AckTransactionStatus AckInfo::getTransactionStatus() const { return transactionStatus; }
|
||||
|
||||
AckInfo::AckInfo() {}
|
||||
|
||||
void AckInfo::setTransactionStatus(cfdp::AckTransactionStatus transactionStatus) {
|
||||
this->transactionStatus = transactionStatus;
|
||||
void AckInfo::setTransactionStatus(cfdp::AckTransactionStatus transactionStatus_) {
|
||||
transactionStatus = transactionStatus_;
|
||||
}
|
||||
|
@ -9,16 +9,16 @@ class AckInfo {
|
||||
AckInfo(cfdp::FileDirectives ackedDirective, cfdp::ConditionCode ackedConditionCode,
|
||||
cfdp::AckTransactionStatus transactionStatus, uint8_t directiveSubtypeCode = 0);
|
||||
|
||||
cfdp::ConditionCode getAckedConditionCode() const;
|
||||
void setAckedConditionCode(cfdp::ConditionCode ackedConditionCode);
|
||||
[[nodiscard]] cfdp::ConditionCode getAckedConditionCode() const;
|
||||
void setAckedConditionCode(cfdp::ConditionCode ackedConditionCode_);
|
||||
|
||||
cfdp::FileDirectives getAckedDirective() const;
|
||||
[[nodiscard]] cfdp::FileDirectives getAckedDirective() const;
|
||||
void setAckedDirective(cfdp::FileDirectives ackedDirective);
|
||||
|
||||
uint8_t getDirectiveSubtypeCode() const;
|
||||
[[nodiscard]] uint8_t getDirectiveSubtypeCode() const;
|
||||
void setDirectiveSubtypeCode(uint8_t directiveSubtypeCode);
|
||||
|
||||
cfdp::AckTransactionStatus getTransactionStatus() const;
|
||||
[[nodiscard]] cfdp::AckTransactionStatus getTransactionStatus() const;
|
||||
void setTransactionStatus(cfdp::AckTransactionStatus transactionStatus);
|
||||
|
||||
private:
|
||||
|
@ -13,7 +13,7 @@ class AckPduDeserializer : public FileDirectiveDeserializer {
|
||||
* @return
|
||||
* - cfdp::INVALID_DIRECTIVE_FIELDS: Invalid fields
|
||||
*/
|
||||
ReturnValue_t parseData();
|
||||
ReturnValue_t parseData() override;
|
||||
|
||||
private:
|
||||
bool checkAndSetCodes(uint8_t rawAckedByte, uint8_t rawAckedConditionCode);
|
||||
|
@ -18,7 +18,7 @@ class AckPduSerializer : public FileDirectiveSerializer {
|
||||
*/
|
||||
AckPduSerializer(AckInfo& ackInfo, PduConfig& pduConf);
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
[[nodiscard]] size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
@ -13,9 +13,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
||||
submode(SUBMODE_NONE),
|
||||
modeHelper(this),
|
||||
healthHelper(this, setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
commandQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
|
||||
}
|
||||
|
||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
@ -28,7 +26,7 @@ ReturnValue_t ControllerBase::initialize() {
|
||||
|
||||
MessageQueueId_t parentQueue = 0;
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
auto* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == nullptr) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
@ -54,7 +52,7 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { return commandQueue->
|
||||
|
||||
void ControllerBase::handleQueue() {
|
||||
CommandMessage command;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result;
|
||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
||||
result = commandQueue->receiveMessage(&command)) {
|
||||
result = modeHelper.handleModeCommand(&command);
|
||||
@ -75,20 +73,20 @@ void ControllerBase::handleQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||
void ControllerBase::startTransition(Mode_t mode_, Submode_t submode_) {
|
||||
changeHK(this->mode, this->submode, false);
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
this->mode = mode;
|
||||
this->submode = submode;
|
||||
mode = mode_;
|
||||
submode = submode_;
|
||||
modeHelper.modeChanged(mode, submode);
|
||||
modeChanged(mode, submode);
|
||||
announceMode(false);
|
||||
changeHK(this->mode, this->submode, true);
|
||||
}
|
||||
|
||||
void ControllerBase::getMode(Mode_t* mode, Submode_t* submode) {
|
||||
*mode = this->mode;
|
||||
*submode = this->submode;
|
||||
void ControllerBase::getMode(Mode_t* mode_, Submode_t* submode_) {
|
||||
*mode_ = this->mode;
|
||||
*submode_ = this->submode;
|
||||
}
|
||||
|
||||
void ControllerBase::setToExternalControl() { healthHelper.setHealth(EXTERNAL_CONTROL); }
|
||||
@ -101,7 +99,7 @@ ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void ControllerBase::modeChanged(Mode_t mode, Submode_t submode) { return; }
|
||||
void ControllerBase::modeChanged(Mode_t mode_, Submode_t submode_) {}
|
||||
|
||||
ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
||||
switch (health) {
|
||||
@ -117,6 +115,6 @@ ReturnValue_t ControllerBase::setHealth(HealthState health) {
|
||||
HasHealthIF::HealthState ControllerBase::getHealth() { return healthHelper.getHealth(); }
|
||||
void ControllerBase::setTaskIF(PeriodicTaskIF* task_) { executingTask = task_; }
|
||||
|
||||
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {}
|
||||
void ControllerBase::changeHK(Mode_t mode_, Submode_t submode_, bool enable) {}
|
||||
|
||||
ReturnValue_t ControllerBase::initializeAfterTaskCreation() { return HasReturnvaluesIF::RETURN_OK; }
|
||||
|
@ -24,21 +24,21 @@ class ControllerBase : public HasModesIF,
|
||||
static const Mode_t MODE_NORMAL = 2;
|
||||
|
||||
ControllerBase(object_id_t setObjectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||
virtual ~ControllerBase();
|
||||
~ControllerBase() override;
|
||||
|
||||
/** SystemObject override */
|
||||
virtual ReturnValue_t initialize() override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue() const override;
|
||||
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||
|
||||
/** HasHealthIF overrides */
|
||||
virtual ReturnValue_t setHealth(HealthState health) override;
|
||||
virtual HasHealthIF::HealthState getHealth() override;
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
HasHealthIF::HealthState getHealth() override;
|
||||
|
||||
/** ExecutableObjectIF overrides */
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
virtual void setTaskIF(PeriodicTaskIF *task) override;
|
||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
void setTaskIF(PeriodicTaskIF *task) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -54,7 +54,7 @@ class ControllerBase : public HasModesIF,
|
||||
*/
|
||||
virtual void performControlOperation() = 0;
|
||||
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) override = 0;
|
||||
|
||||
const object_id_t parentId;
|
||||
@ -80,10 +80,10 @@ class ControllerBase : public HasModesIF,
|
||||
|
||||
/** Mode helpers */
|
||||
virtual void modeChanged(Mode_t mode, Submode_t submode);
|
||||
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);
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
void setToExternalControl() override;
|
||||
void announceMode(bool recursive) override;
|
||||
/** HK helpers */
|
||||
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
|
||||
};
|
||||
|
@ -6,7 +6,7 @@ ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId, object_id_t
|
||||
poolManager(this, commandQueue),
|
||||
actionHelper(this, commandQueue) {}
|
||||
|
||||
ExtendedControllerBase::~ExtendedControllerBase() {}
|
||||
ExtendedControllerBase::~ExtendedControllerBase() = default;
|
||||
|
||||
ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy,
|
||||
@ -31,7 +31,7 @@ ReturnValue_t ExtendedControllerBase::handleCommandMessage(CommandMessage *messa
|
||||
|
||||
void ExtendedControllerBase::handleQueue() {
|
||||
CommandMessage command;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result;
|
||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
||||
result = commandQueue->receiveMessage(&command)) {
|
||||
result = actionHelper.handleActionMessage(&command);
|
||||
|
@ -18,16 +18,16 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
public HasLocalDataPoolIF {
|
||||
public:
|
||||
ExtendedControllerBase(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 3);
|
||||
virtual ~ExtendedControllerBase();
|
||||
~ExtendedControllerBase() override;
|
||||
|
||||
/* SystemObjectIF overrides */
|
||||
virtual ReturnValue_t initialize() override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue() const override;
|
||||
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||
|
||||
/* ExecutableObjectIF overrides */
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
virtual ReturnValue_t initializeAfterTaskCreation() override;
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
protected:
|
||||
LocalDataPoolManager poolManager;
|
||||
@ -39,31 +39,31 @@ class ExtendedControllerBase : public ControllerBase,
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) = 0;
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override = 0;
|
||||
|
||||
/**
|
||||
* Periodic helper from ControllerBase, implemented by child class.
|
||||
*/
|
||||
virtual void performControlOperation() = 0;
|
||||
void performControlOperation() override = 0;
|
||||
|
||||
/* Handle the four messages mentioned above */
|
||||
void handleQueue() override;
|
||||
|
||||
/* HasActionsIF overrides */
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
|
||||
/* HasLocalDatapoolIF overrides */
|
||||
virtual LocalDataPoolManager* getHkManagerHandle() override;
|
||||
virtual object_id_t getObjectId() const override;
|
||||
virtual uint32_t getPeriodicOperationFrequency() const override;
|
||||
LocalDataPoolManager* getHkManagerHandle() override;
|
||||
[[nodiscard]] object_id_t getObjectId() const override;
|
||||
[[nodiscard]] uint32_t getPeriodicOperationFrequency() const override;
|
||||
|
||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override = 0;
|
||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override = 0;
|
||||
|
||||
// Mode abstract functions
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override = 0;
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ class DataSetIF {
|
||||
* @brief This is an empty virtual destructor,
|
||||
* as it is proposed for C++ interfaces.
|
||||
*/
|
||||
virtual ~DataSetIF() {}
|
||||
virtual ~DataSetIF() = default;
|
||||
|
||||
/**
|
||||
* @brief This operation provides a method to register local data pool
|
||||
@ -39,7 +39,7 @@ class DataSetIF {
|
||||
*/
|
||||
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) = 0;
|
||||
|
||||
virtual uint16_t getFillCount() const = 0;
|
||||
[[nodiscard]] virtual uint16_t getFillCount() const = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_DATAPOOL_DATASETIF_H_ */
|
||||
|
@ -9,7 +9,7 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||
const size_t maxFillCount)
|
||||
: registeredVariables(registeredVariablesArray), maxFillCount(maxFillCount) {}
|
||||
|
||||
PoolDataSetBase::~PoolDataSetBase() {}
|
||||
PoolDataSetBase::~PoolDataSetBase() = default;
|
||||
|
||||
ReturnValue_t PoolDataSetBase::registerVariable(PoolVariableIF* variable) {
|
||||
if (registeredVariables == nullptr) {
|
||||
|
@ -64,7 +64,7 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF, public HasRetu
|
||||
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
||||
* commit() in between
|
||||
*/
|
||||
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
ReturnValue_t read(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t lockTimeout = 20) override;
|
||||
/**
|
||||
* @brief The commit call initializes writing back the registered variables.
|
||||
@ -84,7 +84,7 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF, public HasRetu
|
||||
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
||||
* contains non write-only variables
|
||||
*/
|
||||
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
ReturnValue_t commit(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t lockTimeout = 20) override;
|
||||
|
||||
/**
|
||||
@ -92,30 +92,29 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF, public HasRetu
|
||||
* @param variable
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) override;
|
||||
ReturnValue_t registerVariable(PoolVariableIF* variable) override;
|
||||
|
||||
/**
|
||||
* Provides the means to lock the underlying data structure to ensure
|
||||
* thread-safety. Default implementation is empty
|
||||
* @return Always returns -@c RETURN_OK
|
||||
*/
|
||||
virtual ReturnValue_t lockDataPool(
|
||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
ReturnValue_t lockDataPool(MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t timeoutMs = 20) override;
|
||||
/**
|
||||
* Provides the means to unlock the underlying data structure to ensure
|
||||
* thread-safety. Default implementation is empty
|
||||
* @return Always returns -@c RETURN_OK
|
||||
*/
|
||||
virtual ReturnValue_t unlockDataPool() override;
|
||||
ReturnValue_t unlockDataPool() override;
|
||||
|
||||
virtual uint16_t getFillCount() const override;
|
||||
[[nodiscard]] uint16_t getFillCount() const override;
|
||||
|
||||
/* SerializeIF implementations */
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize,
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
SerializeIF::Endianness streamEndianness) const override;
|
||||
virtual size_t getSerializedSize() const override;
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
[[nodiscard]] size_t getSerializedSize() const override;
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
|
||||
/**
|
||||
@ -156,7 +155,7 @@ class PoolDataSetBase : public PoolDataSetIF, public SerializeIF, public HasRetu
|
||||
const size_t maxFillCount = 0;
|
||||
|
||||
void setContainer(PoolVariableIF** variablesContainer);
|
||||
PoolVariableIF** getContainer() const;
|
||||
[[nodiscard]] PoolVariableIF** getContainer() const;
|
||||
|
||||
private:
|
||||
bool protectEveryReadCommitCall = false;
|
||||
|
@ -7,26 +7,24 @@
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
template <typename T>
|
||||
PoolEntry<T>::PoolEntry(uint8_t len, bool setValid) : length(len), valid(setValid) {
|
||||
this->address = new T[this->length]();
|
||||
std::memset(this->address, 0, this->getByteSize());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValues, bool setValid)
|
||||
: length(static_cast<uint8_t>(initValues.size())), valid(setValid) {
|
||||
this->address = new T[this->length]();
|
||||
if (initValues.size() > 0) {
|
||||
std::copy(initValues.begin(), initValues.end(), this->address);
|
||||
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, bool setValid)
|
||||
: length(static_cast<uint8_t>(initValue.size())), valid(setValid) {
|
||||
this->address = new T[this->length];
|
||||
if (initValue.size() == 0) {
|
||||
std::memset(this->address, 0, PoolEntry<T>::getByteSize());
|
||||
} else {
|
||||
std::copy(initValue.begin(), initValue.end(), this->address);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PoolEntry<T>::PoolEntry(const T* initValue, uint8_t setLength, bool setValid)
|
||||
PoolEntry<T>::PoolEntry(T* initValue, uint8_t setLength, bool setValid)
|
||||
: length(setLength), valid(setValid) {
|
||||
this->address = new T[this->length]();
|
||||
this->address = new T[this->length];
|
||||
if (initValue != nullptr) {
|
||||
std::memcpy(this->address, initValue, this->getByteSize());
|
||||
std::memcpy(this->address, initValue, PoolEntry<T>::getByteSize());
|
||||
} else {
|
||||
std::memset(this->address, 0, PoolEntry<T>::getByteSize());
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +62,7 @@ bool PoolEntry<T>::getValid() {
|
||||
|
||||
template <typename T>
|
||||
void PoolEntry<T>::print() {
|
||||
const char* validString = nullptr;
|
||||
const char* validString;
|
||||
if (valid) {
|
||||
validString = "Valid";
|
||||
} else {
|
||||
|
@ -33,9 +33,6 @@ class PoolEntry : public PoolEntryIF {
|
||||
"instead! The ECSS standard defines a boolean as a one bit "
|
||||
"field. Therefore it is preferred to store a boolean as an "
|
||||
"uint8_t");
|
||||
|
||||
PoolEntry(uint8_t len = 1, bool setValid = false);
|
||||
|
||||
/**
|
||||
* @brief In the classe's constructor, space is allocated on the heap and
|
||||
* potential initialization values are copied to that space.
|
||||
@ -52,7 +49,7 @@ class PoolEntry : public PoolEntryIF {
|
||||
* @param setValid
|
||||
* Sets the initialization flag. It is invalid by default.
|
||||
*/
|
||||
PoolEntry(std::initializer_list<T> initValue, bool setValid = false);
|
||||
PoolEntry(std::initializer_list<T> initValue = {0}, bool setValid = false);
|
||||
|
||||
/**
|
||||
* @brief In the classe's constructor, space is allocated on the heap and
|
||||
@ -65,7 +62,7 @@ class PoolEntry : public PoolEntryIF {
|
||||
* @param setValid
|
||||
* Sets the initialization flag. It is invalid by default.
|
||||
*/
|
||||
PoolEntry(const T* initValue, uint8_t setLength = 1, bool setValid = false);
|
||||
explicit PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false);
|
||||
|
||||
//! Explicitely deleted copy ctor, copying is not allowed.
|
||||
PoolEntry(const PoolEntry&) = delete;
|
||||
@ -80,7 +77,7 @@ class PoolEntry : public PoolEntryIF {
|
||||
* PoolEntries shall never be copied, as a copy might delete the variable
|
||||
* on the heap.
|
||||
*/
|
||||
~PoolEntry();
|
||||
~PoolEntry() override;
|
||||
|
||||
/**
|
||||
* Return typed pointer to start of data.
|
||||
@ -94,32 +91,32 @@ class PoolEntry : public PoolEntryIF {
|
||||
* For non-array pool entries return type size, for vector entries
|
||||
* return type size times the number of entries.
|
||||
*/
|
||||
uint8_t getSize();
|
||||
uint8_t getSize() override;
|
||||
/**
|
||||
* @brief This operation returns the size in bytes.
|
||||
* @details The size is calculated by sizeof(type) * array_size.
|
||||
*/
|
||||
uint16_t getByteSize();
|
||||
uint16_t getByteSize() override;
|
||||
/**
|
||||
* @brief This operation returns a the address pointer casted to void*.
|
||||
*/
|
||||
void* getRawData();
|
||||
void* getRawData() override;
|
||||
/**
|
||||
* @brief This method allows to set the valid information
|
||||
* of the pool entry.
|
||||
*/
|
||||
void setValid(bool isValid);
|
||||
void setValid(bool isValid) override;
|
||||
/**
|
||||
* @brief This method allows to get the valid information
|
||||
* of the pool entry.
|
||||
*/
|
||||
bool getValid();
|
||||
bool getValid() override;
|
||||
/**
|
||||
* @brief This is a debug method that prints all values and the valid
|
||||
* information to the screen. It prints all array entries in a row.
|
||||
*/
|
||||
void print();
|
||||
Type getType();
|
||||
void print() override;
|
||||
Type getType() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@ class PoolEntryIF {
|
||||
* @brief This is an empty virtual destructor,
|
||||
* as it is required for C++ interfaces.
|
||||
*/
|
||||
virtual ~PoolEntryIF() {}
|
||||
virtual ~PoolEntryIF() = default;
|
||||
/**
|
||||
* @brief getSize returns the array size of the entry.
|
||||
* A single variable parameter has size 1.
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
class PoolReadGuard {
|
||||
public:
|
||||
PoolReadGuard(ReadCommitIF* readObject,
|
||||
explicit PoolReadGuard(ReadCommitIF* readObject,
|
||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
|
||||
uint32_t mutexTimeout = 20)
|
||||
: readObject(readObject), mutexTimeout(mutexTimeout) {
|
||||
@ -29,7 +29,7 @@ class PoolReadGuard {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t getReadResult() const { return readResult; }
|
||||
[[nodiscard]] ReturnValue_t getReadResult() const { return readResult; }
|
||||
|
||||
/**
|
||||
* @brief Can be used to suppress commit on destruction.
|
||||
|
@ -1,28 +0,0 @@
|
||||
#ifndef FSFW_DATAPOOL_POOLVARLIST_H_
|
||||
#define FSFW_DATAPOOL_POOLVARLIST_H_
|
||||
|
||||
#include "../datapool/PoolVariableIF.h"
|
||||
#include "../datapoolglob/GlobalPoolVariable.h"
|
||||
template <class T, uint8_t n_var>
|
||||
class PoolVarList {
|
||||
private:
|
||||
GlobPoolVar<T> variables[n_var];
|
||||
|
||||
public:
|
||||
PoolVarList(const uint32_t set_id[n_var], DataSetIF* dataSet,
|
||||
PoolVariableIF::ReadWriteMode_t setReadWriteMode) {
|
||||
// I really should have a look at the new init list c++ syntax.
|
||||
if (dataSet == NULL) {
|
||||
return;
|
||||
}
|
||||
for (uint8_t count = 0; count < n_var; count++) {
|
||||
variables[count].dataPoolId = set_id[count];
|
||||
variables[count].readWriteMode = setReadWriteMode;
|
||||
dataSet->registerVariable(&variables[count]);
|
||||
}
|
||||
}
|
||||
|
||||
GlobPoolVar<T>& operator[](int i) { return variables[i]; }
|
||||
};
|
||||
|
||||
#endif /* FSFW_DATAPOOL_POOLVARLIST_H_ */
|
@ -24,8 +24,8 @@ class PoolVariableIF : public SerializeIF, public ReadCommitIF {
|
||||
static constexpr ReturnValue_t INVALID_READ_WRITE_MODE = MAKE_RETURN_CODE(0xA0);
|
||||
static constexpr ReturnValue_t INVALID_POOL_ENTRY = MAKE_RETURN_CODE(0xA1);
|
||||
|
||||
static constexpr bool VALID = 1;
|
||||
static constexpr bool INVALID = 0;
|
||||
static constexpr bool VALID = true;
|
||||
static constexpr bool INVALID = false;
|
||||
static constexpr uint32_t NO_PARAMETER = 0xffffffff;
|
||||
|
||||
enum ReadWriteMode_t { VAR_READ, VAR_WRITE, VAR_READ_WRITE };
|
||||
@ -34,23 +34,23 @@ class PoolVariableIF : public SerializeIF, public ReadCommitIF {
|
||||
* @brief This is an empty virtual destructor,
|
||||
* as it is proposed for C++ interfaces.
|
||||
*/
|
||||
virtual ~PoolVariableIF() {}
|
||||
~PoolVariableIF() override = default;
|
||||
/**
|
||||
* @brief This method returns if the variable is write-only,
|
||||
* read-write or read-only.
|
||||
*/
|
||||
virtual ReadWriteMode_t getReadWriteMode() const = 0;
|
||||
[[nodiscard]] virtual ReadWriteMode_t getReadWriteMode() const = 0;
|
||||
virtual void setReadWriteMode(ReadWriteMode_t newMode) = 0;
|
||||
|
||||
/**
|
||||
* @brief This operation shall return the data pool id of the variable.
|
||||
*/
|
||||
virtual uint32_t getDataPoolId() const = 0;
|
||||
[[nodiscard]] virtual uint32_t getDataPoolId() const = 0;
|
||||
/**
|
||||
* @brief With this call, the valid information of the
|
||||
* variable is returned.
|
||||
*/
|
||||
virtual bool isValid() const = 0;
|
||||
[[nodiscard]] virtual bool isValid() const = 0;
|
||||
/**
|
||||
* @brief With this call, the valid information of the variable is set.
|
||||
*/
|
||||
|
@ -12,7 +12,7 @@ class ReadCommitIF {
|
||||
friend class ReadCommitIFAttorney;
|
||||
|
||||
public:
|
||||
virtual ~ReadCommitIF() {}
|
||||
virtual ~ReadCommitIF() = default;
|
||||
virtual ReturnValue_t read(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) = 0;
|
||||
virtual ReturnValue_t commit(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs) = 0;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
class SharedDataSetIF {
|
||||
public:
|
||||
virtual ~SharedDataSetIF(){};
|
||||
virtual ~SharedDataSetIF() = default;
|
||||
|
||||
private:
|
||||
virtual ReturnValue_t lockDataset(MutexIF::TimeoutType timeoutType,
|
||||
|
@ -9,7 +9,8 @@ class MutexIF;
|
||||
*/
|
||||
class AccessPoolManagerIF {
|
||||
public:
|
||||
virtual ~AccessPoolManagerIF(){};
|
||||
virtual ~AccessPoolManagerIF() = default;
|
||||
;
|
||||
|
||||
virtual MutexIF* getLocalPoolMutex() = 0;
|
||||
|
||||
|
@ -44,14 +44,15 @@ class HasLocalDataPoolIF {
|
||||
friend class HasLocalDpIFUserAttorney;
|
||||
|
||||
public:
|
||||
virtual ~HasLocalDataPoolIF(){};
|
||||
virtual ~HasLocalDataPoolIF() = default;
|
||||
;
|
||||
|
||||
static constexpr uint32_t INVALID_LPID = localpool::INVALID_LPID;
|
||||
|
||||
virtual object_id_t getObjectId() const = 0;
|
||||
[[nodiscard]] virtual object_id_t getObjectId() const = 0;
|
||||
|
||||
/** Command queue for housekeeping messages. */
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
[[nodiscard]] virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
/**
|
||||
* Is used by pool owner to initialize the pool map once
|
||||
@ -66,7 +67,7 @@ class HasLocalDataPoolIF {
|
||||
* usually be the period the pool owner performs its periodic operation.
|
||||
* @return
|
||||
*/
|
||||
virtual dur_millis_t getPeriodicOperationFrequency() const = 0;
|
||||
[[nodiscard]] virtual dur_millis_t getPeriodicOperationFrequency() const = 0;
|
||||
|
||||
/**
|
||||
* @brief This function will be called by the manager if an update
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include "fsfw/datapoollocal.h"
|
||||
@ -57,7 +56,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
||||
}
|
||||
|
||||
if (defaultHkDestination != objects::NO_OBJECT) {
|
||||
AcceptsHkPacketsIF* hkPacketReceiver =
|
||||
auto* hkPacketReceiver =
|
||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
||||
if (hkPacketReceiver != nullptr) {
|
||||
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||
@ -209,9 +208,9 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& recei
|
||||
}
|
||||
|
||||
/* Prepare and send update snapshot */
|
||||
timeval now;
|
||||
timeval now{};
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::CDS_short cds;
|
||||
CCSDSTime::CDS_short cds{};
|
||||
CCSDSTime::convertToCcsds(&cds, &now);
|
||||
HousekeepingSnapshot updatePacket(
|
||||
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
||||
@ -245,9 +244,9 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(HkReceiver& recei
|
||||
}
|
||||
|
||||
/* Prepare and send update snapshot */
|
||||
timeval now;
|
||||
timeval now{};
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::CDS_short cds;
|
||||
CCSDSTime::CDS_short cds{};
|
||||
CCSDSTime::convertToCcsds(&cds, &now);
|
||||
HousekeepingSnapshot updatePacket(
|
||||
reinterpret_cast<uint8_t*>(&cds), sizeof(cds),
|
||||
@ -339,8 +338,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool e
|
||||
float collectionInterval,
|
||||
bool isDiagnostics,
|
||||
object_id_t packetDestination) {
|
||||
AcceptsHkPacketsIF* hkReceiverObject =
|
||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
auto* hkReceiverObject = ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
if (hkReceiverObject == nullptr) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
||||
QUEUE_OR_DESTINATION_INVALID);
|
||||
@ -368,8 +366,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool e
|
||||
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid, bool isDiagnostics,
|
||||
bool reportingEnabled,
|
||||
object_id_t packetDestination) {
|
||||
AcceptsHkPacketsIF* hkReceiverObject =
|
||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
auto* hkReceiverObject = ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
||||
if (hkReceiverObject == nullptr) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
||||
QUEUE_OR_DESTINATION_INVALID);
|
||||
@ -577,10 +574,6 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
||||
|
||||
CommandMessage reply;
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
if (result == WRONG_HK_PACKET_TYPE) {
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
||||
WRONG_HK_PACKET_TYPE);
|
||||
}
|
||||
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
||||
} else {
|
||||
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
||||
@ -700,7 +693,8 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
/* Configuration error */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed." << std::endl;
|
||||
sif::warning << "LocalDataPoolManager::performPeriodicHkOperation: HK generation failed."
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("LocalDataPoolManager::performPeriodicHkOperation: HK generation failed.\n");
|
||||
#endif
|
||||
@ -838,8 +832,6 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
||||
errorPrint = "Dataset not found";
|
||||
} else if (error == POOLOBJECT_NOT_FOUND) {
|
||||
errorPrint = "Pool Object not found";
|
||||
} else if (error == WRONG_HK_PACKET_TYPE) {
|
||||
errorPrint = "Wrong Packet Type";
|
||||
} else if (error == HasReturnvaluesIF::RETURN_FAILED) {
|
||||
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
||||
errorPrint = "Generic Warning";
|
||||
|
@ -80,7 +80,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
*/
|
||||
LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||
bool appendValidityBuffer = true);
|
||||
virtual ~LocalDataPoolManager();
|
||||
~LocalDataPoolManager() override;
|
||||
|
||||
/**
|
||||
* Assigns the queue to use. Make sure to call this in the #initialize
|
||||
@ -151,7 +151,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
* Otherwise, only an notification message is sent.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t subscribeForSetUpdateMessage(const uint32_t setId, object_id_t destinationObject,
|
||||
ReturnValue_t subscribeForSetUpdateMessage(uint32_t setId, object_id_t destinationObject,
|
||||
MessageQueueId_t targetQueueId,
|
||||
bool generateSnapshot) override;
|
||||
|
||||
@ -169,7 +169,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
* Otherwise, only an notification message is sent.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t subscribeForVariableUpdateMessage(const lp_id_t localPoolId,
|
||||
ReturnValue_t subscribeForVariableUpdateMessage(lp_id_t localPoolId,
|
||||
object_id_t destinationObject,
|
||||
MessageQueueId_t targetQueueId,
|
||||
bool generateSnapshot) override;
|
||||
@ -252,7 +252,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
*/
|
||||
void clearReceiversList();
|
||||
|
||||
object_id_t getCreatorObjectId() const;
|
||||
[[nodiscard]] object_id_t getCreatorObjectId() const;
|
||||
|
||||
/**
|
||||
* Get the pointer to the mutex. Can be used to lock the data pool
|
||||
@ -262,7 +262,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
*/
|
||||
MutexIF* getMutexHandle();
|
||||
|
||||
virtual LocalDataPoolManager* getPoolManagerHandle() override;
|
||||
LocalDataPoolManager* getPoolManagerHandle() override;
|
||||
|
||||
protected:
|
||||
/** Core data structure for the actual pool data */
|
||||
@ -306,8 +306,8 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
||||
struct HkUpdateResetHelper {
|
||||
DataType dataType = DataType::DATA_SET;
|
||||
DataId dataId;
|
||||
uint8_t updateCounter;
|
||||
uint8_t currentUpdateCounter;
|
||||
uint8_t updateCounter{};
|
||||
uint8_t currentUpdateCounter{};
|
||||
};
|
||||
|
||||
using HkUpdateResetList = std::vector<struct HkUpdateResetHelper>;
|
||||
|
@ -162,7 +162,6 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||
object_id_t getCreatorObjectId();
|
||||
|
||||
bool getReportingEnabled() const;
|
||||
void setReportingEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* Returns the current periodic HK generation interval this set
|
||||
@ -190,6 +189,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
||||
* Used for periodic generation.
|
||||
*/
|
||||
bool reportingEnabled = false;
|
||||
void setReportingEnabled(bool enabled);
|
||||
|
||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||
uint8_t nonDiagIntervalFactor = 5);
|
||||
|
@ -26,7 +26,11 @@ void AssemblyBase::performChildOperation() {
|
||||
|
||||
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||
doStartTransition(mode, submode);
|
||||
triggerModeHelperEvents(mode, submode);
|
||||
if (modeHelper.isForced()) {
|
||||
triggerEvent(FORCING_MODE, mode, submode);
|
||||
} else {
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
||||
@ -73,10 +77,9 @@ bool AssemblyBase::handleChildrenChangedHealth() {
|
||||
}
|
||||
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
||||
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
||||
triggerEvent(TRYING_RECOVERY, iter->first, 0);
|
||||
triggerEvent(TRYING_RECOVERY);
|
||||
recoveryState = RECOVERY_STARTED;
|
||||
recoveringDevice = iter;
|
||||
// The user needs to take care of commanding the children off in commandChildren
|
||||
doStartTransition(targetMode, targetSubmode);
|
||||
} else {
|
||||
triggerEvent(CHILD_CHANGED_HEALTH);
|
||||
@ -225,9 +228,6 @@ ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
|
||||
bool AssemblyBase::checkAndHandleRecovery() {
|
||||
switch (recoveryState) {
|
||||
case RECOVERY_STARTED:
|
||||
// The recovery was already start in #handleChildrenChangedHealth and we just need
|
||||
// to wait for an off time period.
|
||||
// TODO: make time period configurable
|
||||
recoveryState = RECOVERY_WAIT;
|
||||
recoveryOffTimer.resetTimer();
|
||||
return true;
|
||||
@ -266,11 +266,3 @@ void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, HasHealthIF::Heal
|
||||
modeHelper.setForced(true);
|
||||
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
||||
}
|
||||
|
||||
void AssemblyBase::triggerModeHelperEvents(Mode_t mode, Submode_t submode) {
|
||||
if (modeHelper.isForced()) {
|
||||
triggerEvent(FORCING_MODE, mode, submode);
|
||||
} else {
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,7 @@
|
||||
* Documentation: Dissertation Baetz p.156, 157.
|
||||
*
|
||||
* This class reduces the complexity of controller components which would
|
||||
* otherwise be needed for the handling of redundant devices. However, it can also be used to
|
||||
* manage the mode keeping and recovery of non-redundant devices
|
||||
* otherwise be needed for the handling of redundant devices.
|
||||
*
|
||||
* The template class monitors mode and health state of its children
|
||||
* and checks availability of devices on every detected change.
|
||||
@ -27,9 +26,11 @@
|
||||
*
|
||||
* Important:
|
||||
*
|
||||
* The implementation must call #registerChild for all commanded children during initialization.
|
||||
* The implementation must call registerChild(object_id_t child)
|
||||
* for all commanded children during initialization.
|
||||
* The implementation must call the initialization function of the base class.
|
||||
* (This will call the function in SubsystemBase)
|
||||
*
|
||||
*/
|
||||
class AssemblyBase : public SubsystemBase {
|
||||
public:
|
||||
@ -46,14 +47,13 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Command children to reach [mode,submode] combination. Can be done by setting
|
||||
* #commandsOutstanding correctly, or using #executeTable. In case of an FDIR recovery,
|
||||
* the user needs to ensure that the target devices are healthy. If a device is not healthy,
|
||||
* a recovery might be on-going and the device needs to be commanded to off first.
|
||||
* Command children to reach [mode,submode] combination
|
||||
* Can be done by setting #commandsOutstanding correctly,
|
||||
* or using executeTable()
|
||||
* @param mode
|
||||
* @param submode
|
||||
* @return
|
||||
* - @c RETURN_OK if OK
|
||||
* - @c RETURN_OK if ok
|
||||
* - @c NEED_SECOND_STEP if children need to be commanded again
|
||||
*/
|
||||
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
|
||||
@ -120,19 +120,8 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
||||
|
||||
/**
|
||||
* @brief Default periodic handler
|
||||
* @details
|
||||
* This is the default periodic handler which will be called by the SubsystemBase
|
||||
* performOperation. It performs the child transitions or reacts to changed health/mode states
|
||||
* of children objects
|
||||
*/
|
||||
virtual void performChildOperation() override;
|
||||
virtual void performChildOperation();
|
||||
|
||||
/**
|
||||
* This function handles changed mode or health states of children
|
||||
* @return
|
||||
*/
|
||||
bool handleChildrenChanged();
|
||||
|
||||
/**
|
||||
@ -145,37 +134,12 @@ class AssemblyBase : public SubsystemBase {
|
||||
|
||||
bool handleChildrenChangedHealth();
|
||||
|
||||
/**
|
||||
* Core transition handler. The default implementation will only do something if
|
||||
* #commandsOutstanding is smaller or equal to zero, which means that all mode commands
|
||||
* from the #doPerformTransition call were executed successfully.
|
||||
*
|
||||
* Unless a second step was requested, the function will then use #checkChildrenState to
|
||||
* determine whether the target mode was reached.
|
||||
*
|
||||
* There is some special handling for certain (internal) modes:
|
||||
* - A second step is necessary. #commandChildren will be performed again
|
||||
* - The device health was overwritten. #commandChildren will be called
|
||||
* - A recovery is ongoing. #checkAndHandleRecovery will be called.
|
||||
*/
|
||||
virtual void handleChildrenTransition();
|
||||
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
||||
|
||||
/**
|
||||
* Calls #doStartTransition and triggers an informative event as well that the mode will
|
||||
* change
|
||||
* @param mode
|
||||
* @param submode
|
||||
*/
|
||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
||||
|
||||
/**
|
||||
* This function starts the transition by setting the internal #targetSubmode and #targetMode
|
||||
* variables and then calling the #commandChildren function.
|
||||
* @param mode
|
||||
* @param submode
|
||||
*/
|
||||
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
||||
|
||||
virtual bool isInTransition();
|
||||
@ -196,7 +160,7 @@ class AssemblyBase : public SubsystemBase {
|
||||
* Manages recovery of a device
|
||||
* @return true if recovery is still ongoing, false else.
|
||||
*/
|
||||
virtual bool checkAndHandleRecovery();
|
||||
bool checkAndHandleRecovery();
|
||||
|
||||
/**
|
||||
* Helper method to overwrite health state of one of the children.
|
||||
@ -204,8 +168,6 @@ class AssemblyBase : public SubsystemBase {
|
||||
* @param objectId Must be a registered child.
|
||||
*/
|
||||
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
||||
|
||||
void triggerModeHelperEvents(Mode_t mode, Submode_t submode);
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
||||
|
@ -39,9 +39,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
childTransitionDelay(5000),
|
||||
transitionSourceMode(_MODE_POWER_DOWN),
|
||||
transitionSourceSubMode(SUBMODE_NONE) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
insertInCommandMap(RAW_COMMAND_ID);
|
||||
cookieInfo.state = COOKIE_UNUSED;
|
||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||
@ -49,6 +48,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
|
||||
HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
|
||||
}
|
||||
if (this->fdirInstance == nullptr) {
|
||||
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFdirParentId);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||
@ -124,18 +126,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (this->fdirInstance == nullptr) {
|
||||
this->fdirInstance =
|
||||
new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
||||
}
|
||||
|
||||
if (this->parent != objects::NO_OBJECT) {
|
||||
HasModesIF* modeIF = ObjectManager::instance()->get<HasModesIF>(this->parent);
|
||||
HasHealthIF* healthIF = ObjectManager::instance()->get<HasHealthIF>(this->parent);
|
||||
if (modeIF != nullptr and healthIF != nullptr) {
|
||||
setParentQueue(modeIF->getCommandQueue());
|
||||
}
|
||||
}
|
||||
|
||||
communicationInterface =
|
||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||
@ -243,27 +233,16 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::decrementDeviceReplyMap() {
|
||||
bool timedOut = false;
|
||||
for (std::pair<const DeviceCommandId_t, DeviceReplyInfo>& replyPair : deviceReplyMap) {
|
||||
if (replyPair.second.countdown != nullptr && replyPair.second.active) {
|
||||
if (replyPair.second.countdown->hasTimedOut()) {
|
||||
timedOut = true;
|
||||
}
|
||||
}
|
||||
if (replyPair.second.delayCycles != 0 && replyPair.second.countdown == nullptr) {
|
||||
if (replyPair.second.delayCycles != 0) {
|
||||
replyPair.second.delayCycles--;
|
||||
if (replyPair.second.delayCycles == 0) {
|
||||
if (replyPair.second.periodic) {
|
||||
replyPair.second.delayCycles = replyPair.second.maxDelayCycles;
|
||||
}
|
||||
timedOut = true;
|
||||
}
|
||||
}
|
||||
if (timedOut) {
|
||||
replyToReply(replyPair.first, replyPair.second, TIMEOUT);
|
||||
missedReply(replyPair.first);
|
||||
timedOut = false;
|
||||
replyPair.second.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,12 +352,14 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
}
|
||||
} break;
|
||||
case _MODE_WAIT_OFF: {
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
|
||||
if (powerSwitcher == nullptr) {
|
||||
setMode(MODE_OFF);
|
||||
break;
|
||||
}
|
||||
uint32_t currentUptime;
|
||||
Clock::getUptime(¤tUptime);
|
||||
|
||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||
setMode(MODE_ERROR_ON);
|
||||
@ -427,22 +408,20 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, Submode_t s
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(
|
||||
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase* replyDataSet,
|
||||
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId,
|
||||
Countdown* countdown) {
|
||||
size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) {
|
||||
// No need to check, as we may try to insert multiple times.
|
||||
insertInCommandMap(deviceCommand, hasDifferentReplyId, replyId);
|
||||
if (hasDifferentReplyId) {
|
||||
return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic, countdown);
|
||||
return insertInReplyMap(replyId, maxDelayCycles, replyDataSet, replyLen, periodic);
|
||||
} else {
|
||||
return insertInReplyMap(deviceCommand, maxDelayCycles, replyDataSet, replyLen, periodic,
|
||||
countdown);
|
||||
return insertInReplyMap(deviceCommand, maxDelayCycles, replyDataSet, replyLen, periodic);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
||||
uint16_t maxDelayCycles,
|
||||
LocalPoolDataSetBase* dataSet, size_t replyLen,
|
||||
bool periodic, Countdown* countdown) {
|
||||
bool periodic) {
|
||||
DeviceReplyInfo info;
|
||||
info.maxDelayCycles = maxDelayCycles;
|
||||
info.periodic = periodic;
|
||||
@ -450,10 +429,6 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
|
||||
info.replyLen = replyLen;
|
||||
info.dataSet = dataSet;
|
||||
info.command = deviceCommandMap.end();
|
||||
info.countdown = countdown;
|
||||
if (info.periodic) {
|
||||
info.active = true;
|
||||
}
|
||||
auto resultPair = deviceReplyMap.emplace(replyId, info);
|
||||
if (resultPair.second) {
|
||||
return RETURN_OK;
|
||||
@ -489,8 +464,7 @@ size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId) {
|
||||
}
|
||||
DeviceReplyIter iter = deviceReplyMap.find(replyId);
|
||||
if (iter != deviceReplyMap.end()) {
|
||||
if ((iter->second.delayCycles != 0 && iter->second.countdown == nullptr) ||
|
||||
(iter->second.active && iter->second.countdown != nullptr)) {
|
||||
if (iter->second.delayCycles != 0) {
|
||||
return iter->second.replyLen;
|
||||
}
|
||||
}
|
||||
@ -572,9 +546,6 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
mode = newMode;
|
||||
modeChanged();
|
||||
setNormalDatapoolEntriesInvalid();
|
||||
if (newMode == MODE_OFF) {
|
||||
disableCommandsAndReplies();
|
||||
}
|
||||
if (!isTransitionalMode()) {
|
||||
modeHelper.modeChanged(newMode, newSubmode);
|
||||
announceMode(false);
|
||||
@ -837,18 +808,17 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId
|
||||
|
||||
DeviceReplyInfo* info = &(iter->second);
|
||||
|
||||
if ((info->delayCycles != 0 && info->countdown == nullptr) ||
|
||||
(info->active && info->countdown != nullptr)) {
|
||||
if (info->delayCycles != 0) {
|
||||
result = interpretDeviceReply(foundId, receivedData);
|
||||
|
||||
if (result == IGNORE_REPLY_DATA) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->active && info->countdown != nullptr) {
|
||||
disableTimeoutControlledReply(info);
|
||||
} else if (info->delayCycles != 0) {
|
||||
disableDelayCyclesControlledReply(info);
|
||||
if (info->periodic) {
|
||||
info->delayCycles = info->maxDelayCycles;
|
||||
} else {
|
||||
info->delayCycles = 0;
|
||||
}
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
@ -867,24 +837,6 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::disableTimeoutControlledReply(DeviceReplyInfo* info) {
|
||||
if (info->periodic) {
|
||||
info->countdown->resetTimer();
|
||||
} else {
|
||||
info->active = false;
|
||||
info->countdown->timeOut();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::disableDelayCyclesControlledReply(DeviceReplyInfo* info) {
|
||||
if (info->periodic) {
|
||||
info->delayCycles = info->maxDelayCycles;
|
||||
} else {
|
||||
info->delayCycles = 0;
|
||||
info->active = false;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, uint8_t** data,
|
||||
size_t* len) {
|
||||
size_t lenTmp;
|
||||
@ -1010,10 +962,6 @@ ReturnValue_t DeviceHandlerBase::enableReplyInReplyMap(DeviceCommandMap::iterato
|
||||
info->delayCycles = info->maxDelayCycles;
|
||||
info->command = command;
|
||||
command->second.expectedReplies = expectedReplies;
|
||||
if (info->countdown != nullptr) {
|
||||
info->countdown->resetTimer();
|
||||
}
|
||||
info->active = true;
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
return NO_REPLY_EXPECTED;
|
||||
@ -1248,8 +1196,7 @@ void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) {
|
||||
bool DeviceHandlerBase::isAwaitingReply() {
|
||||
std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter;
|
||||
for (iter = deviceReplyMap.begin(); iter != deviceReplyMap.end(); ++iter) {
|
||||
if ((iter->second.delayCycles != 0 && iter->second.countdown == nullptr) ||
|
||||
(iter->second.active && iter->second.countdown != nullptr)) {
|
||||
if (iter->second.delayCycles != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1404,8 +1351,6 @@ uint8_t DeviceHandlerBase::getReplyDelayCycles(DeviceCommandId_t deviceCommand)
|
||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(deviceCommand);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
return 0;
|
||||
} else if (iter->second.countdown != nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return iter->second.delayCycles;
|
||||
}
|
||||
@ -1454,8 +1399,6 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task) { executingTask = task;
|
||||
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
||||
uint32_t parameter) {}
|
||||
|
||||
Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
|
||||
|
||||
void DeviceHandlerBase::performOperationHook() {}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
@ -1478,7 +1421,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
||||
this->poolManager.initializeAfterTaskCreation();
|
||||
|
||||
if (setStartupImmediately) {
|
||||
startTransition(MODE_ON, getInitialSubmode());
|
||||
startTransition(MODE_ON, SUBMODE_NONE);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
@ -1562,29 +1505,3 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
||||
}
|
||||
return commandIter->second.sendReplyTo;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
||||
|
||||
void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; }
|
||||
|
||||
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) {
|
||||
this->powerSwitcher = switcher;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::disableCommandsAndReplies() {
|
||||
for (auto& command : deviceCommandMap) {
|
||||
if (command.second.isExecuting) {
|
||||
command.second.isExecuting = false;
|
||||
}
|
||||
}
|
||||
for (auto& reply : deviceReplyMap) {
|
||||
if (!reply.second.periodic) {
|
||||
if (reply.second.countdown != nullptr) {
|
||||
reply.second.countdown->timeOut();
|
||||
} else {
|
||||
reply.second.delayCycles = 0;
|
||||
}
|
||||
reply.second.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "DeviceHandlerFailureIsolation.h"
|
||||
#include "DeviceHandlerIF.h"
|
||||
#include "DeviceHandlerThermalSet.h"
|
||||
#include "DhbCfgHelpers.h"
|
||||
#include "fsfw/action/ActionHelper.h"
|
||||
#include "fsfw/action/HasActionsIF.h"
|
||||
#include "fsfw/datapool/PoolVariableIF.h"
|
||||
@ -104,9 +103,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||
|
||||
void setCustomFdir(FailureIsolationBase *fdir);
|
||||
void setParent(object_id_t parent);
|
||||
void setPowerSwitcher(PowerSwitchIF *switcher);
|
||||
void setHkDestination(object_id_t hkDestination);
|
||||
|
||||
/**
|
||||
@ -211,13 +207,11 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
|
||||
Mode_t getTransitionSourceMode() const;
|
||||
Submode_t getTransitionSourceSubMode() const;
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||
HealthState getHealth();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) override;
|
||||
void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
HealthState getHealth() override;
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -452,9 +446,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
||||
* Please note that periodic replies are disabled by default. You can enable them with
|
||||
* #updatePeriodicReply
|
||||
* @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible
|
||||
* to provide a pointer to a Countdown object which will signal the timeout
|
||||
* when expired
|
||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||
* - @c RETURN_FAILED else.
|
||||
*/
|
||||
@ -462,8 +453,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
LocalPoolDataSetBase *replyDataSet = nullptr,
|
||||
size_t replyLen = 0, bool periodic = false,
|
||||
bool hasDifferentReplyId = false,
|
||||
DeviceCommandId_t replyId = 0,
|
||||
Countdown *countdown = nullptr);
|
||||
DeviceCommandId_t replyId = 0);
|
||||
/**
|
||||
* @brief This is a helper method to insert replies in the reply map.
|
||||
* @param deviceCommand Identifier of the reply to add.
|
||||
@ -473,15 +463,12 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
||||
* Please note that periodic replies are disabled by default. You can enable them with
|
||||
* #updatePeriodicReply
|
||||
* @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible
|
||||
* to provide a pointer to a Countdown object which will signal the timeout
|
||||
* when expired
|
||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||
* - @c RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles,
|
||||
LocalPoolDataSetBase *dataSet = nullptr, size_t replyLen = 0,
|
||||
bool periodic = false, Countdown *countdown = nullptr);
|
||||
bool periodic = false);
|
||||
|
||||
/**
|
||||
* @brief A simple command to add a command to the commandList.
|
||||
@ -489,9 +476,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* @return - @c RETURN_OK when the command was successfully inserted,
|
||||
* - @c RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t insertInCommandMap(
|
||||
DeviceCommandId_t deviceCommand, bool useAlternativeReply = false,
|
||||
DeviceCommandId_t alternativeReplyId = DeviceHandlerIF::NO_COMMAND_ID);
|
||||
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand,
|
||||
bool useAlternativeReply = false,
|
||||
DeviceCommandId_t alternativeReplyId = 0);
|
||||
|
||||
/**
|
||||
* Enables a periodic reply for a given command. It sets to delay cycles to the specified
|
||||
@ -660,12 +647,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
||||
uint32_t parameter = 0);
|
||||
|
||||
/**
|
||||
* @brief Can be overwritten by a child to specify the initial submode when device has been set
|
||||
* to startup immediately.
|
||||
*/
|
||||
virtual Submode_t getInitialSubmode();
|
||||
|
||||
protected:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
||||
|
||||
@ -784,18 +765,11 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* This is used to keep track of pending replies.
|
||||
*/
|
||||
struct DeviceReplyInfo {
|
||||
//! For Command-Reply combinations:
|
||||
//! The maximum number of cycles the handler should wait for a reply
|
||||
//! to this command.
|
||||
//!
|
||||
//! Reply Only:
|
||||
//! For periodic replies, this variable will be the number of delay cycles between the replies.
|
||||
//! For the non-periodic variant, this variable is not used as there is no meaningful
|
||||
//! definition for delay
|
||||
uint16_t maxDelayCycles;
|
||||
//! This variable will be set to #maxDelayCycles if a reply is expected.
|
||||
//! For non-periodic replies without a command, this variable is unused.
|
||||
//! A runtime value of 0 means there is no reply is currently expected.
|
||||
//! The currently remaining cycles the handler should wait for a reply,
|
||||
//! 0 means there is no reply expected
|
||||
uint16_t delayCycles;
|
||||
size_t replyLen = 0; //!< Expected size of the reply.
|
||||
//! if this is !=0, the delayCycles will not be reset to 0 but to
|
||||
@ -807,11 +781,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
LocalPoolDataSetBase *dataSet = nullptr;
|
||||
//! The command that expects this reply.
|
||||
DeviceCommandMap::iterator command;
|
||||
//! Instead of using delayCycles to specify the maximum time to wait for the device reply, it
|
||||
//! is also possible specify a countdown
|
||||
Countdown *countdown = nullptr;
|
||||
//! will be set to true when reply is enabled
|
||||
bool active = false;
|
||||
};
|
||||
|
||||
using DeviceReplyMap = std::map<DeviceCommandId_t, DeviceReplyInfo>;
|
||||
@ -851,7 +820,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
/** Pointer to the used FDIR instance. If not provided by child,
|
||||
* default class is instantiated. */
|
||||
FailureIsolationBase *fdirInstance;
|
||||
object_id_t parent = objects::NO_OBJECT;
|
||||
|
||||
//! To correctly delete the default instance.
|
||||
bool defaultFDIRUsed;
|
||||
@ -1072,11 +1040,9 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
bool isAwaitingReply();
|
||||
|
||||
void handleDeviceTM(SerializeIF *dataSet, DeviceCommandId_t replyId, bool forceDirectTm = false);
|
||||
// void handleDeviceTM(uint8_t* data, size_t dataSize, DeviceCommandId_t replyId,
|
||||
// bool forceDirectTm);
|
||||
|
||||
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode);
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) override;
|
||||
|
||||
virtual ReturnValue_t letChildHandleMessage(CommandMessage *message);
|
||||
|
||||
@ -1092,8 +1058,7 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
/**
|
||||
* 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 override;
|
||||
void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override;
|
||||
|
||||
/**
|
||||
* Checks if current mode is transitional mode.
|
||||
@ -1274,17 +1239,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
*/
|
||||
void doGetRead(void);
|
||||
|
||||
/**
|
||||
* @brief Handles disabling of replies which use a timeout to detect missed replies.
|
||||
*/
|
||||
void disableTimeoutControlledReply(DeviceReplyInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Handles disabling of replies which use a number of maximum delay cycles to detect
|
||||
* missed replies.
|
||||
*/
|
||||
void disableDelayCyclesControlledReply(DeviceReplyInfo *info);
|
||||
|
||||
/**
|
||||
* Retrive data from the #IPCStore.
|
||||
*
|
||||
@ -1326,11 +1280,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
void printWarningOrError(sif::OutputTypes errorType, const char *functionName,
|
||||
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
|
||||
const char *errorPrint = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Disables all commands and replies when device is set to MODE_OFF
|
||||
*/
|
||||
void disableCommandsAndReplies();
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||
|
@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
||||
switch (event->getEvent()) {
|
||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
|
||||
// We'll try a recovery as long as defined in MAX_REBOOT.
|
||||
// Might cause some AssemblyBase cycles, so keep number low.
|
||||
handleRecovery(event->getEvent());
|
||||
|
@ -109,7 +109,6 @@ class DeviceHandlerIF {
|
||||
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
||||
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
||||
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
||||
static const Event DEVICE_WANTS_HARD_REBOOT = MAKE_EVENT(11, severity::HIGH);
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
||||
|
||||
|
@ -1,72 +0,0 @@
|
||||
#ifndef FSFW_SRC_FSFW_DEVICEHANDLERS_DHBCFGHELPERS_H_
|
||||
#define FSFW_SRC_FSFW_DEVICEHANDLERS_DHBCFGHELPERS_H_
|
||||
|
||||
/**
|
||||
* @brief This is the base class for configuration related to both DHB commands, replies and their
|
||||
* combination
|
||||
*/
|
||||
struct CfgBase {
|
||||
public:
|
||||
explicit CfgBase(DeviceCommandId_t cmdAndOrReplyId) : cmdAndOrReplyId(cmdAndOrReplyId){};
|
||||
DeviceCommandId_t cmdAndOrReplyId;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configuration class for commands
|
||||
*/
|
||||
struct CmdCfg {
|
||||
public:
|
||||
explicit CmdCfg(DeviceCommandId_t cmdId) : baseCfg(cmdId){};
|
||||
|
||||
CfgBase baseCfg;
|
||||
//! This can be used if a command can trigger multiple replies
|
||||
std::pair<bool, DeviceCommandId_t> alternativeReply = {false, DeviceHandlerIF::NO_COMMAND_ID};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configuration class for replies
|
||||
*/
|
||||
struct ReplyCfg {
|
||||
public:
|
||||
ReplyCfg(DeviceCommandId_t replyId, uint16_t maxDelayCycles)
|
||||
: baseCfg(replyId), maxDelayCycles(maxDelayCycles){};
|
||||
ReplyCfg(DeviceCommandId_t replyId, uint16_t maxDelayCycles, LocalPoolDataSetBase* set)
|
||||
: ReplyCfg(replyId, maxDelayCycles) {
|
||||
dataSet = set;
|
||||
};
|
||||
|
||||
CfgBase baseCfg;
|
||||
//! A data set can be mapped to a reply ID. This allows to omit the #getDataSetHandle
|
||||
//! override in a user device handler as this pointer will be passed as long as the device
|
||||
//! command ID is equal to the set ID.
|
||||
LocalPoolDataSetBase* dataSet = nullptr;
|
||||
//! For Command-Reply combinations:
|
||||
//! The maximum number of cycles the handler should wait for a reply
|
||||
//! to this command.
|
||||
//!
|
||||
//! Reply Only:
|
||||
//! For periodic replies, this variable will be the number of delay cycles between the replies.
|
||||
//! For the non-periodic variant, this variable is not used as there is no meaningful
|
||||
//! definition for delay
|
||||
uint16_t maxDelayCycles = 0;
|
||||
//! First parameter: Specify whether reply is arriving periodically
|
||||
//! Second parameter: Specify whether periodic reply should be enabled immediately
|
||||
std::pair<bool, bool> periodicCfg = {false, false};
|
||||
//! If a reply needs to be requested with a specific length, the length can be specified here
|
||||
size_t replyLen = 0;
|
||||
//! It is also possible to use a time based instead of a cycle based mechanism to specify
|
||||
//! how long a reply takes. For non-periodic replies without a command, this variable is not used.
|
||||
Countdown* countdown = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configuration class for commands and replies
|
||||
*/
|
||||
struct CmdReplyCfg {
|
||||
public:
|
||||
CmdReplyCfg(CmdCfg cmdCfg, ReplyCfg replyCfg) : cmdCfg(cmdCfg), replyCfg(replyCfg) {}
|
||||
CmdCfg cmdCfg;
|
||||
ReplyCfg replyCfg;
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_DEVICEHANDLERS_DHBCFGHELPERS_H_ */
|
@ -8,9 +8,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
|
||||
parentQueue(parentQueue),
|
||||
commandQueue(),
|
||||
healthHelper(this, setObjectId) {
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
||||
}
|
||||
|
||||
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||
|
@ -18,9 +18,8 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
||||
EventManager::EventManager(object_id_t setObjectId)
|
||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
||||
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||
EventMessage::EVENT_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
EventManager::~EventManager() {
|
||||
@ -47,20 +46,9 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
||||
|
||||
void EventManager::notifyListeners(EventMessage* message) {
|
||||
lockMutex();
|
||||
for (auto& listener : listenerList) {
|
||||
if (listener.second.match(message)) {
|
||||
ReturnValue_t result =
|
||||
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
|
||||
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
|
||||
<< result << std::setfill(' ') << std::endl;
|
||||
#else
|
||||
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
|
||||
listener.first, result);
|
||||
#endif
|
||||
}
|
||||
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
||||
if (iter->second.match(message)) {
|
||||
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
||||
}
|
||||
}
|
||||
unlockMutex();
|
||||
@ -201,19 +189,4 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
||||
}
|
||||
}
|
||||
|
||||
void EventManager::printListeners() {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
|
||||
for (auto& listener : listenerList) {
|
||||
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
|
||||
}
|
||||
sif::info << std::dec << std::setfill(' ');
|
||||
#else
|
||||
sif::printInfo("Event manager listener MQ IDs:\n");
|
||||
for (auto& listener : listenerList) {
|
||||
sif::printInfo("0x%08x\n", listener.first);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
||||
|
@ -42,7 +42,6 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||
bool reporterInverted = false);
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
void printListeners();
|
||||
|
||||
protected:
|
||||
MessageQueueIF* eventReportQueue = nullptr;
|
||||
|
@ -9,9 +9,8 @@
|
||||
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
||||
uint8_t messageDepth, uint8_t parameterDomainBase)
|
||||
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
||||
auto mqArgs = MqArgs(owner, static_cast<void*>(this));
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
eventQueue =
|
||||
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
FailureIsolationBase::~FailureIsolationBase() {
|
||||
@ -53,11 +52,10 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
||||
if (parentIF == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "FailureIsolationBase::intialize: Parent object"
|
||||
<< "invalid" << std::endl;
|
||||
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
|
||||
#else
|
||||
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
|
||||
sif::printError("Make sure it implements ConfirmsFailuresIF\n");
|
||||
<< "invalid." << std::endl;
|
||||
#endif
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Make sure it implements ConfirmsFailuresIF." << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
return RETURN_FAILED;
|
||||
|
@ -14,12 +14,13 @@ class FailureIsolationBase : public HasReturnvaluesIF,
|
||||
public HasParametersIF {
|
||||
public:
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
||||
//! FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
|
||||
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO);
|
||||
//! FDIR tries to restart device. Par1: event that caused recovery.
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
|
||||
//! FDIR turns off device. Par1: event that caused recovery.
|
||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM);
|
||||
static const Event FDIR_CHANGED_STATE =
|
||||
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
|
||||
//!< (oldState) to par1 (newState).
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
|
||||
2, severity::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
|
||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(
|
||||
3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||
|
||||
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
||||
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
||||
|
@ -4,7 +4,6 @@ target_sources(
|
||||
AsciiConverter.cpp
|
||||
CRC.cpp
|
||||
DleEncoder.cpp
|
||||
DleParser.cpp
|
||||
PeriodicOperationDivider.cpp
|
||||
timevalOperations.cpp
|
||||
Type.cpp
|
||||
|
@ -1,230 +0,0 @@
|
||||
#include "DleParser.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
DleParser::DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
||||
BufPair decodedBuf, UserHandler handler, void* args)
|
||||
: decodeRingBuf(decodeRingBuf),
|
||||
decoder(decoder),
|
||||
encodedBuf(encodedBuf),
|
||||
decodedBuf(decodedBuf),
|
||||
handler(handler),
|
||||
ctx(args) {
|
||||
if (handler == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DleParser::DleParser: Invalid user handler" << std::endl;
|
||||
#else
|
||||
sif::printError("DleParser::DleParser: Invalid user handler\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t DleParser::passData(uint8_t* data, size_t len) {
|
||||
if (data == nullptr or len == 0 or handler == nullptr) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
size_t copyIntoRingBufFromHere = 0;
|
||||
size_t copyAmount = len;
|
||||
size_t startIdx = 0;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
bool startFoundInThisPacket = false;
|
||||
for (size_t idx = 0; idx < len; idx++) {
|
||||
if (data[idx] == DleEncoder::STX_CHAR) {
|
||||
if (not startFound and not startFoundInThisPacket) {
|
||||
startIdx = idx;
|
||||
copyIntoRingBufFromHere = idx;
|
||||
copyAmount = len - idx;
|
||||
} else {
|
||||
// Maybe print warning, should not happen
|
||||
decodeRingBuf.clear();
|
||||
ErrorInfo info;
|
||||
info.len = idx;
|
||||
prepareErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
|
||||
handler(ctx);
|
||||
copyIntoRingBufFromHere = idx;
|
||||
copyAmount = len - idx;
|
||||
}
|
||||
startFound = true;
|
||||
startFoundInThisPacket = true;
|
||||
} else if (data[idx] == DleEncoder::ETX_CHAR) {
|
||||
if (startFoundInThisPacket) {
|
||||
size_t readLen = 0;
|
||||
size_t decodedLen = 0;
|
||||
result = decoder.decode(data + startIdx, idx + 1 - startIdx, &readLen, decodedBuf.first,
|
||||
decodedBuf.second, &decodedLen);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
ctx.setType(ContextType::PACKET_FOUND);
|
||||
ctx.decodedPacket.first = decodedBuf.first;
|
||||
ctx.decodedPacket.second = decodedLen;
|
||||
this->handler(ctx);
|
||||
} else if (result == DleEncoder::STREAM_TOO_SHORT) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
} else {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
}
|
||||
decodeRingBuf.clear();
|
||||
if ((idx + 1) < len) {
|
||||
copyIntoRingBufFromHere = idx + 1;
|
||||
copyAmount = len - idx - 1;
|
||||
} else {
|
||||
copyAmount = 0;
|
||||
}
|
||||
} else if (startFound) {
|
||||
// ETX found but STX was found in another mini packet. Reconstruct the full packet
|
||||
// to decode it
|
||||
result = decodeRingBuf.writeData(data, idx + 1);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::RING_BUF_ERROR, info);
|
||||
handler(ctx);
|
||||
}
|
||||
size_t fullEncodedLen = decodeRingBuf.getAvailableReadData();
|
||||
if (fullEncodedLen > encodedBuf.second) {
|
||||
ErrorInfo info;
|
||||
info.len = fullEncodedLen;
|
||||
prepareErrorContext(ErrorTypes::ENCODED_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
decodeRingBuf.clear();
|
||||
} else {
|
||||
size_t decodedLen = 0;
|
||||
size_t readLen = 0;
|
||||
decodeRingBuf.readData(encodedBuf.first, fullEncodedLen, true);
|
||||
result = decoder.decode(encodedBuf.first, fullEncodedLen, &readLen, decodedBuf.first,
|
||||
decodedBuf.second, &decodedLen);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
if (this->handler != nullptr) {
|
||||
ctx.setType(ContextType::PACKET_FOUND);
|
||||
ctx.decodedPacket.first = decodedBuf.first;
|
||||
ctx.decodedPacket.second = decodedLen;
|
||||
this->handler(ctx);
|
||||
}
|
||||
} else if (result == DleEncoder::STREAM_TOO_SHORT) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
||||
handler(ctx);
|
||||
} else {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::DECODE_ERROR, info);
|
||||
handler(ctx);
|
||||
}
|
||||
decodeRingBuf.clear();
|
||||
startFound = false;
|
||||
startFoundInThisPacket = false;
|
||||
if ((idx + 1) < len) {
|
||||
copyIntoRingBufFromHere = idx + 1;
|
||||
copyAmount = len - idx - 1;
|
||||
} else {
|
||||
copyAmount = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// End data without preceeding STX
|
||||
ErrorInfo info;
|
||||
info.len = idx + 1;
|
||||
prepareErrorContext(ErrorTypes::CONSECUTIVE_ETX_CHARS, info);
|
||||
handler(ctx);
|
||||
decodeRingBuf.clear();
|
||||
if ((idx + 1) < len) {
|
||||
copyIntoRingBufFromHere = idx + 1;
|
||||
copyAmount = len - idx - 1;
|
||||
} else {
|
||||
copyAmount = 0;
|
||||
}
|
||||
}
|
||||
startFoundInThisPacket = false;
|
||||
startFound = false;
|
||||
}
|
||||
}
|
||||
if (copyAmount > 0) {
|
||||
result = decodeRingBuf.writeData(data + copyIntoRingBufFromHere, copyAmount);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
prepareErrorContext(ErrorTypes::RING_BUF_ERROR, info);
|
||||
handler(ctx);
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void DleParser::defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "DleParserBase::handleFoundPacket: Detected DLE packet with " << len << " bytes"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printInfo("DleParserBase::handleFoundPacket: Detected DLE packet with %d bytes\n", len);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void DleParser::defaultErrorHandler(ErrorTypes err, ErrorInfo ctx) {
|
||||
switch (err) {
|
||||
case (ErrorTypes::NONE): {
|
||||
errorPrinter("No error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::DECODE_ERROR): {
|
||||
errorPrinter("Decode Error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::RING_BUF_ERROR): {
|
||||
errorPrinter("Ring Buffer Error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::ENCODED_BUF_TOO_SMALL):
|
||||
case (ErrorTypes::DECODING_BUF_TOO_SMALL): {
|
||||
char opt[64];
|
||||
snprintf(opt, sizeof(opt), ": Too small for packet with length %zu", ctx.len);
|
||||
if (err == ErrorTypes::ENCODED_BUF_TOO_SMALL) {
|
||||
errorPrinter("Encoded buf too small", opt);
|
||||
} else {
|
||||
errorPrinter("Decoding buf too small", opt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::CONSECUTIVE_STX_CHARS): {
|
||||
errorPrinter("Consecutive STX chars detected");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::CONSECUTIVE_ETX_CHARS): {
|
||||
errorPrinter("Consecutive ETX chars detected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DleParser::errorPrinter(const char* str, const char* opt) {
|
||||
if (opt == nullptr) {
|
||||
opt = "";
|
||||
}
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "DleParserBase::handleParseError: " << str << opt << std::endl;
|
||||
#else
|
||||
sif::printInfo("DleParserBase::handleParseError: %s%s\n", str, opt);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void DleParser::prepareErrorContext(ErrorTypes err, ErrorInfo info) {
|
||||
ctx.setType(ContextType::ERROR);
|
||||
ctx.error.first = err;
|
||||
ctx.error.second = info;
|
||||
}
|
||||
|
||||
void DleParser::reset() {
|
||||
startFound = false;
|
||||
decodeRingBuf.clear();
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/container/SimpleRingBuffer.h>
|
||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* @brief This base helper class can be used to extract DLE encoded packets from a data stream
|
||||
* @details
|
||||
* The core API of the parser takes received packets which can contains DLE packets. The parser
|
||||
* can deal with DLE packets split across multiple packets. It does so by using a dedicated
|
||||
* decoding ring buffer. The user can process received packets and detect errors by
|
||||
* overriding two provided virtual methods. This also allows detecting multiple DLE packets
|
||||
* inside one passed packet.
|
||||
*/
|
||||
class DleParser : public HasReturnvaluesIF {
|
||||
public:
|
||||
using BufPair = std::pair<uint8_t*, size_t>;
|
||||
|
||||
enum class ContextType { PACKET_FOUND, ERROR };
|
||||
|
||||
enum class ErrorTypes {
|
||||
NONE,
|
||||
ENCODED_BUF_TOO_SMALL,
|
||||
DECODING_BUF_TOO_SMALL,
|
||||
DECODE_ERROR,
|
||||
RING_BUF_ERROR,
|
||||
CONSECUTIVE_STX_CHARS,
|
||||
CONSECUTIVE_ETX_CHARS
|
||||
};
|
||||
|
||||
union ErrorInfo {
|
||||
size_t len;
|
||||
ReturnValue_t res;
|
||||
};
|
||||
|
||||
using ErrorPair = std::pair<ErrorTypes, ErrorInfo>;
|
||||
|
||||
struct Context {
|
||||
public:
|
||||
Context(void* args) : userArgs(args) { setType(ContextType::PACKET_FOUND); }
|
||||
|
||||
void setType(ContextType type) {
|
||||
if (type == ContextType::PACKET_FOUND) {
|
||||
error.first = ErrorTypes::NONE;
|
||||
error.second.len = 0;
|
||||
} else {
|
||||
decodedPacket.first = nullptr;
|
||||
decodedPacket.second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ContextType getType() const { return type; }
|
||||
|
||||
BufPair decodedPacket = {};
|
||||
ErrorPair error;
|
||||
void* userArgs;
|
||||
|
||||
private:
|
||||
ContextType type;
|
||||
};
|
||||
|
||||
using UserHandler = void (*)(const Context& ctx);
|
||||
|
||||
/**
|
||||
* Base class constructor
|
||||
* @param decodeRingBuf Ring buffer used to store multiple packets to allow detecting DLE packets
|
||||
* split across multiple packets
|
||||
* @param decoder Decoder instance
|
||||
* @param encodedBuf Buffer used to store encoded packets. It has to be large enough to hold
|
||||
* the largest expected encoded DLE packet size
|
||||
* @param decodedBuf Buffer used to store decoded packets. It has to be large enough to hold the
|
||||
* largest expected decoded DLE packet size
|
||||
* @param handler Function which will be called on a found packet
|
||||
* @param args Arbitrary user argument
|
||||
*/
|
||||
DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
||||
BufPair decodedBuf, UserHandler handler, void* args);
|
||||
|
||||
/**
|
||||
* This function allows to pass new data into the parser. It then scans for DLE packets
|
||||
* automatically and inserts (part of) the packet into a ring buffer if necessary.
|
||||
* @param data
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t passData(uint8_t* data, size_t len);
|
||||
|
||||
/**
|
||||
* Example found packet handler
|
||||
* function call
|
||||
* @param packet Decoded packet
|
||||
* @param len Length of detected packet
|
||||
*/
|
||||
void defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args);
|
||||
/**
|
||||
* Will be called if an error occured in the #passData call
|
||||
* @param err
|
||||
* @param ctx Context information depending on the error type
|
||||
* - For buffer length errors, will be set to the detected packet length which is too large
|
||||
* - For decode or ring buffer errors, will be set to the result returned from the failed call
|
||||
*/
|
||||
static void defaultErrorHandler(ErrorTypes err, ErrorInfo ctx);
|
||||
|
||||
static void errorPrinter(const char* str, const char* opt = nullptr);
|
||||
|
||||
void prepareErrorContext(ErrorTypes err, ErrorInfo ctx);
|
||||
/**
|
||||
* Resets the parser by resetting the internal states and clearing the decoding ring buffer
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
SimpleRingBuffer& decodeRingBuf;
|
||||
DleEncoder& decoder;
|
||||
BufPair encodedBuf;
|
||||
BufPair decodedBuf;
|
||||
UserHandler handler = nullptr;
|
||||
Context ctx;
|
||||
bool startFound = false;
|
||||
};
|
@ -16,28 +16,27 @@ class HasHealthIF {
|
||||
};
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
||||
static constexpr ReturnValue_t OBJECT_NOT_HEALTHY =
|
||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1);
|
||||
static constexpr ReturnValue_t INVALID_HEALTH_STATE =
|
||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2);
|
||||
static constexpr ReturnValue_t IS_EXTERNALLY_CONTROLLED =
|
||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3);
|
||||
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
|
||||
//! P1: New Health, P2: Old Health
|
||||
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
||||
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
||||
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
||||
//! Assembly overwrites health information of children to keep satellite alive.
|
||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
|
||||
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
|
||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
|
||||
//! Recovery is ongoing. Comes twice during recovery.
|
||||
//! P1: 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
|
||||
//! Recovery was completed. Not necessarily successful. No parameters.
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
|
||||
virtual ~HasHealthIF() {}
|
||||
static const Event OVERWRITING_HEALTH =
|
||||
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
|
||||
//!< satellite alive.
|
||||
static const Event TRYING_RECOVERY =
|
||||
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
|
||||
//!< power-cycle). No parameters.
|
||||
static const Event RECOVERY_STEP =
|
||||
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
|
||||
//!< 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(
|
||||
12,
|
||||
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
|
||||
|
||||
virtual ~HasHealthIF() = default;
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
|
@ -55,7 +55,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
||||
: timeStamp(timeStamp), timeStampSize(timeStampSize), updateData(dataSetPtr){};
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
Endianness streamEndianness) const override {
|
||||
if (timeStamp != nullptr) {
|
||||
/* Endianness will always be MACHINE, so we can simply use memcpy
|
||||
here. */
|
||||
@ -70,7 +70,7 @@ class HousekeepingSnapshot : public SerializeIF {
|
||||
return updateData->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
virtual size_t getSerializedSize() const override {
|
||||
if (updateData == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,13 +7,11 @@
|
||||
|
||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||
: SystemObject(setObjectId),
|
||||
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
||||
poolManager(this, commandQueue),
|
||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||
internalErrorDataset(this) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||
@ -38,14 +36,15 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
||||
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
||||
<< "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
|
||||
<< newStoreHits << std::endl;
|
||||
<< "occured!" << std::endl;
|
||||
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
||||
sif::debug << "TM errors: " << newTmHits << std::endl;
|
||||
sif::debug << "Store errors: " << newStoreHits << std::endl;
|
||||
#else
|
||||
sif::printDebug(
|
||||
"InternalErrorReporter::performOperation: Errors occured: Queue | TM | Store: %lu | %lu "
|
||||
"| %lu\n",
|
||||
static_cast<unsigned int>(newQueueHits), static_cast<unsigned int>(newTmHits),
|
||||
static_cast<unsigned int>(newStoreHits));
|
||||
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
|
||||
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
|
||||
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
|
||||
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class CommandMessageIF {
|
||||
static const Command_t CMD_NONE = MAKE_COMMAND_ID(0);
|
||||
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1);
|
||||
//! Reply indicating that the current command was rejected,
|
||||
//! Parameter 1 should contain the error code
|
||||
//! par1 should contain the error code
|
||||
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
||||
|
||||
virtual ~CommandMessageIF(){};
|
||||
|
@ -10,25 +10,25 @@ class MessageQueueBase : public MessageQueueIF {
|
||||
virtual ~MessageQueueBase();
|
||||
|
||||
// Default implementations for MessageQueueIF where possible
|
||||
virtual MessageQueueId_t getLastPartner() const override;
|
||||
virtual MessageQueueId_t getId() const override;
|
||||
virtual MqArgs& getMqArgs() override;
|
||||
virtual void setDefaultDestination(MessageQueueId_t defaultDestination) override;
|
||||
virtual MessageQueueId_t getDefaultDestination() const override;
|
||||
virtual bool isDefaultDestinationSet() const override;
|
||||
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t getLastPartner() const override;
|
||||
MessageQueueId_t getId() const override;
|
||||
MqArgs& getMqArgs() override;
|
||||
void setDefaultDestination(MessageQueueId_t defaultDestination) override;
|
||||
MessageQueueId_t getDefaultDestination() const override;
|
||||
bool isDefaultDestinationSet() const override;
|
||||
ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
bool ignoreFault) override;
|
||||
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
||||
ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t* receivedFrom) override;
|
||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
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;
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override = 0;
|
||||
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) override = 0;
|
||||
|
||||
protected:
|
||||
MessageQueueId_t id = MessageQueueIF::NO_QUEUE;
|
||||
|
@ -19,33 +19,32 @@ class HasModesIF {
|
||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
||||
//! An object announces changing the mode. p1: target mode. p2: target submode
|
||||
static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO);
|
||||
//! An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
|
||||
static const Event CHANGING_MODE =
|
||||
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
|
||||
//!< p2: target submode
|
||||
static const Event MODE_INFO = MAKE_EVENT(
|
||||
1,
|
||||
severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
||||
//! Indicates a bug or configuration failure: Object is in a mode it should never be in.
|
||||
static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW);
|
||||
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
|
||||
//! p1: target mode. p2: target submode
|
||||
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
|
||||
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
|
||||
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
|
||||
static const Event OBJECT_IN_INVALID_MODE =
|
||||
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
|
||||
//!< mode it should never be in.
|
||||
static const Event FORCING_MODE = MAKE_EVENT(
|
||||
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
|
||||
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
|
||||
static const Event MODE_CMD_REJECTED =
|
||||
MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1:
|
||||
//!< called object id, Par2: return code.
|
||||
|
||||
//! The device is powered and ready to perform operations. In this mode, no commands are
|
||||
//! sent by the device handler itself, but direct commands van be commanded and will be
|
||||
//! interpreted
|
||||
static constexpr Mode_t MODE_ON = 1;
|
||||
//! The device is powered off. The only command accepted in this mode is a mode change to on.
|
||||
static constexpr Mode_t MODE_OFF = 0;
|
||||
|
||||
static constexpr Mode_t MODE_INVALID = -1;
|
||||
static constexpr Mode_t MODE_UNDEFINED = -2;
|
||||
|
||||
//! To avoid checks against magic number "0".
|
||||
static const Submode_t SUBMODE_NONE = 0;
|
||||
static const Mode_t MODE_ON =
|
||||
1; //!< The device is powered and ready to perform operations. In this mode, no commands are
|
||||
//!< sent by the device handler itself, but direct commands van be commanded and will be
|
||||
//!< interpreted
|
||||
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
|
||||
//!< this mode is a mode change to on.
|
||||
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
|
||||
|
||||
virtual ~HasModesIF() {}
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
@ -17,8 +17,8 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
||||
limit(limit),
|
||||
violationEvent(violationEvent),
|
||||
aboveIsViolation(aboveIsViolation) {}
|
||||
virtual ~AbsLimitMonitor() {}
|
||||
virtual ReturnValue_t checkSample(T sample, T *crossedLimit) {
|
||||
virtual ~AbsLimitMonitor() = default;
|
||||
ReturnValue_t checkSample(T sample, T *crossedLimit) override {
|
||||
*crossedLimit = limit;
|
||||
if (aboveIsViolation) {
|
||||
if ((std::abs(sample) > limit)) {
|
||||
@ -32,9 +32,9 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
||||
return HasReturnvaluesIF::RETURN_OK; // We're not out of range.
|
||||
}
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) override {
|
||||
ReturnValue_t result = this->MonitorBase<T>::getParameter(
|
||||
domainId, parameterId, parameterWrapper, newValues, startAtIndex);
|
||||
// We'll reuse the DOMAIN_ID of MonitorReporter,
|
||||
@ -61,7 +61,7 @@ class AbsLimitMonitor : public MonitorBase<T> {
|
||||
void setLimit(T value) { limit = value; }
|
||||
|
||||
protected:
|
||||
void sendTransitionEvent(T currentValue, ReturnValue_t state) {
|
||||
void sendTransitionEvent(T currentValue, ReturnValue_t state) override {
|
||||
switch (state) {
|
||||
case MonitoringIF::OUT_OF_RANGE:
|
||||
EventManagerIF::triggerEvent(this->reportingId, violationEvent, this->globalPoolId.objectId,
|
||||
|
@ -51,9 +51,8 @@ class MonitorReporter : public HasParametersIF {
|
||||
return state;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override {
|
||||
if (domainId != monitorId) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
|
@ -95,16 +95,13 @@ void ObjectManager::initialize() {
|
||||
for (auto const& it : objectList) {
|
||||
result = it.second->initialize();
|
||||
if (result != RETURN_OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
object_id_t var = it.first;
|
||||
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
||||
<< std::setfill('0') << it.first << " failed to initialize with code 0x" << result
|
||||
<< std::dec << std::setfill(' ') << std::endl;
|
||||
#else
|
||||
sif::printError(
|
||||
"ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", var,
|
||||
it.first);
|
||||
#endif
|
||||
<< std::setfill('0') << var
|
||||
<< " failed to "
|
||||
"initialize with code 0x"
|
||||
<< result << std::dec << std::setfill(' ') << std::endl;
|
||||
#endif
|
||||
errorCount++;
|
||||
}
|
||||
|
@ -16,9 +16,7 @@ elseif(FSFW_OSAL MATCHES "host")
|
||||
|
||||
else()
|
||||
|
||||
message(
|
||||
WARNING
|
||||
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
||||
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
|
||||
# Not set. Assumuing this is a host build, try to determine host OS
|
||||
if(WIN32)
|
||||
add_subdirectory(host)
|
||||
|
@ -51,7 +51,7 @@ class HasParametersIF {
|
||||
return (domainId << 24) + (uniqueId << 16) + linearIndex;
|
||||
}
|
||||
|
||||
virtual ~HasParametersIF() {}
|
||||
virtual ~HasParametersIF() = default;
|
||||
|
||||
/**
|
||||
* This is the generic function overriden by child classes to set
|
||||
@ -66,7 +66,7 @@ class HasParametersIF {
|
||||
* @param newValues
|
||||
* @param startAtIndex Linear index, runs left to right, top to bottom for
|
||||
* matrix indexes.
|
||||
* @return RETURN_OK if parameter is valid and a set function of the parameter wrapper was called.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
|
@ -211,13 +211,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (data == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable or "
|
||||
"data pointer not set"
|
||||
<< std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable!" << std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"ParameterWrapper::copyFrom: Called on read-only variable "
|
||||
"or data pointer not set\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Called on read-only variable!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return READONLY;
|
||||
@ -226,9 +222,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (from->readonlyData == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Source not set" << std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Source not set!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Source not set\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Source not set!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return SOURCE_NOT_SET;
|
||||
@ -237,9 +233,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (type != from->type) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch" << std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return DATATYPE_MISSMATCH;
|
||||
@ -249,9 +245,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
if (rows == 0 or columns == 0) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero" << std::endl;
|
||||
sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero\n");
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return COLUMN_OR_ROWS_ZERO;
|
||||
|
@ -63,13 +63,13 @@ class Fuse : public SystemObject,
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
void setAllMonitorsToUnchecked();
|
||||
ReturnValue_t performOperation(uint8_t opCode);
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
MessageQueueId_t getCommandQueue() const override;
|
||||
void setDataPoolEntriesInvalid();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
HasHealthIF::HealthState getHealth();
|
||||
ReturnValue_t setHealth(HealthState health) override;
|
||||
HasHealthIF::HealthState getHealth() override;
|
||||
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
|
||||
|
||||
private:
|
||||
uint8_t oldFuseState;
|
||||
@ -81,7 +81,7 @@ class Fuse : public SystemObject,
|
||||
template <typename... Args>
|
||||
PowerMonitor(Args... args) : MonitorReporter<float>(std::forward<Args>(args)...) {}
|
||||
ReturnValue_t checkPower(float sample, float lowerLimit, float upperLimit);
|
||||
void sendTransitionEvent(float currentValue, ReturnValue_t state) {}
|
||||
void sendTransitionEvent(float currentValue, ReturnValue_t state_) override {}
|
||||
};
|
||||
PowerMonitor powerMonitor;
|
||||
StaticLocalDataSet<3> set;
|
||||
|
@ -10,15 +10,15 @@ class PowerComponent : public PowerComponentIF {
|
||||
PowerComponent(object_id_t setId, uint8_t moduleId, float minPower, float maxPower,
|
||||
uint8_t switchId1, bool twoSwitches = false, uint8_t switchId2 = 0xFF);
|
||||
|
||||
virtual object_id_t getDeviceObjectId();
|
||||
object_id_t getDeviceObjectId() override;
|
||||
|
||||
virtual uint8_t getSwitchId1();
|
||||
virtual uint8_t getSwitchId2();
|
||||
uint8_t getSwitchId1() override;
|
||||
uint8_t getSwitchId2() override;
|
||||
|
||||
bool hasTwoSwitches();
|
||||
bool hasTwoSwitches() override;
|
||||
|
||||
float getMin();
|
||||
float getMax();
|
||||
float getMin() override;
|
||||
float getMax() override;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
@ -29,7 +29,7 @@ class PowerComponent : public PowerComponentIF {
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex);
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
|
||||
|
||||
private:
|
||||
const object_id_t deviceObjectId = objects::NO_OBJECT;
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
class PowerComponentIF : public SerializeIF, public HasParametersIF {
|
||||
public:
|
||||
virtual ~PowerComponentIF() {}
|
||||
~PowerComponentIF() override = default;
|
||||
|
||||
virtual object_id_t getDeviceObjectId() = 0;
|
||||
|
||||
|
@ -29,9 +29,9 @@ class PowerSwitchIF : public HasReturnvaluesIF {
|
||||
static const ReturnValue_t FUSE_ON = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t FUSE_OFF = MAKE_RETURN_CODE(4);
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_2;
|
||||
//!< Someone detected that a switch went off which shouldn't. Severity:
|
||||
static const Event SWITCH_WENT_OFF = MAKE_EVENT(
|
||||
0, severity::LOW); //!< Someone detected that a switch went off which shouldn't. Severity:
|
||||
//!< Low, Parameter1: switchId1, Parameter2: switchId2
|
||||
static const Event SWITCH_WENT_OFF = MAKE_EVENT(0, severity::LOW);
|
||||
/**
|
||||
* send a direct command to the Power Unit to enable/disable the specified switch.
|
||||
*
|
||||
|
@ -78,7 +78,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService
|
||||
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
|
||||
// does not work in this case as we are deleting the current element here.
|
||||
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
|
||||
if (it->first <= static_cast<uint32_t>(tNow.tv_sec)) {
|
||||
if (it->first <= tNow.tv_sec) {
|
||||
if (schedulingEnabled) {
|
||||
// release tc
|
||||
TmTcMessage releaseMsg(it->second.storeAddr);
|
||||
|
@ -16,9 +16,7 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
|
||||
apid(apid),
|
||||
serviceId(serviceId),
|
||||
targetDestination(targetDestination) {
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||
}
|
||||
|
||||
Service1TelecommandVerification::~Service1TelecommandVerification() {
|
||||
|
@ -208,17 +208,17 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
|
||||
ReturnValue_t error = HasReturnvaluesIF::RETURN_FAILED;
|
||||
HousekeepingMessage::getHkRequestFailureReply(reply, &error);
|
||||
failureParameter2 = error;
|
||||
return RETURN_FAILED;
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
|
||||
default:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
|
||||
<< "reply command " << command << std::endl;
|
||||
<< "reply command " << command << "!" << std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"Service3Housekeeping::handleReply: Invalid reply with "
|
||||
"reply command %hu\n",
|
||||
"reply command %hu!\n",
|
||||
command);
|
||||
#endif
|
||||
return CommandingServiceBase::INVALID_REPLY;
|
||||
@ -248,25 +248,19 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) {
|
||||
case (HousekeepingMessage::HK_REQUEST_FAILURE): {
|
||||
break;
|
||||
}
|
||||
case (CommandMessage::REPLY_REJECTED): {
|
||||
sif::warning << "Service3Housekeeping::handleUnrequestedReply: Unexpected reply "
|
||||
"rejected with error code"
|
||||
<< reply->getParameter() << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service3Housekeeping::handleUnrequestedReply: Invalid reply with reply "
|
||||
"command "
|
||||
<< command << "" << std::endl;
|
||||
<< command << "!" << std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"Service3Housekeeping::handleUnrequestedReply: Invalid reply with "
|
||||
"reply command %hu\n",
|
||||
"reply command %hu!\n",
|
||||
command);
|
||||
#endif
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +275,6 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) {
|
||||
"Could not generate reply!\n");
|
||||
#endif
|
||||
}
|
||||
CommandingServiceBase::handleUnrequestedReply(reply);
|
||||
}
|
||||
|
||||
MessageQueueId_t Service3Housekeeping::getHkQueue() const { return commandQueue->getId(); }
|
||||
|
@ -12,9 +12,7 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, uint16_t ap
|
||||
uint32_t messageQueueDepth)
|
||||
: PusServiceBase(objectId, apid, serviceId),
|
||||
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||
}
|
||||
|
||||
Service5EventReporting::~Service5EventReporting() {
|
||||
@ -38,6 +36,9 @@ ReturnValue_t Service5EventReporting::performService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service5EventReporting::generateEventReport: Too many events" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
class Service5EventReporting : public PusServiceBase {
|
||||
public:
|
||||
Service5EventReporting(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
||||
size_t maxNumberReportsPerCycle, uint32_t messageQueueDepth);
|
||||
size_t maxNumberReportsPerCycle = 10, uint32_t messageQueueDepth = 10);
|
||||
virtual ~Service5EventReporting();
|
||||
|
||||
/***
|
||||
|
@ -6,10 +6,10 @@
|
||||
class Service9TimeManagement : public PusServiceBase {
|
||||
public:
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
||||
//!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
||||
//!< Clock could not be set. P1: Returncode.
|
||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||
static constexpr Event CLOCK_SET =
|
||||
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||
static constexpr Event CLOCK_SET_FAILURE =
|
||||
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
|
||||
|
||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||
|
||||
|
@ -69,7 +69,7 @@ class FailureReport : public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
size_t getSerializedSize() const override {
|
||||
size_t size = 0;
|
||||
size += SerializeAdapter::getSerializedSize(&packetId);
|
||||
size += sizeof(packetSequenceControl);
|
||||
|
@ -34,7 +34,7 @@ class SerializeIF {
|
||||
static const ReturnValue_t TOO_MANY_ELEMENTS =
|
||||
MAKE_RETURN_CODE(3); // !< There are too many elements to be deserialized
|
||||
|
||||
virtual ~SerializeIF() {}
|
||||
virtual ~SerializeIF() = default;
|
||||
/**
|
||||
* @brief
|
||||
* Function to serialize the object into a buffer with maxSize. Size represents the written
|
||||
@ -66,7 +66,7 @@ class SerializeIF {
|
||||
* Gets the size of a object if it would be serialized in a buffer
|
||||
* @return Size of serialized object
|
||||
*/
|
||||
virtual size_t getSerializedSize() const = 0;
|
||||
[[nodiscard]] virtual size_t getSerializedSize() const = 0;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user