Add Chrono support to EventFlags

pull/12425/head
Kevin Bracey 2020-02-13 09:52:21 +02:00
parent 4f2fa53b37
commit f6e8ecadec
2 changed files with 90 additions and 7 deletions

View File

@ -25,6 +25,7 @@
#include <cstddef> #include <cstddef>
#include <stdint.h> #include <stdint.h>
#include "rtos/Kernel.h"
#include "rtos/mbed_rtos_types.h" #include "rtos/mbed_rtos_types.h"
#include "rtos/mbed_rtos1_types.h" #include "rtos/mbed_rtos1_types.h"
#include "rtos/mbed_rtos_storage.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); 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. /** Wait for any of the specified event flags to become signaled.
@param flags the flags to wait for (default: 0 -- no flags). @param flags the flags to wait for (default: 0 -- no flags).
@param millisec timeout value (default: osWaitForever). @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); 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. /** EventFlags destructor.
@note You cannot call this function from ISR context. @note You cannot call this function from ISR context.
@ -116,7 +157,9 @@ public:
private: private:
void constructor(const char *name = nullptr); 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 #if MBED_CONF_RTOS_PRESENT
osEventFlagsId_t _id; osEventFlagsId_t _id;
mbed_rtos_storage_event_flags_t _obj_mem; mbed_rtos_storage_event_flags_t _obj_mem;

View File

@ -27,6 +27,9 @@
#include "platform/mbed_error.h" #include "platform/mbed_error.h"
#include "platform/mbed_assert.h" #include "platform/mbed_assert.h"
using std::milli;
using std::chrono::duration;
namespace rtos { namespace rtos {
EventFlags::EventFlags() EventFlags::EventFlags()
@ -82,12 +85,32 @@ uint32_t EventFlags::get() const
uint32_t EventFlags::wait_all(uint32_t flags, uint32_t millisec, bool clear) 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<uint32_t, milli>(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) 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<uint32_t, milli>(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() EventFlags::~EventFlags()
@ -97,14 +120,14 @@ EventFlags::~EventFlags()
#endif #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) { if (clear == false) {
opt |= osFlagsNoClear; opt |= osFlagsNoClear;
} }
#if MBED_CONF_RTOS_PRESENT #if MBED_CONF_RTOS_PRESENT
return osEventFlagsWait(_id, flags, opt, millisec); return osEventFlagsWait(_id, flags, opt, rel_time.count());
#else #else
rtos::internal::flags_check_capture check; rtos::internal::flags_check_capture check;
check.flags = &_flags; 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.flags_wanted = flags;
check.result = 0; check.result = 0;
check.match = false; 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) { if (check.match) {
return check.result; return check.result;
} else if (millisec == 0) { } else if (rel_time == rel_time.zero()) {
return osErrorResource; return osErrorResource;
} else { } else {
return osErrorTimeout; return osErrorTimeout;
@ -123,4 +146,21 @@ uint32_t EventFlags::wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool
#endif #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);
}
} }