From dd12853503ae14476b711060679b5f481f643e0e Mon Sep 17 00:00:00 2001 From: Adam Dobrowolski Date: Wed, 23 Feb 2022 16:34:52 +0100 Subject: [PATCH] [MOS-226] Moved algorithms and their data to separate classes This way we have controll over what does what, and can test them separatelly Logging statistics update more and better data presented --- .../windows/advanced/CPUModeTestWindow.cpp | 32 ++- module-bsp/board/linux/CMakeLists.txt | 1 + module-bsp/board/linux/lpm/PowerProfile.cpp | 3 +- module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp | 62 ++++- module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp | 5 +- .../bsp/battery_charger/battery_charger.hpp | 4 - .../rt1051/puretx/bsp/lpm/PowerProfile.cpp | 3 +- .../CurrentMeasurementScope.cpp | 2 +- .../bsp/battery_charger/battery_charger.hpp | 6 + module-bsp/bsp/lpm/PowerProfile.hpp | 1 - module-bsp/bsp/lpm/bsp_lpm.hpp | 5 + module-bsp/drivers/semc/DriverSEMC.hpp | 5 +- .../ConnectionManagerCellularCommands.cpp | 6 +- .../src/ServiceCellularPriv.cpp | 12 +- module-sys/SystemManager/CMakeLists.txt | 5 + module-sys/SystemManager/CpuGovernor.cpp | 27 +- module-sys/SystemManager/CpuLogPrinter.cpp | 3 + module-sys/SystemManager/CpuPackPrinter.cpp | 44 +++- module-sys/SystemManager/CpuSentinel.cpp | 59 +---- module-sys/SystemManager/CpuStatistics.cpp | 11 +- module-sys/SystemManager/PowerManager.cpp | 233 +++++------------- .../SystemManager/SystemManagerCommon.cpp | 35 +-- .../SystemManager/cpu/AlgorithmFactory.cpp | 33 +++ .../SystemManager/cpu/AlgorithmFactory.hpp | 26 ++ .../SystemManager/cpu/algorithm/Algorithm.cpp | 17 ++ .../SystemManager/cpu/algorithm/Algorithm.hpp | 32 +++ .../cpu/algorithm/AlgorithmID.hpp | 15 ++ .../cpu/algorithm/FrequencyHold.cpp | 17 ++ .../cpu/algorithm/FrequencyHold.hpp | 18 ++ .../cpu/algorithm/FrequencyStepping.cpp | 86 +++++++ .../cpu/algorithm/FrequencyStepping.hpp | 26 ++ .../cpu/algorithm/ImmediateUpscale.cpp | 14 ++ .../cpu/algorithm/ImmediateUpscale.hpp | 17 ++ .../include/SystemManager/CpuGovernor.hpp | 30 +-- .../include/SystemManager/CpuPrinter.hpp | 4 + .../include/SystemManager/CpuSentinel.hpp | 18 +- .../include/SystemManager/CpuStatistics.hpp | 4 +- .../include/SystemManager/PowerManager.hpp | 38 +-- .../include/SystemManager/SentinelView.hpp | 28 +++ .../SystemManager/SysCpuUpdateResult.hpp | 14 +- .../SystemManager/SystemManagerCommon.hpp | 6 +- .../include/system/SystemReturnCodes.hpp | 8 +- .../messages/RequestCpuFrequencyMessage.hpp | 42 +++- 43 files changed, 670 insertions(+), 387 deletions(-) create mode 100644 module-bsp/bsp/battery_charger/battery_charger.hpp create mode 100644 module-sys/SystemManager/cpu/AlgorithmFactory.cpp create mode 100644 module-sys/SystemManager/cpu/AlgorithmFactory.hpp create mode 100644 module-sys/SystemManager/cpu/algorithm/Algorithm.cpp create mode 100644 module-sys/SystemManager/cpu/algorithm/Algorithm.hpp create mode 100644 module-sys/SystemManager/cpu/algorithm/AlgorithmID.hpp create mode 100644 module-sys/SystemManager/cpu/algorithm/FrequencyHold.cpp create mode 100644 module-sys/SystemManager/cpu/algorithm/FrequencyHold.hpp create mode 100644 module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp create mode 100644 module-sys/SystemManager/cpu/algorithm/FrequencyStepping.hpp create mode 100644 module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.cpp create mode 100644 module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.hpp create mode 100644 module-sys/SystemManager/include/SystemManager/SentinelView.hpp diff --git a/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp b/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp index 937931e8eacc8f200d0da2deb9a4eafca2f62c96..f2d70f505e49eedcaa021dfee653f33569b5eb27 100644 --- a/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp +++ b/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp @@ -1,9 +1,10 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "CPUModeTestWindow.hpp" #include +#include #include #include #include @@ -131,18 +132,23 @@ namespace gui permanentFreqSpinner = new gui::TextSpinnerBox(permanentFreqBody, {"OFF", "ON"}, Boundaries::Continuous); permanentFreqSpinner->setMinimumSize(100, 30); - permanentFreqSpinner->setCurrentValue(cpuModeTester->isPermanentFrequencyActive() ? "ON" : "OFF"); + auto ret = application->async_call(service::name::system_manager); + application->sync(ret); + permanentFreqSpinner->setCurrentValue( ret.getResult().pernament ? "ON" : "OFF"); permanentFreqBody->inputCallback = [&](Item &item, const InputEvent &event) { auto ret = permanentFreqSpinner->onInput(event); if (ret) { if (permanentFreqSpinner->getCurrentValue() == "ON") { - cpuModeTester->HoldFrequencyPermanently( - magic_enum::enum_cast(std::stoi(currentFreqSpinner->getCurrentValue())) - .value()); + application->bus.sendUnicastSync(std::make_shared( + magic_enum::enum_cast( + std::stoi(currentFreqSpinner->getCurrentValue())) + .value()), + service::name::system_manager, 5000); } else { - cpuModeTester->ReleasePermanentFrequency(); + application->bus.sendUnicastSync(std::make_shared(), + service::name::system_manager, 5000); } } @@ -183,10 +189,16 @@ namespace gui newFreqBody->inputCallback = [&](Item &item, const InputEvent &event) { auto ret = currentFreqSpinner->onInput(event); - if (cpuModeTester->isPermanentFrequencyActive()) { - cpuModeTester->HoldFrequencyPermanently( - magic_enum::enum_cast(std::stoi(currentFreqSpinner->getCurrentValue())) - .value()); + auto async = application->async_call( + service::name::system_manager); + application->sync(async); + if (async.getResult().pernament) { + application->bus.sendUnicastSync( + std::make_shared( + magic_enum::enum_cast(std::stoi(currentFreqSpinner->getCurrentValue())) + .value()), + service::name::system_manager, + 5000); } return ret; diff --git a/module-bsp/board/linux/CMakeLists.txt b/module-bsp/board/linux/CMakeLists.txt index 40fbacf740d1a5ad85131f4c24b6d20db06fd6fa..d662a2f5e434d6b26e092a079867fdfab45cbad2 100644 --- a/module-bsp/board/linux/CMakeLists.txt +++ b/module-bsp/board/linux/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(module-bsp PRIVATE board.cpp + battery_charger/battery_charger.cpp bluetooth/Bluetooth.cpp bluetooth/test/bsp_bt.cpp cellular/linux_cellular.cpp diff --git a/module-bsp/board/linux/lpm/PowerProfile.cpp b/module-bsp/board/linux/lpm/PowerProfile.cpp index 8945af6ea8fa51dfc1515ad134d9319854d3d85f..db17e3839d34b1f38ff8b85254fa72a92522a773 100644 --- a/module-bsp/board/linux/lpm/PowerProfile.cpp +++ b/module-bsp/board/linux/lpm/PowerProfile.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include @@ -15,7 +15,6 @@ namespace bsp linuxPowerProfile.maxBelowThresholdInRowCount = 10; linuxPowerProfile.maxAboveThresholdCount = 3; linuxPowerProfile.minimalFrequency = CpuFrequencyMHz::Level_1; - linuxPowerProfile.frequencyIncreaseIntermediateStep = false; return linuxPowerProfile; } diff --git a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp index 0b2386484308126c5e71a3be740f09edf05afe55..164dfb0b3a0519724a0e80b7c39ee68af8cadff5 100644 --- a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp +++ b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp @@ -14,6 +14,7 @@ #include "ClockState.hpp" #include "Oscillator.hpp" #include "critical.hpp" +#include "drivers/semc/DriverSEMC.hpp" namespace bsp { @@ -22,6 +23,7 @@ namespace bsp RT1051LPM::RT1051LPM() { + driverSEMC = drivers::DriverSEMC::Create(drivers::name::ExternalRAM); gpio_1 = DriverGPIO::Create(static_cast(BoardDefinitions::POWER_SWITCH_HOLD_GPIO), DriverGPIOParams{}); gpio_2 = DriverGPIO::Create(static_cast(BoardDefinitions::DCDC_INVERTER_MODE_GPIO), @@ -72,9 +74,62 @@ namespace bsp return 0; } + enum class Change { + Up, Down + }; + + CpuFrequencyMHz RT1051LPM::onChangeUp(CpuFrequencyMHz freq, bsp::CpuFrequencyMHz newFrequency) + { + if ((freq <= CpuFrequencyMHz::Level_1) && (newFrequency > CpuFrequencyMHz::Level_1)) { + // connect internal the load resistor + ConnectInternalLoadResistor(); + // turn off power save mode for DCDC inverter + DisableDcdcPowerSaveMode(); + // Switch DCDC to full throttle during oscillator switch + SetHighestCoreVoltage(); + // Enable regular 2P5 and 1P1 LDO and Turn off weak 2P5 and 1P1 LDO + SwitchToRegularModeLDO(); + // switch oscillator source + SwitchOscillatorSource(LowPowerMode::OscillatorSource::External); + // then switch external RAM clock source + if (driverSEMC) { + driverSEMC->SwitchToPLL2ClockSource(); + } + // Add intermediate step in frequency + if (newFrequency > CpuFrequencyMHz::Level_4) + return CpuFrequencyMHz::Level_4; + } + return newFrequency; + } + + void RT1051LPM::onChangeDown(CpuFrequencyMHz newFrequency) + { + if (newFrequency <= bsp::CpuFrequencyMHz::Level_1) { + // Enable weak 2P5 and 1P1 LDO and Turn off regular 2P5 and 1P1 LDO + SwitchToLowPowerModeLDO(); + // then switch osc source + SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::Internal); + // and switch external RAM clock source + if (driverSEMC) { + driverSEMC->SwitchToPeripheralClockSource(); + } + // turn on power save mode for DCDC inverter + EnableDcdcPowerSaveMode(); + + // disconnect internal the load resistor + DisconnectInternalLoadResistor(); + } + } + void RT1051LPM::SetCpuFrequency(bsp::CpuFrequencyMHz freq) { - currentFrequency = freq; + if ( currentFrequency == freq ) { + return; + } + Change change = currentFrequency < freq ? Change::Up : Change::Down; + if (Change::Up == change) { + freq = onChangeUp(currentFrequency, freq); + } switch (freq) { case bsp::CpuFrequencyMHz::Level_0: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_4_Mhz); @@ -98,7 +153,12 @@ namespace bsp CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_528_Mhz); break; } + + if (Change::Down == change) { + onChangeDown(freq); + } LOG_INFO("CPU frequency changed to %lu", CLOCK_GetFreq(kCLOCK_CpuClk)); + currentFrequency = freq; } void RT1051LPM::SetHighestCoreVoltage() diff --git a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp index ce957add061f61c2affe22ce3d70a381e68b391f..a9968a6685766c41927be9f03a68830e07693d58 100644 --- a/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp +++ b/module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #ifndef PUREPHONE_RT1051LPM_HPP @@ -32,9 +32,12 @@ namespace bsp void SwitchToLowPowerModeLDO() final; private: + CpuFrequencyMHz onChangeUp(CpuFrequencyMHz freq, CpuFrequencyMHz newFrequency); + void onChangeDown(bsp::CpuFrequencyMHz freq); std::shared_ptr gpio_1; std::shared_ptr gpio_2; std::unique_ptr CpuFreq; + std::shared_ptr driverSEMC; }; } // namespace bsp diff --git a/module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.hpp b/module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.hpp index 0557a5a832172a8070c509607e524f9470570190..d6af46421157e170003cb1f37edf0a3adcf222ec 100644 --- a/module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.hpp +++ b/module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.hpp @@ -92,10 +92,6 @@ namespace bsp::battery_charger int getVoltageFilteredMeasurement(); - int getAvgCurrent(); - - int getCurrentMeasurement(); - MaxMinVolt getMaxMinVolt(); void printFuelGaugeInfo(); diff --git a/module-bsp/board/rt1051/puretx/bsp/lpm/PowerProfile.cpp b/module-bsp/board/rt1051/puretx/bsp/lpm/PowerProfile.cpp index 2b967d54b9b0c862cdc00c97db44d4c8a8d7733d..d386255658a3afe7157612730c8a8044667ec3b2 100644 --- a/module-bsp/board/rt1051/puretx/bsp/lpm/PowerProfile.cpp +++ b/module-bsp/board/rt1051/puretx/bsp/lpm/PowerProfile.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include @@ -15,7 +15,6 @@ namespace bsp purePowerProfile.maxBelowThresholdInRowCount = 1; purePowerProfile.maxAboveThresholdCount = 2; purePowerProfile.minimalFrequency = CpuFrequencyMHz::Level_0; - purePowerProfile.frequencyIncreaseIntermediateStep = true; return purePowerProfile; } diff --git a/module-bsp/board/rt1051/puretx/hal/battery_charger/CurrentMeasurementScope.cpp b/module-bsp/board/rt1051/puretx/hal/battery_charger/CurrentMeasurementScope.cpp index 5d0ffe5f2c78d62f9405c07906ea252eef762d73..99850e909c2866b90944bad61fa7805bea1a7193 100644 --- a/module-bsp/board/rt1051/puretx/hal/battery_charger/CurrentMeasurementScope.cpp +++ b/module-bsp/board/rt1051/puretx/hal/battery_charger/CurrentMeasurementScope.cpp @@ -8,7 +8,7 @@ extern "C" #include "FreeRTOS.h" } #include -#include +#include #include #include diff --git a/module-bsp/bsp/battery_charger/battery_charger.hpp b/module-bsp/bsp/battery_charger/battery_charger.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0d26451c566e07958c6a6d335edb51a043e02b35 --- /dev/null +++ b/module-bsp/bsp/battery_charger/battery_charger.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace bsp::battery_charger { + int getAvgCurrent(); + int getCurrentMeasurement(); +} diff --git a/module-bsp/bsp/lpm/PowerProfile.hpp b/module-bsp/bsp/lpm/PowerProfile.hpp index 6ccce80be9c6b9c4d7eed309d97fdce659f53ba4..75796b067973fe44c5e1281755fa2c17029cb1db 100644 --- a/module-bsp/bsp/lpm/PowerProfile.hpp +++ b/module-bsp/bsp/lpm/PowerProfile.hpp @@ -16,7 +16,6 @@ namespace bsp std::uint32_t maxBelowThresholdInRowCount; std::uint32_t maxAboveThresholdCount; CpuFrequencyMHz minimalFrequency; - bool frequencyIncreaseIntermediateStep; }; const PowerProfile getPowerProfile(); diff --git a/module-bsp/bsp/lpm/bsp_lpm.hpp b/module-bsp/bsp/lpm/bsp_lpm.hpp index 531909e22687703d9f60191fe8576e1b38aeb9c2..2d7f4ec1b8a28d6dce15906375659c6fe8b5dbc7 100644 --- a/module-bsp/bsp/lpm/bsp_lpm.hpp +++ b/module-bsp/bsp/lpm/bsp_lpm.hpp @@ -7,6 +7,11 @@ #include #include +namespace drivers +{ + class DriverSEMC; +} + namespace bsp { diff --git a/module-bsp/drivers/semc/DriverSEMC.hpp b/module-bsp/drivers/semc/DriverSEMC.hpp index 61fc7d857f7dbdf2f8a8afcda52847c187bfff9f..a4e0b11fdd6c481605b60639e17fbaccc83edb74 100644 --- a/module-bsp/drivers/semc/DriverSEMC.hpp +++ b/module-bsp/drivers/semc/DriverSEMC.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -8,6 +8,9 @@ namespace drivers { + namespace name { + constexpr auto ExternalRAM = "ExternalRAM"; + } class DriverSEMC : public devices::Device { diff --git a/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp b/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp index d5102e2fa4660eafd5e07d7b79165053c61a20b7..cfeff202af3887c5266d3c6ee5156b3ae6a389dd 100644 --- a/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp +++ b/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include @@ -100,11 +100,9 @@ void ConnectionManagerCellularCommands::stopConnectionTimer() void ConnectionManagerCellularCommands::holdMinimumCpuFrequency() { - auto handle = cellular.getTaskHandle(); if (cellular.cpuSentinel) { - cellular.cpuSentinel->HoldMinimumFrequencyAndWait(bsp::CpuFrequencyMHz::Level_4, handle, 2000); + cellular.cpuSentinel->HoldMinimumFrequency(bsp::CpuFrequencyMHz::Level_4); } - return; } void ConnectionManagerCellularCommands::retryPhoneModeChange() { diff --git a/module-services/service-cellular/src/ServiceCellularPriv.cpp b/module-services/service-cellular/src/ServiceCellularPriv.cpp index 4c3c8c2a62d017b60e4fda592a12e8550a3cff1c..40218026729720c4eb92b22b4ca7b0aee7822aae 100644 --- a/module-services/service-cellular/src/ServiceCellularPriv.cpp +++ b/module-services/service-cellular/src/ServiceCellularPriv.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "ServiceCellularPriv.hpp" @@ -398,11 +398,8 @@ namespace cellular::internal void ServiceCellularPriv::initCSQHandler() { csqHandler->onEnableCsqReporting = [this]() { - constexpr auto cpuSentinelTimeout = 2000; - auto handle = owner->getTaskHandle(); if (owner->cpuSentinel) { - owner->cpuSentinel->HoldMinimumFrequencyAndWait( - bsp::CpuFrequencyMHz::Level_4, handle, cpuSentinelTimeout); + owner->cpuSentinel->HoldMinimumFrequency(bsp::CpuFrequencyMHz::Level_4); } auto channel = owner->cmux->get(CellularMux::Channel::Commands); @@ -416,11 +413,8 @@ namespace cellular::internal }; csqHandler->onDisableCsqReporting = [this]() { - constexpr auto cpuSentinelTimeout = 2000; - auto handle = owner->getTaskHandle(); if (owner->cpuSentinel) { - owner->cpuSentinel->HoldMinimumFrequencyAndWait( - bsp::CpuFrequencyMHz::Level_4, handle, cpuSentinelTimeout); + owner->cpuSentinel->HoldMinimumFrequency(bsp::CpuFrequencyMHz::Level_4); } auto channel = owner->cmux->get(CellularMux::Channel::Commands); diff --git a/module-sys/SystemManager/CMakeLists.txt b/module-sys/SystemManager/CMakeLists.txt index 4c7a5b59b94a34546f962fceb61a6e03cc5c29c1..ae427d8d101c219739587058b12170db301b5a0f 100644 --- a/module-sys/SystemManager/CMakeLists.txt +++ b/module-sys/SystemManager/CMakeLists.txt @@ -23,6 +23,11 @@ target_sources(sys-manager graph/TopologicalSort.hpp PowerManager.cpp SystemManagerCommon.cpp + cpu/AlgorithmFactory.cpp + cpu/algorithm/Algorithm.cpp + cpu/algorithm/FrequencyHold.cpp + cpu/algorithm/ImmediateUpscale.cpp + cpu/algorithm/FrequencyStepping.cpp ) target_include_directories(sys-manager diff --git a/module-sys/SystemManager/CpuGovernor.cpp b/module-sys/SystemManager/CpuGovernor.cpp index b2911dd7c4466a4961c47012c45d3751f3c3cb5f..af1bcdddebabe479ba72454016149f97ba22472b 100644 --- a/module-sys/SystemManager/CpuGovernor.cpp +++ b/module-sys/SystemManager/CpuGovernor.cpp @@ -83,15 +83,8 @@ namespace sys std::for_each(std::begin(sentinels), std::end(sentinels), PrintName); } - void CpuGovernor::SetCpuFrequencyRequest(std::string sentinelName, - bsp::CpuFrequencyMHz request, - bool permanentBlock) + void CpuGovernor::SetCpuFrequencyRequest(const std::string &sentinelName, bsp::CpuFrequencyMHz request) { - if (permanentBlock) { - permanentFrequencyToHold.isActive = true; - permanentFrequencyToHold.frequencyToHold = request; - return; - } for (auto &sentinel : sentinels) { auto sentinelWeakPointer = sentinel->GetSentinel(); if (!sentinelWeakPointer.expired()) { @@ -103,19 +96,14 @@ namespace sys } } - void CpuGovernor::ResetCpuFrequencyRequest(std::string sentinelName, bool permanentBlock) + void CpuGovernor::ResetCpuFrequencyRequest(const std::string &sentinelName) { - if (permanentBlock) { - permanentFrequencyToHold.isActive = false; - permanentFrequencyToHold.frequencyToHold = bsp::CpuFrequencyMHz::Level_0; - return; - } SetCpuFrequencyRequest(sentinelName, bsp::CpuFrequencyMHz::Level_0); } - [[nodiscard]] auto CpuGovernor::GetMinimumFrequencyRequested() const noexcept -> sentinel::Data + [[nodiscard]] auto CpuGovernor::GetMinimumFrequencyRequested() const noexcept -> sentinel::View { - sentinel::Data d; + sentinel::View d; if (sentinels.empty()) { d.reason = "empty"; return d; @@ -133,7 +121,6 @@ namespace sys d.frequency = (*minSentinel)->GetRequestedFrequency(); if (auto p = (*minSentinel)->GetSentinel().lock()) { d.name = p->GetName(); - d.task = p->getTask(); d.reason = p->getReason(); } else { @@ -161,10 +148,4 @@ namespace sys LOG_INFO("Sentinel %s", sharedResource->GetName().c_str()); } } - - [[nodiscard]] auto CpuGovernor::GetPermanentFrequencyRequested() const noexcept -> PermanentFrequencyToHold - { - return permanentFrequencyToHold; - } - } // namespace sys diff --git a/module-sys/SystemManager/CpuLogPrinter.cpp b/module-sys/SystemManager/CpuLogPrinter.cpp index df40d5a5b3e27e712c7477dfb934e805e129081f..f923de71536f505873cbb473e84da59a663a401d 100644 --- a/module-sys/SystemManager/CpuLogPrinter.cpp +++ b/module-sys/SystemManager/CpuLogPrinter.cpp @@ -44,4 +44,7 @@ namespace sys::cpu::stats int(ret.data.frequency), CLOCK_GetFreq(0)); } + + void LogPrinter::printPowerConsumption() + {} } // namespace sys::cpu::stats diff --git a/module-sys/SystemManager/CpuPackPrinter.cpp b/module-sys/SystemManager/CpuPackPrinter.cpp index 27456989524b0e32ad31cbff6aafd6f2697ede7c..b18ed7275fa6d9bfeb520955ad673a998f589d5a 100644 --- a/module-sys/SystemManager/CpuPackPrinter.cpp +++ b/module-sys/SystemManager/CpuPackPrinter.cpp @@ -5,6 +5,8 @@ #include "SystemManager/SysCpuUpdateResult.hpp" #include #include "third-party/msgpack11/msgpack11/msgpack11.hpp" +#include "battery_charger/battery_charger.hpp" +#include "time/time_conversion.hpp" namespace sys::cpu::stats { @@ -12,35 +14,57 @@ namespace sys::cpu::stats using namespace msgpack11; enum class PackID { - Proc, - Usage, + Usage = 1, + ProcEnd = 2, + Proc = 3, + Power = 4, }; void PackPrinter::printSysUsage(struct task_prof_data *data, size_t size) { + MsgPack procEnd = MsgPack::object({{"id",uint8_t(PackID::ProcEnd)}}); vTaskSuspendAll(); { for (size_t i = 0; i < size; ++i) { if (data[i].exec_time == 0 && data[i].switches == 0) { continue; } - MsgPack obj = MsgPack::object{{"id", uint32_t(PackID::Proc)}, - {"name", SystemManagerCommon::ServiceProcessor(i)}, - {"tcb", uint32_t(data[i].task_TCB_id)}, - {"t", data[i].exec_time}}; - LOG_PRINTF("%c%s\n", 2, obj.dump().c_str()); + MsgPack obj = MsgPack::object{ + {"name", SystemManagerCommon::ServiceProcessor(i)}, + {"tcb", uint16_t(data[i].task_TCB_id)}, + {"time", data[i].exec_time}, + {"id", uint8_t(PackID::Proc)} + }; + + LOG_PRINTF("\n%c%s\n", 2, obj.dump().c_str()); } + LOG_PRINTF("\n%c%s\n", 2, procEnd.dump().c_str()); } xTaskResumeAll(); } void PackPrinter::printCPUChange(const cpu::UpdateResult &ret) { - MsgPack obj = MsgPack::object{{"id", uint32_t(PackID::Usage)}, + MsgPack obj = MsgPack::object{{"id", uint8_t(PackID::Usage)}, {"freq", uint32_t(ret.frequencySet)}, {"name", ret.data.name}, {"reason", ret.data.reason}, - {"requested", uint32_t(ret.data.frequency)}}; - LOG_PRINTF("%c%s\n", 2, obj.dump().c_str()); + {"requested", uint32_t(ret.data.frequency)}, + {"avgA" , int32_t(bsp::battery_charger::getAvgCurrent())}, + {"nowA" , int32_t(bsp::battery_charger::getCurrentMeasurement())}, + {"ts", static_cast(utils::time::getCurrentTimestamp().getTime())} + }; + LOG_PRINTF("\n%c%s\n",2, obj.dump().c_str()); + } + + + void PackPrinter::printPowerConsumption() + { + MsgPack obj = MsgPack::object{{"id", uint8_t(PackID::Power)}, + {"avgA" , int32_t(bsp::battery_charger::getAvgCurrent())}, + {"nowA" , int32_t(bsp::battery_charger::getCurrentMeasurement())}, + {"ts", static_cast(utils::time::getCurrentTimestamp().getTime())} + }; + LOG_PRINTF("\n%c%s\n",2, obj.dump().c_str()); } } // namespace sys::cpu::stats diff --git a/module-sys/SystemManager/CpuSentinel.cpp b/module-sys/SystemManager/CpuSentinel.cpp index df74944956c4771d15c8827c6512f9c35654b56f..c49bb341ee657587025c3f30e6c7c57cbdfd1cbd 100644 --- a/module-sys/SystemManager/CpuSentinel.cpp +++ b/module-sys/SystemManager/CpuSentinel.cpp @@ -28,11 +28,12 @@ namespace sys void CpuSentinel::HoldMinimumFrequency(bsp::CpuFrequencyMHz frequencyToHold) { if (currentFrequencyToHold != frequencyToHold) { - auto msg = std::make_shared(GetName(), frequencyToHold); + auto msg = std::make_shared(GetName(), frequencyToHold, xTaskGetCurrentTaskHandle()); owner->bus.sendUnicast(std::move(msg), service::name::system_manager); currentFrequencyToHold = frequencyToHold; currentReason = std::string("up: ") + owner->getCurrentProcessing() + std::string(" req: ") + std::to_string(int(frequencyToHold)); + ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100)); } } @@ -46,37 +47,9 @@ namespace sys } } - void CpuSentinel::HoldFrequencyPermanently(bsp::CpuFrequencyMHz frequencyToHold) - { - permanentFrequencyToHold.isActive = true; - permanentFrequencyToHold.frequencyToHold = frequencyToHold; - auto msg = std::make_shared(GetName(), frequencyToHold); - owner->bus.sendUnicast(std::move(msg), service::name::system_manager); - } - [[nodiscard]] auto CpuSentinel::GetFrequency() const noexcept -> bsp::CpuFrequencyMHz { - if (permanentFrequencyToHold.isActive) { - return permanentFrequencyToHold.frequencyToHold; - } - else { return currentFrequency; - } - } - - void CpuSentinel::ReleasePermanentFrequency() - { - if (permanentFrequencyToHold.isActive) { - auto msg = std::make_shared(GetName()); - owner->bus.sendUnicast(std::move(msg), service::name::system_manager); - permanentFrequencyToHold.isActive = false; - permanentFrequencyToHold.frequencyToHold = bsp::CpuFrequencyMHz::Level_0; - } - } - - bool CpuSentinel::isPermanentFrequencyActive() - { - return permanentFrequencyToHold.isActive; } void CpuSentinel::CpuFrequencyHasChanged(bsp::CpuFrequencyMHz newFrequency) @@ -85,35 +58,11 @@ namespace sys if (callback) { callback(newFrequency); } - if (taskWaitingForFrequency != nullptr && newFrequency >= currentFrequencyToHold) { - xTaskNotifyGive(taskWaitingForFrequency); - taskWaitingForFrequency = nullptr; - } } - bool CpuSentinel::HoldMinimumFrequencyAndWait(bsp::CpuFrequencyMHz frequencyToHold, - TaskHandle_t taskToNotify, - uint32_t timeout) + void CpuSentinel::ReadRegistrationData(bsp::CpuFrequencyMHz frequencyHz) { - currentReason = std::string("h+w: ") + owner->getCurrentProcessing(); - HoldMinimumFrequency(frequencyToHold); - - if (currentFrequencyToHold < frequencyToHold) { - taskWaitingForFrequency = taskToNotify; - return ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(timeout)) == 0; - } - - return true; - } - - void CpuSentinel::ReadRegistrationData(bsp::CpuFrequencyMHz frequencyHz, bool permanentFrequency) - { - currentFrequency = frequencyHz; - permanentFrequencyToHold.isActive = permanentFrequency; - - if (permanentFrequencyToHold.isActive) { - permanentFrequencyToHold.frequencyToHold = currentFrequency; - } + currentFrequency = frequencyHz; } TimedCpuSentinel::TimedCpuSentinel(std::string name, sys::Service *service) diff --git a/module-sys/SystemManager/CpuStatistics.cpp b/module-sys/SystemManager/CpuStatistics.cpp index bdcc90a156bffd3adad65a3d3b80534fc65a628e..b24c87c596918d6d723ed241e3af9e37056b9145 100644 --- a/module-sys/SystemManager/CpuStatistics.cpp +++ b/module-sys/SystemManager/CpuStatistics.cpp @@ -22,7 +22,10 @@ namespace sys data_size = prof_pool_get_data().size; data = new task_prof_data[data_size]; #endif - printer = std::make_unique(); + // to change printer change assignment + // printer = std::make_unique(); + printer = std::make_unique(); + // printer = std::make_unique(); } CpuStatistics::~CpuStatistics() @@ -47,12 +50,13 @@ namespace sys void CpuStatistics::TrackChange(const cpu::UpdateResult &ret) { - if (ret.changed) { + if (ret.changed != sys::cpu::UpdateResult::Result::NoChange) { printer->printCPUChange(ret); #if PROF_ON printer->printSysUsage(data, data_size); #endif } + printer->printPowerConsumption(); StoreSysUsage(); } @@ -72,8 +76,9 @@ namespace sys } } - uint32_t CpuStatistics::GetPercentageCpuLoad() const noexcept + uint32_t CpuStatistics::GetPercentageCpuLoad() { + UpdatePercentageCpuLoad(); return cpuLoad; } diff --git a/module-sys/SystemManager/PowerManager.cpp b/module-sys/SystemManager/PowerManager.cpp index 488f5b28c598a0be4d76ae21751e75273676ccb3..3844a6bdf0ade0bab9e1ce0030e2a06278b1136a 100644 --- a/module-sys/SystemManager/PowerManager.cpp +++ b/module-sys/SystemManager/PowerManager.cpp @@ -1,11 +1,16 @@ // Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md +#include "SystemManager/cpu/algorithm/FrequencyHold.hpp" +#include "SystemManager/cpu/algorithm/ImmediateUpscale.hpp" +#include "SystemManager/cpu/algorithm/FrequencyStepping.hpp" +#include "cpu/AlgorithmFactory.hpp" +#include "magic_enum.hpp" +#include +#include #include #include -#include - namespace sys { namespace @@ -34,12 +39,18 @@ namespace sys totalTicksCount += ticks; } - PowerManager::PowerManager() : powerProfile{bsp::getPowerProfile()} + + PowerManager::PowerManager(CpuStatistics &stats) : powerProfile{bsp::getPowerProfile()}, cpuStatistics(stats) { + driverSEMC = drivers::DriverSEMC::Create(drivers::name::ExternalRAM); lowPowerControl = bsp::LowPowerMode::Create().value_or(nullptr); - driverSEMC = drivers::DriverSEMC::Create("ExternalRAM"); cpuGovernor = std::make_unique(); + cpuAlgorithms = std::make_unique(); + cpuAlgorithms->emplace(sys::cpu::AlgoID::ImmediateUpscale, std::make_unique()); + cpuAlgorithms->emplace(sys::cpu::AlgoID::FrequencyStepping, + std::make_unique(powerProfile, *cpuGovernor)); + cpuFrequencyMonitor.push_back(CpuFrequencyMonitor(lowestLevelName)); cpuFrequencyMonitor.push_back(CpuFrequencyMonitor(middleLevelName)); cpuFrequencyMonitor.push_back(CpuFrequencyMonitor(highestLevelName)); @@ -77,202 +88,94 @@ namespace sys } } - [[nodiscard]] cpu::UpdateResult PowerManager::UpdateCpuFrequency(uint32_t cpuLoad) + [[nodiscard]] cpu::UpdateResult PowerManager::UpdateCpuFrequency() { + uint32_t cpuLoad = cpuStatistics.GetPercentageCpuLoad(); cpu::UpdateResult result; + cpu::AlgorithmData data {cpuLoad,lowPowerControl->GetCurrentFrequencyLevel(), cpuGovernor->GetMinimumFrequencyRequested()}; - const auto currentCpuFreq = lowPowerControl->GetCurrentFrequencyLevel(); - const auto min = cpuGovernor->GetMinimumFrequencyRequested(); - const auto permanent = cpuGovernor->GetPermanentFrequencyRequested(); - - auto _ = gsl::finally([&result, this, ¤tCpuFreq, min, permanent] { + auto _ = gsl::finally([&result, this, data] { result.frequencySet = lowPowerControl->GetCurrentFrequencyLevel(); - result.changed = result.frequencySet != currentCpuFreq; - if (not permanent.isActive) { - result.data = min; - } - else { - result.data.reason = "perm"; - } + result.changed = result.frequencySet > data.curentFrequency ? sys::cpu::UpdateResult::Result::UpScaled + : result.frequencySet < data.curentFrequency ? sys::cpu::UpdateResult::Result::Downscaled + : sys::cpu::UpdateResult::Result::NoChange; + result.data = data.sentinel; }); - if (permanent.isActive) { - auto frequencyToHold = std::max(permanent.frequencyToHold, powerProfile.minimalFrequency); - - if (currentCpuFreq < frequencyToHold) { - IncreaseCpuFrequency(frequencyToHold); - } - else if (currentCpuFreq > frequencyToHold) { - do { - DecreaseCpuFrequency(); - } while (lowPowerControl->GetCurrentFrequencyLevel() > frequencyToHold); + auto algorithms = { + sys::cpu::AlgoID::FrequencyHold, sys::cpu::AlgoID::ImmediateUpscale, sys::cpu::AlgoID::FrequencyStepping}; + + for (auto id : algorithms) { + auto algo = cpuAlgorithms->get(id); + if (algo != nullptr) { + if (auto frequencyToSet = algo->calculate(data); frequencyToSet != data.curentFrequency) { + result.id = id; + SetCpuFrequency(frequencyToSet); + for (auto again : algorithms) { + if (auto al = cpuAlgorithms->get(again); al != nullptr) { + al->reset(); + } + } + return result; + } } - ResetFrequencyShiftCounter(); - return result; } - if (cpuLoad > powerProfile.frequencyShiftUpperThreshold && currentCpuFreq < bsp::CpuFrequencyMHz::Level_6) { - aboveThresholdCounter++; - belowThresholdCounter = 0; - } - else if (cpuLoad < powerProfile.frequencyShiftLowerThreshold && - currentCpuFreq > powerProfile.minimalFrequency) { - belowThresholdCounter++; - aboveThresholdCounter = 0; - } - else { - ResetFrequencyShiftCounter(); - } - - if (!belowThresholdCounter) { - isFrequencyLoweringInProgress = false; - } - - if (min.frequency > currentCpuFreq) { - ResetFrequencyShiftCounter(); - IncreaseCpuFrequency(min.frequency); - } - else if (aboveThresholdCounter >= powerProfile.maxAboveThresholdCount) { - if (powerProfile.frequencyIncreaseIntermediateStep && currentCpuFreq < bsp::CpuFrequencyMHz::Level_4) { - ResetFrequencyShiftCounter(); - IncreaseCpuFrequency(bsp::CpuFrequencyMHz::Level_4); - } - else { - ResetFrequencyShiftCounter(); - IncreaseCpuFrequency(bsp::CpuFrequencyMHz::Level_6); - } - } - else { - if (belowThresholdCounter >= (isFrequencyLoweringInProgress ? powerProfile.maxBelowThresholdInRowCount - : powerProfile.maxBelowThresholdCount) && - currentCpuFreq > min.frequency) { - ResetFrequencyShiftCounter(); - DecreaseCpuFrequency(); - } - } return result; } - void PowerManager::IncreaseCpuFrequency(bsp::CpuFrequencyMHz newFrequency) + void PowerManager::RegisterNewSentinel(std::shared_ptr newSentinel) const { - const auto freq = lowPowerControl->GetCurrentFrequencyLevel(); - - if ((freq <= bsp::CpuFrequencyMHz::Level_1) && (newFrequency > bsp::CpuFrequencyMHz::Level_1)) { - // connect internal the load resistor - lowPowerControl->ConnectInternalLoadResistor(); - // turn off power save mode for DCDC inverter - lowPowerControl->DisableDcdcPowerSaveMode(); - // Switch DCDC to full throttle during oscillator switch - lowPowerControl->SetHighestCoreVoltage(); - // Enable regular 2P5 and 1P1 LDO and Turn off weak 2P5 and 1P1 LDO - lowPowerControl->SwitchToRegularModeLDO(); - // switch oscillator source - lowPowerControl->SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::External); - // then switch external RAM clock source - if (driverSEMC) { - driverSEMC->SwitchToPLL2ClockSource(); - } - // Add intermediate step in frequency - if (newFrequency > bsp::CpuFrequencyMHz::Level_4) - SetCpuFrequency(bsp::CpuFrequencyMHz::Level_4); - } - - // and increase frequency - if (freq < newFrequency) { - SetCpuFrequency(newFrequency); + if (cpuGovernor->RegisterNewSentinel(newSentinel)) { + newSentinel->ReadRegistrationData(lowPowerControl->GetCurrentFrequencyLevel()); } } - void PowerManager::DecreaseCpuFrequency() + void PowerManager::RemoveSentinel(std::string sentinelName) const { - const auto freq = lowPowerControl->GetCurrentFrequencyLevel(); - auto level = powerProfile.minimalFrequency; - - switch (freq) { - case bsp::CpuFrequencyMHz::Level_6: - level = bsp::CpuFrequencyMHz::Level_5; - break; - case bsp::CpuFrequencyMHz::Level_5: - level = bsp::CpuFrequencyMHz::Level_4; - break; - case bsp::CpuFrequencyMHz::Level_4: - level = bsp::CpuFrequencyMHz::Level_3; - break; - case bsp::CpuFrequencyMHz::Level_3: - level = bsp::CpuFrequencyMHz::Level_2; - break; - case bsp::CpuFrequencyMHz::Level_2: - level = powerProfile.minimalFrequency; - break; - case bsp::CpuFrequencyMHz::Level_1: - [[fallthrough]]; - case bsp::CpuFrequencyMHz::Level_0: - break; - } - - // decrease frequency first - if (level != freq) { - SetCpuFrequency(level); - } - - if (level <= bsp::CpuFrequencyMHz::Level_1) { - // Enable weak 2P5 and 1P1 LDO and Turn off regular 2P5 and 1P1 LDO - lowPowerControl->SwitchToLowPowerModeLDO(); - - // then switch osc source - lowPowerControl->SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::Internal); - - // and switch external RAM clock source - if (driverSEMC) { - driverSEMC->SwitchToPeripheralClockSource(); - } - - // turn on power save mode for DCDC inverter - lowPowerControl->EnableDcdcPowerSaveMode(); - - // disconnect internal the load resistor - lowPowerControl->DisconnectInternalLoadResistor(); - } - - isFrequencyLoweringInProgress = true; + cpuGovernor->RemoveSentinel(sentinelName); } - void PowerManager::RegisterNewSentinel(std::shared_ptr newSentinel) const + void PowerManager::SetCpuFrequencyRequest(const std::string &sentinelName, bsp::CpuFrequencyMHz request) { - if (cpuGovernor->RegisterNewSentinel(newSentinel)) { - newSentinel->ReadRegistrationData(lowPowerControl->GetCurrentFrequencyLevel(), - cpuGovernor->GetPermanentFrequencyRequested().isActive); - } + cpuGovernor->SetCpuFrequencyRequest(sentinelName, request); + // TODO: + // - move other UpdateCpuFrequency usages too + // - if it's ok to trigger algorithms on leave? + auto ret = UpdateCpuFrequency(); + cpuStatistics.TrackChange(ret); } - void PowerManager::RemoveSentinel(std::string sentinelName) const + void PowerManager::ResetCpuFrequencyRequest(const std::string &sentinelName) { - cpuGovernor->RemoveSentinel(sentinelName); + cpuGovernor->ResetCpuFrequencyRequest(sentinelName); + // TODO - same as above + auto ret = UpdateCpuFrequency(); + cpuStatistics.TrackChange(ret); } - void PowerManager::SetCpuFrequencyRequest(std::string sentinelName, - bsp::CpuFrequencyMHz request, - bool permanentBlock) + bool PowerManager::IsCpuPernamentFrequency() { - cpuGovernor->SetCpuFrequencyRequest(std::move(sentinelName), request, permanentBlock); + return cpuAlgorithms->get(sys::cpu::AlgoID::FrequencyHold) != nullptr; } - void PowerManager::ResetCpuFrequencyRequest(std::string sentinelName, bool permanentBlock) + void PowerManager::SetPernamentFrequency(bsp::CpuFrequencyMHz freq) { - cpuGovernor->ResetCpuFrequencyRequest(std::move(sentinelName), permanentBlock); + cpuAlgorithms->emplace(sys::cpu::AlgoID::FrequencyHold, std::make_unique(freq,powerProfile)); } - void PowerManager::SetCpuFrequency(bsp::CpuFrequencyMHz freq) + void PowerManager::ResetPernamentFrequency() { - UpdateCpuFrequencyMonitor(lowPowerControl->GetCurrentFrequencyLevel()); - lowPowerControl->SetCpuFrequency(freq); - cpuGovernor->InformSentinelsAboutCpuFrequencyChange(freq); + cpuAlgorithms->remove(sys::cpu::AlgoID::FrequencyHold); } - void PowerManager::ResetFrequencyShiftCounter() + void PowerManager::SetCpuFrequency(bsp::CpuFrequencyMHz freq) { - aboveThresholdCounter = 0; - belowThresholdCounter = 0; + UpdateCpuFrequencyMonitor(lowPowerControl->GetCurrentFrequencyLevel()); + while ( lowPowerControl->GetCurrentFrequencyLevel() != freq ) { + lowPowerControl->SetCpuFrequency(freq); + cpuGovernor->InformSentinelsAboutCpuFrequencyChange(freq); + } } [[nodiscard]] auto PowerManager::getExternalRamDevice() const noexcept -> std::shared_ptr diff --git a/module-sys/SystemManager/SystemManagerCommon.cpp b/module-sys/SystemManager/SystemManagerCommon.cpp index 06cbac1fb7c691c8c325789e25bf19d7a0d37708..ac6301cd01dee2f28356fa51b9813e0b3494ae7d 100644 --- a/module-sys/SystemManager/SystemManagerCommon.cpp +++ b/module-sys/SystemManager/SystemManagerCommon.cpp @@ -84,7 +84,7 @@ namespace sys } SystemManagerCommon::SystemManagerCommon(std::vector> &&creators) - : Service(service::name::system_manager, "", systemManagerStack), systemServiceCreators{std::move(creators)} + : Service(service::name::system_manager, "", systemManagerStack, ServicePriority::Low), systemServiceCreators{std::move(creators)} { // Specify list of channels which System Manager is registered to bus.channels = {BusChannel::SystemManagerRequests}; @@ -192,6 +192,7 @@ namespace sys // Power off request (pending) PowerOff(); + // TODO these were globals = never cleared, is it needed now? powerManager.reset(); cpuStatistics.reset(); deviceManager.reset(); @@ -241,8 +242,8 @@ namespace sys void SystemManagerCommon::StartSystem(InitFunction sysInit, InitFunction appSpaceInit, DeinitFunction sysDeinit) { - powerManager = std::make_unique(); cpuStatistics = std::make_unique(); + powerManager = std::make_unique(*cpuStatistics); deviceManager = std::make_unique(); systemInit = std::move(sysInit); @@ -256,7 +257,7 @@ namespace sys freqTimer.start(); powerManagerEfficiencyTimer = sys::TimerFactory::createPeriodicTimer( - this, "logPowerManagerEfficiency", constants::powerManagerLogsTimerInterval, [](sys::Timer &) { + this, "logPowerManagerEfficiency", constants::powerManagerLogsTimerInterval, [this](sys::Timer &) { powerManager->LogPowerManagerEfficiency(); }); powerManagerEfficiencyTimer.start(); @@ -633,7 +634,9 @@ namespace sys connect(typeid(sys::HoldCpuFrequencyMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); powerManager->SetCpuFrequencyRequest(msg->getName(), msg->getRequest()); - + if ( msg->getHandle() != nullptr ) { + xTaskNotifyGive(msg->getHandle()); + } return sys::MessageNone{}; }); @@ -644,17 +647,19 @@ namespace sys return sys::MessageNone{}; }); + connect(typeid(sys::IsCpuPernament), [this](sys::Message *message) -> sys::MessagePointer { + return std::make_shared(powerManager->IsCpuPernamentFrequency()); + }); + connect(typeid(sys::HoldCpuFrequencyPermanentlyMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); - powerManager->SetCpuFrequencyRequest(msg->getName(), msg->getRequest(), true); - - return sys::MessageNone{}; + powerManager->SetPernamentFrequency(msg->request); + return std::make_shared(); }); connect(typeid(sys::ReleaseCpuPermanentFrequencyMessage), [this](sys::Message *message) -> sys::MessagePointer { - auto msg = static_cast(message); - powerManager->ResetCpuFrequencyRequest(msg->getName(), true); - return sys::MessageNone{}; + powerManager->ResetPernamentFrequency(); + return std::make_shared(); }); connect(typeid(app::manager::CheckIfStartAllowedMessage), [this](sys::Message *) -> sys::MessagePointer { @@ -685,7 +690,8 @@ namespace sys deviceManager->RegisterNewDevice(powerManager->getExternalRamDevice()); cpuSentinel = std::make_shared( - service::name::system_manager, this, [this](bsp::CpuFrequencyMHz newFrequency) { + service::name::system_manager + , this, [this](bsp::CpuFrequencyMHz newFrequency) { UpdateResourcesAfterCpuFrequencyChange(newFrequency); }); powerManager->RegisterNewSentinel(cpuSentinel); @@ -781,8 +787,7 @@ namespace sys freqTimer.restart(constants::timerPeriodInterval); } - cpuStatistics->UpdatePercentageCpuLoad(); - auto ret = powerManager->UpdateCpuFrequency(cpuStatistics->GetPercentageCpuLoad()); + auto ret = powerManager->UpdateCpuFrequency(); cpuStatistics->TrackChange(ret); } @@ -800,8 +805,4 @@ namespace sys std::vector> SystemManagerCommon::applicationsList; cpp_freertos::MutexStandard SystemManagerCommon::serviceDestroyMutex; cpp_freertos::MutexStandard SystemManagerCommon::appDestroyMutex; - std::unique_ptr SystemManagerCommon::powerManager; - std::unique_ptr SystemManagerCommon::cpuStatistics; - std::unique_ptr SystemManagerCommon::deviceManager; - } // namespace sys diff --git a/module-sys/SystemManager/cpu/AlgorithmFactory.cpp b/module-sys/SystemManager/cpu/AlgorithmFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..300c4d4aa67c057e44e45f78d2597f0df3823a3b --- /dev/null +++ b/module-sys/SystemManager/cpu/AlgorithmFactory.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "AlgorithmFactory.hpp" +#include "SystemManager/cpu/algorithm/FrequencyHold.hpp" +#include + +namespace sys::cpu { + + AlgorithmFactory::PutResult AlgorithmFactory::emplace(sys::cpu::AlgoID id, std::unique_ptr&&algorithm) + { + if ( algorithms.find(id) != std::end(algorithms)) { + algorithms[id] = std::move(algorithm); + return PutResult::Replaced; + } + algorithms.emplace(id, std::move(algorithm)); + return PutResult::Added; + } + + + Algorithm* AlgorithmFactory::get(sys::cpu::AlgoID id) + { + if ( auto el = algorithms.find(id); el != std::end(algorithms)) { + return el->second.get(); + } + return nullptr; + } + + void AlgorithmFactory::remove(sys::cpu::AlgoID id) + { + algorithms.erase(id); + } +} // namespace sys::cpu diff --git a/module-sys/SystemManager/cpu/AlgorithmFactory.hpp b/module-sys/SystemManager/cpu/AlgorithmFactory.hpp new file mode 100644 index 0000000000000000000000000000000000000000..35e416c81c40e87bd63aa57fc9754f4fe1c31865 --- /dev/null +++ b/module-sys/SystemManager/cpu/AlgorithmFactory.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "algorithm/Algorithm.hpp" +#include +#include + + +namespace sys::cpu { + + class AlgorithmFactory + { + std::map> algorithms; + + public: + Algorithm* get(sys::cpu::AlgoID); + enum class PutResult { + Added, + Replaced, + }; + PutResult emplace(sys::cpu::AlgoID id, std::unique_ptr&&algorithm); + void remove(sys::cpu::AlgoID id); + }; +}; diff --git a/module-sys/SystemManager/cpu/algorithm/Algorithm.cpp b/module-sys/SystemManager/cpu/algorithm/Algorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83a5e5d5dce43a0b32bc318200d719265279ee78 --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/Algorithm.cpp @@ -0,0 +1,17 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "Algorithm.hpp" + +namespace sys::cpu +{ + bsp::CpuFrequencyMHz Algorithm::calculate(const AlgorithmData &data) + { + return calculateImplementation(data); + } + + void Algorithm::reset() + { + resetImplementation(); + } +} // namespace sys::cpu diff --git a/module-sys/SystemManager/cpu/algorithm/Algorithm.hpp b/module-sys/SystemManager/cpu/algorithm/Algorithm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f080223fc7f007c7ce69f21972e17be57210fcc2 --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/Algorithm.hpp @@ -0,0 +1,32 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "AlgorithmID.hpp" +#include "SystemManager/SentinelView.hpp" +#include "common.hpp" + +namespace sys::cpu +{ + struct AlgorithmData + { + unsigned int CPUload = 0; + bsp::CpuFrequencyMHz curentFrequency = bsp::CpuFrequencyMHz::Level_6; + sentinel::View sentinel; + }; + + class Algorithm + { + private: + [[nodiscard]] virtual bsp::CpuFrequencyMHz calculateImplementation(const AlgorithmData &) = 0; + virtual void resetImplementation() + {} + + public: + [[nodiscard]] virtual bsp::CpuFrequencyMHz calculate(const AlgorithmData &) final; + virtual void reset() final; + + virtual ~Algorithm() = default; + }; +} // namespace sys::cpu diff --git a/module-sys/SystemManager/cpu/algorithm/AlgorithmID.hpp b/module-sys/SystemManager/cpu/algorithm/AlgorithmID.hpp new file mode 100644 index 0000000000000000000000000000000000000000..43c545a42569065c5d2daef85c5f4052bbf6d68c --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/AlgorithmID.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +namespace sys::cpu +{ + enum class AlgoID + { + None, + FrequencyHold, + ImmediateUpscale, + FrequencyStepping, + }; +} diff --git a/module-sys/SystemManager/cpu/algorithm/FrequencyHold.cpp b/module-sys/SystemManager/cpu/algorithm/FrequencyHold.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b0950dc95cebde55075eb776dccea9177d1caac --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/FrequencyHold.cpp @@ -0,0 +1,17 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "FrequencyHold.hpp" +#include + +namespace sys::cpu +{ + FrequencyHold::FrequencyHold(bsp::CpuFrequencyMHz toHold, const bsp::PowerProfile &profile) + : toHold(toHold), profile(profile) + {} + + bsp::CpuFrequencyMHz FrequencyHold::calculateImplementation(const AlgorithmData&data) + { + return std::max(toHold, profile.minimalFrequency); + } +}; diff --git a/module-sys/SystemManager/cpu/algorithm/FrequencyHold.hpp b/module-sys/SystemManager/cpu/algorithm/FrequencyHold.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d734a8df40af2755f649afe2acbe760a78bc331c --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/FrequencyHold.hpp @@ -0,0 +1,18 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "Algorithm.hpp" +#include "lpm/PowerProfile.hpp" + +namespace sys::cpu +{ + class FrequencyHold : public Algorithm { + bsp::CpuFrequencyMHz toHold; + const bsp::PowerProfile &profile; + [[nodiscard]] bsp::CpuFrequencyMHz calculateImplementation(const AlgorithmData& data) override; + public: + explicit FrequencyHold(bsp::CpuFrequencyMHz toHold, const bsp::PowerProfile &profile); + }; +} diff --git a/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp b/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb84d9437cd19907f3e8b3586a29a67a76976568 --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp @@ -0,0 +1,86 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "FrequencyStepping.hpp" +#include "SystemManager/CpuGovernor.hpp" + +namespace sys::cpu +{ + + FrequencyStepping::FrequencyStepping(const bsp::PowerProfile &powerProfile, CpuGovernor &cpuGovernor) + : powerProfile(powerProfile), cpuGovernor(cpuGovernor) + {} + + bsp::CpuFrequencyMHz stepDown(bsp::CpuFrequencyMHz freq, const bsp::PowerProfile &profile) + { + switch (freq) { + case bsp::CpuFrequencyMHz::Level_6: + return bsp::CpuFrequencyMHz::Level_5; + case bsp::CpuFrequencyMHz::Level_5: + return bsp::CpuFrequencyMHz::Level_4; + case bsp::CpuFrequencyMHz::Level_4: + return bsp::CpuFrequencyMHz::Level_3; + case bsp::CpuFrequencyMHz::Level_3: + return bsp::CpuFrequencyMHz::Level_2; + case bsp::CpuFrequencyMHz::Level_2: + [[fallthrough]]; + case bsp::CpuFrequencyMHz::Level_1: + [[fallthrough]]; + case bsp::CpuFrequencyMHz::Level_0: + return profile.minimalFrequency; + } + return freq; + } + + bsp::CpuFrequencyMHz FrequencyStepping::calculateImplementation(const AlgorithmData&data) + { + auto load = data.CPUload; + auto startFrequency = data.curentFrequency; + const auto min = cpuGovernor.GetMinimumFrequencyRequested(); + + if (load > powerProfile.frequencyShiftUpperThreshold && startFrequency < bsp::CpuFrequencyMHz::Level_6) { + aboveThresholdCounter++; + belowThresholdCounter = 0; + } + else if (load < powerProfile.frequencyShiftLowerThreshold && + startFrequency > powerProfile.minimalFrequency) { + belowThresholdCounter++; + aboveThresholdCounter = 0; + } + else { + reset(); + } + + if (belowThresholdCounter == 0u) { + isFrequencyLoweringInProgress = false; + } + + if (min.frequency > startFrequency) {} + else if (aboveThresholdCounter >= powerProfile.maxAboveThresholdCount) { + if (startFrequency < bsp::CpuFrequencyMHz::Level_4) { + reset(); + return bsp::CpuFrequencyMHz::Level_4; + } + else { + reset(); + return bsp::CpuFrequencyMHz::Level_6; + } + } + else { + if (belowThresholdCounter >= (isFrequencyLoweringInProgress ? powerProfile.maxBelowThresholdInRowCount + : powerProfile.maxBelowThresholdCount) && + startFrequency > min.frequency) { + reset(); + return stepDown(startFrequency, powerProfile); + } + } + + return startFrequency; + } + + void FrequencyStepping::resetImplementation() + { + aboveThresholdCounter = 0; + belowThresholdCounter = 0; + } +} diff --git a/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.hpp b/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.hpp new file mode 100644 index 0000000000000000000000000000000000000000..373b3b9368db76d250318848cda3cd5cbe5db5ca --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "Algorithm.hpp" +#include "lpm/PowerProfile.hpp" + +namespace sys { + class CpuGovernor; +} + +namespace sys::cpu +{ + class FrequencyStepping : public Algorithm { + const bsp::PowerProfile &powerProfile; + CpuGovernor &cpuGovernor; + unsigned int aboveThresholdCounter = 0; + unsigned int belowThresholdCounter = 0; + bool isFrequencyLoweringInProgress = true; + public: + FrequencyStepping(const bsp::PowerProfile&powerProfile, CpuGovernor &cpuGovernor); + [[nodiscard]] bsp::CpuFrequencyMHz calculateImplementation(const AlgorithmData&data) override; + void resetImplementation() override; + }; +} diff --git a/module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.cpp b/module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ee43163a77680e97e61e771e4e6aa8f97c10d39 --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "ImmediateUpscale.hpp" + +namespace sys::cpu +{ + bsp::CpuFrequencyMHz ImmediateUpscale::calculateImplementation(const AlgorithmData&data) + { + auto now = data.sentinel.frequency; + auto was = data.curentFrequency; + return std::max(now,was); + } +} // namespace sys::cpu diff --git a/module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.hpp b/module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9524517103304ca89017b44526d96ff5ff41e53c --- /dev/null +++ b/module-sys/SystemManager/cpu/algorithm/ImmediateUpscale.hpp @@ -0,0 +1,17 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "Algorithm.hpp" +#include "lpm/PowerProfile.hpp" +#include +#include + +namespace sys::cpu +{ + class ImmediateUpscale : public Algorithm { + public: + bsp::CpuFrequencyMHz calculateImplementation(const AlgorithmData&data) override; + }; +} diff --git a/module-sys/SystemManager/include/SystemManager/CpuGovernor.hpp b/module-sys/SystemManager/include/SystemManager/CpuGovernor.hpp index bbc75defb46bf0fc3d03aaf0b43347715a385d94..5660487d37be409530b0fd208cf2fe7ee122766e 100644 --- a/module-sys/SystemManager/include/SystemManager/CpuGovernor.hpp +++ b/module-sys/SystemManager/include/SystemManager/CpuGovernor.hpp @@ -6,26 +6,11 @@ #include #include #include "SystemManager/CpuSentinel.hpp" +#include "SentinelView.hpp" namespace sys { - namespace sentinel - { - struct Data - { - UBaseType_t ownerTCBNumber = 0; - /// name of sentinel thread responsible for curent minimum load - std::string name; - /// curent minimum frequency set in sentinel - bsp::CpuFrequencyMHz frequency = bsp::CpuFrequencyMHz::Level_0; - /// please do not use this task handle to perform actions, it's just for reference sake - TaskHandle_t task; - /// textual information on what actually happens - std::string reason; - }; - }; // namespace sentinel - using SentinelPointer = std::weak_ptr; class GovernorSentinel @@ -55,22 +40,19 @@ namespace sys [[nodiscard]] auto GetNumberOfRegisteredSentinels() const noexcept -> uint32_t; void PrintAllSentinels() const noexcept; - void SetCpuFrequencyRequest(std::string sentinelName, - bsp::CpuFrequencyMHz request, - bool permanentBlock = false); - void ResetCpuFrequencyRequest(std::string sentinelName, bool permanentBlock = false); + void SetCpuFrequencyRequest(const std::string& sentinelName, + bsp::CpuFrequencyMHz request + ); + void ResetCpuFrequencyRequest(const std::string& sentinelName); - [[nodiscard]] auto GetMinimumFrequencyRequested() const noexcept -> sentinel::Data; + [[nodiscard]] auto GetMinimumFrequencyRequested() const noexcept -> sentinel::View; void InformSentinelsAboutCpuFrequencyChange(bsp::CpuFrequencyMHz newFrequency) const noexcept; - [[nodiscard]] auto GetPermanentFrequencyRequested() const noexcept -> PermanentFrequencyToHold; - private: static void PrintName(const GovernorSentinelPointer &element); /// this could be set - set is sorted :) GovernorSentinelsVector sentinels; - PermanentFrequencyToHold permanentFrequencyToHold{false, bsp::CpuFrequencyMHz::Level_0}; }; } // namespace sys diff --git a/module-sys/SystemManager/include/SystemManager/CpuPrinter.hpp b/module-sys/SystemManager/include/SystemManager/CpuPrinter.hpp index dedfffe1a4d81b14c23e93065d62d31b084e5c1e..de46b3db0176c932b567d3c4b8e758179703960c 100644 --- a/module-sys/SystemManager/include/SystemManager/CpuPrinter.hpp +++ b/module-sys/SystemManager/include/SystemManager/CpuPrinter.hpp @@ -17,6 +17,7 @@ namespace sys::cpu public: virtual void printSysUsage(struct task_prof_data *data, size_t size) = 0; virtual void printCPUChange(const cpu::UpdateResult &ret) = 0; + virtual void printPowerConsumption() = 0; }; class NullPrinter : public Printer @@ -25,6 +26,7 @@ namespace sys::cpu {} void printCPUChange(const cpu::UpdateResult &ret) {} + void printPowerConsumption() {} }; class LogPrinter : public Printer @@ -32,6 +34,7 @@ namespace sys::cpu public: void printSysUsage(struct task_prof_data *data, size_t size) override; void printCPUChange(const cpu::UpdateResult &ret) override; + void printPowerConsumption() override; }; class PackPrinter : public Printer @@ -39,6 +42,7 @@ namespace sys::cpu public: void printSysUsage(struct task_prof_data *data, size_t size) override; void printCPUChange(const cpu::UpdateResult &ret) override; + void printPowerConsumption() override; }; }; // namespace stats }; // namespace sys::cpu diff --git a/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp b/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp index 1e436c005773e325b708bd0c2f2cd231ddc3b629..e2b98cfadcf44dfaf790d9388a086df675e7989b 100644 --- a/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp +++ b/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp @@ -13,12 +13,6 @@ namespace sys { - struct PermanentFrequencyToHold - { - bool isActive; - bsp::CpuFrequencyMHz frequencyToHold; - }; - /// Each sentinel manages the requests, i.e. when it is needed it sends messages to CpuGovernor with the required /// minimum CPU frequency to perform the task (e.g. screen redraw). Furthermore, every sentinel is informed /// immediately after changing the frequency. This allows it to invoke a callback to the service to update their @@ -30,29 +24,24 @@ namespace sys explicit CpuSentinel(std::string name, sys::Service *service, std::function callback = nullptr); - ~CpuSentinel() = default; [[nodiscard]] auto GetName() const noexcept -> std::string; void HoldMinimumFrequency(bsp::CpuFrequencyMHz frequencyToHold); - bool HoldMinimumFrequencyAndWait(bsp::CpuFrequencyMHz frequencyToHold, - TaskHandle_t taskToNotify, - uint32_t timeout); void ReleaseMinimumFrequency(); + // TODO actually sentinel provides api here so i.e. in case of irq is useless void HoldFrequencyPermanently(bsp::CpuFrequencyMHz frequencyToHold); [[nodiscard]] auto GetFrequency() const noexcept -> bsp::CpuFrequencyMHz; - void ReleasePermanentFrequency(); - [[nodiscard]] bool isPermanentFrequencyActive(); void CpuFrequencyHasChanged(bsp::CpuFrequencyMHz newFrequency); - void ReadRegistrationData(bsp::CpuFrequencyMHz frequencyHz, bool permanentFrequency); + + void ReadRegistrationData(bsp::CpuFrequencyMHz frequencyHz); TaskHandle_t getTask(); std::string getReason(); protected: const std::string name; bsp::CpuFrequencyMHz currentFrequencyToHold{bsp::CpuFrequencyMHz::Level_0}; - PermanentFrequencyToHold permanentFrequencyToHold{false, bsp::CpuFrequencyMHz::Level_0}; std::atomic currentFrequency{bsp::CpuFrequencyMHz::Level_0}; sys::Service *owner{nullptr}; @@ -61,7 +50,6 @@ namespace sys /// critical section or mutex support necessary std::function callback; - TaskHandle_t taskWaitingForFrequency = nullptr; std::string currentReason; }; diff --git a/module-sys/SystemManager/include/SystemManager/CpuStatistics.hpp b/module-sys/SystemManager/include/SystemManager/CpuStatistics.hpp index 0babb6343fbd3cf312d226114b9b168b9f4761dd..e4845e3c3e0ba17dcf39e7672455ea760d598cc7 100644 --- a/module-sys/SystemManager/include/SystemManager/CpuStatistics.hpp +++ b/module-sys/SystemManager/include/SystemManager/CpuStatistics.hpp @@ -24,11 +24,11 @@ namespace sys /// stores system usage, should be called before any CPU frequency change /// this way we know what services were in use and for how long before it happened void StoreSysUsage(); - [[nodiscard]] uint32_t GetPercentageCpuLoad() const noexcept; - void UpdatePercentageCpuLoad(); + [[nodiscard]] uint32_t GetPercentageCpuLoad(); void TrackChange(const cpu::UpdateResult &ret); private: + void UpdatePercentageCpuLoad(); /// used to print stored data in CpuStatistics on change std::unique_ptr printer; uint32_t ComputeIncrease(uint32_t currentCount, uint32_t lastCount) const; diff --git a/module-sys/SystemManager/include/SystemManager/PowerManager.hpp b/module-sys/SystemManager/include/SystemManager/PowerManager.hpp index c57a062cab42d51ea136bad1dff16986c87b34a6..ad699d1c97f43e16ee9e10233f53c9192ee2f591 100644 --- a/module-sys/SystemManager/include/SystemManager/PowerManager.hpp +++ b/module-sys/SystemManager/include/SystemManager/PowerManager.hpp @@ -13,8 +13,15 @@ #include #include +namespace sys::cpu +{ + class AlgorithmFactory; +} + namespace sys { + class CpuStatistics; + class CpuFrequencyMonitor { public: @@ -31,9 +38,8 @@ namespace sys class PowerManager { - public: - PowerManager(); + explicit PowerManager(CpuStatistics& stats); ~PowerManager(); int32_t PowerOff(); @@ -47,44 +53,38 @@ namespace sys /// limit (frequencyShiftUpperThreshold), CPU frequency is increased; if for the last 'maxBelowThresholdCount' /// periods the current CPU usage was below the lower limit (frequencyShiftLowerThreshold), CPU frequency is /// reduced frequency - /// @param current cpu load - [[nodiscard]] cpu::UpdateResult UpdateCpuFrequency(uint32_t cpuLoad); + [[nodiscard]] cpu::UpdateResult UpdateCpuFrequency(); [[nodiscard]] auto getExternalRamDevice() const noexcept -> std::shared_ptr; void RegisterNewSentinel(std::shared_ptr newSentinel) const; void RemoveSentinel(std::string sentinelName) const; - void SetCpuFrequencyRequest(std::string sentinelName, - bsp::CpuFrequencyMHz request, - bool permanentBlock = false); - void ResetCpuFrequencyRequest(std::string sentinelName, bool permanentBlock = false); + void SetCpuFrequencyRequest(const std::string &sentinelName, bsp::CpuFrequencyMHz request); + void ResetCpuFrequencyRequest(const std::string &sentinelName); + bool IsCpuPernamentFrequency(); + void SetPernamentFrequency(bsp::CpuFrequencyMHz freq); + void ResetPernamentFrequency(); + void LogPowerManagerEfficiency(); void SetBootSuccess(); private: - /// called when the CPU frequency needs to be increased - void IncreaseCpuFrequency(bsp::CpuFrequencyMHz newFrequency); - - /// called when the CPU frequency needs to be reduced - /// @note the frequency is always reduced by one step - void DecreaseCpuFrequency(); - void ResetFrequencyShiftCounter(); void SetCpuFrequency(bsp::CpuFrequencyMHz freq); void UpdateCpuFrequencyMonitor(bsp::CpuFrequencyMHz currentFreq); - uint32_t belowThresholdCounter{0}; - uint32_t aboveThresholdCounter{0}; TickType_t lastCpuFrequencyChangeTimestamp{0}; - bool isFrequencyLoweringInProgress{false}; std::vector cpuFrequencyMonitor; - std::unique_ptr lowPowerControl; std::shared_ptr driverSEMC; + std::unique_ptr lowPowerControl; std::unique_ptr cpuGovernor; const bsp::PowerProfile powerProfile; + + std::unique_ptr cpuAlgorithms; + CpuStatistics& cpuStatistics; }; } // namespace sys diff --git a/module-sys/SystemManager/include/SystemManager/SentinelView.hpp b/module-sys/SystemManager/include/SystemManager/SentinelView.hpp new file mode 100644 index 0000000000000000000000000000000000000000..80d8f6038170e23a2ff0af966260ab81b6a77e99 --- /dev/null +++ b/module-sys/SystemManager/include/SystemManager/SentinelView.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "common.hpp" +#include "FreeRTOS.h" +#include "portmacro.h" +#include + +namespace sys +{ + + namespace sentinel + { + struct View + { + UBaseType_t ownerTCBNumber = 0; + /// name of sentinel thread responsible for curent minimum load + std::string name; + /// curent minimum frequency set in sentinel + bsp::CpuFrequencyMHz frequency = bsp::CpuFrequencyMHz::Level_0; + /// textual information on what actually happens + std::string reason; + }; + }; // namespace sentinel +} + diff --git a/module-sys/SystemManager/include/SystemManager/SysCpuUpdateResult.hpp b/module-sys/SystemManager/include/SystemManager/SysCpuUpdateResult.hpp index 53f8f28badf26a1f469fbcbdb60e00052bc94a11..f52bbb592f534c750e0f73e4d73be73071a35f19 100644 --- a/module-sys/SystemManager/include/SystemManager/SysCpuUpdateResult.hpp +++ b/module-sys/SystemManager/include/SystemManager/SysCpuUpdateResult.hpp @@ -3,13 +3,21 @@ #pragma once -#include "SystemManager/CpuGovernor.hpp" +#include "SystemManager/cpu/algorithm/AlgorithmID.hpp" +#include "SystemManager/SentinelView.hpp" + namespace sys::cpu { struct UpdateResult { - bool changed = false; + enum class Result { + UpScaled, /// frequency risen + Downscaled, /// frequency downscaled + NoChange /// nothing to do + }; + Result changed = Result::NoChange; bsp::CpuFrequencyMHz frequencySet = bsp::CpuFrequencyMHz::Level_0; - sentinel::Data data{}; + sentinel::View data{}; + AlgoID id = AlgoID::None; }; }; // namespace sys::cpu diff --git a/module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp b/module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp index 5bba97aee1501789573abf56a5d64313c7fbe502..ef5850b72e272e3c53b078263dc17760da5b9bbd 100644 --- a/module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp +++ b/module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp @@ -211,9 +211,9 @@ namespace sys static std::vector> applicationsList; static cpp_freertos::MutexStandard serviceDestroyMutex; static cpp_freertos::MutexStandard appDestroyMutex; - static std::unique_ptr powerManager; - static std::unique_ptr cpuStatistics; - static std::unique_ptr deviceManager; + std::unique_ptr cpuStatistics; + std::unique_ptr powerManager; + std::unique_ptr deviceManager; }; } // namespace sys diff --git a/module-sys/common/include/system/SystemReturnCodes.hpp b/module-sys/common/include/system/SystemReturnCodes.hpp index 7a93ab6d64b616d92c9afc737a1028e17a043787..ef97f5610cd03da2ff34de6789a1bde8408b9b6b 100644 --- a/module-sys/common/include/system/SystemReturnCodes.hpp +++ b/module-sys/common/include/system/SystemReturnCodes.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -11,9 +11,9 @@ namespace sys Failure, Timeout, ServiceDoesntExist, - // This is used in application's template in base class messages handler. The meaning is that - // message that was processed by base class implementation of the DataReceivedHandler was not processed - // and it should be handled by the class next in hierarchy. + /// This is used in application's template in base class messages handler. The meaning is that + /// message that was processed by base class implementation of the DataReceivedHandler was not processed + /// and it should be handled by the class next in hierarchy. Unresolved }; } diff --git a/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp b/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp index 1902eb116550eb326ffd3f84abfeca6ac5af0a06..1358c4d761ef126782594f466ea65370c984f5e2 100644 --- a/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp +++ b/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp @@ -1,20 +1,23 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once +#include "FreeRTOS.h" +#include "task.h" #include #include namespace sys { + /// TODO move data to struct... class HoldCpuFrequencyMessage : public sys::DataMessage { public: - HoldCpuFrequencyMessage(std::string sentinelName, bsp::CpuFrequencyMHz request) + HoldCpuFrequencyMessage(std::string sentinelName, bsp::CpuFrequencyMHz request, TaskHandle_t handle) : sys::DataMessage(MessageType::SystemManagerCpuFrequency), sentinelName(std::move(sentinelName)), - frequencyRequested(request) + frequencyRequested(request), handle(handle) {} [[nodiscard]] auto getRequest() const noexcept @@ -27,9 +30,15 @@ namespace sys return sentinelName; }; + [[nodiscard]] TaskHandle_t getHandle() const + { + return handle; + } + private: std::string sentinelName; bsp::CpuFrequencyMHz frequencyRequested = bsp::CpuFrequencyMHz::Level_0; + TaskHandle_t handle; }; class ReleaseCpuFrequencyMessage : public sys::DataMessage @@ -48,19 +57,36 @@ namespace sys std::string sentinelName; }; - class HoldCpuFrequencyPermanentlyMessage : public HoldCpuFrequencyMessage + struct IsCpuPernament : public sys::DataMessage { public: - HoldCpuFrequencyPermanentlyMessage(std::string sentinelName, bsp::CpuFrequencyMHz request) - : HoldCpuFrequencyMessage(sentinelName, request) + explicit IsCpuPernament() {} }; - class ReleaseCpuPermanentFrequencyMessage : public ReleaseCpuFrequencyMessage + struct IsCpuPernamentResponse : public sys::ResponseMessage { public: - ReleaseCpuPermanentFrequencyMessage(std::string sentinelName) : ReleaseCpuFrequencyMessage(sentinelName) + explicit IsCpuPernamentResponse(bool pernament) : pernament(pernament) {} + const bool pernament = false; }; + + + struct HoldCpuFrequencyPermanentlyMessage : public sys::DataMessage + { + public: + explicit HoldCpuFrequencyPermanentlyMessage(bsp::CpuFrequencyMHz request) : request(request) + {} + const bsp::CpuFrequencyMHz request; + }; + + class HoldCpuFrequencyPermanentlyResponse : public sys::ResponseMessage + { + }; + + class ReleaseCpuPermanentFrequencyMessage : public sys::DataMessage + {}; + } // namespace sys