diff --git a/module-cellular/at/cmd/src/CFUN.cpp b/module-cellular/at/cmd/src/CFUN.cpp index 8735c0e2c..daaf61009 100644 --- a/module-cellular/at/cmd/src/CFUN.cpp +++ b/module-cellular/at/cmd/src/CFUN.cpp @@ -13,7 +13,7 @@ namespace at namespace cmd { using namespace std::chrono_literals; - CFUN::CFUN(at::cmd::Modifier mod) noexcept : Cmd("AT+CFUN", mod, 150s) + CFUN::CFUN(at::cmd::Modifier mod) noexcept : Cmd("AT+CFUN", mod, 17s) {} CFUN::CFUN() noexcept : CFUN(at::cmd::Modifier::None) diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index 376d2ad2e..8b2bb95f3 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -2277,3 +2277,7 @@ auto ServiceCellular::logTetheringCalls() -> void tetheringCalllog.clear(); } } +TaskHandle_t ServiceCellular::getTaskHandle() +{ + return xTaskGetCurrentTaskHandle(); +} diff --git a/module-services/service-cellular/connection-manager/ConnectionManager.cpp b/module-services/service-cellular/connection-manager/ConnectionManager.cpp index a6c1bab22..46228981a 100644 --- a/module-services/service-cellular/connection-manager/ConnectionManager.cpp +++ b/module-services/service-cellular/connection-manager/ConnectionManager.cpp @@ -7,6 +7,8 @@ auto ConnectionManager::onPhoneModeChange(sys::phone_modes::PhoneMode mode) -> bool { + cellular->holdMinimumCpuFrequency(); + if (mode == sys::phone_modes::PhoneMode::Offline) { forceDismissCallsFlag = true; return handleModeChangeToCommonOffline(); @@ -24,8 +26,8 @@ void ConnectionManager::onTimerTick() minutesOfflineElapsed++; if (minutesOfflineElapsed.count() >= connectionInterval.count()) { minutesOfflineElapsed = static_cast(0); - ; onlinePeriod = true; + cellular->holdMinimumCpuFrequency(); cellular->connectToNetwork(); return; } @@ -34,6 +36,7 @@ void ConnectionManager::onTimerTick() if (minutesOnlineElapsed.count() >= connectedPeriod.count()) { minutesOnlineElapsed = static_cast(0); onlinePeriod = false; + cellular->holdMinimumCpuFrequency(); cellular->disconnectFromNetwork(); } } @@ -43,9 +46,7 @@ void ConnectionManager::setInterval(const std::chrono::minutes interval) { connectionInterval = interval; minutesOnlineElapsed = static_cast(0); - ; minutesOfflineElapsed = static_cast(0); - ; } void ConnectionManager::setFlightMode(const bool mode) @@ -67,9 +68,7 @@ auto ConnectionManager::handleModeChangeToCommonOffline() -> bool } minutesOfflineElapsed = static_cast(0); - ; minutesOnlineElapsed = static_cast(0); - ; if (isMessagesOnlyMode()) { handleModeChangeToMessageOnlyMode(); diff --git a/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp b/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp index d13130dbd..629f27ac1 100644 --- a/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp +++ b/module-services/service-cellular/connection-manager/ConnectionManagerCellularCommands.cpp @@ -97,3 +97,12 @@ void ConnectionManagerCellularCommands::stopConnectionTimer() { cellular.connectionTimer.stop(); } + +void ConnectionManagerCellularCommands::holdMinimumCpuFrequency() +{ + auto handle = cellular.getTaskHandle(); + if (cellular.cpuSentinel) { + cellular.cpuSentinel->HoldMinimumFrequencyAndWait(bsp::CpuFrequencyHz::Level_4, handle, 2000); + } + return; +} diff --git a/module-services/service-cellular/service-cellular/ServiceCellular.hpp b/module-services/service-cellular/service-cellular/ServiceCellular.hpp index 99808ada7..04438d5fa 100644 --- a/module-services/service-cellular/service-cellular/ServiceCellular.hpp +++ b/module-services/service-cellular/service-cellular/ServiceCellular.hpp @@ -316,6 +316,7 @@ class ServiceCellular : public sys::Service private: std::unique_ptr priv; cellular::internal::SimpleCallManager callManager; + TaskHandle_t getTaskHandle(); }; namespace sys diff --git a/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommands.hpp b/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommands.hpp index eb967dc44..1d345d619 100644 --- a/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommands.hpp +++ b/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommands.hpp @@ -20,6 +20,7 @@ class ConnectionManagerCellularCommands : public ConnectionManagerCellularComman auto isConnectionTimerActive() -> bool final; void startConnectionTimer() final; void stopConnectionTimer() final; + void holdMinimumCpuFrequency() final; private: ServiceCellular &cellular; diff --git a/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommandsInterface.hpp b/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommandsInterface.hpp index 91cbca164..a70eb29c4 100644 --- a/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommandsInterface.hpp +++ b/module-services/service-cellular/service-cellular/connection-manager/ConnectionManagerCellularCommandsInterface.hpp @@ -49,4 +49,8 @@ class ConnectionManagerCellularCommandsInterface * @brief Stops connectionTimer */ virtual void stopConnectionTimer() = 0; + /** + * @brief Holds minimum cpu frequency + */ + virtual void holdMinimumCpuFrequency() = 0; }; diff --git a/module-services/service-cellular/tests/unittest_connection-manager.cpp b/module-services/service-cellular/tests/unittest_connection-manager.cpp index 07184ef6d..c667ea461 100644 --- a/module-services/service-cellular/tests/unittest_connection-manager.cpp +++ b/module-services/service-cellular/tests/unittest_connection-manager.cpp @@ -20,6 +20,7 @@ class MockCellular : public ConnectionManagerCellularCommandsInterface MOCK_METHOD(bool, isConnectionTimerActive, (), (override)); MOCK_METHOD(void, startConnectionTimer, (), (override)); MOCK_METHOD(void, stopConnectionTimer, (), (override)); + MOCK_METHOD(void, holdMinimumCpuFrequency, (), (override)); }; TEST(ConnectionManager, onPhoneModeChange) diff --git a/module-sys/SystemManager/CpuSentinel.cpp b/module-sys/SystemManager/CpuSentinel.cpp index b0b7ff52a..b368f2018 100644 --- a/module-sys/SystemManager/CpuSentinel.cpp +++ b/module-sys/SystemManager/CpuSentinel.cpp @@ -38,9 +38,27 @@ namespace sys void CpuSentinel::CpuFrequencyHasChanged(bsp::CpuFrequencyHz newFrequency) { + currentFrequency = newFrequency; if (callback) { callback(newFrequency); } + if (taskHandle != nullptr && newFrequency >= currentFrequencyToHold) { + xTaskNotifyGive(taskHandle); + taskHandle = nullptr; + } } + bool CpuSentinel::HoldMinimumFrequencyAndWait(bsp::CpuFrequencyHz frequencyToHold, + TaskHandle_t taskToNotify, + uint32_t timeout) + { + HoldMinimumFrequency(frequencyToHold); + + if (currentFrequencyToHold < frequencyToHold) { + taskHandle = taskToNotify; + return ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(timeout)) == 0; + } + + return true; + } } // namespace sys diff --git a/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp b/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp index 3f5908703..07d8136be 100644 --- a/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp +++ b/module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace sys { @@ -26,18 +27,24 @@ namespace sys [[nodiscard]] auto GetName() const noexcept -> std::string; void HoldMinimumFrequency(bsp::CpuFrequencyHz frequencyToHold); + bool HoldMinimumFrequencyAndWait(bsp::CpuFrequencyHz frequencyToHold, + TaskHandle_t taskToNotify, + uint32_t timeout); void ReleaseMinimumFrequency(); void CpuFrequencyHasChanged(bsp::CpuFrequencyHz newFrequency); protected: const std::string name; bsp::CpuFrequencyHz currentFrequencyToHold{bsp::CpuFrequencyHz::Level_0}; + std::atomic currentFrequency{bsp::CpuFrequencyHz::Level_0}; sys::Service *owner{nullptr}; /// function called from the PowerManager context /// to update resources immediately /// critical section or mutex support necessary std::function callback; + + TaskHandle_t taskHandle = nullptr; }; } // namespace sys