Update FSFW #24
@ -26,7 +26,8 @@ enum GpioOperation {
|
|||||||
|
|
||||||
enum GpioTypes {
|
enum GpioTypes {
|
||||||
NONE,
|
NONE,
|
||||||
GPIO_REGULAR,
|
GPIO_REGULAR_BY_CHIP,
|
||||||
|
GPIO_REGULAR_BY_LABEL,
|
||||||
CALLBACK
|
CALLBACK
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,28 +69,57 @@ public:
|
|||||||
int initValue = 0;
|
int initValue = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GpiodRegular: public GpioBase {
|
class GpiodRegularBase: public GpioBase {
|
||||||
public:
|
public:
|
||||||
GpiodRegular() :
|
GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||||
GpioBase(gpio::GpioTypes::GPIO_REGULAR, std::string(), gpio::Direction::IN, 0) {
|
int initValue, int lineNum): GpioBase(gpioType, consumer, direction, initValue),
|
||||||
|
lineNum(lineNum) {
|
||||||
}
|
}
|
||||||
;
|
|
||||||
|
|
||||||
GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_,
|
|
||||||
gpio::Direction direction_, int initValue_) :
|
|
||||||
GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, direction_, initValue_),
|
|
||||||
chipname(chipname_), lineNum(lineNum_) {
|
|
||||||
}
|
|
||||||
|
|
||||||
GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_) :
|
|
||||||
GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, gpio::Direction::IN, 0),
|
|
||||||
chipname(chipname_), lineNum(lineNum_) {
|
|
||||||
}
|
|
||||||
std::string chipname;
|
|
||||||
int lineNum = 0;
|
int lineNum = 0;
|
||||||
struct gpiod_line* lineHandle = nullptr;
|
struct gpiod_line* lineHandle = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GpiodRegularByChip: public GpiodRegularBase {
|
||||||
|
public:
|
||||||
|
GpiodRegularByChip() :
|
||||||
|
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP,
|
||||||
|
std::string(), gpio::Direction::IN, gpio::LOW, 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_,
|
||||||
|
gpio::Direction direction_, int initValue_) :
|
||||||
|
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP,
|
||||||
|
consumer_, direction_, initValue_, lineNum_),
|
||||||
|
chipname(chipname_){
|
||||||
|
}
|
||||||
|
|
||||||
|
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_) :
|
||||||
|
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, consumer_,
|
||||||
|
gpio::Direction::IN, gpio::LOW, lineNum_),
|
||||||
|
chipname(chipname_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string chipname;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GpiodRegularByLabel: public GpiodRegularBase {
|
||||||
|
public:
|
||||||
|
GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_,
|
||||||
|
gpio::Direction direction_, int initValue_) :
|
||||||
|
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_,
|
||||||
|
direction_, initValue_, lineNum_),
|
||||||
|
label(label_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_) :
|
||||||
|
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_,
|
||||||
|
gpio::Direction::IN, gpio::LOW, lineNum_),
|
||||||
|
label(label_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string label;
|
||||||
|
};
|
||||||
|
|
||||||
class GpioCallback: public GpioBase {
|
class GpioCallback: public GpioBase {
|
||||||
public:
|
public:
|
||||||
GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_,
|
GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
|
#include "GyroL3GD20Handler.h"
|
||||||
|
|
||||||
#include "fsfw/datapool/PoolReadGuard.h"
|
#include "fsfw/datapool/PoolReadGuard.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication,
|
GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication,
|
||||||
CookieIF *comCookie, uint32_t transitionDelayMs):
|
CookieIF *comCookie, uint32_t transitionDelayMs):
|
||||||
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication,
|
MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication,
|
||||||
CookieIF* comCookie, uint32_t transitionDelay):
|
CookieIF* comCookie, uint32_t transitionDelay):
|
||||||
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
|
@ -89,9 +89,16 @@ ReturnValue_t MgmRM3100Handler::buildTransitionDeviceCommand(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
// Might be a configuration error
|
// Might be a configuration error
|
||||||
sif::warning << "MgmRM3100Handler::buildTransitionDeviceCommand: Unknown internal state!" <<
|
sif::warning << "MgmRM3100Handler::buildTransitionDeviceCommand: "
|
||||||
std::endl;
|
"Unknown internal state" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("MgmRM3100Handler::buildTransitionDeviceCommand: "
|
||||||
|
"Unknown internal state\n");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,12 +349,18 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
|
|||||||
|
|
||||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
||||||
if(debugDivider->checkAndIncrement()) {
|
if(debugDivider->checkAndIncrement()) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "MgmRM3100Handler: Magnetic field strength in"
|
sif::info << "MgmRM3100Handler: Magnetic field strength in"
|
||||||
" microtesla:" << std::endl;
|
" microtesla:" << std::endl;
|
||||||
/* Set terminal to utf-8 if there is an issue with micro printout. */
|
|
||||||
sif::info << "X: " << fieldStrengthX << " uT" << std::endl;
|
sif::info << "X: " << fieldStrengthX << " uT" << std::endl;
|
||||||
sif::info << "Y: " << fieldStrengthY << " uT" << std::endl;
|
sif::info << "Y: " << fieldStrengthY << " uT" << std::endl;
|
||||||
sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl;
|
sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printInfo("MgmRM3100Handler: Magnetic field strength in microtesla:\n");
|
||||||
|
sif::printInfo("X: %f uT\n", fieldStrengthX);
|
||||||
|
sif::printInfo("Y: %f uT\n", fieldStrengthY);
|
||||||
|
sif::printInfo("Z: %f uT\n", fieldStrengthZ);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ LinuxLibgpioIF::~LinuxLibgpioIF() {
|
|||||||
ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
if(gpioCookie == nullptr) {
|
if(gpioCookie == nullptr) {
|
||||||
sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl;
|
sif::error << "LinuxLibgpioIF::addGpios: Invalid cookie" << std::endl;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,16 +45,25 @@ ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
|||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||||
for(auto& gpioConfig: mapToAdd) {
|
for(auto& gpioConfig: mapToAdd) {
|
||||||
switch(gpioConfig.second->gpioType) {
|
auto& gpioType = gpioConfig.second->gpioType;
|
||||||
|
switch(gpioType) {
|
||||||
case(gpio::GpioTypes::NONE): {
|
case(gpio::GpioTypes::NONE): {
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
case(gpio::GpioTypes::GPIO_REGULAR): {
|
case(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP): {
|
||||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
auto regularGpio = dynamic_cast<GpiodRegularByChip*>(gpioConfig.second);
|
||||||
if(regularGpio == nullptr) {
|
if(regularGpio == nullptr) {
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
configureRegularGpio(gpioConfig.first, regularGpio);
|
configureGpioByChip(gpioConfig.first, *regularGpio);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL):{
|
||||||
|
auto regularGpio = dynamic_cast<GpiodRegularByLabel*>(gpioConfig.second);
|
||||||
|
if(regularGpio == nullptr) {
|
||||||
|
return GPIO_INVALID_INSTANCE;
|
||||||
|
}
|
||||||
|
configureGpioByLabel(gpioConfig.first, *regularGpio);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpio::GpioTypes::CALLBACK): {
|
case(gpio::GpioTypes::CALLBACK): {
|
||||||
@ -70,41 +79,59 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
|||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular *regularGpio) {
|
ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId,
|
||||||
std::string chipname;
|
GpiodRegularByLabel &gpioByLabel) {
|
||||||
|
std::string& label = gpioByLabel.label;
|
||||||
|
struct gpiod_chip* chip = gpiod_chip_open_by_label(label.c_str());
|
||||||
|
if (chip == nullptr) {
|
||||||
|
sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open gpio from gpio "
|
||||||
|
<< "group with label " << label << ". Gpio ID: " << gpioId << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
|
||||||
|
}
|
||||||
|
std::string failOutput = "label: " + label;
|
||||||
|
return configureRegularGpio(gpioId, gpioByLabel.gpioType, chip, gpioByLabel, failOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId,
|
||||||
|
GpiodRegularByChip &gpioByChip) {
|
||||||
|
std::string& chipname = gpioByChip.chipname;
|
||||||
|
struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname.c_str());
|
||||||
|
if (chip == nullptr) {
|
||||||
|
sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip "
|
||||||
|
<< chipname << ". Gpio ID: " << gpioId << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
std::string failOutput = "chipname: " + chipname;
|
||||||
|
return configureRegularGpio(gpioId, gpioByChip.gpioType, chip, gpioByChip, failOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType,
|
||||||
|
struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput) {
|
||||||
unsigned int lineNum;
|
unsigned int lineNum;
|
||||||
struct gpiod_chip *chip;
|
|
||||||
gpio::Direction direction;
|
gpio::Direction direction;
|
||||||
std::string consumer;
|
std::string consumer;
|
||||||
struct gpiod_line *lineHandle;
|
struct gpiod_line *lineHandle;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
chipname = regularGpio->chipname;
|
lineNum = regularGpio.lineNum;
|
||||||
chip = gpiod_chip_open_by_name(chipname.c_str());
|
|
||||||
if (!chip) {
|
|
||||||
sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip "
|
|
||||||
<< chipname << ". Gpio ID: " << gpioId << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
lineNum = regularGpio->lineNum;
|
|
||||||
lineHandle = gpiod_chip_get_line(chip, lineNum);
|
lineHandle = gpiod_chip_get_line(chip, lineNum);
|
||||||
if (!lineHandle) {
|
if (!lineHandle) {
|
||||||
sif::debug << "LinuxLibgpioIF::configureRegularGpio: Failed to open line " << std::endl;
|
sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open line " << std::endl;
|
||||||
sif::debug << "GPIO ID: " << gpioId << ", line number: " << lineNum <<
|
sif::warning << "GPIO ID: " << gpioId << ", line number: " << lineNum <<
|
||||||
", chipname: " << chipname << std::endl;
|
", " << failOutput << std::endl;
|
||||||
sif::debug << "Check if linux GPIO configuration has changed. " << std::endl;
|
sif::warning << "Check if Linux GPIO configuration has changed. " << std::endl;
|
||||||
gpiod_chip_close(chip);
|
gpiod_chip_close(chip);
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
direction = regularGpio->direction;
|
direction = regularGpio.direction;
|
||||||
consumer = regularGpio->consumer;
|
consumer = regularGpio.consumer;
|
||||||
/* Configure direction and add a description to the GPIO */
|
/* Configure direction and add a description to the GPIO */
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case(gpio::OUT): {
|
case(gpio::OUT): {
|
||||||
result = gpiod_line_request_output(lineHandle, consumer.c_str(),
|
result = gpiod_line_request_output(lineHandle, consumer.c_str(),
|
||||||
regularGpio->initValue);
|
regularGpio.initValue);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
sif::error << "LinuxLibgpioIF::configureRegularGpio: Failed to request line " << lineNum <<
|
sif::error << "LinuxLibgpioIF::configureRegularGpio: Failed to request line " << lineNum <<
|
||||||
" from GPIO instance with ID: " << gpioId << std::endl;
|
" from GPIO instance with ID: " << gpioId << std::endl;
|
||||||
@ -134,7 +161,7 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular
|
|||||||
* Write line handle to GPIO configuration instance so it can later be used to set or
|
* Write line handle to GPIO configuration instance so it can later be used to set or
|
||||||
* read states of GPIOs.
|
* read states of GPIOs.
|
||||||
*/
|
*/
|
||||||
regularGpio->lineHandle = lineHandle;
|
regularGpio.lineHandle = lineHandle;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +172,14 @@ ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
|||||||
return UNKNOWN_GPIO_ID;
|
return UNKNOWN_GPIO_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIO_REGULAR) {
|
auto gpioType = gpioMapIter->second->gpioType;
|
||||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 1);
|
if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or
|
||||||
|
gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) {
|
||||||
|
auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second);
|
||||||
|
if(regularGpio == nullptr) {
|
||||||
|
return GPIO_TYPE_FAILURE;
|
||||||
|
}
|
||||||
|
return driveGpio(gpioId, *regularGpio, gpio::HIGH);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||||
@ -167,8 +200,14 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
|||||||
return UNKNOWN_GPIO_ID;
|
return UNKNOWN_GPIO_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIO_REGULAR) {
|
auto& gpioType = gpioMapIter->second->gpioType;
|
||||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 0);
|
if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or
|
||||||
|
gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) {
|
||||||
|
auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second);
|
||||||
|
if(regularGpio == nullptr) {
|
||||||
|
return GPIO_TYPE_FAILURE;
|
||||||
|
}
|
||||||
|
return driveGpio(gpioId, *regularGpio, gpio::LOW);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||||
@ -183,12 +222,8 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
|
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
|
||||||
GpiodRegular* regularGpio, unsigned int logicLevel) {
|
GpiodRegularBase& regularGpio, gpio::Levels logicLevel) {
|
||||||
if(regularGpio == nullptr) {
|
int result = gpiod_line_set_value(regularGpio.lineHandle, logicLevel);
|
||||||
return GPIO_TYPE_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel);
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId <<
|
sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId <<
|
||||||
" to logic level " << logicLevel << std::endl;
|
" to logic level " << logicLevel << std::endl;
|
||||||
@ -204,9 +239,10 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
|
|||||||
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||||
return UNKNOWN_GPIO_ID;
|
return UNKNOWN_GPIO_ID;
|
||||||
}
|
}
|
||||||
|
auto gpioType = gpioMapIter->second->gpioType;
|
||||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIO_REGULAR) {
|
if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or
|
||||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) {
|
||||||
|
auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second);
|
||||||
if(regularGpio == nullptr) {
|
if(regularGpio == nullptr) {
|
||||||
return GPIO_TYPE_FAILURE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
}
|
||||||
@ -225,13 +261,14 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){
|
|||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
for(auto& gpioConfig: mapToAdd) {
|
for(auto& gpioConfig: mapToAdd) {
|
||||||
switch(gpioConfig.second->gpioType) {
|
switch(gpioConfig.second->gpioType) {
|
||||||
case(gpio::GpioTypes::GPIO_REGULAR): {
|
case(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP):
|
||||||
auto regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
case(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): {
|
||||||
|
auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioConfig.second);
|
||||||
if(regularGpio == nullptr) {
|
if(regularGpio == nullptr) {
|
||||||
return GPIO_TYPE_FAILURE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
}
|
||||||
/* Check for conflicts and remove duplicates if necessary */
|
/* Check for conflicts and remove duplicates if necessary */
|
||||||
result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd);
|
result = checkForConflictsRegularGpio(gpioConfig.first, *regularGpio, mapToAdd);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
status = result;
|
status = result;
|
||||||
}
|
}
|
||||||
@ -259,17 +296,19 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){
|
|||||||
|
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck,
|
ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck,
|
||||||
GpiodRegular* gpioToCheck, GpioMap& mapToAdd) {
|
GpiodRegularBase& gpioToCheck, GpioMap& mapToAdd) {
|
||||||
/* Cross check with private map */
|
/* Cross check with private map */
|
||||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||||
if(gpioMapIter != gpioMap.end()) {
|
if(gpioMapIter != gpioMap.end()) {
|
||||||
if(gpioMapIter->second->gpioType != gpio::GpioTypes::GPIO_REGULAR) {
|
auto& gpioType = gpioMapIter->second->gpioType;
|
||||||
|
if(gpioType != gpio::GpioTypes::GPIO_REGULAR_BY_CHIP and
|
||||||
|
gpioType != gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) {
|
||||||
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
||||||
"GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl;
|
"GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl;
|
||||||
mapToAdd.erase(gpioIdToCheck);
|
mapToAdd.erase(gpioIdToCheck);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
auto ownRegularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
auto ownRegularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second);
|
||||||
if(ownRegularGpio == nullptr) {
|
if(ownRegularGpio == nullptr) {
|
||||||
return GPIO_TYPE_FAILURE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
|
||||||
class GpioCookie;
|
class GpioCookie;
|
||||||
|
class GpiodRegularIF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class implements the GpioIF for a linux based system. The
|
* @brief This class implements the GpioIF for a linux based system. The
|
||||||
@ -47,9 +48,13 @@ private:
|
|||||||
* @param gpioId The GPIO ID of the GPIO to drive.
|
* @param gpioId The GPIO ID of the GPIO to drive.
|
||||||
* @param logiclevel The logic level to set. O or 1.
|
* @param logiclevel The logic level to set. O or 1.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio, unsigned int logiclevel);
|
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio,
|
||||||
|
gpio::Levels logicLevel);
|
||||||
|
|
||||||
ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio);
|
ReturnValue_t configureGpioByLabel(gpioId_t gpioId, GpiodRegularByLabel& gpioByLabel);
|
||||||
|
ReturnValue_t configureGpioByChip(gpioId_t gpioId, GpiodRegularByChip& gpioByChip);
|
||||||
|
ReturnValue_t configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType,
|
||||||
|
struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function checks if GPIOs are already registered and whether
|
* @brief This function checks if GPIOs are already registered and whether
|
||||||
@ -62,7 +67,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t checkForConflicts(GpioMap& mapToAdd);
|
ReturnValue_t checkForConflicts(GpioMap& mapToAdd);
|
||||||
|
|
||||||
ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio,
|
ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegularBase& regularGpio,
|
||||||
GpioMap& mapToAdd);
|
GpioMap& mapToAdd);
|
||||||
ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio,
|
ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio,
|
||||||
GpioMap& mapToAdd);
|
GpioMap& mapToAdd);
|
||||||
|
@ -12,7 +12,7 @@ ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int
|
|||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpiodRegular* config = new GpiodRegular();
|
auto config = new GpiodRegularByChip();
|
||||||
/* Default chipname for Raspberry Pi. There is still gpiochip1 for expansion, but most users
|
/* Default chipname for Raspberry Pi. There is still gpiochip1 for expansion, but most users
|
||||||
will not need this */
|
will not need this */
|
||||||
config->chipname = "gpiochip0";
|
config->chipname = "gpiochip0";
|
||||||
|
@ -141,8 +141,8 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s
|
|||||||
if(sendLen > spiCookie->getMaxBufferSize()) {
|
if(sendLen > spiCookie->getMaxBufferSize()) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SpiComIF::sendMessage: Too much data sent, send length" << sendLen <<
|
sif::warning << "SpiComIF::sendMessage: Too much data sent, send length " << sendLen <<
|
||||||
"larger than maximum buffer length" << spiCookie->getMaxBufferSize() << std::endl;
|
"larger than maximum buffer length " << spiCookie->getMaxBufferSize() << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("SpiComIF::sendMessage: Too much data sent, send length %lu larger "
|
sif::printWarning("SpiComIF::sendMessage: Too much data sent, send length %lu larger "
|
||||||
"than maximum buffer length %lu!\n", static_cast<unsigned long>(sendLen),
|
"than maximum buffer length %lu!\n", static_cast<unsigned long>(sendLen),
|
||||||
@ -197,12 +197,26 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const
|
|||||||
if(gpioId != gpio::NO_GPIO) {
|
if(gpioId != gpio::NO_GPIO) {
|
||||||
result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl;
|
sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("SpiComIF::sendMessage: Failed to lock mutex\n");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
ReturnValue_t result = gpioComIF->pullLow(gpioId);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "SpiComIF::sendMessage: Pulling low CS pin failed" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("SpiComIF::sendMessage: Pulling low CS pin failed");
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
gpioComIF->pullLow(gpioId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute transfer */
|
/* Execute transfer */
|
||||||
@ -213,7 +227,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const
|
|||||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
result = FULL_DUPLEX_TRANSFER_FAILED;
|
result = FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
#if FSFW_HAL_LINUX_SPI_WIRETAPPING == 1
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
performSpiWiretapping(spiCookie);
|
performSpiWiretapping(spiCookie);
|
||||||
#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
|
#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
|
||||||
}
|
}
|
||||||
@ -384,11 +398,11 @@ GpioIF* SpiComIF::getGpioInterface() {
|
|||||||
void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
||||||
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast<uint8_t*>(&mode));
|
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast<uint8_t*>(&mode));
|
||||||
if(retval != 0) {
|
if(retval != 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!");
|
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI mode failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||||
if(retval != 0) {
|
if(retval != 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!");
|
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,15 @@
|
|||||||
#cmakedefine FSFW_ADD_MONITORING
|
#cmakedefine FSFW_ADD_MONITORING
|
||||||
#cmakedefine FSFW_ADD_SGP4_PROPAGATOR
|
#cmakedefine FSFW_ADD_SGP4_PROPAGATOR
|
||||||
|
|
||||||
|
#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED
|
||||||
|
#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Can be used for low-level debugging of the SPI bus
|
||||||
|
#ifndef FSFW_HAL_SPI_WIRETAPPING
|
||||||
|
#define FSFW_HAL_SPI_WIRETAPPING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG
|
#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG
|
||||||
#define FSFW_HAL_L3GD20_GYRO_DEBUG 0
|
#define FSFW_HAL_L3GD20_GYRO_DEBUG 0
|
||||||
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */
|
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Base class to implement reconfiguration and failure handling for
|
* @brief Base class to implement reconfiguration and failure handling for
|
||||||
* redundant devices by monitoring their modes health states.
|
* redundant devices by monitoring their modes and health states.
|
||||||
* @details
|
* @details
|
||||||
* Documentation: Dissertation Baetz p.156, 157.
|
* Documentation: Dissertation Baetz p.156, 157.
|
||||||
*
|
*
|
||||||
|
@ -85,9 +85,10 @@ public:
|
|||||||
* Called by DHB in the GET_WRITE doGetWrite().
|
* Called by DHB in the GET_WRITE doGetWrite().
|
||||||
* Get send confirmation that the data in sendMessage() was sent successfully.
|
* Get send confirmation that the data in sendMessage() was sent successfully.
|
||||||
* @param cookie
|
* @param cookie
|
||||||
* @return - @c RETURN_OK if data was sent successfull
|
* @return
|
||||||
* - Everything else triggers falure event with
|
* - @c RETURN_OK if data was sent successfully but a reply is expected
|
||||||
* returnvalue as parameter 1
|
* - NO_REPLY_EXPECTED if data was sent successfully and no reply is expected
|
||||||
|
* - Everything else to indicate failure
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0;
|
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0;
|
||||||
|
|
||||||
|
@ -335,8 +335,7 @@ protected:
|
|||||||
* - @c RETURN_OK to send command after #rawPacket and #rawPacketLen
|
* - @c RETURN_OK to send command after #rawPacket and #rawPacketLen
|
||||||
* have been set.
|
* have been set.
|
||||||
* - @c HasActionsIF::EXECUTION_COMPLETE to generate a finish reply immediately. This can
|
* - @c HasActionsIF::EXECUTION_COMPLETE to generate a finish reply immediately. This can
|
||||||
* be used if no reply is expected. Otherwise, the developer can call #actionHelper.finish
|
* be used if no reply is expected
|
||||||
* to finish the command handling.
|
|
||||||
* - Anything else triggers an event with the return code as a parameter as well as a
|
* - Anything else triggers an event with the return code as a parameter as well as a
|
||||||
* step reply failed with the return code
|
* step reply failed with the return code
|
||||||
*/
|
*/
|
||||||
|
@ -120,7 +120,8 @@ public:
|
|||||||
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
|
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
|
||||||
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6);
|
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6);
|
||||||
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7);
|
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7);
|
||||||
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command.
|
//!< Used to indicate that this is a command-only command.
|
||||||
|
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8);
|
||||||
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
|
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
|
||||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ enum: uint8_t {
|
|||||||
PUS_SERVICE_9 = 89,
|
PUS_SERVICE_9 = 89,
|
||||||
PUS_SERVICE_17 = 97,
|
PUS_SERVICE_17 = 97,
|
||||||
PUS_SERVICE_23 = 103,
|
PUS_SERVICE_23 = 103,
|
||||||
|
MGM_LIS3MDL = 106,
|
||||||
|
MGM_RM3100 = 107,
|
||||||
|
|
||||||
FW_SUBSYSTEM_ID_RANGE
|
FW_SUBSYSTEM_ID_RANGE
|
||||||
};
|
};
|
||||||
|
@ -7,14 +7,13 @@ PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PeriodicOperationDivider::checkAndIncrement() {
|
bool PeriodicOperationDivider::checkAndIncrement() {
|
||||||
|
counter++;
|
||||||
bool opNecessary = check();
|
bool opNecessary = check();
|
||||||
if(opNecessary) {
|
if(opNecessary) {
|
||||||
if(resetAutomatically) {
|
if(resetAutomatically) {
|
||||||
counter = 0;
|
resetCounter();
|
||||||
}
|
}
|
||||||
return opNecessary;
|
|
||||||
}
|
}
|
||||||
counter ++;
|
|
||||||
return opNecessary;
|
return opNecessary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include "fsfw/osal/common/TcpTmTcServer.h"
|
|
||||||
#include "fsfw/osal/common/TcpTmTcBridge.h"
|
|
||||||
#include "fsfw/osal/common/tcpipHelpers.h"
|
|
||||||
|
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
|
#include "fsfw/FSFW.h"
|
||||||
|
|
||||||
|
#include "TcpTmTcServer.h"
|
||||||
|
#include "TcpTmTcBridge.h"
|
||||||
|
#include "tcpipHelpers.h"
|
||||||
|
|
||||||
#include "fsfw/container/SharedRingBuffer.h"
|
#include "fsfw/container/SharedRingBuffer.h"
|
||||||
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
|
@ -285,10 +285,10 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
|
|
||||||
utility::printUnixErrorGeneric(CLASS_NAME, "sendMessageFromMessageQueue", "EBADF");
|
utility::printUnixErrorGeneric(CLASS_NAME, "sendMessageFromMessageQueue", "EBADF");
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "mq_send to: " << sendTo << " sent from "
|
sif::warning << "mq_send to " << sendTo << " sent from "
|
||||||
<< sentFrom << "failed" << std::endl;
|
<< sentFrom << " failed" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("mq_send to: %d sent from %d failed\n", sendTo, sentFrom);
|
sif::printWarning("mq_send to %d sent from %d failed\n", sendTo, sentFrom);
|
||||||
#endif
|
#endif
|
||||||
return DESTINATION_INVALID;
|
return DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,7 @@ ReturnValue_t Service5EventReporting::performService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Service5EventReporting::generateEventReport:"
|
sif::warning << "Service5EventReporting::generateEventReport: Too many events" << std::endl;
|
||||||
" Too many events" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -64,8 +63,11 @@ ReturnValue_t Service5EventReporting::generateEventReport(
|
|||||||
requestQueue->getDefaultDestination(),requestQueue->getId());
|
requestQueue->getDefaultDestination(),requestQueue->getId());
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Service5EventReporting::generateEventReport:"
|
sif::warning << "Service5EventReporting::generateEventReport: "
|
||||||
" Could not send TM packet" << std::endl;
|
"Could not send TM packet" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("Service5EventReporting::generateEventReport: "
|
||||||
|
"Could not send TM packet\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -33,8 +33,8 @@ ReturnValue_t Service8FunctionManagement::getMessageQueueAndObject(
|
|||||||
if(tcDataLen < sizeof(object_id_t)) {
|
if(tcDataLen < sizeof(object_id_t)) {
|
||||||
return CommandingServiceBase::INVALID_TC;
|
return CommandingServiceBase::INVALID_TC;
|
||||||
}
|
}
|
||||||
SerializeAdapter::deSerialize(objectId, &tcData,
|
// Can't fail, size was checked before
|
||||||
&tcDataLen, SerializeIF::Endianness::BIG);
|
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
||||||
|
|
||||||
return checkInterfaceAndAcquireMessageQueue(id,objectId);
|
return checkInterfaceAndAcquireMessageQueue(id,objectId);
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,9 @@ enum: uint8_t {
|
|||||||
HAL_UART, //HURT
|
HAL_UART, //HURT
|
||||||
HAL_I2C, //HI2C
|
HAL_I2C, //HI2C
|
||||||
HAL_GPIO, //HGIO
|
HAL_GPIO, //HGIO
|
||||||
|
FIXED_SLOT_TASK_IF, //FTIF
|
||||||
|
MGM_LIS3MDL, //MGMLIS3
|
||||||
|
MGM_RM3100, //MGMRM3100
|
||||||
FW_CLASS_ID_COUNT // [EXPORT] : [END]
|
FW_CLASS_ID_COUNT // [EXPORT] : [END]
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -62,7 +62,8 @@ protected:
|
|||||||
struct ChildInfo {
|
struct ChildInfo {
|
||||||
MessageQueueId_t commandQueue;
|
MessageQueueId_t commandQueue;
|
||||||
Mode_t mode;
|
Mode_t mode;
|
||||||
Submode_t submode;bool healthChanged;
|
Submode_t submode;
|
||||||
|
bool healthChanged;
|
||||||
};
|
};
|
||||||
|
|
||||||
Mode_t mode;
|
Mode_t mode;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "fsfw/tasks/FixedSlotSequence.h"
|
#include "fsfw/tasks/FixedSlotSequence.h"
|
||||||
|
#include "fsfw/tasks/FixedTimeslotTaskIF.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
@ -92,10 +93,9 @@ void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
|
|||||||
ReturnValue_t FixedSlotSequence::checkSequence() const {
|
ReturnValue_t FixedSlotSequence::checkSequence() const {
|
||||||
if(slotList.empty()) {
|
if(slotList.empty()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FixedSlotSequence::checkSequence:"
|
sif::warning << "FixedSlotSequence::checkSequence: Slot list is empty!" << std::endl;
|
||||||
<< " Slot list is empty!" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return FixedTimeslotTaskIF::SLOT_LIST_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(customCheckFunction != nullptr) {
|
if(customCheckFunction != nullptr) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define FSFW_TASKS_FIXEDSLOTSEQUENCE_H_
|
#define FSFW_TASKS_FIXEDSLOTSEQUENCE_H_
|
||||||
|
|
||||||
#include "FixedSequenceSlot.h"
|
#include "FixedSequenceSlot.h"
|
||||||
#include "../objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@ -136,6 +136,7 @@ public:
|
|||||||
* @details
|
* @details
|
||||||
* Checks if timing is ok (must be ascending) and if all handlers were found.
|
* Checks if timing is ok (must be ascending) and if all handlers were found.
|
||||||
* @return
|
* @return
|
||||||
|
* - SLOT_LIST_EMPTY if the slot list is empty
|
||||||
*/
|
*/
|
||||||
ReturnValue_t checkSequence() const;
|
ReturnValue_t checkSequence() const;
|
||||||
|
|
||||||
@ -147,6 +148,7 @@ public:
|
|||||||
* The general check will be continued for now if the custom check function
|
* The general check will be continued for now if the custom check function
|
||||||
* fails but a diagnostic debug output will be given.
|
* fails but a diagnostic debug output will be given.
|
||||||
* @param customCheckFunction
|
* @param customCheckFunction
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
void addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList &));
|
void addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList &));
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
#define FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_
|
#define FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_
|
||||||
|
|
||||||
#include "PeriodicTaskIF.h"
|
#include "PeriodicTaskIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||||
|
#include "fsfw/returnvalues/FwClassIds.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Following the same principle as the base class IF.
|
* @brief Following the same principle as the base class IF.
|
||||||
@ -12,6 +13,8 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF {
|
|||||||
public:
|
public:
|
||||||
virtual ~FixedTimeslotTaskIF() {}
|
virtual ~FixedTimeslotTaskIF() {}
|
||||||
|
|
||||||
|
static constexpr ReturnValue_t SLOT_LIST_EMPTY = HasReturnvaluesIF::makeReturnCode(
|
||||||
|
CLASS_ID::FIXED_SLOT_TASK_IF, 0);
|
||||||
/**
|
/**
|
||||||
* Add an object with a slot time and the execution step to the task.
|
* Add an object with a slot time and the execution step to the task.
|
||||||
* The execution step will be passed to the object (e.g. as an operation
|
* The execution step will be passed to the object (e.g. as an operation
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
SpacePacketBase::SpacePacketBase( const uint8_t* set_address ) {
|
SpacePacketBase::SpacePacketBase(const uint8_t* setAddress) {
|
||||||
this->data = (SpacePacketPointer*) set_address;
|
this->data = reinterpret_cast<SpacePacketPointer*>(const_cast<uint8_t*>(setAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpacePacketBase::~SpacePacketBase() {
|
SpacePacketBase::~SpacePacketBase() {
|
||||||
@ -15,10 +15,21 @@ uint8_t SpacePacketBase::getPacketVersionNumber( void ) {
|
|||||||
return (this->data->header.packet_id_h & 0b11100000) >> 5;
|
return (this->data->header.packet_id_h & 0b11100000) >> 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpacePacketBase::initSpacePacketHeader(bool isTelecommand,
|
ReturnValue_t SpacePacketBase::initSpacePacketHeader(bool isTelecommand,
|
||||||
bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount) {
|
bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount) {
|
||||||
|
if(data == nullptr) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "SpacePacketBase::initSpacePacketHeader: Data pointer is invalid"
|
||||||
|
<< std::endl;
|
||||||
|
#else
|
||||||
|
sif::printWarning("SpacePacketBase::initSpacePacketHeader: Data pointer is invalid!\n");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
//reset header to zero:
|
//reset header to zero:
|
||||||
memset(data,0, sizeof(this->data->header) );
|
memset(data, 0, sizeof(this->data->header) );
|
||||||
//Set TC/TM bit.
|
//Set TC/TM bit.
|
||||||
data->header.packet_id_h = ((isTelecommand? 1 : 0)) << 4;
|
data->header.packet_id_h = ((isTelecommand? 1 : 0)) << 4;
|
||||||
//Set secondaryHeader bit
|
//Set secondaryHeader bit
|
||||||
@ -27,7 +38,7 @@ void SpacePacketBase::initSpacePacketHeader(bool isTelecommand,
|
|||||||
//Always initialize as standalone packets.
|
//Always initialize as standalone packets.
|
||||||
data->header.sequence_control_h = 0b11000000;
|
data->header.sequence_control_h = 0b11000000;
|
||||||
setPacketSequenceCount(sequenceCount);
|
setPacketSequenceCount(sequenceCount);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpacePacketBase::isTelecommand( void ) {
|
bool SpacePacketBase::isTelecommand( void ) {
|
||||||
@ -54,6 +65,11 @@ void SpacePacketBase::setAPID( uint16_t new_apid ) {
|
|||||||
this->data->header.packet_id_l = ( new_apid & 0x00FF );
|
this->data->header.packet_id_l = ( new_apid & 0x00FF );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpacePacketBase::setSequenceFlags( uint8_t sequenceflags ) {
|
||||||
|
this->data->header.sequence_control_h &= 0x3F;
|
||||||
|
this->data->header.sequence_control_h |= sequenceflags << 6;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t SpacePacketBase::getPacketSequenceControl( void ) {
|
uint16_t SpacePacketBase::getPacketSequenceControl( void ) {
|
||||||
return ( (this->data->header.sequence_control_h) << 8 )
|
return ( (this->data->header.sequence_control_h) << 8 )
|
||||||
+ this->data->header.sequence_control_l;
|
+ this->data->header.sequence_control_l;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define FSFW_TMTCPACKET_SPACEPACKETBASE_H_
|
#define FSFW_TMTCPACKET_SPACEPACKETBASE_H_
|
||||||
|
|
||||||
#include "ccsds_header.h"
|
#include "ccsds_header.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +84,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isTelecommand( void );
|
bool isTelecommand( void );
|
||||||
|
|
||||||
void initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader,
|
ReturnValue_t initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader,
|
||||||
uint16_t apid, uint16_t sequenceCount = 0);
|
uint16_t apid, uint16_t sequenceCount = 0);
|
||||||
/**
|
/**
|
||||||
* The CCSDS header provides a secondary header flag (the fifth-highest bit),
|
* The CCSDS header provides a secondary header flag (the fifth-highest bit),
|
||||||
@ -109,6 +111,13 @@ public:
|
|||||||
* ignored.
|
* ignored.
|
||||||
*/
|
*/
|
||||||
void setAPID( uint16_t setAPID );
|
void setAPID( uint16_t setAPID );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the sequence flags of a packet, which are bit 17 and 18 in the space packet header.
|
||||||
|
* @param The sequence flags to set
|
||||||
|
*/
|
||||||
|
void setSequenceFlags( uint8_t sequenceflags );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the CCSDS packet sequence control field, which are the third and
|
* Returns the CCSDS packet sequence control field, which are the third and
|
||||||
* the fourth byte of the CCSDS primary header.
|
* the fourth byte of the CCSDS primary header.
|
||||||
|
@ -53,11 +53,14 @@ uint8_t* TmPacketPusC::getPacketTimeRaw() const{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service,
|
ReturnValue_t TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service,
|
||||||
uint8_t subservice, uint16_t packetSubcounter, uint16_t destinationId,
|
uint8_t subservice, uint16_t packetSubcounter, uint16_t destinationId,
|
||||||
uint8_t timeRefField) {
|
uint8_t timeRefField) {
|
||||||
//Set primary header:
|
//Set primary header:
|
||||||
initSpacePacketHeader(false, true, apid);
|
ReturnValue_t result = initSpacePacketHeader(false, true, apid);
|
||||||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
//Set data Field Header:
|
//Set data Field Header:
|
||||||
//First, set to zero.
|
//First, set to zero.
|
||||||
memset(&tmData->dataField, 0, sizeof(tmData->dataField));
|
memset(&tmData->dataField, 0, sizeof(tmData->dataField));
|
||||||
@ -76,6 +79,7 @@ void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service,
|
|||||||
timeStamper->addTimeStamp(tmData->dataField.time,
|
timeStamper->addTimeStamp(tmData->dataField.time,
|
||||||
sizeof(tmData->dataField.time));
|
sizeof(tmData->dataField.time));
|
||||||
}
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmPacketPusC::setSourceDataSize(uint16_t size) {
|
void TmPacketPusC::setSourceDataSize(uint16_t size) {
|
||||||
|
@ -100,7 +100,7 @@ protected:
|
|||||||
* @param subservice PUS Subservice
|
* @param subservice PUS Subservice
|
||||||
* @param packetSubcounter Additional subcounter used.
|
* @param packetSubcounter Additional subcounter used.
|
||||||
*/
|
*/
|
||||||
void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice,
|
ReturnValue_t initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice,
|
||||||
uint16_t packetSubcounter, uint16_t destinationId = 0, uint8_t timeRefField = 0);
|
uint16_t packetSubcounter, uint16_t destinationId = 0, uint8_t timeRefField = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,27 +43,55 @@ TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t sourceDataSize = 0;
|
size_t sourceDataSize = 0;
|
||||||
if (content != NULL) {
|
if (content != nullptr) {
|
||||||
sourceDataSize += content->getSerializedSize();
|
sourceDataSize += content->getSerializedSize();
|
||||||
}
|
}
|
||||||
if (header != NULL) {
|
if (header != nullptr) {
|
||||||
sourceDataSize += header->getSerializedSize();
|
sourceDataSize += header->getSerializedSize();
|
||||||
}
|
}
|
||||||
uint8_t *p_data = NULL;
|
uint8_t *pData = nullptr;
|
||||||
ReturnValue_t returnValue = store->getFreeElement(&storeAddress,
|
size_t sizeToReserve = getPacketMinimumSize() + sourceDataSize;
|
||||||
(getPacketMinimumSize() + sourceDataSize), &p_data);
|
ReturnValue_t returnValue = store->getFreeElement(&storeAddress, sizeToReserve, &pData);
|
||||||
if (returnValue != store->RETURN_OK) {
|
if (returnValue != store->RETURN_OK) {
|
||||||
TmPacketStoredBase::checkAndReportLostTm();
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
switch(returnValue) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
case(StorageManagerIF::DATA_STORAGE_FULL): {
|
||||||
|
sif::warning << "TmPacketStoredPusC::TmPacketStoredPusC: Store full for packet with "
|
||||||
|
"size " << sizeToReserve << std::endl;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
setData(p_data);
|
case(StorageManagerIF::DATA_TOO_LARGE): {
|
||||||
|
sif::warning << "TmPacketStoredPusC::TmPacketStoredPusC: Data with size " <<
|
||||||
|
sizeToReserve << " too large" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
case(StorageManagerIF::DATA_STORAGE_FULL): {
|
||||||
|
sif::printWarning("TmPacketStoredPusC::TmPacketStoredPusC: Store full for packet with "
|
||||||
|
"size %d\n", sizeToReserve);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(StorageManagerIF::DATA_TOO_LARGE): {
|
||||||
|
sif::printWarning("TmPacketStoredPusC::TmPacketStoredPusC: Data with size "
|
||||||
|
"%d too large\n", sizeToReserve);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
TmPacketStoredBase::checkAndReportLostTm();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setData(pData);
|
||||||
initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField);
|
initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField);
|
||||||
uint8_t *putDataHere = getSourceData();
|
uint8_t *putDataHere = getSourceData();
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
if (header != NULL) {
|
if (header != nullptr) {
|
||||||
header->serialize(&putDataHere, &size, sourceDataSize,
|
header->serialize(&putDataHere, &size, sourceDataSize,
|
||||||
SerializeIF::Endianness::BIG);
|
SerializeIF::Endianness::BIG);
|
||||||
}
|
}
|
||||||
if (content != NULL) {
|
if (content != nullptr) {
|
||||||
content->serialize(&putDataHere, &size, sourceDataSize,
|
content->serialize(&putDataHere, &size, sourceDataSize,
|
||||||
SerializeIF::Endianness::BIG);
|
SerializeIF::Endianness::BIG);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
public:
|
public:
|
||||||
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
||||||
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
|
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
|
||||||
static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 20;
|
static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 200;
|
||||||
|
|
||||||
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
||||||
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
||||||
|
Loading…
Reference in New Issue
Block a user