~aleteoryx/muditaos

f9b9967b0ebea232eadffedcf7ed6a86c94c5e48 — Maciej-Mudita 5 years ago 981f958
[EGD-4694] Add CPU frequency shift mechanism

The CPU frequency changes automatically which saves energy
M changelog.md => changelog.md +1 -0
@@ 10,6 10,7 @@
* `[cellular]`  Add GUI for Custom MMI messages- call forwarding.
* Add Bluetooth virtual audio device.
* Add custom repeat window for the alarm application
* `[PowerManagement]` Add CPU frequency shift mechanism.

### Fixed


M module-apps/application-desktop/windows/PowerOffWindow.cpp => module-apps/application-desktop/windows/PowerOffWindow.cpp +0 -3
@@ 148,13 148,10 @@ namespace gui
        eventMgrLabel->activatedCallback = [=](gui::Item &item) {
            static bool state = false;
            if (state == false) {
                // sys::SystemManager::DestroyService(ServiceCellular::serviceName,application);
                sys::SystemManager::SuspendSystem(application);
                LOG_INFO("SUSPEND SYSTEM");
                state = true;
            }
            else {
                sys::SystemManager::ResumeSystem(application);
                LOG_INFO("RESUME SYSTEM");
                state = false;
            }

M module-bsp/board/linux/lpm/LinuxLPM.cpp => module-bsp/board/linux/lpm/LinuxLPM.cpp +3 -7
@@ 10,12 10,6 @@
namespace bsp
{

    int32_t LinuxLPM::Switch(const bsp::LowPowerMode::Mode mode)
    {
        currentMode = mode;
        return 0;
    }

    int32_t LinuxLPM::PowerOff()
    {
        return 0;


@@ 27,5 21,7 @@ namespace bsp
    }

    void LinuxLPM::SetCpuFrequency(bsp::LowPowerMode::CpuFrequency freq)
    {}
    {
        currentFrequency = freq;
    }
} // namespace bsp

M module-bsp/board/linux/lpm/LinuxLPM.h => module-bsp/board/linux/lpm/LinuxLPM.h +0 -1
@@ 13,7 13,6 @@ namespace bsp
    class LinuxLPM : public LowPowerMode
    {
      public:
        int32_t Switch(const Mode mode) override final;
        int32_t PowerOff() override final;
        int32_t Reboot() override final;
        void SetCpuFrequency(CpuFrequency freq) final;

M module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp => module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp +1 -40
@@ 28,23 28,6 @@ namespace bsp
        CpuFreq = std::make_unique<CpuFreqLPM>();
    }

    int32_t RT1051LPM::Switch(const bsp::LowPowerMode::Mode mode)
    {
        currentMode = mode;
        switch (mode) {
        case Mode ::FullSpeed:
            return EnterFullSpeed();
        case Mode ::LowPowerRun:
            return EnterLowPowerRun();
        case Mode ::LowPowerIdle:
            return EnterLowPowerIdle();
        case Mode ::Suspend:
            return EnterSuspend();
        default:
            return 0;
        }
    }

    int32_t RT1051LPM::PowerOff()
    {
        gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::POWER_SWITCH_HOLD_BUTTON), 0);


