diff --git a/docs/usage_with_microcontroller.md b/docs/usage_with_microcontroller.md index 6496878e4297f3176fdde2231321184ca07d3614..6c318409050f0316fdf13ab07393aa47ae554a49 100644 --- a/docs/usage_with_microcontroller.md +++ b/docs/usage_with_microcontroller.md @@ -173,7 +173,6 @@ UTCTimestamp TimeGetter::getCurrentTimeUTC() { } ``` - ## Service initialisation Platform-specific code also gives a chance to every Service to use pre-initialised entities (e.g. parameters, monitoring @@ -193,6 +192,41 @@ void ParameterService::initializeParameterMap() { } ``` +2. @ref ParameterStatisticsService::initializeStatisticsMap + +The function is called by the constructor of the class, making sure that the statistics will be initialized properly +after creating an instance of the ST04 Service. This function should be implemented according to the specific +needs, structure and parameters of an individual project. It basically iterates over the statistics list and initializes +statistics for parameters of selected IDs. An example is provided below. Let's assume that we have stored the +parameter IDs, and we use a data structure to store the statistics. Our initialization function, based on such +structure should look like this: + +```c++ +namespace PlatformParameters { + enum ParameterIDs : uint16_t { + OnBoardMinute = 0, + Temperature = 1, + }; +} + +namespace ParameterStatistics { + static etl::array<Statistic, ECSSMaxStatisticParameters> statistics = { + Statistic(), + Statistic(), + }; +} + +void ParameterStatisticsService::initializeStatisticsMap() { + using namespace PlatformParameters; + uint16_t statisticParameterIDs[] = {parameterIDs::onBoardMinute, parameterIDs::temperature}; + uint8_t idIndex = 0; + + for (auto& statistic: ParameterStatistics::statistics) { + statisticsMap.insert({statisticParameterIDs[idIndex++], statistic}); + } +} +``` + ## Receiving messages After making sure that your code compiles, you need to provide a way of feeding received TC into the services. This can diff --git a/inc/Services/ParameterStatisticsService.hpp b/inc/Services/ParameterStatisticsService.hpp index f2836767a26cbff0dafcd811d7942d0dacbd03bf..4ac9ecbc831e7a11b2904032809a31dd6f30352a 100644 --- a/inc/Services/ParameterStatisticsService.hpp +++ b/inc/Services/ParameterStatisticsService.hpp @@ -23,6 +23,21 @@ private: */ Time::CustomCUC_t evaluationStartTime; + /** + * true means that the periodic statistics reporting is enabled + */ + bool periodicStatisticsReportingStatus = true; + + /** + * The parameter statistics reporting interval + */ + uint16_t reportingIntervalMs = 700; + + /** + * Initializer of the statistics map, so that its content can be accessed by FreeRTOS tasks. + */ + void initializeStatisticsMap(); + public: inline static const uint8_t ServiceType = 4; @@ -45,10 +60,6 @@ public: */ etl::map<uint16_t, Statistic, ECSSMaxStatisticParameters> statisticsMap; - /** - * true means that the periodic statistics reporting is enabled - */ - bool periodicStatisticsReportingStatus = false; /** * If true, after every report reset the parameter statistics. */ @@ -57,10 +68,27 @@ public: * Indicates whether to append/read the sampling interval to/from message */ const bool supportsSamplingInterval = true; + /** - * The parameter statistics reporting interval + * Returns the periodic statistics reporting status + */ + inline bool getPeriodicReportingStatus() { + return periodicStatisticsReportingStatus; + } + + /** + * Sets the value of the periodic statistics reporting status + */ + inline void setPeriodicReportingStatus(bool status) { + periodicStatisticsReportingStatus = status; + } + + /** + * Returns the periodic statistics reporting status */ - uint16_t reportingInterval = 5; // TODO: Must define units. Same as parameter sampling rates + inline const uint16_t getReportingIntervalMs() { + return reportingIntervalMs; + } /** * TC[4,1] report the parameter statistics, by calling parameterStatisticsReport() diff --git a/src/Platform/x86/Services/ParameterService.cpp b/src/Platform/x86/Services/ParameterService.cpp index da7b4c439e937b854db079a4efd93bf972153c0f..268cfd279b2d9d773f34965643d9e30d30b63c70 100644 --- a/src/Platform/x86/Services/ParameterService.cpp +++ b/src/Platform/x86/Services/ParameterService.cpp @@ -1,8 +1,8 @@ #include "ECSS_Configuration.hpp" #ifdef SERVICE_PARAMETER -#include "Services/ParameterService.hpp" #include "Parameters/PlatformParameters.hpp" +#include "Services/ParameterService.hpp" void ParameterService::initializeParameterMap() { parameters = {{static_cast<uint16_t>(0), PlatformParameters::parameter1}, @@ -10,4 +10,4 @@ void ParameterService::initializeParameterMap() { {static_cast<uint16_t>(2), PlatformParameters::parameter3}}; } -#endif \ No newline at end of file +#endif diff --git a/src/Platform/x86/Services/ParameterStatisticsService.cpp b/src/Platform/x86/Services/ParameterStatisticsService.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac6e9aa2e093bc9e3a72a26b89b8818cfabec395 --- /dev/null +++ b/src/Platform/x86/Services/ParameterStatisticsService.cpp @@ -0,0 +1,10 @@ +#include "Services/ParameterStatisticsService.hpp" +#include "ECSS_Configuration.hpp" + +#ifdef SERVICE_PARAMETERSTATISTICS + +void ParameterStatisticsService::initializeStatisticsMap() { + statisticsMap = {}; +} + +#endif diff --git a/src/Services/ParameterStatisticsService.cpp b/src/Services/ParameterStatisticsService.cpp index 45982157bfd7faf096da411dc932c670c3296cfd..5197e9b9f171913f5726aff888634c8fd1eeac81 100644 --- a/src/Services/ParameterStatisticsService.cpp +++ b/src/Services/ParameterStatisticsService.cpp @@ -4,6 +4,7 @@ #include "Services/ParameterStatisticsService.hpp" ParameterStatisticsService::ParameterStatisticsService() : evaluationStartTime(TimeGetter::getCurrentTimeCustomCUC()) { + initializeStatisticsMap(); serviceType = ServiceType; } @@ -77,14 +78,14 @@ void ParameterStatisticsService::enablePeriodicStatisticsReporting(Message& requ return; } periodicStatisticsReportingStatus = true; - reportingInterval = timeInterval; + reportingIntervalMs = timeInterval; } void ParameterStatisticsService::disablePeriodicStatisticsReporting(Message& request) { request.assertTC(ServiceType, MessageType::DisablePeriodicParameterReporting); periodicStatisticsReportingStatus = false; - reportingInterval = 0; + reportingIntervalMs = 0; } void ParameterStatisticsService::addOrUpdateStatisticsDefinitions(Message& request) { @@ -104,7 +105,7 @@ void ParameterStatisticsService::addOrUpdateStatisticsDefinitions(Message& reque uint16_t interval = 0; if (supportsSamplingInterval) { interval = request.readUint16(); - if (interval < reportingInterval) { + if (interval < reportingIntervalMs) { ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::InvalidSamplingRateError); continue; } @@ -160,11 +161,11 @@ void ParameterStatisticsService::reportStatisticsDefinitions(Message& request) { void ParameterStatisticsService::statisticsDefinitionsReport() { Message definitionsReport = createTM(ParameterStatisticsDefinitionsReport); - uint16_t currentReportingInterval = 0; + uint16_t currentReportingIntervalMs = 0; if (periodicStatisticsReportingStatus) { - currentReportingInterval = reportingInterval; + currentReportingIntervalMs = reportingIntervalMs; } - definitionsReport.appendUint16(currentReportingInterval); + definitionsReport.appendUint16(currentReportingIntervalMs); definitionsReport.appendUint16(statisticsMap.size()); for (auto& currentParam: statisticsMap) { diff --git a/test/Services/ParameterStatisticsService.cpp b/test/Services/ParameterStatisticsService.cpp index b950df1ebe7da3f02ef1b858ab8081885a178798..1f7d3bba14ae786a8830f2b5fbc83d3dda21e919 100644 --- a/test/Services/ParameterStatisticsService.cpp +++ b/test/Services/ParameterStatisticsService.cpp @@ -44,7 +44,7 @@ TEST_CASE("Reporting of statistics") { Message report = ServiceTests::get(0); CHECK(report.serviceType == ParameterStatisticsService::ServiceType); CHECK(report.messageType == ParameterStatisticsService::MessageType::ParameterStatisticsReport); - CHECK(report.readUint64() == 86769000); // start time + CHECK(report.readUint64() == 86769000); // start time CHECK(report.readUint64() == 86769000); // end time CHECK(report.readUint16() == 2); // number of parameters reported // Parameter B @@ -145,14 +145,14 @@ TEST_CASE("Enable the periodic reporting of statistics") { Message(ParameterStatisticsService::ServiceType, ParameterStatisticsService::MessageType::EnablePeriodicParameterReporting, Message::TC, 1); request.appendUint16(6); - Services.parameterStatistics.periodicStatisticsReportingStatus = false; - CHECK(Services.parameterStatistics.reportingInterval == 5); + Services.parameterStatistics.setPeriodicReportingStatus(false); + CHECK(Services.parameterStatistics.getReportingIntervalMs() == 700); MessageParser::execute(request); CHECK(ServiceTests::count() == 0); - CHECK(Services.parameterStatistics.periodicStatisticsReportingStatus == true); - CHECK(Services.parameterStatistics.reportingInterval == 6); + CHECK(Services.parameterStatistics.getPeriodicReportingStatus() == true); + CHECK(Services.parameterStatistics.getReportingIntervalMs() == 6); } SECTION("Invalid reporting interval requested") { @@ -160,14 +160,14 @@ TEST_CASE("Enable the periodic reporting of statistics") { Message(ParameterStatisticsService::ServiceType, ParameterStatisticsService::MessageType::EnablePeriodicParameterReporting, Message::TC, 1); request2.appendUint16(3); - Services.parameterStatistics.periodicStatisticsReportingStatus = false; - CHECK(Services.parameterStatistics.reportingInterval == 6); + Services.parameterStatistics.setPeriodicReportingStatus(false); + CHECK(Services.parameterStatistics.getReportingIntervalMs() == 6); MessageParser::execute(request2); CHECK(ServiceTests::count() == 1); CHECK(ServiceTests::countThrownErrors(ErrorHandler::InvalidSamplingRateError) == 1); - CHECK(Services.parameterStatistics.periodicStatisticsReportingStatus == false); - CHECK(Services.parameterStatistics.reportingInterval == 6); + CHECK(Services.parameterStatistics.getPeriodicReportingStatus() == false); + CHECK(Services.parameterStatistics.getReportingIntervalMs() == 6); resetSystem(); ServiceTests::reset(); @@ -181,10 +181,10 @@ TEST_CASE("Disabling the periodic reporting of statistics") { Message request = Message(ParameterStatisticsService::ServiceType, ParameterStatisticsService::MessageType::DisablePeriodicParameterReporting, Message::TC, 1); - Services.parameterStatistics.periodicStatisticsReportingStatus = true; + Services.parameterStatistics.setPeriodicReportingStatus(true); MessageParser::execute(request); - REQUIRE(Services.parameterStatistics.periodicStatisticsReportingStatus == false); + REQUIRE(Services.parameterStatistics.getPeriodicReportingStatus() == false); resetSystem(); ServiceTests::reset(); @@ -194,7 +194,7 @@ TEST_CASE("Disabling the periodic reporting of statistics") { TEST_CASE("Add/Update statistics definitions") { SECTION("Update existing parameter statistic definition") { - initializeStatistics(7, 6); + initializeStatistics(750, 2400); Statistic newStatistic; newStatistic.setSelfSamplingInterval(0); Services.parameterStatistics.statisticsMap.insert({0, newStatistic}); @@ -206,7 +206,7 @@ TEST_CASE("Add/Update statistics definitions") { request.appendUint16(numOfIds); uint16_t paramId1 = 0; - uint16_t interval1 = 14; + uint16_t interval1 = 1400; request.appendUint16(paramId1); request.appendUint16(interval1); @@ -216,7 +216,7 @@ TEST_CASE("Add/Update statistics definitions") { REQUIRE(ServiceTests::count() == 0); CHECK(Services.parameterStatistics.statisticsMap.size() == 3); - CHECK(Services.parameterStatistics.statisticsMap[0].selfSamplingInterval == 14); + CHECK(Services.parameterStatistics.statisticsMap[0].selfSamplingInterval == 1400); resetSystem(); ServiceTests::reset(); @@ -232,7 +232,7 @@ TEST_CASE("Add/Update statistics definitions") { request.appendUint16(numOfIds); uint16_t paramId1 = 1; - uint16_t interval1 = 32; + uint16_t interval1 = 3200; request.appendUint16(paramId1); request.appendUint16(interval1); @@ -242,7 +242,7 @@ TEST_CASE("Add/Update statistics definitions") { REQUIRE(ServiceTests::count() == 0); CHECK(Services.parameterStatistics.statisticsMap.size() == 3); - CHECK(Services.parameterStatistics.statisticsMap[1].selfSamplingInterval == 32); + CHECK(Services.parameterStatistics.statisticsMap[1].selfSamplingInterval == 3200); resetSystem(); ServiceTests::reset(); @@ -250,7 +250,7 @@ TEST_CASE("Add/Update statistics definitions") { } SECTION("All possible invalid requests combined with add/update") { - initializeStatistics(7, 6); + initializeStatistics(7000, 6000); Statistic newStatistic; newStatistic.setSelfSamplingInterval(0); Services.parameterStatistics.statisticsMap.insert({0, newStatistic}); @@ -268,12 +268,12 @@ TEST_CASE("Add/Update statistics definitions") { uint16_t paramId5 = ECSSParameterCount + 1; uint16_t paramId6 = 3; - uint16_t interval1 = 14; - uint16_t interval2 = 32; - uint16_t interval3 = 2; - uint16_t interval4 = 7; - uint16_t interval5 = 8; - uint16_t interval6 = 9; + uint16_t interval1 = 14000; + uint16_t interval2 = 32000; + uint16_t interval3 = 20; + uint16_t interval4 = 7000; + uint16_t interval5 = 8000; + uint16_t interval6 = 9000; request.appendUint16(paramId1); request.appendUint16(interval1); @@ -297,8 +297,8 @@ TEST_CASE("Add/Update statistics definitions") { CHECK(ServiceTests::countThrownErrors(ErrorHandler::InvalidSamplingRateError) == 1); CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetNonExistingParameter) == 2); CHECK(ServiceTests::countThrownErrors(ErrorHandler::MaxStatisticDefinitionsReached) == 1); - CHECK(Services.parameterStatistics.statisticsMap[0].selfSamplingInterval == 14); - CHECK(Services.parameterStatistics.statisticsMap[1].selfSamplingInterval == 32); + CHECK(Services.parameterStatistics.statisticsMap[0].selfSamplingInterval == 14000); + CHECK(Services.parameterStatistics.statisticsMap[1].selfSamplingInterval == 32000); resetSystem(); ServiceTests::reset(); @@ -330,10 +330,10 @@ TEST_CASE("Delete statistics definitions") { request.appendUint16(id1); request.appendUint16(id2); - Services.parameterStatistics.periodicStatisticsReportingStatus = true; + Services.parameterStatistics.setPeriodicReportingStatus(true); MessageParser::execute(request); - CHECK(Services.parameterStatistics.periodicStatisticsReportingStatus == true); + CHECK(Services.parameterStatistics.getPeriodicReportingStatus() == true); CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetNonExistingParameter) == 1); CHECK(Services.parameterStatistics.statisticsMap.size() == 2); } @@ -347,7 +347,7 @@ TEST_CASE("Delete statistics definitions") { MessageParser::execute(request); - CHECK(Services.parameterStatistics.periodicStatisticsReportingStatus == false); + CHECK(Services.parameterStatistics.getPeriodicReportingStatus() == false); CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetNonExistingParameter) == 1); CHECK(Services.parameterStatistics.statisticsMap.empty()); @@ -372,10 +372,10 @@ TEST_CASE("Parameter statistics definition report") { CHECK(ServiceTests::count() == 1); Message report = ServiceTests::get(0); - CHECK(report.readUint16() == 0); // Reporting interval - CHECK(report.readUint16() == 2); // Num of valid Ids - CHECK(report.readUint16() == 5); // Valid parameter ID - CHECK(report.readUint16() == 12); // Sampling interval + CHECK(report.readUint16() == 700); // Reporting interval + CHECK(report.readUint16() == 2); // Num of valid Ids + CHECK(report.readUint16() == 5); // Valid parameter ID + CHECK(report.readUint16() == 12); // Sampling interval CHECK(report.readUint16() == 7); CHECK(report.readUint16() == 0); diff --git a/test/TestPlatform.cpp b/test/TestPlatform.cpp index f5560304dd7d7cdaa925363a5d71002cfb492473..1c7233e4334c06c47468dbd427df03a80bdb2dcb 100644 --- a/test/TestPlatform.cpp +++ b/test/TestPlatform.cpp @@ -8,6 +8,7 @@ #include "Helpers/TimeGetter.hpp" #include "Parameters/PlatformParameters.hpp" #include "Services/ParameterService.hpp" +#include "Services/ParameterStatisticsService.hpp" #include "Services/ServiceTests.hpp" UTCTimestamp TimeGetter::getCurrentTimeUTC() { @@ -107,4 +108,9 @@ void ParameterService::initializeParameterMap() { {static_cast<uint16_t>(10), PlatformParameters::parameter11}, {static_cast<uint16_t>(11), PlatformParameters::parameter12}}; } + +void ParameterStatisticsService::initializeStatisticsMap() { + statisticsMap = {}; +} + CATCH_REGISTER_LISTENER(ServiceTestsListener)