~aleteoryx/muditaos

ref: 37c5c2fcc83cf7382610d8823a5f45e5066be83b muditaos/module-sys/Service/Timer.cpp -rw-r--r-- 3.0 KiB
37c5c2fc — Lucjan Bryndza [EGD-5153] Fix errors in generate image script 5 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
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "Timer.hpp"
#include "Service.hpp"              // for Service, Service::Timers
#include "Service/TimerMessage.hpp" // for TimerMessage
#include "log/log.hpp"              // for LOG_ERROR
#include "projdefs.h"
#include <Service/Bus.hpp> // for Bus
#include <limits>          // for numeric_limits
#include <memory>          // for make_shared
#include <cstdint>         // for uint32_t

#if DEBUG_TIMER == 1
#define log_timers(...) LOG_DEBUG(__VA_ARGS__)
#else
#define log_timers(...)
#endif

namespace sys
{

    const ms Timer::timeout_infinite = std::numeric_limits<ms>().max();
    static uint32_t timer_id;

    auto toName(const std::string &val, uint32_t no) -> std::string
    {
        return val + "_" + std::to_string(no);
    }

    Timer::Timer(const std::string &name, Service *service, ms interval, Type type)
        : cpp_freertos::Timer((toName(name, timer_id)).c_str(), pdMS_TO_TICKS(interval), type == Type::Periodic),
          parent(service), type(type), interval(interval), name(toName(name, timer_id))
    {
        if (service != nullptr) {
            service->getTimers().attach(this);
        }
        else {
            LOG_ERROR("Bad timer creation!");
        }
        ++timer_id;
        log_timers("Timer %s created %s", name.c_str(), type == Type::Periodic ? "periodic" : "singleshot");
    }

    Timer::Timer(Service *parent, ms interval, Type type) : Timer("Timer", parent, interval, type)
    {}

    Timer::~Timer()
    {
        parent->getTimers().detach(this);
        stop();
    }

    void Timer::Run()
    {
        auto msg = std::make_shared<TimerMessage>(this);
        if (parent == nullptr) {
            LOG_ERROR("Timer %s error: no parent service", name.c_str());
            return;
        }
        if (!Bus::SendUnicast(msg, parent->GetName(), parent)) {
            LOG_ERROR("Timer %s error: bus error", name.c_str());
            return;
        }
    }

    void Timer::start()
    {
        log_timers("Timer %s start!", name.c_str());
        Start(0);
    }

    void Timer::reload(ms from_time)
    {
        Stop(0); // to avoid retriggering timer
        if (from_time != 0) {
            interval = from_time;
            SetPeriod(pdMS_TO_TICKS(interval));
        }
        log_timers("Timer %s reload!", name.c_str());
        Start(0); // start with no waittime
    }

    void Timer::stop()
    {
        log_timers("Timer %s stop!", name.c_str());
        callback = nullptr;
        Stop(0);
    }

    void Timer::setInterval(ms new_interval)
    {
        log_timers("Timer %s set interval to: %d ms!", name.c_str(), static_cast<unsigned int>(interval));
        interval = new_interval;
        SetPeriod(pdMS_TO_TICKS(new_interval), 0);
    }

    void Timer::onTimeout()
    {
        log_timers("Timer %s tick", name.c_str());
        if (callback != nullptr) {
            log_timers("Timer %s callback run!", name.c_str());
            callback(*this);
        }
    }
} // namespace sys