nrfcxx
0.1.0
C++-17 Framework for Nordic nRF5 Devices
|
Class supporting an alarm with custom callback and repeatability. More...
#include <nrfcxx/clock.hpp>
Public Types | |
enum | state_type { ST_unscheduled, ST_scheduled, ST_ready, ST_in_callback, ST_cancelled } |
Constants identifying the alarm state. More... | |
using | mutex_type = uptime::mutex_type |
An RAII type for mutex access blocking changes to alarm state. | |
using | callback_type = std::function< bool(alarm &alarm)> |
The signature of an alarm callback function. More... | |
Public Member Functions | |
state_type | state () const |
The current state of the alarm. | |
bool | active () const |
Return true if the alarm state is one of ST_scheduled, ST_ready, or ST_in_callback. More... | |
alarm (const alarm &)=delete | |
alarm & | operator= (const alarm &)=delete |
alarm (alarm &&)=delete | |
alarm & | operator= (alarm &&)=delete |
alarm (callback_type callback, unsigned int interval=0, void *md=0) | |
Standard alarm constructor. More... | |
alarm (callback_type callback, void *md) | |
Overload for common case of configuring with static callback. More... | |
template<typename DurT , typename DurT::rep = 0> | |
constexpr | alarm (callback_type callback, DurT interval, void *md=0) |
Duration-specified alarm constructor. More... | |
~alarm () | |
On destruction the alarm is cancelled. | |
void | schedule () |
Queue the alarm to execute at its current deadline(). More... | |
void | schedule_offset (int offset) |
Queue the alarm to execute at offset ticks from the current time. More... | |
template<typename DurT > | |
void | schedule_offset (DurT offset) |
Schedule an alarm using a std::chrono duration. More... | |
state_type | cancel () |
Cancel a potentially-scheduled alarm. More... | |
unsigned int | interval () const |
An offset added to deadline() prior to invoking the callback when the alarm fires. | |
alarm & | set_interval (unsigned int interval) |
Set the interval() in uptime ticks. More... | |
template<typename DurT , typename DurT::rep = 0> | |
alarm & | set_interval (DurT interval) |
Set the interval() using a given duration. | |
unsigned int | deadline () const |
The value of (the low 32 bits of) uptime::now() at which the alarm should fire. | |
alarm & | set_deadline (unsigned int deadline) |
Set the deadline for the alarm to fire. More... | |
Static Public Member Functions | |
template<event_set::event_type EVT, bool reschedule = false> | |
static alarm | for_event (event_set &events) |
Factory producing an alarm with a callback that sets an event. More... | |
Data Fields | |
void *const | metadata |
Pointer to arbitrary data associated with the alarm. More... | |
Protected Member Functions | |
int | ordinal_ (unsigned int now) const noexcept |
Calculate an ordinal for the alarm using the distance from now until its deadline. | |
Protected Attributes | |
callback_type const | callback_ |
unsigned int | deadline_ = 0 |
unsigned int | interval_ |
state_type volatile | state_ = ST_unscheduled |
alarm * | next_ = nullptr |
Static Protected Attributes | |
static alarm_queue | queue_ |
Class supporting an alarm with custom callback and repeatability.
This capability supports an unbounded number of alarms multiplexed onto a capture/compare register in the clock::uptime infrastructure. Alarms are given a deadline(), which is normally specified relative to the time at which they are scheduled but can be absolute.
They may have a non-zero interval() which is used to support periodic alarms.
They generally have a callback which is invoked from the uptime interrupt handler performs alarm-specific actions, as well as controlling whether the alarm is rescheduled.
using nrfcxx::clock::alarm::callback_type = std::function<bool(alarm& alarm)> |
The signature of an alarm callback function.
In addition to performing other operations the callback may change the deadline() of the alarm and, through the return value, control whether the alarm is rescheduled. If interval() is not zero the deadline() when the callback is invoked is interval() ticks past the deadline that caused the callback to be invoked.
alarm | reference to the alarm associated with the callback. This may be cast to a subclass type to access callback/alarm-specific data. |
true
if the alarm should be rescheduled, otherwise false
.Constants identifying the alarm state.
Enumerator | |
---|---|
ST_unscheduled | Alarm has been constructed but has either not yet been scheduled or has completed. Transitions to ST_scheduled on a schedule() operation. |
ST_scheduled | Alarm is in the queue to execute at some point in the future. Transitions to ST_ready (asynchronously) or ST_cancelled (through cancel()). |
ST_ready | Alarm deadline has been reached and the callback will soon be invoked. If any alarm is in this state the uptime FLIH is executing. Transitions to ST_in_callback (asynchronously) or ST_cancelled (through cancel()). |
ST_in_callback | The callback is being invoked. If any alarm is in this state the uptime FLIH is executing. Transitions to ST_scheduled or ST_unscheduled based on callback_type return value. |
ST_cancelled | The alarm has been cancelled. No transitions unless schedule() is re-invoked. |
|
inline |
Standard alarm constructor.
callback | the function to be invoked when the alarm fires. |
interval | an interval that is added to the previous deadline() prior to invoking callback , to simplify rescheduling repeating alarms. The effect of #no_callback is to reschedule the alarm if and only if interval() is not zero. |
md | optional pointer stored as metadata. |
|
inline |
Overload for common case of configuring with static callback.
The alarm is configured without an initial interval.
callback | as usual |
md | as usual |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
|
inlineconstexpr |
Duration-specified alarm constructor.
as | with the standard construtor. |
interval | an interval specified as a C++ standard duration. |
md | optional pointer stored as metadata. |
|
inline |
Return true
if the alarm state is one of ST_scheduled, ST_ready, or ST_in_callback.
If false
the alarm must be scheduled.
state_type nrfcxx::clock::alarm::cancel | ( | ) |
Cancel a potentially-scheduled alarm.
If the alarm is found in the scheduled or ready queue its state() will be updated to ST_cancelled.
|
inlinestatic |
Factory producing an alarm with a callback that sets an event.
This is a fairly common need. While you can do this with:
alarm clock::alarm{[&events](auto&) { events.set(EVT); return true; }};
that's pretty verbose. Attempts to push the lambda construction down into a constructor end up pulling in malloc because the resulting object requires external storage either for the values it captures (reference to events, value of event, return value) or because it has to make copy of the function object rather than construct it in place (even if the constant values are captured in template constructor parameters).
The following has the same efficiency and is a little cleaner:
auto alarm = alarm::for_event<EVT, true>(events);
EVT | the event that is to be set. |
reschedule | the value to be returned from the synthesized alarm callback. |
events | reference to the event set to which EVT will be added when the alarm fires. |
void nrfcxx::clock::alarm::schedule | ( | ) |
Queue the alarm to execute at its current deadline().
|
inline |
Schedule an alarm using a std::chrono
duration.
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
void nrfcxx::clock::alarm::schedule_offset | ( | int | offset | ) |
Queue the alarm to execute at offset
ticks from the current time.
This atomically sets the deadline to the current time plus offset
and invokes schedule(). If the offset is negative the deadline will appear to be in the past and the alarm will fire immediately (possibly before this function returns, if interrupts are enabled).
offset | the time until the alarm should go off. |
|
inline |
Set the deadline for the alarm to fire.
This function is generally invoked only from within a callback_type, to change the deadline of an alarm that will be rescheduled.
It may also be used to set the deadline of an unscheduled alarm prior to invoking schedule(), as in the case where alarms do not automatically reschedule and the desired interval must be offset from the last deadline rather than the current time as with schedule_offset().
deadline | the counter value at which the alarm will fire, nominally when the low 32 bits of uptime::now() increment to deadline . Although this is an absolute value, the difference from the current time will be interpreted as signed value when schedule() is invoked (explicitly or implicitly). |
|
inline |
Set the interval() in uptime ticks.
void* const nrfcxx::clock::alarm::metadata |
Pointer to arbitrary data associated with the alarm.
This exists because in modern C++ you can't generally pull the trick of using offsetof(struct, field)
to derive a pointer to a structure from a pointer to a member of that structure. Such a cast is only allowed when the structure is a POD or has standard layout, which excludes anything that has non-static data members that are references. As callbacks are passed pointers to alarms, and the operation of the callback may require access to sibling members, casting this pointer instead provides a solution:
bool my_callback (clock::alarm& alarm) { auto self = static_cast<my_container*>(alarm.metadata); self->events.set(self.event); return false; }