diff --git a/CMakeLists.txt b/CMakeLists.txt index d56b1c4e859d1de9b54dd2558ff170eb8584363b..fdfe6916d74e3510a0872ff0a7751a5fbf22acf9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ add_library(common OBJECT src/Helpers/CRCHelper.cpp src/Helpers/TimeAndDate.cpp src/Helpers/TimeHelper.cpp + src/Parameters/Parameters.cpp src/Services/EventReportService.cpp src/Services/MemoryManagementService.cpp src/Services/ParameterService.cpp diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp index 07510f25615205b3c3d46e226f10ed5bef065570..ce2b551c5aa6717634a23a66d5d835039b7e528c 100644 --- a/inc/ErrorHandler.hpp +++ b/inc/ErrorHandler.hpp @@ -70,7 +70,7 @@ public: */ OtherMessageType = 9, /** - * Attempt to insert new element in a full map (ST[08], ST[20]) + * Attempt to insert new element in a full map ST[08] */ MapFull = 10, /** diff --git a/inc/Parameters/Parameters.hpp b/inc/Parameters/Parameters.hpp index d225fbfa48775709fd93fe333f9557ac4607a819..d3a58827ddea7dadcbb0b310c820df0b12347d1c 100644 --- a/inc/Parameters/Parameters.hpp +++ b/inc/Parameters/Parameters.hpp @@ -1,5 +1,14 @@ #include "Services/Parameter.hpp" +#include "etl/vector.h" +class SystemParameters { +public: + Parameter<uint8_t> parameter1 = Parameter<uint8_t>(5); + Parameter<char> parameter2= Parameter<char>('a'); + Parameter<int> parameter3 = Parameter<int>('b'); + Parameter<uint8_t> parameter4 = Parameter<uint8_t>(5); + Parameter<uint8_t> parameter5 = Parameter<uint8_t>(5); + etl::vector<std::reference_wrapper<ParameterBase>, ECSS_ST_20_MAX_PARAMETERS> parametersArray; + SystemParameters() = default; +}; -namespace SystemParameters { - // initialize all system parameters here -} \ No newline at end of file +extern SystemParameters systemParameters; diff --git a/inc/Services/Parameter.hpp b/inc/Services/Parameter.hpp index dc9f791014a93bb471792389043d4547d0562c86..b59f5d0d9e50bf0232ee9ba139cf6005db84ef31 100644 --- a/inc/Services/Parameter.hpp +++ b/inc/Services/Parameter.hpp @@ -46,13 +46,6 @@ * */ -/** - * Useful type definitions - * (DEPRECATED - MARK FOR REMOVAL) - * @typedef ParamId: the unique ID of a parameter, used for searching - */ -typedef uint16_t ParamId; - /* * MILLION DOLLAR QUESTIONS - OLD IMPLEMENTATION: * setCurrentValue is templated. Since Parameter (a template class) inherits ParameterBase @@ -86,14 +79,15 @@ public: template <typename DataType> class Parameter : public ParameterBase { +private: DataType currentValue; void (* updateFunction)(DataType*); public: Parameter(DataType initialValue, void (* updateFunction)(DataType*) = nullptr) { - this.updateFunction = updateFunction; + this->updateFunction = updateFunction; - if (this.updateFunction != nullptr) { + if (this->updateFunction != nullptr) { (*updateFunction)(¤tValue); } else { @@ -110,43 +104,4 @@ public: return String<ECSS_ST_20_MAX_STRING_LENGTH>("DUMMY STRING"); } }; - -// class ParameterBase { -// public: - -// virtual String<ECSS_ST_20_MAX_STRING_LENGTH> getValueAsString() = 0; -// virtual void setValueFromMessage(Message message) = 0; - -// template <typename ValueType> -// void setCurrentValue(ValueType newVal) { -// *reinterpret_cast<ValueType*>(valuePtr) = newVal; -// } -// }; - -// template <typename ValueType> -// class Parameter : public ParameterBase { -// void (* ptr)(ValueType*); -// ValueType currentValue; - -// public: -// Parameter(ValueType initialValue = 0, void(* newPtr)(ValueType*) = nullptr) { -// ptr = newPtr; -// sizeInBytes = sizeof(initialValue); -// // previously null valuePtr now points to the currentValue field -// valuePtr = static_cast<void*>(¤tValue); - -// if (ptr != nullptr) { -// (*ptr)(¤tValue); // call the update function for the initial value -// } else { -// currentValue = initialValue; -// } -// } - -// String<ECSS_ST_20_MAX_STRING_LENGTH> getValueAsString() override { -// String<ECSS_ST_20_MAX_STRING_LENGTH> contents(reinterpret_cast<uint8_t*>(¤tValue), sizeInBytes); -// return contents; -// } -// }; - - #endif //ECSS_SERVICES_PARAMETER_HPP diff --git a/inc/Services/ParameterService.hpp b/inc/Services/ParameterService.hpp index e2f4be64e451503d23f7b6e98a642cfef6c7b749..228f6a59d3db512c962c2bd0e455343dfdca2fc4 100644 --- a/inc/Services/ParameterService.hpp +++ b/inc/Services/ParameterService.hpp @@ -5,14 +5,15 @@ #include "Service.hpp" #include "ErrorHandler.hpp" #include "Parameter.hpp" -#include "etl/map.h" #include "etl/vector.h" +#include "Parameters/Parameters.hpp" /** * Implementation of the ST[20] parameter management service, * as defined in ECSS-E-ST-70-41C * * @author Grigoris Pavlakis <grigpavl@ece.auth.gr> + * @author Athanasios Theocharis <athatheoc@gmail.com> */ /** @@ -23,17 +24,18 @@ * The parameter list is stored in a map with the parameter IDs as keys and values * corresponding Parameter classes containing the parameter's value. */ - - class ParameterService : public Service { -private: - etl::map<ParamId, ParameterBase*, ECSS_ST_20_MAX_PARAMETERS> paramsList; - public: /** * @brief Initializes the parameter list. */ - ParameterService(); + ParameterService() { + addToParameterArray(1, systemParameters.parameter1); + addToParameterArray(2, systemParameters.parameter2); + addToParameterArray(3, systemParameters.parameter3); + addToParameterArray(4, systemParameters.parameter4); + addToParameterArray(5, systemParameters.parameter5); + } /** * @brief Adds a new parameter. Emits an InternalError::MapFull if an attempt is made to insert @@ -42,7 +44,7 @@ public: * @param id: the desired ID for this parameter * @param param: the parameter field to be included */ - void addNewParameter(uint16_t id, ParameterBase* param); + void addToParameterArray(uint16_t id, ParameterBase& param); /** * This function receives a TC[20, 1] packet and returns a TM[20, 2] packet @@ -60,7 +62,7 @@ public: * * Everything apart from the setting data is uint16 (setting data are uint32 for now) */ - void reportParameterIds(Message& paramIds); + void reportParameters(Message& paramIds); /** * This function receives a TC[20, 3] message and after checking whether its type is correct, @@ -73,7 +75,7 @@ public: * * @todo Use pointers for changing and storing addresses to comply with the standard */ - void setParameterIds(Message& newParamValues); + void setParameters(Message& newParamValues); /** * It is responsible to call the suitable function that executes a telecommand packet. The source of that packet diff --git a/src/Parameters/Parameters.cpp b/src/Parameters/Parameters.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a67683703449d32acec673bd8cf02aea8e027203 --- /dev/null +++ b/src/Parameters/Parameters.cpp @@ -0,0 +1,3 @@ +#include "Parameters/Parameters.hpp" + +SystemParameters systemParameters; \ No newline at end of file diff --git a/src/Platform/x86/main.cpp b/src/Platform/x86/main.cpp index 391780a790d452b7d5e0fd46a3aec0c280882818..07e1f968d556647caa0db2e5b0e7b0c7ea41457c 100644 --- a/src/Platform/x86/main.cpp +++ b/src/Platform/x86/main.cpp @@ -55,7 +55,7 @@ int main() { sentPacket.appendUint16(2); // number of contained IDs sentPacket.appendUint16(0); // first ID sentPacket.appendUint16(1); // second ID - paramService.reportParameterIds(sentPacket); + paramService.reportParameters(sentPacket); // Test code for setParameter Message sentPacket2 = Message(20, 3, Message::TC, 1); // application id is a dummy number (1) @@ -65,8 +65,8 @@ int main() { sentPacket2.appendUint16(1); // 2nd parameter ID sentPacket2.appendUint32(45823); // settings for 2nd parameter - paramService.setParameterIds(sentPacket2); - paramService.reportParameterIds(sentPacket); + paramService.setParameters(sentPacket2); + paramService.reportParameters(sentPacket); // ST[06] testing char anotherStr[8] = "Fgthred"; diff --git a/src/Services/ParameterService.cpp b/src/Services/ParameterService.cpp index a20b5b80f15dbc3fc0322d598a78aa688800c03d..a43bb572ea086b0a6ee4296333e6d6d8f32eb81d 100644 --- a/src/Services/ParameterService.cpp +++ b/src/Services/ParameterService.cpp @@ -4,37 +4,15 @@ #include "Services/ParameterService.hpp" #include "Services/Parameter.hpp" -ParameterService::ParameterService() { - // test addings -// addNewParameter(3, 14); -// addNewParameter(3, 14); +void ParameterService::addToParameterArray(uint16_t id, ParameterBase& param) { + systemParameters.parametersArray[id] = param; } -void ParameterService::addNewParameter(uint16_t id, ParameterBase* param) { - if (paramsList.full()) { - ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MapFull); - } - else { - if (paramsList.find(id) == paramsList.end()) { - paramsList.insert(std::make_pair(id, param)); - } - else { - ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::ExistingParameterId); - } - } -} - -void ParameterService::reportParameterIds(Message& paramIds) { - etl::vector<std::pair<uint16_t, String<ECSS_ST_20_MAX_STRING_LENGTH>>, ECSS_ST_20_MAX_PARAMETERS> validParams; +void ParameterService::reportParameters(Message& paramIds) { + // TM[20,2] Message reqParam(20, 2, Message::TM, 1); - // empty TM[20, 2] parameter report message paramIds.resetRead(); - // since we're passing a reference, the reading position shall be reset - // to its default before any read operations (to ensure the correct data is being read) - - // assertion: correct message, packet and service type (at failure throws an - // InternalError::UnacceptableMessage) ErrorHandler::assertRequest(paramIds.packetType == Message::TC, paramIds, ErrorHandler::AcceptanceErrorType::UnacceptableMessage); ErrorHandler::assertRequest(paramIds.messageType == 1, paramIds, @@ -42,38 +20,23 @@ void ParameterService::reportParameterIds(Message& paramIds) { ErrorHandler::assertRequest(paramIds.serviceType == 20, paramIds, ErrorHandler::AcceptanceErrorType::UnacceptableMessage); - uint16_t numOfIds = paramIds.readUint16(); // total number of parameter IDs carried in the message - uint16_t validIds = 0; // number of valid IDs + uint16_t numOfIds = paramIds.readUint16(); + uint16_t validIds = 0; for (uint16_t i = 0; i < numOfIds; i++) { uint16_t currId = paramIds.readUint16(); - - if (paramsList.find(currId) != paramsList.end()) { - std::pair<uint16_t, String<ECSS_ST_20_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); + if (currId < ECSS_ST_20_MAX_PARAMETERS) { + reqParam.appendUint16(currId); + reqParam.appendString(systemParameters.parametersArray[currId].get().getValueAsString()); validIds++; } - else { - ErrorHandler::reportError(paramIds, ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError); - continue; // generate failed start of execution notification & ignore - } } + reqParam.appendUint16(validIds); - reqParam.appendUint16(validIds); // append the number of valid IDs - - for (auto const& i: validParams) { - reqParam.appendUint16(i.first); // append the parameter ID - reqParam.appendString(i.second); // and its value - } - - storeMessage(reqParam); // then store the message + storeMessage(reqParam); } -void ParameterService::setParameterIds(Message& newParamValues) { - // assertion: correct message, packet and service type (at failure throws an - // InternalError::UnacceptablePacket which gets logged) +void ParameterService::setParameters(Message& newParamValues) { ErrorHandler::assertRequest(newParamValues.packetType == Message::TC, newParamValues, ErrorHandler::AcceptanceErrorType::UnacceptableMessage); @@ -82,21 +45,12 @@ void ParameterService::setParameterIds(Message& newParamValues) { ErrorHandler::assertRequest(newParamValues.serviceType == 20, newParamValues, ErrorHandler::AcceptanceErrorType::UnacceptableMessage); - uint16_t numOfIds = newParamValues.readUint16(); // get number of ID's contained in the message + uint16_t numOfIds = newParamValues.readUint16(); for (uint16_t i = 0; i < numOfIds; i++) { uint16_t currId = newParamValues.readUint16(); - // the parameter is checked for read-only status and manual update availability - if (paramsList.find(currId) != paramsList.end()) { - - // WARNING! SETTING WORKS ONLY WITH UINT32_T INPUT! - // I need a way to know the input's type! - paramsList.at(currId)->setCurrentValue(newParamValues.readUint32()); - } - else { - ErrorHandler::reportError(newParamValues, - ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError); - continue; // generate failed start of execution notification & ignore + if (currId < ECSS_ST_20_MAX_PARAMETERS) { + systemParameters.parametersArray[currId].get().setValueFromMessage(newParamValues); } } } @@ -104,10 +58,10 @@ void ParameterService::setParameterIds(Message& newParamValues) { void ParameterService::execute(Message& message) { switch (message.messageType) { case 1: - reportParameterIds(message); // TC[20,1] + reportParameters(message); // TC[20,1] break; case 3: - setParameterIds(message); // TC[20,3] + setParameters(message); // TC[20,3] break; default: ErrorHandler::reportInternalError(ErrorHandler::OtherMessageType); diff --git a/test/Services/ParameterService.cpp b/test/Services/ParameterService.cpp index 16b3ae329e9426a84341c8549745ca64f2c199ae..eee01ed47ac4bcc4a4be1d7d53dbe6a07adeacc7 100644 --- a/test/Services/ParameterService.cpp +++ b/test/Services/ParameterService.cpp @@ -8,7 +8,7 @@ ParameterService& pserv = Services.parameterManagement; TEST_CASE("Parameter Service - General") { SECTION("Addition to full map") { - Parameter<int> param0 = Parameter<int>(); + Parameter<int> param0 = Parameter<int>(1); Parameter<int> param1 = Parameter<int>(12); Parameter<int> param2 = Parameter<int>(3, nullptr); Parameter<int> param3 = Parameter<int>(6); @@ -29,7 +29,7 @@ TEST_CASE("Parameter Service - General") { } SECTION("Addition of already existing parameter") { - Parameter<int> param0 = Parameter<int>(); + Parameter<int> param0 = Parameter<int>(1); pserv.addNewParameter(0, static_cast<ParameterBase*>(¶m0)); pserv.addNewParameter(0, static_cast<ParameterBase*>(¶m0));