Added time_to_next() status function

This commit is contained in:
John Wellbelove 2023-08-21 20:58:44 +01:00
parent 870759fcab
commit 11daaa398b
17 changed files with 549 additions and 13 deletions

1
.gitignore vendored
View File

@ -384,3 +384,4 @@ test/vs2022/Debug MSVC C++ 20 - No Tests
test/vs2022/enc_temp_folder
test/vs2022/Debug MSVC C++20 - No virtual messages
examples/MutexMessageRouter/.vs
support/time remaining test.xlsx

View File

@ -139,7 +139,6 @@ namespace etl
{
}
#if ETL_USING_CPP11
//*******************************************
/// ETL delegate callback
//*******************************************
@ -157,7 +156,6 @@ namespace etl
cbk_type(DELEGATE)
{
}
#endif
//*******************************************
/// Returns true if the timer is active.
@ -324,6 +322,12 @@ namespace etl
return ptimers[head];
}
//*******************************
const etl::callback_timer_data& front() const
{
return ptimers[head];
}
//*******************************
etl::timer::id::type begin()
{
@ -704,6 +708,16 @@ namespace etl
return false;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = active_list.front().delta;
return delta;
}
protected:
//*******************************************
@ -742,7 +756,7 @@ namespace etl
#endif
#endif
etl::timer_semaphore_t process_semaphore;
mutable etl::timer_semaphore_t process_semaphore;
#endif
uint_least8_t registered_timers;

View File

@ -297,6 +297,18 @@ namespace etl
return false;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
++process_semaphore;
uint32_t delta = active_list.front().delta;
--process_semaphore;
return delta;
}
protected:
//*************************************************************************
@ -509,6 +521,12 @@ namespace etl
return ptimers[head];
}
//*******************************
const timer_data& front() const
{
return ptimers[head];
}
//*******************************
etl::timer::id::type begin()
{
@ -563,7 +581,7 @@ namespace etl
timer_list active_list;
bool enabled;
TSemaphore process_semaphore;
mutable TSemaphore process_semaphore;
uint_least8_t number_of_registered_timers;
public:

View File

@ -300,6 +300,19 @@ namespace etl
return false;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
uint32_t delta = active_list.front().delta;
return delta;
}
protected:
//*************************************************************************

View File

@ -309,6 +309,18 @@ namespace etl
unlock = unlock_;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
lock();
uint32_t delta = active_list.front().delta;
unlock();
return delta;
}
protected:
//*************************************************************************
@ -520,6 +532,12 @@ namespace etl
return ptimers[head];
}
//*******************************
const timer_data& front() const
{
return ptimers[head];
}
//*******************************
etl::timer::id::type begin()
{

View File

@ -280,6 +280,12 @@ namespace etl
return ptimers[head];
}
//*******************************
const etl::message_timer_data& front() const
{
return ptimers[head];
}
//*******************************
etl::timer::id::type begin()
{
@ -583,6 +589,18 @@ namespace etl
return false;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
ETL_DISABLE_TIMER_UPDATES;
uint32_t delta = active_list.front().delta;
ETL_ENABLE_TIMER_UPDATES;
return delta;
}
protected:
//*******************************************
@ -629,7 +647,7 @@ namespace etl
#endif
#endif
etl::timer_semaphore_t process_semaphore;
mutable etl::timer_semaphore_t process_semaphore;
#endif
uint_least8_t registered_timers;

View File

