~aleteoryx/muditaos

ref: 082966f9aff05b48009499a1d9b6290b497d5a82 muditaos/module-sys/SystemManager/CpuSentinel.cpp -rw-r--r-- 4.9 KiB
082966f9 — Pawel Olejniczak [MOS-36] Disallow going to normal contact list after emergency call 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <SystemManager/CpuSentinel.hpp>
#include "system/messages/RequestCpuFrequencyMessage.hpp"
#include "system/Constants.hpp"
#include <Timers/TimerFactory.hpp>
#include <memory>

namespace sys
{
    namespace
    {
        constexpr std::chrono::seconds defaultHoldFrequencyTime{1};
    } // namespace

    CpuSentinel::CpuSentinel(std::string name,
                             sys::Service *service,
                             std::function<void(bsp::CpuFrequencyMHz)> callback)
        : name(name), owner(service), callback(callback)
    {}

    [[nodiscard]] auto CpuSentinel::GetName() const noexcept -> std::string
    {
        return name;
    }

    void CpuSentinel::HoldMinimumFrequency(bsp::CpuFrequencyMHz frequencyToHold)
    {
        if (currentFrequencyToHold != frequencyToHold) {
            auto msg = std::make_shared<sys::HoldCpuFrequencyMessage>(GetName(), frequencyToHold);
            owner->bus.sendUnicast(std::move(msg), service::name::system_manager);
            currentFrequencyToHold = frequencyToHold;
        }
    }

    void CpuSentinel::ReleaseMinimumFrequency()
    {
        if (currentFrequencyToHold != bsp::CpuFrequencyMHz::Level_0) {
            auto msg = std::make_shared<sys::ReleaseCpuFrequencyMessage>(GetName());
            owner->bus.sendUnicast(std::move(msg), service::name::system_manager);
            currentFrequencyToHold = bsp::CpuFrequencyMHz::Level_0;
        }
    }

    void CpuSentinel::HoldFrequencyPermanently(bsp::CpuFrequencyMHz frequencyToHold)
    {
        permanentFrequencyToHold.isActive        = true;
        permanentFrequencyToHold.frequencyToHold = frequencyToHold;
        auto msg = std::make_shared<sys::HoldCpuFrequencyPermanentlyMessage>(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<sys::ReleaseCpuPermanentFrequencyMessage>(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)
    {
        currentFrequency = newFrequency;
        if (callback) {
            callback(newFrequency);
        }
        if (taskHandle != nullptr && newFrequency >= currentFrequencyToHold) {
            xTaskNotifyGive(taskHandle);
            taskHandle = nullptr;
        }
    }

    bool CpuSentinel::HoldMinimumFrequencyAndWait(bsp::CpuFrequencyMHz frequencyToHold,
                                                  TaskHandle_t taskToNotify,
                                                  uint32_t timeout)
    {
        HoldMinimumFrequency(frequencyToHold);

        if (currentFrequencyToHold < frequencyToHold) {
            taskHandle = 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;
        }
    }

    TimedCpuSentinel::TimedCpuSentinel(std::string name, sys::Service *service)
        : CpuSentinel(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