pub struct IsrReactor<const N: usize> { /* private fields */ }
Expand description

IsrReactor is a utility allowing Waker instances to be awoken fron an ISR context.

General problem: In an interrupt, using Waker instances coming from generic executors is impossible, because these are not designed with an ISR-safety in mind.

Waking a waker means that its task would be scheduled on the executor queue, which might involve allocation, and/or synchronization primitives which are not safe to use from an ISR context.

Similarly, dropping a waker might also drop the executor task, resulting in a deallocation, which is also not safe in an ISR context.

These problems are alleviated by replacing direct waker.wake() calls to WakerRunner::schedule(waker). What IsrReactor::schedule does is to push the waker into a bounded queue and then notify a hidden FreeRTOS task. Once the FreeRTOS task gets awoken, it wakes all wakers scheduled on the bounded queue and empties the queue.

Implementations§

source§

impl<const N: usize> IsrReactor<N>

source

pub const fn new(config: IsrReactorConfig) -> Self

Create a new IsrReactor instance.

source

pub fn is_started(&self) -> bool

Returns true if the wake runner is started.

source

pub fn start(&'static self) -> Result<bool, EspError>

Starts the wake runner. Returns false if it had been already started.

source

pub fn stop(&self) -> bool

Stops the wake runner. Returns false if it had been already stopped.

source

pub fn schedule(&self, waker: Waker)

Schedules a waker to be awoken by the hidden FreeRTOS task running in the background. If not called from within an ISR context, calls waker.wake() directly instead of scheduling the waker. NOTE: If the wake runner is not started yet, scheduling fron an ISR content would fail silently.

This and only this method is safe to call from an ISR context.

Trait Implementations§

source§

impl<const N: usize> Drop for IsrReactor<N>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<const N: usize> Send for IsrReactor<N>

source§

impl<const N: usize> Sync for IsrReactor<N>

Auto Trait Implementations§

§

impl<const N: usize> !RefUnwindSafe for IsrReactor<N>

§

impl<const N: usize> Unpin for IsrReactor<N>

§

impl<const N: usize> UnwindSafe for IsrReactor<N>

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.