@ -302,6 +302,18 @@ namespace etl
return false;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
++process_semaphore;
uint32_t delta = active_list.front().delta;
--process_semaphore;
return delta;
}
protected:
//*************************************************************************
@ -405,10 +417,10 @@ namespace etl
//*******************************
timer_list(timer_data* ptimers_)
: head(etl::timer::id::NO_TIMER),
tail(etl::timer::id::NO_TIMER),
current(etl::timer::id::NO_TIMER),
ptimers(ptimers_)
: head(etl::timer::id::NO_TIMER)
, tail(etl::timer::id::NO_TIMER)
, current(etl::timer::id::NO_TIMER)
, ptimers(ptimers_)
{
}
@ -527,6 +539,12 @@ namespace etl
return ptimers[head];
}
//*******************************
const timer_data& front() const
{
return ptimers[head];
}
//*******************************
etl::timer::id::type begin()
{
@ -581,7 +599,7 @@ namespace etl
timer_list active_list;
bool enabled;
TSemaphore process_semaphore;
mutable TSemaphore process_semaphore;
uint_least8_t registered_timers;
public:

View File

@ -311,6 +311,19 @@ namespace etl
return false;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
uint32_t delta = active_list.front().delta;
return delta;
}
protected:
//*************************************************************************
@ -535,6 +548,12 @@ namespace etl
return ptimers[head];
}
//*******************************
const timer_data& front() const
{
return ptimers[head];
}
//*******************************
etl::timer::id::type begin()
{

View File

@ -318,6 +318,18 @@ namespace etl
unlock = unlock_;
}
//*******************************************
/// Get the time to the next timer event.
//*******************************************
uint32_t time_to_next() const
{
lock();
uint32_t delta = active_list.front().delta;
return delta;
}
protected:
//*************************************************************************
@ -542,6 +554,12 @@ namespace etl
return ptimers[head];
}
//*******************************
const timer_data& front() const
{
return ptimers[head];
}
//*******************************
etl::timer::id::type begin()
{

View File

@ -646,6 +646,54 @@ namespace
CHECK_ARRAY_EQUAL(compare1.data(), free_tick_list1.data(), compare1.size());
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
etl::callback_timer<3> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::REPEATING);
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
class test_object
{

View File

@ -541,7 +541,7 @@ namespace
etl::timer::id::type id1 = timer_controller.register_timer(member_callback1, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback1, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::REPEATING);
test.tick_list.clear();
free_tick_list1.clear();
@ -653,6 +653,54 @@ namespace
CHECK_ARRAY_EQUAL(compare1.data(), free_tick_list1.data(), compare1.size());
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
etl::callback_timer_atomic<3, std::atomic_uint32_t> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(member_callback1, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback1, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::REPEATING);
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
class test_object
{

View File

@ -692,6 +692,54 @@ namespace
CHECK_EQUAL(0U, ScopedGuard::guard_count);
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
etl::callback_timer_interrupt<3, ScopedGuard> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::REPEATING);
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
class test_object
{

View File

@ -818,6 +818,59 @@ namespace
CHECK_EQUAL(0U, locks.lock_count);
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
locks.clear();
try_lock_type try_lock = try_lock_type::create<Locks, locks, &Locks::try_lock>();
lock_type lock = lock_type::create<Locks, locks, &Locks::lock>();
unlock_type unlock = unlock_type::create<Locks, locks, &Locks::unlock>();
etl::callback_timer_locked<3> timer_controller(try_lock, lock, unlock);
etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::REPEATING);
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
#if REALTIME_TEST

View File

@ -593,6 +593,56 @@ namespace
CHECK_ARRAY_EQUAL(compare1.data(), router1.message1.data(), compare1.size());
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
etl::message_timer<3> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::REPEATING);
router1.clear();
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
#if REALTIME_TEST

View File

@ -593,6 +593,56 @@ namespace
CHECK_ARRAY_EQUAL(compare1.data(), router1.message1.data(), compare1.size());
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
etl::message_timer_atomic<3, std::atomic_uint32_t> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::REPEATING);
router1.clear();
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
#if REALTIME_TEST

View File

@ -641,9 +641,56 @@ namespace
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
etl::message_timer_interrupt<3, ScopedGuard> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::REPEATING);
router1.clear();
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
class RouterLog : public etl::message_router<RouterLog, Message1, Message2, Message3, Message4>
{
public:

View File

@ -715,6 +715,61 @@ namespace
CHECK_EQUAL(0U, locks.lock_count);
}
//*************************************************************************
TEST(message_timer_time_to_next)
{
locks.clear();
try_lock_type try_lock = try_lock_type::create<Locks, locks, &Locks::try_lock>();
lock_type lock = lock_type::create<Locks, locks, &Locks::lock>();
unlock_type unlock = unlock_type::create<Locks, locks, &Locks::unlock>();
etl::message_timer_locked<3> timer_controller(try_lock, lock, unlock);
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::REPEATING);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::REPEATING);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::REPEATING);
router1.clear();
timer_controller.start(id1);
timer_controller.start(id3);
timer_controller.start(id2);
timer_controller.enable(true);
CHECK_EQUAL(11, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(8, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(1, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(5, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(2, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(6, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(10, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(3, timer_controller.time_to_next());
timer_controller.tick(7);
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
#if REALTIME_TEST