@@ 58,31 41,9 @@ namespace bsp
        return 0;
    }

    int32_t RT1051LPM::EnterFullSpeed()
    {
        LPM_EnterFullSpeed();
        return 0;
    }

    int32_t RT1051LPM::EnterLowPowerRun()
    {
        LPM_EnterLowPowerRun();
        return 0;
    }

    int32_t RT1051LPM::EnterLowPowerIdle()
    {
        LPM_EnterLowPowerIdle();
        return 0;
    }

    int32_t RT1051LPM::EnterSuspend()
    {
        return 0;
    }

    void RT1051LPM::SetCpuFrequency(bsp::LowPowerMode::CpuFrequency freq)
    {
        currentFrequency = freq;
        switch (freq) {
        case bsp::LowPowerMode::CpuFrequency::Level_1:
            CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_12_Mhz);

M module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp => module-bsp/board/rt1051/bsp/lpm/RT1051LPM.hpp +0 -6
@@ 15,17 15,11 @@ namespace bsp
    {
      public:
        RT1051LPM();
        int32_t Switch(const Mode mode) override final;
        int32_t PowerOff() override final;
        int32_t Reboot() override final;
        void SetCpuFrequency(CpuFrequency freq) final;

      private:
        int32_t EnterLowPowerRun();
        int32_t EnterFullSpeed();
        int32_t EnterLowPowerIdle();
        int32_t EnterSuspend();

        std::shared_ptr<drivers::DriverGPIO> gpio;
        std::unique_ptr<bsp::CpuFreqLPM> CpuFreq;
    };

M module-bsp/bsp/lpm/bsp_lpm.cpp => module-bsp/bsp/lpm/bsp_lpm.cpp +4 -0
@@ 26,4 26,8 @@ namespace bsp{
        return inst;
    }

    LowPowerMode::CpuFrequency LowPowerMode::GetCurrentFrequency() const noexcept
    {
    	return currentFrequency;
    }
}

