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 <stdint.h>
#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;

View File

@ -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<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)
{
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()
@ -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);
}
}