From f6e8ecadecf318c9f2ada158d75ef9e62e959865 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Thu, 13 Feb 2020 09:52:21 +0200 Subject: [PATCH] Add Chrono support to EventFlags --- rtos/EventFlags.h | 45 ++++++++++++++++++++++++++++++++- rtos/source/EventFlags.cpp | 52 +++++++++++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/rtos/EventFlags.h b/rtos/EventFlags.h index 2e8a81f63b..67691428bc 100644 --- a/rtos/EventFlags.h +++ b/rtos/EventFlags.h @@ -25,6 +25,7 @@ #include #include +#include "rtos/Kernel.h" #include "rtos/mbed_rtos_types.h" #include "rtos/mbed_rtos1_types.h" #include "rtos/mbed_rtos_storage.h" @@ -98,6 +99,26 @@ public: */ uint32_t wait_all(uint32_t flags = 0, uint32_t millisec = osWaitForever, bool clear = true); + /** Wait for all of the specified event flags to become signaled. + @param flags the flags to wait for. + @param rel_time timeout value. + @param clear clear specified event flags after waiting for them (default: true). + @return event flags before clearing or error code if highest bit set (see @a osFlagsError for details). + + @note You may call this function from ISR context if the rel_time parameter is set to 0. + */ + uint32_t wait_all_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear = true); + + /** Wait for all of the specified event flags to become signaled. + @param flags the flags to wait for. + @param abs_time timeout value. + @param clear clear specified event flags after waiting for them (default: true). + @return event flags before clearing or error code if highest bit set (see @a osFlagsError for details). + + @note You cannot call this function from ISR context. + */ + uint32_t wait_all_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear = true); + /** Wait for any of the specified event flags to become signaled. @param flags the flags to wait for (default: 0 -- no flags). @param millisec timeout value (default: osWaitForever). @@ -108,6 +129,26 @@ public: */ uint32_t wait_any(uint32_t flags = 0, uint32_t millisec = osWaitForever, bool clear = true); + /** Wait for any of the specified event flags to become signaled. + @param flags the flags to wait for. + @param rel_time timeout value. + @param clear clear specified event flags after waiting for them (default: true). + @return event flags before clearing or error code if highest bit set (see @a osFlagsError for details). + + @note This function may be called from ISR context if the millisec parameter is set to 0. + */ + uint32_t wait_any_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear = true); + + /** Wait for any of the specified event flags to become signaled. + @param flags the flags to wait for. + @param abs_time timeout value. + @param clear clear specified event flags after waiting for them (default: true). + @return event flags before clearing or error code if highest bit set (see @a osFlagsError for details). + + @note You cannot call this function from ISR context. + */ + uint32_t wait_any_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear = true); + /** EventFlags destructor. @note You cannot call this function from ISR context. @@ -116,7 +157,9 @@ public: private: void constructor(const char *name = nullptr); - uint32_t wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool clear); + uint32_t wait_for(uint32_t flags, uint32_t opt, Kernel::Clock::duration_u32 rel_time, bool clear); + uint32_t wait_until(uint32_t flags, uint32_t opt, Kernel::Clock::time_point abs_time, bool clear); + #if MBED_CONF_RTOS_PRESENT osEventFlagsId_t _id; mbed_rtos_storage_event_flags_t _obj_mem; diff --git a/rtos/source/EventFlags.cpp b/rtos/source/EventFlags.cpp index ea3b5cc1db..bd235cd81f 100644 --- a/rtos/source/EventFlags.cpp +++ b/rtos/source/EventFlags.cpp @@ -27,6 +27,9 @@ #include "platform/mbed_error.h" #include "platform/mbed_assert.h" +using std::milli; +using std::chrono::duration; + namespace rtos { EventFlags::EventFlags() @@ -82,12 +85,32 @@ uint32_t EventFlags::get() const uint32_t EventFlags::wait_all(uint32_t flags, uint32_t millisec, bool clear) { - return wait(flags, osFlagsWaitAll, millisec, clear); + return wait_all_for(flags, duration(millisec), clear); +} + +uint32_t EventFlags::wait_all_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear) +{ + return wait_for(flags, osFlagsWaitAll, rel_time, clear); +} + +uint32_t EventFlags::wait_all_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear) +{ + return wait_until(flags, osFlagsWaitAll, abs_time, clear); } uint32_t EventFlags::wait_any(uint32_t flags, uint32_t millisec, bool clear) { - return wait(flags, osFlagsWaitAny, millisec, clear); + return wait_any_for(flags, duration(millisec), clear); +} + +uint32_t EventFlags::wait_any_for(uint32_t flags, Kernel::Clock::duration_u32 rel_time, bool clear) +{ + return wait_for(flags, osFlagsWaitAny, rel_time, clear); +} + +uint32_t EventFlags::wait_any_until(uint32_t flags, Kernel::Clock::time_point abs_time, bool clear) +{ + return wait_until(flags, osFlagsWaitAny, abs_time, clear); } EventFlags::~EventFlags() @@ -97,14 +120,14 @@ EventFlags::~EventFlags() #endif } -uint32_t EventFlags::wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool clear) +uint32_t EventFlags::wait_for(uint32_t flags, uint32_t opt, Kernel::Clock::duration_u32 rel_time, bool clear) { if (clear == false) { opt |= osFlagsNoClear; } #if MBED_CONF_RTOS_PRESENT - return osEventFlagsWait(_id, flags, opt, millisec); + return osEventFlagsWait(_id, flags, opt, rel_time.count()); #else rtos::internal::flags_check_capture check; check.flags = &_flags; @@ -112,10 +135,10 @@ uint32_t EventFlags::wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool check.flags_wanted = flags; check.result = 0; check.match = false; - mbed::internal::do_timed_sleep_relative_or_forever(millisec, rtos::internal::non_rtos_check_flags, &check); + mbed::internal::do_timed_sleep_relative_or_forever(rel_time, rtos::internal::non_rtos_check_flags, &check); if (check.match) { return check.result; - } else if (millisec == 0) { + } else if (rel_time == rel_time.zero()) { return osErrorResource; } else { return osErrorTimeout; @@ -123,4 +146,21 @@ uint32_t EventFlags::wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool #endif } +uint32_t EventFlags::wait_until(uint32_t flags, uint32_t opt, Kernel::Clock::time_point abs_time, bool clear) +{ + Kernel::Clock::time_point now = Kernel::Clock::now(); + + Kernel::Clock::duration_u32 rel_time; + if (now >= abs_time) { + rel_time = rel_time.zero(); + } else if (abs_time - now > Kernel::wait_for_u32_max) { + // Documentation permits early return for big offsets + rel_time = Kernel::wait_for_u32_max; + } else { + rel_time = abs_time - now; + } + return wait_for(flags, opt, rel_time, clear); +} + + }