29#ifndef ETL_MESSAGE_TIMER_INCLUDED
30#define ETL_MESSAGE_TIMER_INCLUDED
34#include "message_types.h"
36#include "message_router.h"
37#include "message_bus.h"
38#include "static_assert.h"
46#if defined(ETL_IN_UNIT_TEST) && ETL_NOT_USING_STL
47 #define ETL_DISABLE_TIMER_UPDATES
48 #define ETL_ENABLE_TIMER_UPDATES
49 #define ETL_TIMER_UPDATES_ENABLED true
51 #undef ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK
52 #undef ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK
54 #if !defined(ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK) && !defined(ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK)
55 #error ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK or ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK not defined
58 #if defined(ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK) && defined(ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK)
59 #error Only define one of ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK or ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK
62 #if defined(ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK)
63 #define ETL_DISABLE_TIMER_UPDATES (++process_semaphore)
64 #define ETL_ENABLE_TIMER_UPDATES (--process_semaphore)
65 #define ETL_TIMER_UPDATES_ENABLED (process_semaphore.load() == 0)
68 #if defined(ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK)
69 #if !defined(ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS) || !defined(ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS)
70 #error ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS and/or ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS not defined
73 #define ETL_DISABLE_TIMER_UPDATES ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS
74 #define ETL_ENABLE_TIMER_UPDATES ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS
75 #define ETL_TIMER_UPDATES_ENABLED true
87 : p_message(ETL_NULLPTR),
88 p_router(ETL_NULLPTR),
90 delta(etl::timer::state::Inactive),
91 destination_router_id(etl::imessage_bus::ALL_MESSAGE_ROUTERS),
92 id(etl::timer::id::NO_TIMER),
93 previous(etl::timer::id::NO_TIMER),
94 next(etl::timer::id::NO_TIMER),
109 delta(etl::timer::state::Inactive),
112 previous(etl::timer::id::NO_TIMER),
113 next(etl::timer::id::NO_TIMER),
123 return delta != etl::timer::state::Inactive;
131 delta = etl::timer::state::Inactive;
138 etl::message_router_id_t destination_router_id;
139 etl::timer::id::type id;
151 namespace private_message_timer
162 : head(
etl::timer::id::NO_TIMER),
163 tail(
etl::timer::id::NO_TIMER),
164 current(
etl::timer::id::NO_TIMER),
172 return head == etl::timer::id::NO_TIMER;
178 void insert(etl::timer::id::type
id_)
182 if (head == etl::timer::id::NO_TIMER)
187 timer.previous = etl::timer::id::NO_TIMER;
188 timer.next = etl::timer::id::NO_TIMER;
195 while (
test_id != etl::timer::id::NO_TIMER)
200 if (timer.delta <= test.delta)
208 timer.previous = test.previous;
209 test.previous = timer.id;
210 timer.next = test.id;
213 test.delta -= timer.delta;
215 if (timer.previous != etl::timer::id::NO_TIMER)
217 ptimers[timer.previous].next = timer.id;
223 timer.delta -= test.delta;
230 if (
test_id == etl::timer::id::NO_TIMER)
233 ptimers[tail].next = timer.id;
234 timer.previous = tail;
235 timer.next = etl::timer::id::NO_TIMER;
252 ptimers[timer.previous].next = timer.next;
257 tail = timer.previous;
261 ptimers[timer.next].previous = timer.previous;
267 if (timer.next != etl::timer::id::NO_TIMER)
269 ptimers[timer.next].delta += timer.delta;
273 timer.previous = etl::timer::id::NO_TIMER;
274 timer.next = etl::timer::id::NO_TIMER;
275 timer.delta = etl::timer::state::Inactive;
281 return ptimers[head];
287 return ptimers[head];
291 etl::timer::id::type
begin()
298 etl::timer::id::type previous(etl::timer::id::type last)
300 current = ptimers[last].previous;
305 etl::timer::id::type next(etl::timer::id::type last)
307 current = ptimers[last].next;
314 etl::timer::id::type
id =
begin();
316 while (
id != etl::timer::id::NO_TIMER)
320 timer.next = etl::timer::id::NO_TIMER;
323 head = etl::timer::id::NO_TIMER;
324 tail = etl::timer::id::NO_TIMER;
325 current = etl::timer::id::NO_TIMER;
330 etl::timer::id::type head;
331 etl::timer::id::type tail;
332 etl::timer::id::type current;
356 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
358 bool is_space = (registered_timers < Max_Timers);
370 if (
timer.
id == etl::timer::id::NO_TIMER)
392 if (
id_ != etl::timer::id::NO_TIMER)
396 if (
timer.
id != etl::timer::id::NO_TIMER)
398 if (
timer.is_active())
401 active_list.remove(
timer.
id,
true);
402 remove_callback.call_if(
timer.
id);
442 for (
int i = 0; i < Max_Timers; ++i)
447 registered_timers = 0;
467 while (
has_active && (count >= active_list.front().delta))
471 count -=
timer.delta;
473 active_list.remove(
timer.
id,
true);
474 remove_callback.call_if(
timer.
id);
480 insert_callback.call_if(
timer.
id);
483 if (timer.p_router != ETL_NULLPTR)
485 timer.p_router->receive(timer.destination_router_id, *(timer.p_message));
494 active_list.front().delta -= count;
513 if (
id_ != etl::timer::id::NO_TIMER)
518 if (
timer.
id != etl::timer::id::NO_TIMER)
521 if (
timer.period != etl::timer::state::Inactive)
524 if (
timer.is_active())
526 active_list.remove(
timer.
id,
false);
527 remove_callback.call_if(
timer.
id);
532 insert_callback.call_if(
timer.
id);
551 if (
id_ != etl::timer::id::NO_TIMER)
556 if (
timer.
id != etl::timer::id::NO_TIMER)
558 if (
timer.is_active())
561 active_list.remove(
timer.
id,
false);
562 remove_callback.call_if(
timer.
id);
607 bool result = !active_list.empty();
619 uint32_t delta =
static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
622 if (!active_list.empty())
624 delta = active_list.front().delta;
648 void clear_insert_callback()
650 insert_callback.clear();
654 void clear_remove_callback()
656 remove_callback.clear();
669 process_semaphore(0),
671 registered_timers(0),
689 private_message_timer::list active_list;
693#if defined(ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK)
695#if defined(ETL_TIMER_SEMAPHORE_TYPE)
701 #error No atomic type available
709 event_callback_type insert_callback;
710 event_callback_type remove_callback;
720 template <u
int_least8_t Max_Timers_>
725 ETL_STATIC_ASSERT(
Max_Timers_ <= 254,
"No more than 254 timers are allowed");
741#undef ETL_DISABLE_TIMER_UPDATES
742#undef ETL_ENABLE_TIMER_UPDATES
743#undef ETL_TIMER_UPDATES_ENABLED
Declaration.
Definition delegate_cpp03.h:191
This is the base of all message routers.
Definition message_router_generator.h:121
Interface for message timer.
Definition message_timer.h:342
uint32_t time_to_next() const
Definition message_timer.h:617
bool has_active_timer() const
Check if there is an active timer.
Definition message_timer.h:604
void set_remove_callback(event_callback_type remove_)
Set a callback when a timer is removed from list.
Definition message_timer.h:642
void enable(bool state_)
Enable/disable the timer.
Definition message_timer.h:420
bool start(etl::timer::id::type id_, bool immediate_=false)
Starts a timer.
Definition message_timer.h:508
bool unregister_timer(etl::timer::id::type id_)
Unregister a timer.
Definition message_timer.h:388
imessage_timer(message_timer_data *const timer_array_, const uint_least8_t Max_Timers_)
Constructor.
Definition message_timer.h:664
etl::timer::id::type register_timer(const etl::imessage &message_, etl::imessage_router &router_, uint32_t period_, bool repeating_, etl::message_router_id_t destination_router_id_=etl::imessage_router::ALL_MESSAGE_ROUTERS)
Register a timer.
Definition message_timer.h:350
bool is_running() const
Get the enable/disable state.
Definition message_timer.h:428
bool set_mode(etl::timer::id::type id_, bool repeating_)
Sets a timer's mode.
Definition message_timer.h:590
void set_insert_callback(event_callback_type insert_)
Set a callback when a timer is inserted on list.
Definition message_timer.h:634
void clear()
Clears the timer of data.
Definition message_timer.h:436
bool stop(etl::timer::id::type id_)
Stops a timer.
Definition message_timer.h:546
~imessage_timer()
Destructor.
Definition message_timer.h:679
bool set_period(etl::timer::id::type id_, uint32_t period_)
Sets a timer's period.
Definition message_timer.h:576
The message timer.
Definition message_timer.h:722
message_timer()
Constructor.
Definition message_timer.h:730
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2300
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:315
The configuration of a timer.
Definition message_timer.h:84
bool is_active() const
Returns true if the timer is active.
Definition message_timer.h:121
void set_inactive()
Sets the timer to the inactive state.
Definition message_timer.h:129
Common definitions for the timer framework.
Definition timer.h:55