M module-bsp/bsp/lpm/bsp_lpm.hpp => module-bsp/bsp/lpm/bsp_lpm.hpp +2 -13
@@ 8,16 8,7 @@ namespace bsp {

    class LowPowerMode
    {
      private:
      public:
        enum class Mode
        {
            FullSpeed,
            LowPowerRun,
            LowPowerIdle,
            Suspend

        };
        enum class CpuFrequency
        {
            Level_1, // 12 MHz


@@ 33,15 24,13 @@ namespace bsp {

        static std::optional<std::unique_ptr<LowPowerMode>> Create();

        virtual int32_t Switch(const Mode mode) = 0;
        Mode GetCurrentMode(){return currentMode;}

        virtual int32_t PowerOff() = 0;
        virtual int32_t Reboot() = 0;
        virtual void SetCpuFrequency(CpuFrequency freq) = 0;
        [[nodiscard]] CpuFrequency GetCurrentFrequency() const noexcept;

    protected:
      Mode currentMode = Mode::FullSpeed;
        CpuFrequency currentFrequency = CpuFrequency::Level_6;
    };
} // namespace bsp


M module-cellular/at/Commands.hpp => module-cellular/at/Commands.hpp +1 -1
@@ 167,7 167,7 @@ namespace at
            {AT::URC_NOTIF_CHANNEL, {"AT+QCFG=\"cmux/urcport\",1"}},
            {AT::RI_PIN_AUTO_CALL, {"AT+QCFG=\"urc/ri/ring\",\"auto\""}},
            {AT::RI_PIN_OFF_CALL, {"AT+QCFG=\"urc/ri/ring\",\"off\""}},
            {AT::RI_PIN_PULSE_SMS, {"AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",200"}},
            {AT::RI_PIN_PULSE_SMS, {"AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",450"}},
            {AT::RI_PIN_OFF_SMS, {"AT+QCFG=\"urc/ri/smsincoming\",\"off\""}},
            {AT::RI_PIN_OFF_OTHER, {"AT+QCFG=\"urc/ri/other\",\"off\""}},
            {AT::URC_DELAY_ON, {"AT+QCFG=\"urc/delay\",1"}},

M module-services/service-appmgr/model/ApplicationManager.cpp => module-services/service-appmgr/model/ApplicationManager.cpp +0 -2
@@ 326,8 326,6 @@ namespace app::manager
    auto ApplicationManager::handlePowerSavingModeInit() -> bool
    {
        LOG_INFO("Going to suspend mode");
        suspendSystemServices();
        sys::SystemManager::SuspendSystem(this);
        return true;
    }


M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +3 -24
@@ 37,6 37,7 @@
#include <tuple>
#include <vector>
#include <module-apps/messages/AppMessage.hpp>
#include <SystemManager/messages/CpuFrequencyMessage.hpp>

EventManager::EventManager(const std::string &name) : sys::Service(name)
{


@@ 98,10 99,6 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
        auto message = std::make_shared<sevm::KbdMessage>();
        message->key = msg->key;

        if (suspended && (message->key.state == RawKey::State::Pressed)) {
            suspended = false;
            sys::SystemManager::ResumeSystem(this);
        }
        if (message->key.state == RawKey::State::Pressed && message->key.key_code == bsp::KeyCodes::FnRight) {
            // and state == ShutDown
            sys::Bus::SendUnicast(message, service::name::system_manager, this);


@@ 126,11 123,6 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
    else if (msgl->messageType == MessageType::EVMBatteryLevel && msgl->sender == this->GetName()) {
        auto *msg = static_cast<sevm::BatteryLevelMessage *>(msgl);

        if (suspended) {
            suspended = false;
            sys::SystemManager::ResumeSystem(this);
        }

        auto message           = std::make_shared<sevm::BatteryLevelMessage>();
        message->levelPercents = msg->levelPercents;
        message->fullyCharged  = msg->fullyCharged;


@@ 144,11 136,6 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
    else if (msgl->messageType == MessageType::EVMChargerPlugged && msgl->sender == this->GetName()) {
        auto *msg = static_cast<sevm::BatteryPlugMessage *>(msgl);

        if (suspended) {
            suspended = false;
            sys::SystemManager::ResumeSystem(this);
        }

        auto message     = std::make_shared<sevm::BatteryPlugMessage>();
        message->plugged = msg->plugged;



@@ 163,12 150,6 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
    }
    else if (msgl->messageType == MessageType::EVMMinuteUpdated && msgl->sender == this->GetName()) {

        // resume system first
        if (suspended) {
            // suspended = false;
            // sys::SystemManager::ResumeSystem(this);
        }

        // HandleAlarmTrigger(msgl);

        handled = true;


@@ 235,7 216,8 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
        }
    }
    else if (msgl->messageType == MessageType::EVMRingIndicator) {
        sys::SystemManager::ResumeSystem(this);
        auto msg = std::make_shared<sys::CpuFrequencyMessage>(sys::CpuFrequencyMessage::Action::Increase);
        sys::Bus::SendUnicast(msg, service::name::system_manager, this);
    }

    if (handled) {


@@ 346,11 328,8 @@ sys::ReturnCodes EventManager::SwitchPowerModeHandler(const sys::ServicePowerMod
{
    LOG_FATAL("[ServiceEvtMgr] PowerModeHandler: %s", c_str(mode));

    suspended = true;

    switch (mode) {
    case sys::ServicePowerMode ::Active:
        suspended = false;
        break;
    case sys::ServicePowerMode ::SuspendToRAM:
    case sys::ServicePowerMode ::SuspendToNVM:

M module-services/service-evtmgr/service-evtmgr/EventManager.hpp => module-services/service-evtmgr/service-evtmgr/EventManager.hpp +0 -2
@@ 39,8 39,6 @@ class EventManager : public sys::Service
    bool alarmDBEmpty = false;
    // flag set when there is alarm to handle
    bool alarmIsValid = false;
    // flag informs about suspend/resume status
    bool suspended = false;

  public:
    EventManager(const std::string &name);

M module-sys/SystemManager/PowerManager.cpp => module-sys/SystemManager/PowerManager.cpp +64 -24
@@ 7,7 7,6 @@

namespace sys
{

    PowerManager::PowerManager()
    {
        lowPowerControl = bsp::LowPowerMode::Create().value_or(nullptr);


@@ 16,42 15,83 @@ namespace sys
    PowerManager::~PowerManager()
    {}

    int32_t PowerManager::Switch(const sys::PowerManager::Mode mode)
    int32_t PowerManager::PowerOff()
    {
        return lowPowerControl->PowerOff();
    }

        int32_t ret = 0;
        switch (mode) {
        case Mode::FullSpeed:
            ret = lowPowerControl->Switch(bsp::LowPowerMode::Mode::FullSpeed);
            break;
        case Mode::LowPowerIdle:
        case Mode::LowPowerRun:
        case Mode::Suspend:
            LOG_FATAL("LowPowerIdle temporary disabled!");
            // Low power is temporary disabled it was breaking i.e. GSM
            // ret = lowPowerControl->Switch(bsp::LowPowerMode::Mode::LowPowerIdle);
            break;
    int32_t PowerManager::Reboot()
    {
        return lowPowerControl->Reboot();
    }

    void PowerManager::UpdateCpuFrequency(uint32_t cpuLoad)
    {
        const auto freq = lowPowerControl->GetCurrentFrequency();

        if (cpuLoad > frequencyShiftUpperThreshold && freq < bsp::LowPowerMode::CpuFrequency::Level_6) {
            aboveThresholdCounter++;
            belowThresholdCounter = 0;
        }
        else if (cpuLoad < frequencyShiftLowerThreshold && freq > bsp::LowPowerMode::CpuFrequency::Level_1) {
            belowThresholdCounter++;
            aboveThresholdCounter = 0;
        }
        else {
            ResetFrequencyShiftCounter();
        }

        if (ret == 0) {
            currentPowerMode = mode;
        if (aboveThresholdCounter >= maxAboveThresholdCount) {
            ResetFrequencyShiftCounter();
            IncreaseCpuFrequency();
        }
        if (belowThresholdCounter >= maxBelowThresholdCount) {
            ResetFrequencyShiftCounter();
            DecreaseCpuFrequency();
        }
        return ret;
    }

    int32_t PowerManager::PowerOff()
    void PowerManager::IncreaseCpuFrequency() const
    {
        return lowPowerControl->PowerOff();
        bsp::LowPowerMode::CpuFrequency freq = lowPowerControl->GetCurrentFrequency();
        if (freq < bsp::LowPowerMode::CpuFrequency::Level_6) {
            lowPowerControl->SetCpuFrequency(bsp::LowPowerMode::CpuFrequency::Level_6);
        }
    }

    int32_t PowerManager::Reboot()
    void PowerManager::DecreaseCpuFrequency() const
    {
        return lowPowerControl->Reboot();
        const auto freq = lowPowerControl->GetCurrentFrequency();
        auto level      = bsp::LowPowerMode::CpuFrequency::Level_1;

        switch (freq) {
        case bsp::LowPowerMode::CpuFrequency::Level_6:
            level = bsp::LowPowerMode::CpuFrequency::Level_5;
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_5:
            level = bsp::LowPowerMode::CpuFrequency::Level_4;
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_4:
            level = bsp::LowPowerMode::CpuFrequency::Level_3;
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_3:
            level = bsp::LowPowerMode::CpuFrequency::Level_2;
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_2:
            level = bsp::LowPowerMode::CpuFrequency::Level_1;
            break;
        case bsp::LowPowerMode::CpuFrequency::Level_1:
            break;
        }

        if (level != freq) {
            lowPowerControl->SetCpuFrequency(level);
        }
    }

    void PowerManager::SetCpuFrequency(const bsp::LowPowerMode::CpuFrequency freq)
    void PowerManager::ResetFrequencyShiftCounter()
    {
        lowPowerControl->SetCpuFrequency(freq);
        aboveThresholdCounter = 0;
        belowThresholdCounter = 0;
    }

} // namespace sys

M module-sys/SystemManager/PowerManager.hpp => module-sys/SystemManager/PowerManager.hpp +24 -17
@@ 10,38 10,45 @@

namespace sys
{
    inline constexpr uint32_t frequencyShiftLowerThreshold{40};
    inline constexpr uint32_t frequencyShiftUpperThreshold{60};
    inline constexpr uint32_t maxBelowThresholdCount{50};
    inline constexpr uint32_t maxAboveThresholdCount{3};

    class PowerManager
    {

      public:
        enum class Mode
        {
            FullSpeed,
            LowPowerRun,
            LowPowerIdle,
            Suspend

        };

        PowerManager();
        ~PowerManager();

        int32_t Switch(const Mode mode);
        int32_t PowerOff();
        int32_t Reboot();

        void SetCpuFrequency(const bsp::LowPowerMode::CpuFrequency freq);
        /// called periodically to calculate the CPU requirement
        ///
        /// if for the last 'maxAboveThresholdCount' periods the current CPU consumption has been above the set upper
        /// 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
        void UpdateCpuFrequency(uint32_t cpuLoad);

        /// called when the CPU frequency needs to be increased
        /// @note the frequency is always increased to the maximum value
        void IncreaseCpuFrequency() const;

        Mode GetCurrentMode()
        {
            return currentPowerMode;
        }
        /// called when the CPU frequency needs to be reduced
        /// @note the frequency is always reduced by one step
        void DecreaseCpuFrequency() const;

      private:
        std::unique_ptr<bsp::LowPowerMode> lowPowerControl;
        void ResetFrequencyShiftCounter();

        uint32_t belowThresholdCounter{0};
        uint32_t aboveThresholdCounter{0};

        Mode currentPowerMode = Mode ::FullSpeed;
        std::unique_ptr<bsp::LowPowerMode> lowPowerControl;
    };

} // namespace sys

M module-sys/SystemManager/SystemManager.cpp => module-sys/SystemManager/SystemManager.cpp +23 -59
@@ 12,6 12,7 @@
#include <service-evtmgr/BatteryMessages.hpp>
#include <service-evtmgr/Constants.hpp>
#include <Service/Timer.hpp>
#include "messages/CpuFrequencyMessage.hpp"

const inline size_t systemManagerStack = 4096 * 2;



@@ 102,8 103,6 @@ namespace sys
        powerManager = std::make_unique<PowerManager>();
        cpuStatistics = std::make_unique<CpuStatistics>();

        // Switch system to full functionality(clocks and power domains configured to max values)
        powerManager->Switch(PowerManager::Mode::FullSpeed);
        userInit = init;

        // Start System manager


@@ 113,7 112,7 @@ namespace sys
        // pingPongTimerID = CreateTimer(Ticks::MsToTicks(pingInterval), true);
        // ReloadTimer(pingPongTimerID);

        cpuStatisticsTimer = std::make_unique<sys::Timer>("cpuStatistics", this, 1000);
        cpuStatisticsTimer = std::make_unique<sys::Timer>("cpuStatistics", this, timerInitInterval.count());
        cpuStatisticsTimer->connect([&](sys::Timer &) { CpuStatisticsTimerHandler(); });
        cpuStatisticsTimer->start();
    }


@@ 130,62 129,6 @@ namespace sys
        return true;
    }

    bool SystemManager::SuspendSystem(Service *caller)
    {

        if (powerManager->GetCurrentMode() != PowerManager::Mode::FullSpeed) {
            LOG_WARN("System is already suspended.");
            return false;
        }

        for (auto w = servicesList.rbegin(); w != servicesList.rend(); ++w) {
            if ((*w)->parent == "" && (*w)->GetName() != caller->GetName()) {
                auto ret = Bus::SendUnicast(
                    std::make_shared<SystemMessage>(SystemMessageType::SwitchPowerMode, ServicePowerMode::SuspendToRAM),
                    (*w)->GetName(),
                    caller,
                    1000);

                auto resp = std::static_pointer_cast<ResponseMessage>(ret.second);
                if (ret.first != ReturnCodes::Success && (resp->retCode != ReturnCodes::Success)) {
                    LOG_FATAL("Service %s failed to enter low-power mode", (*w)->GetName().c_str());
                }
            }
        }

        powerManager->Switch(PowerManager::Mode::LowPowerIdle);

        return true;
    }

    bool SystemManager::ResumeSystem(Service *caller)
    {

        if (powerManager->GetCurrentMode() == PowerManager::Mode::FullSpeed) {
            LOG_WARN("System is already resumed.");
            return false;
        }

        powerManager->Switch(PowerManager::Mode::FullSpeed);

        for (const auto &w : servicesList) {

            if (w->parent == "" && w->GetName() != caller->GetName()) {
                auto ret = Bus::SendUnicast(
                    std::make_shared<SystemMessage>(SystemMessageType::SwitchPowerMode, ServicePowerMode::Active),
                    w->GetName(),
                    caller,
                    1000);
                auto resp = std::static_pointer_cast<ResponseMessage>(ret.second);

                if (ret.first != ReturnCodes::Success && (resp->retCode != ReturnCodes::Success)) {
                    LOG_FATAL("Service %s failed to exit low-power mode", w->GetName().c_str());
                }
            }
        }
        return true;
    }

    bool SystemManager::SuspendService(const std::string &name, sys::Service *caller)
    {
        auto ret = Bus::SendUnicast(


@@ 317,6 260,21 @@ namespace sys
            return MessageNone{};
        });

        connect(typeid(sys::CpuFrequencyMessage), [this](sys::Message *message) -> sys::MessagePointer {
            auto msg = static_cast<sys::CpuFrequencyMessage *>(message);

            if (msg->getAction() == sys::CpuFrequencyMessage::Action::Increase) {
                powerManager->IncreaseCpuFrequency();
                cpuStatisticsTimer->reload();
            }
            else if (msg->getAction() == sys::CpuFrequencyMessage::Action::Decrease) {
                powerManager->DecreaseCpuFrequency();
                cpuStatisticsTimer->reload();
            }

            return sys::MessageNone{};
        });

        return ReturnCodes::Success;
    }



@@ 365,7 323,13 @@ namespace sys

    void SystemManager::CpuStatisticsTimerHandler()
    {
        if (!cpuStatisticsTimerInit) {
            cpuStatisticsTimerInit = true;
            cpuStatisticsTimer->setInterval(timerPeriodInterval.count());
        }

        cpuStatistics->Update();
        powerManager->UpdateCpuFrequency(cpuStatistics->GetPercentageCpuLoad());
    }

    std::vector<std::shared_ptr<Service>> SystemManager::servicesList;

M module-sys/SystemManager/SystemManager.hpp => module-sys/SystemManager/SystemManager.hpp +6 -4
@@ 22,9 22,14 @@
#include "PowerManager.hpp"
#include "Constants.hpp"
#include "CpuStatistics.hpp"
#include <chrono>

namespace sys
{
    using namespace std::chrono_literals;
    inline constexpr std::chrono::milliseconds timerInitInterval{30s};
    inline constexpr std::chrono::milliseconds timerPeriodInterval{100ms};

    enum class Code
    {
        CloseSystem,


@@ 66,10 71,6 @@ namespace sys

        static bool Reboot(Service *s);

        static bool SuspendSystem(Service *caller);

        static bool ResumeSystem(Service *caller);

        static bool SuspendService(const std::string &name, Service *caller);

        static bool ResumeService(const std::string &name, Service *caller);


@@ 130,6 131,7 @@ namespace sys

        TickType_t pingInterval;
        uint32_t pingPongTimerID;
        bool cpuStatisticsTimerInit{false};

        InitFunction userInit;


A module-sys/SystemManager/messages/CpuFrequencyMessage.hpp => module-sys/SystemManager/messages/CpuFrequencyMessage.hpp +30 -0
@@ 0,0 1,30 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "SystemManagerMessage.hpp"

namespace sys
{
    class CpuFrequencyMessage : public SystemManagerMessage
    {
      public:
        enum class Action
        {
            Increase,
            Decrease
        };

        CpuFrequencyMessage(Action action) : SystemManagerMessage(), action(action)
        {}

        [[nodiscard]] auto getAction() const noexcept
        {
            return action;
        };

      private:
        Action action = Action::Increase;
    };
} // namespace sys

A module-sys/SystemManager/messages/SystemManagerMessage.hpp => module-sys/SystemManager/messages/SystemManagerMessage.hpp +18 -0
@@ 0,0 1,18 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <MessageType.hpp>
#include <Service/Message.hpp>

namespace sys
{

    class SystemManagerMessage : public sys::DataMessage
    {
      public:
        SystemManagerMessage() : sys::DataMessage(MessageType::PMChangePowerMode){};
    };

} // namespace sys