From 96afef6b8f06ef4cab619035216b78f83f5b39fb Mon Sep 17 00:00:00 2001 From: Grigoris Pavlakis <grigpavl@ece.auth.gr> Date: Sat, 31 Aug 2019 21:28:56 +0300 Subject: [PATCH] Create templated version of Parameter --- inc/Services/Parameter.hpp | 41 ++++++++++++-------- inc/Services/ParameterService.hpp | 4 +- src/Services/Parameter.cpp | 26 ++++++++----- src/Services/ParameterService.cpp | 13 ++++--- test/Services/ParameterService.cpp | 62 ++++++++++++++---------------- 5 files changed, 79 insertions(+), 67 deletions(-) diff --git a/inc/Services/Parameter.hpp b/inc/Services/Parameter.hpp index 54a40bb1..5e90a72b 100644 --- a/inc/Services/Parameter.hpp +++ b/inc/Services/Parameter.hpp @@ -2,10 +2,12 @@ #define ECSS_SERVICES_PARAMETER_HPP #include "etl/bitset.h" +#include "etl/String.hpp" // Number of binary flags in every parameter. Final number TBD. #define NUM_OF_FLAGS 3 - +// Maximum etl::string length in bytes +#define MAX_STRING_LENGTH 5 /** * Implementation of a Parameter field, as specified in ECSS-E-ST-70-41C. * Fully compliant with the standards requirements, while adding some small, @@ -23,8 +25,8 @@ * @typedef Flags: container for the binary flags */ typedef uint16_t ParamId; -typedef uint32_t ValueType; -typedef void(*UpdatePtr)(ValueType*); +//typedef uint32_t ValueType; +//#typedef ; typedef etl::bitset<NUM_OF_FLAGS> Flags; /** @@ -55,24 +57,31 @@ typedef etl::bitset<NUM_OF_FLAGS> Flags; * @public getCurrentValue(): Gets the current value of the parameter * @public getPTC(), getPFC(): Returns the PFC and PTC of the parameter */ -class Parameter { - uint8_t ptc; - uint8_t pfc; - UpdatePtr ptr; - Flags flags; - ValueType currentValue = 0; +class ParameterBase { + protected: + uint8_t ptc; + uint8_t pfc; + uint8_t sizeInBytes; + void* valuePtr; + Flags flags; public: - Parameter(uint8_t newPtc, uint8_t newPfc, uint32_t initialValue = 0, UpdatePtr newPtr = nullptr); - - void setCurrentValue(ValueType newVal); - void setFlags(const char* flags); - - ValueType getCurrentValue(); uint8_t getPTC(); - + void setFlags(const char* flags); uint8_t getPFC(); + virtual String<MAX_STRING_LENGTH> getValueAsString() = 0; + template <typename ValueType> void setCurrentValue(ValueType newVal); +}; +template <typename ValueType> +class Parameter : public ParameterBase { + void(*ptr)(ValueType*); + ValueType currentValue; + + public: + Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue = 0, void(*newPtr) + (ValueType*) = nullptr); + String<MAX_STRING_LENGTH> getValueAsString() override; }; diff --git a/inc/Services/ParameterService.hpp b/inc/Services/ParameterService.hpp index 3d473103..d7f64751 100644 --- a/inc/Services/ParameterService.hpp +++ b/inc/Services/ParameterService.hpp @@ -27,7 +27,7 @@ class ParameterService : public Service { private: - etl::map<ParamId, Parameter, ECSS_ST_20_MAX_PARAMETERS> paramsList; + etl::map<ParamId, ParameterBase*, ECSS_ST_20_MAX_PARAMETERS> paramsList; public: /** @@ -43,7 +43,7 @@ public: * @param param: the parameter field to be included * @param flags: the flags to be set for this field (see Parameter.hpp) */ - void addNewParameter(uint16_t id, Parameter param, const char* flags = "110"); + void addNewParameter(uint16_t id, ParameterBase* param, const char* flags = "110"); /** * This function receives a TC[20, 1] packet and returns a TM[20, 2] packet diff --git a/src/Services/Parameter.cpp b/src/Services/Parameter.cpp index 2ab92271..8bf1603f 100644 --- a/src/Services/Parameter.cpp +++ b/src/Services/Parameter.cpp @@ -1,10 +1,13 @@ #include "Services/Parameter.hpp" -Parameter::Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue, UpdatePtr newPtr) { +template <typename ValueType> +Parameter<ValueType>::Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue, void (* +newPtr)(ValueType*)) { ptc = newPtc; pfc = newPfc; ptr = newPtr; - + sizeInBytes = sizeof(initialValue); + valuePtr = static_cast<void *>(¤tValue); // see Parameter.hpp for explanation on flags // by default: no update priority, manual and automatic update available @@ -15,25 +18,28 @@ Parameter::Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue, Upd } } -void Parameter::setCurrentValue(ValueType newVal) { +template <typename ValueType> +void ParameterBase::setCurrentValue(ValueType newVal) { // set the value only if the parameter can be updated manually if (flags[1]) { - currentValue = newVal; + *reinterpret_cast<ValueType>(valuePtr) = newVal; } } -ValueType Parameter::getCurrentValue() { - return currentValue; +template <typename ValueType> +String<MAX_STRING_LENGTH> Parameter<ValueType>::getValueAsString() { + String<MAX_STRING_LENGTH> contents(reinterpret_cast<uint8_t*>(¤tValue), sizeInBytes); + return contents; } -uint8_t Parameter::getPTC() { +uint8_t ParameterBase::getPTC() { return ptc; } -uint8_t Parameter::getPFC() { +uint8_t ParameterBase::getPFC() { return pfc; } -void Parameter::setFlags(const char* flags) { +void ParameterBase::setFlags(const char* flags) { this->flags = Flags(flags); -} +} \ No newline at end of file diff --git a/src/Services/ParameterService.cpp b/src/Services/ParameterService.cpp index 2ac5d101..aff371d1 100644 --- a/src/Services/ParameterService.cpp +++ b/src/Services/ParameterService.cpp @@ -7,14 +7,14 @@ ParameterService::ParameterService() { // addNewParameter(3, 14); } -void ParameterService::addNewParameter(uint16_t id, Parameter param, const char* flags) { +void ParameterService::addNewParameter(uint16_t id, ParameterBase* param, const char* flags) { if (paramsList.full()) { ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MapFull); return; } else { if (paramsList.find(id) == paramsList.end()) { - param.setFlags(flags); + param->setFlags(flags); paramsList.insert(std::make_pair(id, param)); return; } @@ -26,7 +26,7 @@ void ParameterService::addNewParameter(uint16_t id, Parameter param, const char* } void ParameterService::reportParameterIds(Message& paramIds) { - etl::vector<std::pair<uint16_t, ValueType>, ECSS_ST_20_MAX_PARAMETERS> validParams; + etl::vector<std::pair<uint16_t, String<MAX_STRING_LENGTH>>, ECSS_ST_20_MAX_PARAMETERS> validParams; Message reqParam(20, 2, Message::TM, 1); // empty TM[20, 2] parameter report message @@ -50,7 +50,8 @@ void ParameterService::reportParameterIds(Message& paramIds) { uint16_t currId = paramIds.readUint16(); if (paramsList.find(currId) != paramsList.end()) { - std::pair<uint16_t, ValueType> p = std::make_pair(currId, paramsList.at(currId).getCurrentValue()); + std::pair<uint16_t, String<MAX_STRING_LENGTH>> p = std::make_pair(currId, paramsList.at(currId) + ->getValueAsString()); // pair containing the parameter's ID as first element and its current value as second validParams.push_back(p); validIds++; @@ -65,7 +66,7 @@ void ParameterService::reportParameterIds(Message& paramIds) { for (auto i: validParams) { reqParam.appendUint16(i.first); // append the parameter ID - reqParam.appendUint32(i.second); // and its value + reqParam.appendString(i.second); // and its value } storeMessage(reqParam); // then store the message @@ -88,7 +89,7 @@ void ParameterService::setParameterIds(Message& newParamValues) { uint16_t currId = newParamValues.readUint16(); // the parameter is checked for read-only status and manual update availability if (paramsList.find(currId) != paramsList.end()) { - paramsList.at(currId).setCurrentValue(newParamValues.readUint32()); + paramsList.at(currId)->setCurrentValue(newParamValues.readUint32()); } else { ErrorHandler::reportError(newParamValues, diff --git a/test/Services/ParameterService.cpp b/test/Services/ParameterService.cpp index ee678cd5..86987f9e 100644 --- a/test/Services/ParameterService.cpp +++ b/test/Services/ParameterService.cpp @@ -5,38 +5,34 @@ ParameterService& pserv = Services.parameterManagement; -void foo(ValueType* bar) { // sample function - *bar = 0xDEADBEEF; -} - TEST_CASE("Parameter Service - General") { SECTION("Addition to full map") { - Parameter param0 = Parameter(3, 14); - Parameter param1 = Parameter(1, 7, 12); - Parameter param2 = Parameter(4, 12, 3, nullptr); - Parameter param3 = Parameter(12, 3, 6, &foo); - Parameter param4 = Parameter(15, 7, 3, &foo); + Parameter<int> param0 = Parameter<int>(3, 14); + Parameter<int> param1 = Parameter<int>(1, 7, 12); + Parameter<int> param2 = Parameter<int>(4, 12, 3, nullptr); + Parameter<int> param3 = Parameter<int>(12, 3, 6); + Parameter<int> param4 = Parameter<int>(15, 7, 3); - Parameter param5 = Parameter(15, 5, 4); + Parameter<int> param5 = Parameter<int>(15, 5, 4); - pserv.addNewParameter(0, param0); - pserv.addNewParameter(1, param1); - pserv.addNewParameter(2, param2); - pserv.addNewParameter(3, param3); - pserv.addNewParameter(4, param4); + pserv.addNewParameter(0, static_cast<ParameterBase*>(¶m0)); + pserv.addNewParameter(1, static_cast<ParameterBase*>(¶m1)); + pserv.addNewParameter(2, static_cast<ParameterBase*>(¶m2)); + pserv.addNewParameter(3, static_cast<ParameterBase*>(¶m3)); + pserv.addNewParameter(4, static_cast<ParameterBase*>(¶m4)); - pserv.addNewParameter(5, param5); // addNewParameter should return false + pserv.addNewParameter(5, static_cast<ParameterBase*>(¶m5)); // addNewParameter should return false CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::MapFull)); ServiceTests::reset(); Services.reset(); // reset all services } SECTION("Addition of already existing parameter") { - Parameter param0 = Parameter(1, 3); - pserv.addNewParameter(0, param0); + Parameter<int> param0 = Parameter<int>(1, 3); + pserv.addNewParameter(0, static_cast<ParameterBase*>(¶m0)); - pserv.addNewParameter(0, param0); + pserv.addNewParameter(0, static_cast<ParameterBase*>(¶m0)); CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::ExistingParameterId)); ServiceTests::reset(); Services.reset(); @@ -69,12 +65,12 @@ TEST_CASE("Parameter Report Subservice") { } SECTION("Faulty instruction handling") { - Parameter param0 = Parameter(3, 14); - Parameter param1 = Parameter(1, 7, 12); - Parameter param2 = Parameter(4, 12, 3, nullptr); - pserv.addNewParameter(0, param0); - pserv.addNewParameter(1, param1); - pserv.addNewParameter(2, param2); + Parameter<int> param0 = Parameter<int>(3, 14); + Parameter<int> param1 = Parameter<int>(1, 7, 12); + Parameter<int> param2 = Parameter<int>(4, 12, 3, nullptr); + pserv.addNewParameter(0, static_cast<ParameterBase*>(¶m0)); + pserv.addNewParameter(1, static_cast<ParameterBase*>(¶m1)); + pserv.addNewParameter(2, static_cast<ParameterBase*>(¶m2)); Message request(20, 1, Message::TC, 1); request.appendUint16(2); // number of requested IDs @@ -117,12 +113,12 @@ TEST_CASE("Parameter Report Subservice") { TEST_CASE("Parameter Setting Subservice") { SECTION("Faulty Instruction Handling Test") { - Parameter param0 = Parameter(3, 14); - Parameter param1 = Parameter(1, 7, 12); - Parameter param2 = Parameter(4, 12, 3, nullptr); - pserv.addNewParameter(0, param0); - pserv.addNewParameter(1, param1); - pserv.addNewParameter(2, param2); + Parameter<int> param0 = Parameter<int>(3, 14); + Parameter<int> param1 = Parameter<int>(1, 7, 12); + Parameter<int> param2 = Parameter<int>(4, 12, 3, nullptr); + pserv.addNewParameter(0, static_cast<ParameterBase*>(¶m0)); + pserv.addNewParameter(1, static_cast<ParameterBase*>(¶m1)); + pserv.addNewParameter(2, static_cast<ParameterBase*>(¶m2)); Message setRequest(20, 3, Message::TC, 1); setRequest.appendUint16(2); // total number of IDs @@ -154,8 +150,8 @@ TEST_CASE("Parameter Setting Subservice") { } SECTION("Attempt to set parameter with no manual update availability") { - Parameter param1 = Parameter(1, 7, 12); - pserv.addNewParameter(1, param1, "100"); + Parameter<int> param1 = Parameter<int>(1, 7, 12); + pserv.addNewParameter(1, static_cast<ParameterBase*>(¶m1), "100"); Message setRequest = Message(20, 3, Message::TC, 1); setRequest.appendUint16(1); -- GitLab