// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include #include "system/messages/RequestCpuFrequencyMessage.hpp" #include "system/messages/HoldCpuFrequency.hpp" #include "system/messages/BlockWfiMode.hpp" #include "system/Constants.hpp" #include #include #include namespace sys { namespace { constexpr std::chrono::seconds defaultHoldFrequencyTime{1}; } // namespace CpuSentinel::CpuSentinel(std::string name, sys::Service *service, std::function callback) : name(std::move(name)), owner(service), callback(std::move(callback)) {} [[nodiscard]] auto CpuSentinel::GetName() const noexcept -> std::string { return name; } void CpuSentinel::HoldMinimumFrequency(bsp::CpuFrequencyMHz frequencyToHold) { holdTicks = xTaskGetTickCount(); if (currentFrequencyToHold != 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(static_cast(frequencyToHold)); ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100)); } } void CpuSentinel::ReleaseMinimumFrequency() { if (currentFrequencyToHold != bsp::CpuFrequencyMHz::Level_0) { auto msg = std::make_shared(GetName()); owner->bus.sendUnicast(std::move(msg), service::name::system_manager); currentFrequencyToHold = bsp::CpuFrequencyMHz::Level_0; currentReason = std::string("down: ") + owner->getCurrentProcessing(); } } void CpuSentinel::BlockWfiMode(bool block) { if (blockWfiMode != block) { auto msg = std::make_shared(GetName(), block, xTaskGetCurrentTaskHandle()); owner->bus.sendUnicast(std::move(msg), service::name::system_manager); blockWfiMode = block; ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100)); } } [[nodiscard]] auto CpuSentinel::GetFrequency() const noexcept -> bsp::CpuFrequencyMHz { return currentFrequency; } void CpuSentinel::CpuFrequencyHasChanged(bsp::CpuFrequencyMHz newFrequency) { currentFrequency = newFrequency; if (callback) { callback(newFrequency); } } void CpuSentinel::ReadRegistrationData(bsp::CpuFrequencyMHz frequencyHz) { currentFrequency = frequencyHz; } TaskHandle_t CpuSentinel::getTask() { return owner->GetHandle(); } std::string CpuSentinel::getReason() { return currentReason; } TickType_t CpuSentinel::getHoldTicks() const noexcept { return utils::computeIncrease(xTaskGetTickCount(), holdTicks); } TimedCpuSentinel::TimedCpuSentinel(std::string name, sys::Service *service) : CpuSentinel(std::move(name), service), timerHandle{sys::TimerFactory::createSingleShotTimer( owner, "holdFrequencyTimer", defaultHoldFrequencyTime, [this](sys::Timer &) { ReleaseMinimumFrequency(); })} {} TimedCpuSentinel::~TimedCpuSentinel() { if (timerHandle.isActive()) { timerHandle.stop(); } } void TimedCpuSentinel::HoldMinimumFrequencyForTime(bsp::CpuFrequencyMHz frequencyToHold, std::chrono::milliseconds timeout) { if (currentFrequencyToHold != frequencyToHold) { HoldMinimumFrequency(frequencyToHold); timerHandle.restart(timeout); } } } // namespace sys