Merge pull request 'FSFW Update - Parameter Service (PUS 20)' (#365) from mueller/fsfw-update into development
Reviewed-on: fsfw/fsfw#365
This commit is contained in:
commit
0416aaf3fe
@ -1286,18 +1286,17 @@ ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId,
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::buildInternalCommand(void) {
|
||||
//Neither Raw nor Direct could build a command
|
||||
/* Neither raw nor direct could build a command */
|
||||
ReturnValue_t result = NOTHING_TO_SEND;
|
||||
DeviceCommandId_t deviceCommandId = NO_COMMAND_ID;
|
||||
if (mode == MODE_NORMAL) {
|
||||
result = buildNormalDeviceCommand(&deviceCommandId);
|
||||
if (result == BUSY) {
|
||||
// so we can track misconfigurations
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING,
|
||||
"buildInternalCommand",
|
||||
HasReturnvaluesIF::RETURN_FAILED,
|
||||
"Busy.");
|
||||
result = NOTHING_TO_SEND; //no need to report this
|
||||
/* So we can track misconfigurations */
|
||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "buildInternalCommand",
|
||||
HasReturnvaluesIF::RETURN_FAILED, "Busy.");
|
||||
/* No need to report this */
|
||||
result = NOTHING_TO_SEND;
|
||||
}
|
||||
}
|
||||
else if (mode == MODE_RAW) {
|
||||
@ -1319,7 +1318,8 @@ void DeviceHandlerBase::buildInternalCommand(void) {
|
||||
deviceCommandId);
|
||||
if (iter == deviceCommandMap.end()) {
|
||||
result = COMMAND_NOT_SUPPORTED;
|
||||
} else if (iter->second.isExecuting) {
|
||||
}
|
||||
else if (iter->second.isExecuting) {
|
||||
#if FSFW_DISABLE_PRINTOUT == 0
|
||||
char output[36];
|
||||
sprintf(output, "Command 0x%08x is executing",
|
||||
@ -1380,10 +1380,10 @@ void DeviceHandlerBase::doOffActivity() {
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::getParameter(uint8_t domainId,
|
||||
uint16_t parameterId, ParameterWrapper* parameterWrapper,
|
||||
uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t result = fdirInstance->getParameter(domainId, parameterId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
ReturnValue_t result = fdirInstance->getParameter(domainId, uniqueId, parameterWrapper,
|
||||
newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ public:
|
||||
virtual void getMode(Mode_t *mode, Submode_t *submode);
|
||||
HealthState getHealth();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
|
||||
|
||||
|
@ -209,20 +209,20 @@ void DeviceHandlerFailureIsolation::startRecovery(Event reason) {
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerFailureIsolation::getParameter(uint8_t domainId,
|
||||
uint16_t parameterId, ParameterWrapper* parameterWrapper,
|
||||
uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t result = strangeReplyCount.getParameter(domainId, parameterId,
|
||||
ReturnValue_t result = strangeReplyCount.getParameter(domainId, uniqueId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
result = missedReplyCount.getParameter(domainId, parameterId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
result = missedReplyCount.getParameter(domainId, uniqueId, parameterWrapper, newValues,
|
||||
startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
result = recoveryCounter.getParameter(domainId, parameterId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
result = recoveryCounter.getParameter(domainId, uniqueId, parameterWrapper, newValues,
|
||||
startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ public:
|
||||
ReturnValue_t initialize();
|
||||
void triggerEvent(Event event, uint32_t parameter1 = 0,
|
||||
uint32_t parameter2 = 0);bool isFdirActionInProgress();
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex);
|
||||
|
||||
protected:
|
||||
FaultCounter strangeReplyCount;
|
||||
|
@ -58,14 +58,14 @@ FaultCounter::FaultCounter() :
|
||||
parameterDomain(0), timer(), faultCount(0), failureThreshold(0) {
|
||||
}
|
||||
|
||||
ReturnValue_t FaultCounter::getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ReturnValue_t FaultCounter::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) {
|
||||
if (domainId != parameterDomain) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
parameterWrapper->set(failureThreshold);
|
||||
break;
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
void setFailureThreshold(uint32_t failureThreshold);
|
||||
void setFaultDecrementTimeMs(uint32_t timeMs);
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
|
||||
|
@ -37,16 +37,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) {
|
||||
ReturnValue_t result = this->MonitorBase<T>::getParameter(domainId,
|
||||
parameterId, parameterWrapper, newValues, startAtIndex);
|
||||
uniqueId, parameterWrapper, newValues, startAtIndex);
|
||||
//We'll reuse the DOMAIN_ID of MonitorReporter, as we know the parameterIds used there.
|
||||
if (result != this->INVALID_IDENTIFIER_ID) {
|
||||
return result;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 10:
|
||||
parameterWrapper->set(this->lowerLimit);
|
||||
break;
|
||||
|
@ -51,13 +51,13 @@ public:
|
||||
return state;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) {
|
||||
if (domainId != monitorId) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
parameterWrapper->set(this->confirmationLimit);
|
||||
break;
|
||||
|
@ -71,13 +71,13 @@ public:
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
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 uniqueId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) {
|
||||
if (domainId != this->domainId) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
parameterWrapper->set(limit);
|
||||
break;
|
||||
|
@ -14,6 +14,7 @@ enum framework_objects: object_id_t {
|
||||
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
|
||||
PUS_SERVICE_9_TIME_MGMT = 0x53000009,
|
||||
PUS_SERVICE_17_TEST = 0x53000017,
|
||||
PUS_SERVICE_20_PARAMETERS = 0x53000020,
|
||||
PUS_SERVICE_200_MODE_MGMT = 0x53000200,
|
||||
|
||||
//Generic IDs for IPC, modes, health, events
|
||||
|
@ -25,7 +25,8 @@
|
||||
#else
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
|
||||
#define BYTE_ORDER_SYSTEM LITTLE_ENDIAN
|
||||
#else
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <chrono>
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#include <sysinfoapi.h>
|
||||
#elif defined(LINUX)
|
||||
#include <fstream>
|
||||
#endif
|
||||
@ -15,35 +15,34 @@ using SystemClock = std::chrono::system_clock;
|
||||
|
||||
uint32_t Clock::getTicksPerSecond(void){
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::getTicksPerSecond: not implemented yet" << std::endl;
|
||||
sif::warning << "Clock::getTicksPerSecond: Not implemented for host OSAL" << std::endl;
|
||||
#else
|
||||
sif::printWarning("Clock::getTicksPerSecond: Not implemented for host OSAL\n");
|
||||
#endif
|
||||
return 0;
|
||||
//return CLOCKS_PER_SEC;
|
||||
//uint32_t ticks = sysconf(_SC_CLK_TCK);
|
||||
//return ticks;
|
||||
/* To avoid division by zero */
|
||||
return 1;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const TimeOfDay_t* time) {
|
||||
// do some magic with chrono
|
||||
/* I don't know why someone would need to set a clock which is probably perfectly fine on a
|
||||
host system with internet access so this is not implemented for now. */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::setClock: not implemented yet" << std::endl;
|
||||
sif::warning << "Clock::setClock: Not implemented for host OSAL" << std::endl;
|
||||
#else
|
||||
sif::printWarning("Clock::setClock: Not implemented for host OSAL\n");
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
// do some magic with chrono
|
||||
#if defined(WIN32)
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
#elif defined(LINUX)
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
#else
|
||||
|
||||
#endif
|
||||
/* I don't know why someone would need to set a clock which is probably perfectly fine on a
|
||||
host system with internet access so this is not implemented for now. */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl;
|
||||
sif::warning << "Clock::setClock: Not implemented for host OSAL" << std::endl;
|
||||
#else
|
||||
sif::printWarning("Clock::setClock: Not implemented for host OSAL\n");
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
@ -76,10 +75,11 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
// do some magic with chrono
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::gerClock_usecs: not implemented yet" << std::endl;
|
||||
#endif
|
||||
if(time == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
using namespace std::chrono;
|
||||
*time = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -121,9 +121,9 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) {
|
||||
|
||||
|
||||
ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
// do some magic with chrono (C++20!)
|
||||
// Right now, the library doesn't have the new features yet.
|
||||
// so we work around that for now.
|
||||
/* Do some magic with chrono (C++20!) */
|
||||
/* Right now, the library doesn't have the new features to get the required values yet.
|
||||
so we work around that for now. */
|
||||
auto now = SystemClock::now();
|
||||
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
|
||||
auto fraction = now - seconds;
|
||||
@ -138,10 +138,6 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) {
|
||||
time->second = timeInfo->tm_sec;
|
||||
auto usecond = std::chrono::duration_cast<std::chrono::microseconds>(fraction);
|
||||
time->usecond = usecond.count();
|
||||
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
//sif::warning << "Clock::getDateAndTime: not implemented yet" << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <chrono>
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#include <processthreadsapi.h>
|
||||
#elif defined(LINUX)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
@ -52,9 +52,8 @@ public:
|
||||
return id;
|
||||
}
|
||||
|
||||
static uint32_t getFullParameterId(uint8_t domainId,
|
||||
uint8_t uniqueIdentifier, uint16_t linearIndex) {
|
||||
return (domainId << 24) + (uniqueIdentifier << 16) + linearIndex;
|
||||
static uint32_t getFullParameterId(uint8_t domainId, uint8_t uniqueId, uint16_t linearIndex) {
|
||||
return (domainId << 24) + (uniqueId << 16) + linearIndex;
|
||||
}
|
||||
|
||||
virtual ~HasParametersIF() {}
|
||||
@ -74,9 +73,9 @@ public:
|
||||
* matrix indexes.
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId,
|
||||
uint16_t uniqueIdentifier, ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) = 0;
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_PARAMETERS_HASPARAMETERSIF_H_ */
|
||||
|
@ -90,7 +90,7 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id,
|
||||
const ParameterWrapper* description) {
|
||||
size_t serializedSize = description->getSerializedSize();
|
||||
|
||||
uint8_t *storeElement;
|
||||
uint8_t *storeElement = nullptr;
|
||||
store_address_t address;
|
||||
|
||||
ReturnValue_t result = storage->getFreeElement(&address, serializedSize,
|
||||
|
@ -38,7 +38,7 @@ void ParameterMessage::setParameterLoadCommand(CommandMessage* message,
|
||||
store_address_t ParameterMessage::getParameterLoadCommand(
|
||||
const CommandMessage *message, ParameterId_t* parameterId, uint8_t *ptc,
|
||||
uint8_t *pfc, uint8_t *rows, uint8_t *columns) {
|
||||
*parameterId = message->getParameter2();
|
||||
*parameterId = message->getParameter();
|
||||
uint32_t packedParamSettings = message->getParameter3();
|
||||
*ptc = packedParamSettings >> 24 & 0xff;
|
||||
*pfc = packedParamSettings >> 16 & 0xff;
|
||||
|
@ -1,17 +1,19 @@
|
||||
#include "ParameterWrapper.h"
|
||||
#include <FSFWConfig.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
ParameterWrapper::ParameterWrapper() :
|
||||
pointsToStream(false), type(Type::UNKNOWN_TYPE) {
|
||||
}
|
||||
|
||||
ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns,
|
||||
void *data) :
|
||||
void *data):
|
||||
pointsToStream(false), type(type), rows(rows), columns(columns),
|
||||
data(data), readonlyData(data) {
|
||||
}
|
||||
|
||||
ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns,
|
||||
const void *data) :
|
||||
const void *data):
|
||||
pointsToStream(false), type(type), rows(rows), columns(columns),
|
||||
data(nullptr), readonlyData(data) {
|
||||
}
|
||||
@ -40,8 +42,8 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t **buffer, size_t *size,
|
||||
return result;
|
||||
}
|
||||
|
||||
//serialize uses readonlyData, as it is always valid
|
||||
if (readonlyData == NULL) {
|
||||
/* serialize uses readonlyData, as it is always valid */
|
||||
if (readonlyData == nullptr) {
|
||||
return NOT_SET;
|
||||
}
|
||||
switch (type) {
|
||||
@ -75,7 +77,7 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t **buffer, size_t *size,
|
||||
result = serializeData<double>(buffer, size, maxSize, streamEndianness);
|
||||
break;
|
||||
default:
|
||||
result = UNKNOW_DATATYPE;
|
||||
result = UNKNOWN_DATATYPE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
@ -220,22 +222,48 @@ ReturnValue_t ParameterWrapper::set(const uint8_t *stream, size_t streamSize,
|
||||
|
||||
ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
uint16_t startWritingAtIndex) {
|
||||
// TODO: Optional diagnostic output (which can be disabled in FSFWConfig)
|
||||
// to determined faulty implementations and configuration errors quickly.
|
||||
if (data == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Called on read-only variable!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return READONLY;
|
||||
}
|
||||
|
||||
if (from->readonlyData == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Source not set!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Source not set!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return SOURCE_NOT_SET;
|
||||
}
|
||||
|
||||
if (type != from->type) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return DATATYPE_MISSMATCH;
|
||||
}
|
||||
|
||||
// The smallest allowed value for rows and columns is one.
|
||||
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;
|
||||
#else
|
||||
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero!\n");
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return COLUMN_OR_ROWS_ZERO;
|
||||
}
|
||||
|
||||
@ -289,7 +317,7 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
||||
from->readonlyData, from->rows, from->columns);
|
||||
break;
|
||||
default:
|
||||
result = UNKNOW_DATATYPE;
|
||||
result = UNKNOWN_DATATYPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,23 @@
|
||||
#include <cstddef>
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @brief This wrapper encapsulates the access to parameters provided by HasParametersIF.
|
||||
* @details
|
||||
* This wrapper is used by the ParameterHelper to interface with the on-board parameters
|
||||
* exposed by the software via the HasParametersIF. A handle of this wrapper is passed
|
||||
* to the user which then can be used to set or dump the parameters.
|
||||
*
|
||||
* The wrapper provides a set of setter functions. The user should call those setter functions,
|
||||
* supplying an address to the local parameters. The user can also deserialize or
|
||||
* serialize the parameter data. Please note that this will also serialize and deserialize
|
||||
* the parameter information field (4 bytes) containing the ECSS PTC, PFC and rows and columns
|
||||
* number.
|
||||
*/
|
||||
class ParameterWrapper: public SerializeIF {
|
||||
friend class DataPoolParameterWrapper;
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PARAMETER_WRAPPER;
|
||||
static const ReturnValue_t UNKNOW_DATATYPE = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t UNKNOWN_DATATYPE = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t DATATYPE_MISSMATCH = MAKE_RETURN_CODE(0x02);
|
||||
static const ReturnValue_t READONLY = MAKE_RETURN_CODE(0x03);
|
||||
static const ReturnValue_t TOO_BIG = MAKE_RETURN_CODE(0x04);
|
||||
@ -26,8 +35,7 @@ public:
|
||||
|
||||
ParameterWrapper();
|
||||
ParameterWrapper(Type type, uint8_t rows, uint8_t columns, void *data);
|
||||
ParameterWrapper(Type type, uint8_t rows, uint8_t columns,
|
||||
const void *data);
|
||||
ParameterWrapper(Type type, uint8_t rows, uint8_t columns, const void *data);
|
||||
virtual ~ParameterWrapper();
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
@ -77,11 +85,23 @@ public:
|
||||
this->pointsToStream = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter function for scalar non-const entries
|
||||
* @tparam T
|
||||
* @param member
|
||||
*/
|
||||
template<typename T>
|
||||
void set(T& member) {
|
||||
this->set(&member, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter function for scalar const entries.
|
||||
* TODO: This is confusing, it should not be called set. Maybe we should call all functions
|
||||
* assign instead?
|
||||
* @tparam T
|
||||
* @param readonlyMember
|
||||
*/
|
||||
template<typename T>
|
||||
void set(const T& readonlyMember) {
|
||||
this->set(&readonlyMember, 1, 1);
|
||||
@ -89,12 +109,16 @@ public:
|
||||
|
||||
template<typename T>
|
||||
void setVector(T& member) {
|
||||
this->set(member, sizeof(member)/sizeof(member[0]), 1);
|
||||
/* For a vector entry, the number of rows will be one
|
||||
(left to right, top to bottom indexing) */
|
||||
this->set(member, 1, sizeof(member) / sizeof(member[0]));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void setVector(const T& member) {
|
||||
this->set(member, 1, sizeof(member)/sizeof(member[0]));
|
||||
/* For a vector entry, the number of rows will be one
|
||||
(left to right, top to bottom indexing) */
|
||||
this->set(member, 1, sizeof(member) / sizeof(member[0]));
|
||||
}
|
||||
template<typename T>
|
||||
void setMatrix(T& member) {
|
||||
|
@ -210,15 +210,15 @@ void Fuse::setDataPoolEntriesInvalid() {
|
||||
set.commit();
|
||||
}
|
||||
|
||||
ReturnValue_t Fuse::getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ReturnValue_t Fuse::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) {
|
||||
ReturnValue_t result = currentLimit.getParameter(domainId, parameterId,
|
||||
ReturnValue_t result = currentLimit.getParameter(domainId, uniqueId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
result = powerMonitor.getParameter(domainId, parameterId, parameterWrapper,
|
||||
result = powerMonitor.getParameter(domainId, uniqueId, parameterWrapper,
|
||||
newValues, startAtIndex);
|
||||
return result;
|
||||
}
|
||||
|
@ -62,9 +62,9 @@ public:
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
HasHealthIF::HealthState getHealth();
|
||||
|
||||
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 uniqueId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex);
|
||||
|
||||
private:
|
||||
uint8_t oldFuseState;
|
||||
|
@ -61,13 +61,13 @@ ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size,
|
||||
return SerializeAdapter::deSerialize(&max, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
ReturnValue_t PowerComponent::getParameter(uint8_t domainId,
|
||||
uint16_t parameterId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t PowerComponent::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) {
|
||||
if (domainId != moduleId) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
parameterWrapper->set<>(min);
|
||||
break;
|
||||
|
@ -31,9 +31,9 @@ public:
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
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 uniqueId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex);
|
||||
private:
|
||||
const object_id_t deviceObjectId = objects::NO_OBJECT;
|
||||
const uint8_t switchId1;
|
||||
|
@ -119,15 +119,15 @@ HasHealthIF::HealthState PowerSensor::getHealth() {
|
||||
return healthHelper.getHealth();
|
||||
}
|
||||
|
||||
ReturnValue_t PowerSensor::getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ReturnValue_t PowerSensor::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) {
|
||||
ReturnValue_t result = currentLimit.getParameter(domainId, parameterId,
|
||||
ReturnValue_t result = currentLimit.getParameter(domainId, uniqueId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
result = voltageLimit.getParameter(domainId, parameterId, parameterWrapper,
|
||||
result = voltageLimit.getParameter(domainId, uniqueId, parameterWrapper,
|
||||
newValues, startAtIndex);
|
||||
return result;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
float getPower();
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
HasHealthIF::HealthState getHealth();
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
private:
|
||||
|
@ -1,12 +1,12 @@
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
CService200ModeCommanding.cpp
|
||||
CService201HealthCommanding.cpp
|
||||
Service17Test.cpp
|
||||
Service1TelecommandVerification.cpp
|
||||
Service2DeviceAccess.cpp
|
||||
Service3Housekeeping.cpp
|
||||
Service5EventReporting.cpp
|
||||
Service8FunctionManagement.cpp
|
||||
Service9TimeManagement.cpp
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
Service1TelecommandVerification.cpp
|
||||
Service2DeviceAccess.cpp
|
||||
Service3Housekeeping.cpp
|
||||
Service5EventReporting.cpp
|
||||
Service8FunctionManagement.cpp
|
||||
Service9TimeManagement.cpp
|
||||
Service17Test.cpp
|
||||
Service20ParameterManagement.cpp
|
||||
CService200ModeCommanding.cpp
|
||||
CService201HealthCommanding.cpp
|
||||
)
|
@ -15,7 +15,7 @@ Service17Test::~Service17Test() {
|
||||
}
|
||||
|
||||
ReturnValue_t Service17Test::handleRequest(uint8_t subservice) {
|
||||
switch(subservice){
|
||||
switch(subservice) {
|
||||
case Subservice::CONNECTION_TEST: {
|
||||
TmPacketStored connectionPacket(apid, serviceId,
|
||||
Subservice::CONNECTION_TEST_REPORT, packetSubCounter++);
|
||||
|
186
pus/Service20ParameterManagement.cpp
Normal file
186
pus/Service20ParameterManagement.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
#include "Service20ParameterManagement.h"
|
||||
#include "servicepackets/Service20Packets.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/parameters/HasParametersIF.h>
|
||||
#include <fsfw/parameters/ParameterMessage.h>
|
||||
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
|
||||
#include <tmtc/pusIds.h>
|
||||
|
||||
|
||||
Service20ParameterManagement::Service20ParameterManagement(object_id_t objectId, uint16_t apid,
|
||||
uint8_t serviceId, uint8_t numberOfParallelCommands, uint16_t commandTimeoutSeconds) :
|
||||
CommandingServiceBase(objectId, apid, serviceId,
|
||||
numberOfParallelCommands,commandTimeoutSeconds) {}
|
||||
|
||||
Service20ParameterManagement::~Service20ParameterManagement() {}
|
||||
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::isValidSubservice(
|
||||
uint8_t subservice) {
|
||||
switch(static_cast<Subservice>(subservice)) {
|
||||
case Subservice::PARAMETER_LOAD:
|
||||
case Subservice::PARAMETER_DUMP:
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
default:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Invalid Subservice for Service 20" << std::endl;
|
||||
#else
|
||||
sif::printError("Invalid Subservice for Service 20\n");
|
||||
#endif
|
||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::getMessageQueueAndObject(
|
||||
uint8_t subservice, const uint8_t* tcData, size_t tcDataLen,
|
||||
MessageQueueId_t* id, object_id_t* objectId) {
|
||||
ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen);
|
||||
if(result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return checkInterfaceAndAcquireMessageQueue(id,objectId);
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::checkAndAcquireTargetID(
|
||||
object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) {
|
||||
if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, &tcDataLen,
|
||||
SerializeIF::Endianness::BIG) != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Service20ParameterManagement::checkAndAcquireTargetID: "
|
||||
<< "Invalid data." << std::endl;
|
||||
#else
|
||||
sif::printError("Service20ParameterManagement::"
|
||||
"checkAndAcquireTargetID: Invalid data.\n");
|
||||
#endif
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue(
|
||||
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
|
||||
// check ReceivesParameterMessagesIF property of target
|
||||
ReceivesParameterMessagesIF* possibleTarget =
|
||||
objectManager->get<ReceivesParameterMessagesIF>(*objectId);
|
||||
if(possibleTarget == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||
<<"MessageQueue: Can't access object" << std::endl;
|
||||
sif::error << "Object ID: " << std::hex << objectId << std::dec << std::endl;
|
||||
sif::error << "Make sure it implements ReceivesParameterMessagesIF!" << std::endl;
|
||||
#else
|
||||
sif::printError("Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||
"MessageQueue: Can't access object\n");
|
||||
sif::printError("Object ID: 0x%08x\n", objectId);
|
||||
sif::printError("Make sure it implements "
|
||||
"ReceivesParameterMessagesIF!\n");
|
||||
#endif
|
||||
|
||||
return CommandingServiceBase::INVALID_OBJECT;
|
||||
}
|
||||
*messageQueueToSet = possibleTarget->getCommandQueue();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::prepareCommand(
|
||||
CommandMessage* message, uint8_t subservice, const uint8_t* tcData,
|
||||
size_t tcDataLen, uint32_t* state, object_id_t objectId) {
|
||||
switch(static_cast<Subservice>(subservice)){
|
||||
case Subservice::PARAMETER_DUMP: {
|
||||
return prepareDumpCommand(message, tcData, tcDataLen);
|
||||
}
|
||||
break;
|
||||
case Subservice::PARAMETER_LOAD: {
|
||||
return prepareLoadCommand(message, tcData, tcDataLen);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::prepareDumpCommand(
|
||||
CommandMessage* message, const uint8_t* tcData, size_t tcDataLen) {
|
||||
/* the first part is the objectId, but we have extracted that earlier
|
||||
and only need the parameterId */
|
||||
tcData += sizeof(object_id_t);
|
||||
tcDataLen -= sizeof(object_id_t);
|
||||
ParameterId_t parameterId;
|
||||
if(SerializeAdapter::deSerialize(¶meterId, &tcData, &tcDataLen,
|
||||
SerializeIF::Endianness::BIG) != HasReturnvaluesIF::RETURN_OK) {
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
/* The length should have been decremented to 0 by this point */
|
||||
if(tcDataLen != 0) {
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
|
||||
ParameterMessage::setParameterDumpCommand(message, parameterId);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::prepareLoadCommand(
|
||||
CommandMessage* message, const uint8_t* tcData, size_t tcDataLen) {
|
||||
if(tcDataLen < sizeof(object_id_t) + sizeof(ParameterId_t) +
|
||||
sizeof(uint32_t)) {
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
|
||||
uint8_t* storePointer = nullptr;
|
||||
store_address_t storeAddress;
|
||||
size_t parameterDataLen = tcDataLen - sizeof(object_id_t) - sizeof(ParameterId_t) -
|
||||
sizeof(uint32_t);
|
||||
ReturnValue_t result = IPCStore->getFreeElement(&storeAddress,
|
||||
parameterDataLen, &storePointer);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Following format is expected: The first 4 bytes in the TC data are the 4 byte
|
||||
parameter ID (ParameterId_t). The second 4 bytes are the parameter information field,
|
||||
containing the following 1 byte fields:
|
||||
1. ECSS PTC field
|
||||
2. ECSS PFC field
|
||||
3. Number of rows
|
||||
4. Number of columns */
|
||||
ParameterLoadCommand command(storePointer, parameterDataLen);
|
||||
result = command.deSerialize(&tcData, &tcDataLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ParameterMessage::setParameterLoadCommand(message, command.getParameterId(), storeAddress,
|
||||
command.getPtc(), command.getPfc(), command.getRows(), command.getColumns());
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Service20ParameterManagement::handleReply(
|
||||
const CommandMessage* reply, Command_t previousCommand, uint32_t* state,
|
||||
CommandMessage* optionalNextCommand, object_id_t objectId,
|
||||
bool* isStep) {
|
||||
Command_t replyId = reply->getCommand();
|
||||
|
||||
switch(replyId) {
|
||||
case ParameterMessage::REPLY_PARAMETER_DUMP: {
|
||||
ConstAccessorPair parameterData = IPCStore->getData(
|
||||
ParameterMessage::getStoreId(reply));
|
||||
if(parameterData.first != HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
ParameterId_t parameterId = ParameterMessage::getParameterId(reply);
|
||||
ParameterDumpReply parameterReply(objectId, parameterId,
|
||||
parameterData.second.data(), parameterData.second.size());
|
||||
sendTmPacket(static_cast<uint8_t>(
|
||||
Subservice::PARAMETER_DUMP_REPLY), ¶meterReply);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
default:
|
||||
return CommandingServiceBase::INVALID_REPLY;
|
||||
}
|
||||
}
|
60
pus/Service20ParameterManagement.h
Normal file
60
pus/Service20ParameterManagement.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef FSFW_PUS_SERVICE20PARAMETERMANAGEMENT_H_
|
||||
#define FSFW_PUS_SERVICE20PARAMETERMANAGEMENT_H_
|
||||
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
|
||||
/**
|
||||
* @brief PUS Service 20 Parameter Service implementation
|
||||
* @details
|
||||
* This service handles PUS service requests related to parameter management and forwards
|
||||
* them to the internal software bus.
|
||||
* @author J. Gerhards
|
||||
*
|
||||
*/
|
||||
class Service20ParameterManagement : public CommandingServiceBase
|
||||
{
|
||||
public:
|
||||
Service20ParameterManagement(object_id_t objectId, uint16_t apid, uint8_t serviceId,
|
||||
uint8_t numberOfParallelCommands = 4, uint16_t commandTimeoutSeconds = 60);
|
||||
virtual ~Service20ParameterManagement();
|
||||
|
||||
static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4;
|
||||
static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60;
|
||||
protected:
|
||||
/* CommandingServiceBase (CSB) abstract functions. See CSB documentation. */
|
||||
ReturnValue_t isValidSubservice(uint8_t subservice) override;
|
||||
ReturnValue_t getMessageQueueAndObject(uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id,
|
||||
object_id_t *objectId) override;
|
||||
ReturnValue_t prepareCommand(CommandMessage* message, uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen, uint32_t *state,
|
||||
object_id_t objectId) override;
|
||||
ReturnValue_t handleReply(const CommandMessage* reply,
|
||||
Command_t previousCommand, uint32_t *state,
|
||||
CommandMessage* optionalNextCommand, object_id_t objectId,
|
||||
bool *isStep) override;
|
||||
|
||||
private:
|
||||
|
||||
ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet,
|
||||
const uint8_t* tcData, size_t tcDataLen);
|
||||
ReturnValue_t checkInterfaceAndAcquireMessageQueue(
|
||||
MessageQueueId_t* messageQueueToSet, object_id_t* objectId);
|
||||
ReturnValue_t prepareDirectCommand(CommandMessage* message,
|
||||
const uint8_t* tcData, size_t tcDataLen);
|
||||
|
||||
ReturnValue_t prepareDumpCommand(CommandMessage* message,
|
||||
const uint8_t* tcData, size_t tcDataLen);
|
||||
ReturnValue_t prepareLoadCommand(CommandMessage* message,
|
||||
const uint8_t* tcData, size_t tcDataLen);
|
||||
|
||||
enum class Subservice {
|
||||
PARAMETER_LOAD = 128, //!< [EXPORT] : Load a Parameter
|
||||
PARAMETER_DUMP = 129, //!< [EXPORT] : Dump a Parameter
|
||||
PARAMETER_DUMP_REPLY = 130, //!< [EXPORT] : Dump a Parameter
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* FSFW_PUS_SERVICE20PARAMETERMANAGEMENT_H_ */
|
142
pus/servicepackets/Service20Packets.h
Normal file
142
pus/servicepackets/Service20Packets.h
Normal file
@ -0,0 +1,142 @@
|
||||
#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE20PACKETS_H_
|
||||
#define FSFW_PUS_SERVICEPACKETS_SERVICE20PACKETS_H_
|
||||
|
||||
#include <FSFWConfig.h>
|
||||
#include <fsfw/parameters/HasParametersIF.h>
|
||||
#include <fsfw/serialize/SerialBufferAdapter.h>
|
||||
#include <fsfw/serialize/SerializeElement.h>
|
||||
#include <fsfw/serialize/SerialLinkedListAdapter.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
/**
|
||||
* @brief This class encapsulates the packets sent to the PUS service 20 or sent by the
|
||||
* PUS service 20
|
||||
* @details
|
||||
* This command can be used to handle both load and dump commands as well.
|
||||
* @author
|
||||
*/
|
||||
class ParameterCommand: public SerialLinkedListAdapter<SerializeIF> { //!< [EXPORT] : [SUBSERVICE] 128, 129, 130
|
||||
public:
|
||||
|
||||
/**
|
||||
* This constructor is used for load replies. The data is expected in the correct formast
|
||||
* in the store pointer.
|
||||
* @param storePointer
|
||||
* @param parameterDataLen
|
||||
*/
|
||||
ParameterCommand(uint8_t* storePointer, size_t parameterDataLen):
|
||||
parameterBuffer(storePointer, parameterDataLen) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
if(parameterDataLen < sizeof(object_id_t) + sizeof(ParameterId_t) + 4) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "ParameterCommand: Parameter data length is less than 12!"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("ParameterCommand: Parameter data length is less than 12!\n");
|
||||
#endif
|
||||
}
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
setLoadLinks();
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is used for dump replies. It is assumed the 4 byte parameter
|
||||
* information field is located inside the parameter buffer.
|
||||
* @param objectId
|
||||
* @param parameterId
|
||||
* @param parameterBuffer
|
||||
* @param parameterBufferSize
|
||||
*/
|
||||
ParameterCommand(object_id_t objectId, ParameterId_t parameterId,
|
||||
const uint8_t* parameterBuffer, size_t parameterBufferSize):
|
||||
objectId(objectId), parameterId(parameterId),
|
||||
parameterBuffer(parameterBuffer, parameterBufferSize) {
|
||||
setDumpReplyLinks();
|
||||
}
|
||||
|
||||
ParameterId_t getParameterId() const {
|
||||
return parameterId.entry;
|
||||
}
|
||||
|
||||
const uint8_t* getParameterBuffer() {
|
||||
return parameterBuffer.entry.getConstBuffer();
|
||||
}
|
||||
|
||||
size_t getParameterBufferLen() const {
|
||||
return parameterBuffer.getSerializedSize();
|
||||
}
|
||||
|
||||
uint8_t getDomainId() const {
|
||||
return (parameterId.entry >> 24) & 0xff;
|
||||
}
|
||||
|
||||
uint8_t getUniqueId() const {
|
||||
return (parameterId.entry >> 16) & 0xff;
|
||||
}
|
||||
|
||||
uint16_t getLinearIndex() const {
|
||||
return parameterId.entry & 0xffff;
|
||||
}
|
||||
|
||||
uint8_t getPtc() const {
|
||||
return ccsdsType.entry >> 8 & 0xff;
|
||||
}
|
||||
|
||||
uint8_t getPfc() const {
|
||||
return ccsdsType.entry & 0xff;
|
||||
}
|
||||
|
||||
uint8_t getRows() const {
|
||||
return rows.entry;
|
||||
}
|
||||
|
||||
uint8_t getColumns() const {
|
||||
return columns.entry;
|
||||
}
|
||||
|
||||
private:
|
||||
void setLoadLinks() {
|
||||
setStart(&objectId);
|
||||
objectId.setNext(¶meterId);
|
||||
parameterId.setNext(&ccsdsType);
|
||||
ccsdsType.setNext(&rows);
|
||||
rows.setNext(&columns);
|
||||
columns.setNext(¶meterBuffer);
|
||||
}
|
||||
|
||||
void setDumpReplyLinks() {
|
||||
/* For a dump reply, the parameter information is contained in the parameter buffer
|
||||
with the actual parameters */
|
||||
setStart(&objectId);
|
||||
objectId.setNext(¶meterId);
|
||||
parameterId.setNext(¶meterBuffer);
|
||||
}
|
||||
|
||||
void setDumpRequestLinks() {
|
||||
setStart(&objectId);
|
||||
objectId.setNext(¶meterId);
|
||||
}
|
||||
|
||||
SerializeElement<object_id_t> objectId = 0;
|
||||
SerializeElement<ParameterId_t> parameterId = 0;
|
||||
//! [EXPORT] : [COMMENT] Type consisting of one byte PTC and one byte PFC.
|
||||
SerializeElement<uint16_t> ccsdsType = 0;
|
||||
SerializeElement<uint8_t> rows = 0;
|
||||
SerializeElement<uint8_t> columns = 0;
|
||||
SerializeElement<SerialBufferAdapter<uint8_t>> parameterBuffer;
|
||||
};
|
||||
|
||||
class ParameterLoadCommand: public ParameterCommand {
|
||||
public:
|
||||
ParameterLoadCommand(uint8_t* parameterPacket, size_t parameterDataLen):
|
||||
ParameterCommand(parameterPacket, parameterDataLen) {}
|
||||
};
|
||||
|
||||
class ParameterDumpReply: public ParameterCommand {
|
||||
public:
|
||||
ParameterDumpReply(object_id_t objectId, ParameterId_t parameterId,
|
||||
const uint8_t* parameterBuffer, size_t parameterBufferSize):
|
||||
ParameterCommand(objectId, parameterId, parameterBuffer, parameterBufferSize) {}
|
||||
};
|
||||
|
||||
#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE20PACKETS_H_ */
|
@ -290,13 +290,13 @@ void Heater::handleQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t Heater::getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
ReturnValue_t Heater::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) {
|
||||
if (domainId != DOMAIN_ID_BASE) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
parameterWrapper->set(heaterOnCountdown.timeout);
|
||||
break;
|
||||
|
@ -34,8 +34,8 @@ public:
|
||||
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
|
||||
protected:
|
||||
|
@ -183,10 +183,10 @@ public:
|
||||
|
||||
static const uint8_t DOMAIN_ID_SENSOR = 1;
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t result = sensorMonitor.getParameter(domainId, parameterId,
|
||||
ReturnValue_t result = sensorMonitor.getParameter(domainId, uniqueId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
@ -194,7 +194,7 @@ public:
|
||||
if (domainId != this->DOMAIN_ID_BASE) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case ADDRESS_A:
|
||||
parameterWrapper->set(parameters.a);
|
||||
break;
|
||||
|
@ -148,14 +148,14 @@ ThermalComponentIF::State ThermalComponent::getIgnoredState(int8_t state) {
|
||||
}
|
||||
|
||||
ReturnValue_t ThermalComponent::getParameter(uint8_t domainId,
|
||||
uint16_t parameterId, ParameterWrapper* parameterWrapper,
|
||||
uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t result = ThermalComponentCore::getParameter(domainId, parameterId,
|
||||
ReturnValue_t result = ThermalComponentCore::getParameter(domainId, uniqueId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_IDENTIFIER_ID) {
|
||||
return result;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 12:
|
||||
parameterWrapper->set(nopParameters.lowerNopLimit);
|
||||
break;
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
|
||||
virtual ReturnValue_t setLimits( const uint8_t* data, size_t size);
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
|
||||
|
@ -247,17 +247,17 @@ ThermalComponentCore::Parameters ThermalComponentCore::getParameters() {
|
||||
}
|
||||
|
||||
ReturnValue_t ThermalComponentCore::getParameter(uint8_t domainId,
|
||||
uint16_t parameterId, ParameterWrapper* parameterWrapper,
|
||||
uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t result = temperatureMonitor.getParameter(domainId,
|
||||
parameterId, parameterWrapper, newValues, startAtIndex);
|
||||
uniqueId, parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
if (domainId != this->domainId) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
parameterWrapper->set(parameters.heaterOn);
|
||||
break;
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
|
||||
virtual void setOutputInvalid();
|
||||
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "TmTcBridge.h"
|
||||
|
||||
#include "../ipc/QueueFactory.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../serviceinterface/ServiceInterface.h"
|
||||
#include "../globalfunctions/arrayprinter.h"
|
||||
|
||||
TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
@ -109,9 +109,8 @@ ReturnValue_t TmTcBridge::handleTm() {
|
||||
ReturnValue_t result = handleTmQueue();
|
||||
if(result != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmTcBridge::handleTm: Error handling TM queue with "
|
||||
<< "error code 0x" << std::hex << result << std::dec
|
||||
<< "!" << std::endl;
|
||||
sif::error << "TmTcBridge::handleTm: Error handling TM queue with error code 0x" <<
|
||||
std::hex << result << std::dec << "!" << std::endl;
|
||||
#endif
|
||||
status = result;
|
||||
}
|
||||
@ -121,8 +120,7 @@ ReturnValue_t TmTcBridge::handleTm() {
|
||||
result = handleStoredTm();
|
||||
if(result != RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "TmTcBridge::handleTm: Error handling stored TMs!"
|
||||
<< std::endl;
|
||||
sif::error << "TmTcBridge::handleTm: Error handling stored TMs!" << std::endl;
|
||||
#endif
|
||||
status = result;
|
||||
}
|
||||
@ -140,9 +138,15 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
||||
result == HasReturnvaluesIF::RETURN_OK;
|
||||
result = tmTcReceptionQueue->receiveMessage(&message))
|
||||
{
|
||||
|
||||
#if FSFW_VERBOSE_LEVEL >= 3
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
//sif::info << (int) packetSentCounter << std::endl;
|
||||
sif::info << "Sent packet counter: " << static_cast<int>(packetSentCounter) << std::endl;
|
||||
#else
|
||||
sif::printInfo("Sent packet counter: %d\n", packetSentCounter);
|
||||
#endif
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
|
||||
|
||||
if(communicationLinkUp == false or
|
||||
packetSentCounter >= sentPacketsPerCycle) {
|
||||
storeDownlinkData(&message);
|
||||
|
Loading…
Reference in New Issue
Block a user