Struct InterruptPoller

Source
pub struct InterruptPoller { /* private fields */ }
Expand description

A mechanism for synchronously managing and polling x86 interrupts.

Tock uses synchronous polling to service interrupts. This means that the kernel’s main loop will periodically call some function to detect and service interrupts. The reasoning for this approach (as opposed to doing work directly within ISRs) is so we can lean on Rust’s borrow checker to avoid race conditions.

The InterruptPoller type provides a somewhat higher-level API for working with x86 interrupts that fits well with Tock’s synchronous lifecycle. It is modeled after the Plic API from the e310x chip crate.

Internally, it maintains a large bitfield with a separate flag for every possible interrupt vector (total of NUM_VECTORS). When an interrupt occurs, a very lightweight ISR is responsible for setting the corresponding flag. To poll for pending interrupts from within the kernel loop, we simply need to iterate over this bitfield and return the index of each active bit.

Note that for reasons of safety, InterruptPoller is a singleton. You cannot create an instance directly. Instead, you must access the singleton instance using InterruptPoller::access.

Implementations§

Source§

impl InterruptPoller

Source

pub fn access<F, R>(f: F) -> R
where F: FnOnce(&InterruptPoller) -> R,

Provides safe access to the singleton instance of InterruptPoller.

The given closure f is executed with interrupts disabled (using support::atomic) and passed a reference to the singleton.

Source

pub unsafe fn set_pending(num: u32)

Marks that the specified interrupt as pending.

§Safety

Interrupts must be disabled when this function is called. This function is intended to be called from within an ISR, so hopefully this is already true.

Source

pub fn next_pending(&self) -> Option<u32>

Polls for the next pending interrupt.

If multiple interrupts are currently pending, then the highest priority (i.e. numerically lowest) is returned.

Once handled, interrupts should call clear_pending to clear the interrupt’s pending status so that lower-priority interrupts can be serviced.

Source

pub fn clear_pending(&self, num: u32)

Clears the pending status of the specified interrupt, allowing lower priority interrupts to be serviced.

Don’t forget to call this method after servicing an interrupt.

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.